 I hope I won't bore you to death now. So please be awake. So first I wanted to say hi in all the languages of Singapore. I think I missed a four language, or how many languages are in Singapore? Four. So I pretty missed one, right? You missed Malay. I missed Malay, I'm sorry. So Ni Hao is in Chinese, right? And I in English. So my name is Lorenz. I'm the founder of Ibuy, the company that makes Ruby Motion. I'm also the author of Ruby Motion. I was the original author. And now I actually work with smarter people than me to help me finish it. I'm a long-time Ruby programmer. I discovered Ruby when I was a student at university in 2001. Because I needed a better pair. I discovered that I couldn't maintain a power code I wrote last week. But I never actually used Ruby on race. That's pretty unique, I guess, in this community. I never did any web programming. And before doing Ruby Motion, I worked for Apple for close to seven years on a lot of things, from a high-life application to OS 10. I also maintained a Ruby distribution of OS 10 from Loper to Mountain Lion. And I'm on Twitter, where I only post. I try to make pants as good as tenderloaf, but they are not as good. Anyway, so I'm from Belgium. It rains all the time in Belgium, close to 300 days a year. When I don't do Ruby Motion, I try to maintain the Ruby user group in my hometown. It's called Ruby Boulet. Boulet is French for huge meatballs, which are the main dish of the city. So if you guys ever come to Belgium, Belgium is a very small country. And you want to try this specialty of our hometown, please let me know, and I will set something up. I'm also the founder of Orval.club, an association of people who strongly believe that Orval is the best beer of the world. I actually created this club last week, so it's relatively new. So this is a picture of the beer. It is the best beer of the world, believe me. And I made a website. I'm really not a web programmer, as you can see. So I wrote it in pure HTML, because I was told that this day you have to go native, right? So it's pure HTML, and we have six members now. So if there are overall overs in that room, if you want to join the club, it's free. But you need to show a proof of face. So you need to be initiated by a member. Anyway, I'm the agenda for today. We talk a little bit about the state of native mobile development. I will describe a little bit what remote motion is, for those who don't know. And I will show a couple of remote motion gems that are very interesting. And finally, we'll do some future stuff. That's a secret. Hopefully, if I have time. So the state of mobile development. Right now, as you know, there are two major mobile platforms, which is IS and Android. This is what they look like in the latest versions. ISA.something and Android 5.2, I think. So how many IS users are here? Can you raise your hand? That's not that much, actually. And Android. There are more Android users, I think. So the guys who use Android, can you raise your hand if you enjoy the experience? Yeah. So it's still good, right? OK. So I'm not a business person, but I took this number off from the internet, the smart for market. Basically, the share in unit shipments. And Android was winning the last three years. But this year, it's actually reducing. The market share is reducing slightly. And IS is getting more market share this year. But clearly, Android has more units than IS. And it pretty depends on the country. But if you do a mobile app these days, you can't just do IS only anymore. You have to do Android now. So it's not like you're possible to do to go IS only. And you need to go cross-platform. And the best way, also, is to go native, to write native apps for each platform. There are many tool chains around that will promise you that you can write one code base, and it works on all the platforms. And they are very nice in theory. But in practice, you will run into a lot of problems. You will have performance issues. You will not be able to code the entire set of APIs of each platform. You have user experience problems. And eventually, you have to write native code. There was this blog post that was published, I think, two weeks ago that really resumed well the situation of web technologies to do mobile development these days. And the guy is a web developer. So he actually tried to cititize all the problems of what that are happening right now. So I recommend to read it. It's called Web vs. Native. Let's concede defeat. So it's very pessimist title, but it's very interesting. And native apps provide the best user experience at the end because you really write an application for the entire features of the platform. And it turns out that consumers, they also want the best user experience. So if you do consumer app, you pretty have to go native. And as my personal hero say, no pain, no gain, right? So doing native development is much harder than writing an application once in JavaScript and running everywhere. But at the end, you have something very nice. So let's talk a little bit about the architecture of the mobile platforms. If you look at iOS, iOS is mainly split in four layers. You have CoreS, CoreServices, Media, and CocoaTouch. CoreS is mostly the low-level layer of iOS. So it has the kernel, it has the BSD unique layer, and also the user-run libraries. So you normally never use these when you write an app for iOS unless you do low-level programming. But CoreServices include the foundation libraries, the powers in the entire set of APIs. Like you will find the foundation framework there. Foundation defines the built-in classes. Like you have the NS object class, which is the base class of everything else. You will find NS string, NS array. So all the built-in types. You will also find networking APIs for data, which is a persistence library. I assume it's like active record, but for iOS. But since I don't know race, I'm not sure. You also have call location. If you work for a secret agency, you probably want to use that to track your users. The media layer has everything, graphics, audio, and video. And in the graphics side, you obviously have UIQ. UIQ is the biggest framework. It has all the controls, classes. Like, for instance, a button is going to be defined there. And finally, you have the coca-touch layer, which has additional frameworks that you can use on top of your app. For instance, if you want to access the address book, you have an API for that. If you want to access the game board, the game center API, or something, if you want to have maps in your app, you have mapped it. Anyway, you will pretty have to use the three last layers. And all the APIs are either in pure C or in Objective C. So these are the two languages that Apple use. And it's mostly Objective C. It's very 90%, 95% Objective C. So you have to use at least a language that lets you call into Objective C. If you want to use all these APIs, and you have to use Xcode. Xcode is the ID, the default ID of Apple. And if you want to do Objective C, you're pretty much stuck to Xcode. You can use other IDE. But if you want to do the Apple way, you need to use that. So it's a new program. You need to learn how to use it. When it comes to Android, Android also has four layers, more or less. You have Linux, the core libraries, the GDK, and the application frameworks. And Linux is mostly drivers and stuff you will never need to write an app. Core libraries are C-based libraries. For instance, OpenGL, SQLite, WebKit, all the libraries that are actually used to implement Android. So you will probably never use them as well. There are pre-Java APIs built on top of that. So the GDK is the base of Android, is the implementation of the Java language. So you will find them there, the string class, the arrays, all the integers, classes. And finally, you have the blue layer. The application framework is the stuff that Google wrote for Android. So you will have all the widgets and everything that lets you write an Android app. So you have to use the last two layers if you want to write an application for Android. And it's all Java. Java is the only language. So you need to call into Java APIs. And you need to use another IDE, obviously. So Google used to have Eclipse. They used to force people to use Eclipse. And people were suffering because Eclipse is a very bad program, so they switched to something else, Android Studio. Android Studio is based on JetBrains IntelliJ, so it's much, much better. But it's still an IDE, so you need to learn how to use it. Eventually, if you do native development for the two platforms, you need to use either Objective-C or Swift in the iOS part, or Java in the Android part. You need to use Xcode on the iOS part, or Android Studio in the Android part. And you need to call the iOS SDK APIs in the iOS part and the Android SDK APIs in the Android part. So can you see the problem here? You're actually juggling between two different set of languages, two different set of IDEs, and two different set of APIs. So if you need to write an application across platform app, it's going to be a problem. So can we make this simpler? And obviously, yes, with RubyMotion, right? Yeah. So RubyMotion is basically a tool chain to write native mobile apps in Ruby. And I underline native here because it's really native. It's important, really native. It's cross-platform, so it does iOS and Android, and also OS then. You can write OS then apps in RubyMotion, but people don't really care much. But you can write OS then apps. It's designed for Ruby programmers. So it's really designed for Ruby programmers. So I will explain a little bit later how RubyMotion is being used to create projects. But basically, if you are a programmer, if you use the Ruby ecosystem, you should be at home. And the main goal is to provide a consistent experience for cross-platform native development. So let's go back to the table here. With RubyMotion, we basically replace the two languages by Ruby. And so you can use Ruby on both platforms. You don't have to use Objective-C, Swift, and Java. And we replace all the IDEs by the editor you already use. It can be anything. And the terminal, which is something you already know as a Ruby programmer. So as we can see, you still need to learn the iOS SDK APIs and the Android SDK APIs. So RubyMotion will not make you a mobile developer right away if you're not Ruby. You still need to learn something. So there is a learning curve, but it's still easier than having to mix languages and having to mix IDEs. And since you use the same language on both platforms, we can no share command code on projects. So a few slides about RubyMotion as a company. It's actually a company. So it's commercial and proprietary. It's not free and open source. So because we want to support it for the long term, so the best way we found is to actually ask money for it. If you want to find this picture, you can go go for Angry Richard Stallman, which I did. Richard Stallman is not happy. It's 100% bootstrap. So we never took funding. We're only funded by our customers. It's profitable since day one. Yeah, funded by our customers. So the customers are actually our investors. They invest in the product directly. We have thousands of them, actually tens of thousands now. If you go to remotion.com, you will find a list of customers and success stories. But my favorite is a dark room. Does anyone know here dark for dark room? Can you raise your hand if you play the game? Some of you. So everyone else should actually buy the game. It was rated by a guy called Amir Rajan who's actually a C-sharp developer. He actually learned Ruby for RubyMotion because he didn't want to use C-sharp to write games. And it's an adventure game. It's a text-based. It's an iOS. It's extremely popular. Last year it was the number one top paid app in the US app store above everything else. So it's very, very popular. And it's 12,000 lines of Ruby. There is pretty a few thousand lines for the engine. Everything else is a DSL that Amir created for the game. So, and Amir said in the interview that he used RubyMotion because Ruby is nice to write domain-specific languages and abstractions. So he really wanted to create the whole story as code. And if you want to know more, you can go get up for a press coverage. Here's a nice article on the New Yorker. So if you want to support indie game developers, it's great. The timeline of RubyMotion, we launched in 2012 with iOS support. In 2013 we did OS 10 support. Last year we did Android. And this year we do other things. Not only one thing that I would like to show you at the end of the presentation, but I'm afraid that RubyMotion is no longer hype. It's no longer a hyped technology. And the best metric is the number of Acre news, front page articles, which is down to zero for this year. And our revenue is relatively growing. So I just wanted to show you that we are not falling apart, but we no longer get on the front page of Acre news. So it means that we are basically boring, right? So RubyMotion is no boring product. But boring means stable, right? Anyway. Yeah. Actually, I watched, sometimes people post something on Acre news, it goes to the front page and it gets killed immediately. People really hate it there. So anyway. So let's talk a little bit about RubyMotion internally. And a very important principle are the unified Ruby runtime approach that we decide to go with the motion. So basically, we provide custom implementations of the Ruby language for each platform we support. So we have an implementation for IS and implementation for Android. So it's a lot of work because we have basically to rewrite a Ruby runtime every time. But at the end, it has a lot of benefits. For IS, we decided to rewrite Ruby on top of the same runtime that powers the Object EC language. So this runtime is called the Object EC runtime. It's a small C library that Object EC programs use at runtime to create classes, methods, and some objects. And we decided to rewrite the Ruby object model on top of the same runtime. And this runtime obviously powers all the APIs of iOS. For Android, we decided to do something very similar. We rewrote the Ruby object model and all the Ruby runtime on top of GNI, which is a C API that's exposed by the Java machine. And so we are at the same level as Java. And since all the APIs are written in Java in Android, we basically see the top of the same layer. So it's another implementation of Ruby. So the approach is very important because since we implement the Ruby object model on top of the native platform runtime every time, it means that all the classes in Ruby version for iOS are actually Object EC classes. All the methods are Object EC methods. All the objects are Object EC objects. And this versa. All the classes defined by Apple in Object EC are automatically available in Ruby as if they were Ruby classes. And actually there is no distinction between the Ruby class and the Object EC class. They're all the same. And the same thing goes for Android. Everything is Java from classes, methods, and objects. So we are doing this because we don't need to, we don't have to ship a separate runtime that talks to the Java or the Object EC runtime. There won't be any conversion of objects. There won't be exchange or messages. There won't be, they basically won't be anything. There won't be any bridge. So the Ruby code that you write is going to access the exact same runtime as the Java or the Object EC code. That is, so it's extremely performant. At the same time, we also re-implemented the Ruby built-in types on top of the native counterparts. The Ruby built-in types include the string class or the array class or the hash class. The idea behind it is that if we, if we don't have our whole implementation, if we actually use the implementation of the platform, if you call a native API that expects a string, for instance, and you can pass any string, it won't have to be converted to a native string. If all strings are native, then we don't need to convert objects. So for iOS, for instance, string is actually based on NSMittableString, which is a mutable version of NSString defined by Apple in the Foundation Frameworks. So all strings are actually NSMittableStrings in RubyMotion. The same thing goes for array, hash, fix them. And for Android, we do something extremely similar. A string in Android is actually a class that implements the Java line car sequence protocol because we can't use Java line string directly because it's, first, it's immutable and second, it cannot be subclassed. But we do something very similar. And then, for instance, an array is always Java utility arrays, which is the closest thing as an array in Java. So all the building basic types in RubyMotion for Android are actually going to be GDK objects. So by doing this, we get to call the entire set of APIs for each platform and all the types are also native. So for instance, this is a hello world for iOS. So it's a little bit verbose, but this is how iOS is working. You start by creating an application delegate, which will be the delegate of the NSApplication object. And then you need to override the application, the finish, launching, resubption method. Here we extended the Ruby syntax a little bit so that you can define small talk selectors from Ruby. And from there, this is the entry point of your app. And then you can create a UI label, assign it to something. You can create a view controller, put the label in the view controller, and then create a window. Put the view controller in the window and then show the window. So this is extremely verbose, but this is hello world in Objective-C. And the thing is, this is a one by line mapping with Objective-C. If you write the same thing in Objective-C or Swift, it's going to be the exact same code, more or less. So you really get to call all the APIs of the platform. There is no abstractions, there is no magic here. UI screen is a class defined in Objective-C, UI, window. All the methods that you see there are actually Objective-C methods. That you get to call them from Ruby. And if you type rake, you will get this in the simulator, hello world. The exact same app that you would get if you write it in Objective-C and run, click on run in Xcode. For Android, this is hello world in Android. It's much simpler, in my opinion. To create an app in Android, you need to have an activity. You need to subclass at least an activity, which is the main one. And then you can overload the onCreate method. There, you must call super as the first expression. And then we can create a text view, assign it to a text, and then set the content view of our activity to our text view. Again, this is all, if you had to do it in Java, it would be the exact same thing more or less. But here, we do it in Ruby. There is no magic, there are no abstractions. These are direct APIs, direct classes defined in Java. If you type REC, you get this in the emulator. Exactly as if it was written in Java. So with this approach, you can call the entire set of APIs at no performance cost, because we don't breach an existing runtime, we actually use the same runtime to implement the object model. And the building types also don't have to be exchanged. So all the strings are in the strings or Java line strings. And also, with this approach, we can support the new versions of IS and Android automatically. So when Apple releases a new version of IS or Google releases a new version of Android, we support it right away. We don't have to create wrappers because it's all dynamic. As an example, last week, Google releases Android M as a preview, and we support it in less than eight hours. We had to generate files for the compiler and then make a release for customers, but we support all the new versions right away. But another example is static compilation. It's different from other release. Remote motion apps are not interpreted. And in fact, there is no interpreter in remote motion apps. So if you try to call the eval method with a string, it will raise an exception. So everything is statically compiled into machine code. And with our different architectures, we mostly target ARM for devices and Intel for emulators or simulators. And we target 32-bit and 64-bit variants. And the compilation process is not very hard, but it's very, very different from other rubies. So we start with the Ruby file and we use the LVM compiler framework to generate intermediate representation and we apply optimization passes. And finally, we generate assembly and then we create a binary, a self-contained binary. So remote motion apps are actually native binaries. And for iOS, you will find a native executable. And for Android, you will find a GNI share library inside the application package. And the original Ruby source code is not present in the application. So you won't find .rb files in the application. They are all compiled. So the command line interface is everything is driven by the command line. We use rake files, rake as the build system and rake file as the entire project configuration file. So if you need to modify something, it has to be in the rake file. So you don't need to go into an Xcode project or an Android Studio project. And it has a bunch of tasks that you can do that. So it's the terminal and then your favorite editor. And there are plugins for most editors. Obviously, you should be using Vim, but you can use other editors if you want. Actually, one of them is RubyMind. RubyMind supports Android natively. So it has auto-completion of APIs, integration with the debugging. So it's pretty nice. Creating a new project from the command line is easy. Motion, create, you specify your template and boom. Your project is created. You can go there. If you look at the rake file with VI, of course, you will see that it's only three lines. The default rake file just sets the name of the application. Everything else is generated for you dynamically. So if you want to set the deployment target, for instance, you would do app.deploymenttarget equals something. So that's pretty nice. The configuration is already. So as I was saying, everything is in the rake file. And if you want to run the application locally, you can use the default rake task on both platforms. For iOS, you can use rake simulator, which is the default one. And as soon as you type rake simulator, it will build the app and then run it in the simulator. And then you will have an IRB prompt interactive Ruby shell. There, you can type expressions and they will be executed on the simulator. For Android, it is the exact same thing. Type rake and then you can type expressions there. To run apps on the device, you can just type rake device. It will push the application on your device, iOS or Android, and it will run it. And for Android, we attach the dynamic, the interactive Ruby prompt as well. So it's all rake commands, right? There's no magic there. And once you're ready to make money, you can type rake archive distribution for iOS. It will generate an IPA file for you and you can send this IPA file to Apple to upload it to the app store. For Android, you type rake release and you will get an APK file. You obviously need to do some configuration before you need to generate a provisioning profile, your code certificate for iOS. For Android, you need to create a key chain from Google. You can request it, it's free. But eventually, once you do that, you just generate packages. And these packages are the same packages that you would generate from Objective-C, Swift or Java. So let's go back to our table here. So with Ruby has the same language and your editor and the terminal has the main environment. But you still need to learn the IS SDK APIs and the Android SDK APIs, right? So there is definitely a learning curve but it makes RubyMotion developers true native mobile developers. So if you do mobile development with RubyMotion, you're actually using the same APIs of an Objective-C programmer or a Java programmer. But there is definitely a learning curve. It's very hard. It takes time to master both APIs. So can we make this even simpler? And the answer is yes, of course. Now that we support both platforms, there are cross-platform gems available. Basically, a piece of Ruby code that works on both platforms that you can use. And these are just one API that works on both platforms. So this really makes things easier. So for iOS, there is a project called Red Potion and for Android, there is a project called Blue Potion. So people say that it's the race of RubyMotion but since I don't know race, I have no idea if it's true. So these are RubyMotion potions. So it's basically an environment package for RubyMotion development. So these are project templates and then a set of portable gems that works on iOS and Android. So for iOS, it's Red Potion. For Android, it's Blue Potion. These are written and maintained by the community so I have no idea what they are doing. But it's used in production. Actually, there are many, many apps using this in production. So I assume it's stable, right? This is how you create a project with a Red Potion. So they have their own command line, Potion Create. I don't know why actually I should ask them. And then you can just go to the directory. You can do Potion Create Screen which would probably create a screen file. Then you can just bundle and rake and it will run the application, right? Here is a piece of code that they actually sent me today this morning so that I can include in the presentation. Can you guys read the code, right? So these are two files. The first file defines a new PM screen that has an action bar, a title, and a style sheet. And then on the onload, onload is a callback. We'll define a button that is using the click me button style. And then on the button we provide the handler that will open another screen, right? And on the right side of the screen you have the definition for a style sheet which basically provides the user the look and feel of our button. The click me button is defined there as you can see. So they decided to go with a, like in HTML and CSS I guess to have presentation separate from content. So you basically define a style sheet, objects, and screen objects. So this is a piece of code and then it generates applications for both IS and Android and they are exactly the same. So you have two buttons, click me, you have the title bar. So these three reduce, this makes remote cross-platform work much, much easier. So obviously this is just an example, right? If you make apps, the interfaces would be very different from IS to Android. For IS you really want to follow what Apple does with its own apps which right now are animations and transparency. And for Android you want to follow the design language from Google and it's relatively stable these days. But still it's kind of nice to be able to actually share the same, really the same DSL on both platforms. And they have another very cool feature which is live reloading. If you start changing your screen files, it will reload the application in the simulator. So here I think it's basically changing stuff in the file. As you can see on the right, there is the IS simulator and the application is automatically reloading. So they actually wrote a piece of code that watches all the RB files of the project. Then they do a diff and then they just inject it into the ripple. So the code will be reevaluated and I guess they have some dark magic to the IS to reload the classes and the controllers. But this is called reloading. So there is more information on redpushion.org if you want to use that. And now let's talk about future stuff. I think I have some time. And the future stuff are video games. I really want to be motioned to be used to write cross-platform mobile games in Ruby. So this is the next thing I want to do. And I will do a demo. I will write this program. I will write this program in front of you. So it's gonna be interesting. So we try to do it as fast as possible. Okay, so this is my terminal simulator here. And so I have, so for that, we are using a new product that I've been working on that will ship inside RubyMotion this year. It's called motion game. I will talk about it later. But basically we have this game scene file that's relatively empty. And I'm going to write a Flappy Bird in front of you in 100 lines of code. So very small, right? So I'm actually going to load it in my game. What's happening here? Edit anyway. Okay, I'm going to cheat because I'm not going to type the code. I'm going to use a program that I wrote to copy, paste stuff. Because I know if I type, it's going to take long and I'm going to introduce typos. So first let's initialize some backgrounds. Boom. So we create an array, right? You get it, right? Oh, I forgot to mention. So this is a game scene. So we subclass an MC. And the update method here will be called for every frame. So by default it's 60 times a second. So let's add my skyline. So that's a method. So actually let me define this here, okay? So I define a hot skyline method that basically create two sprites, skyline.png. I create it twice. And I store the sprite in my background array. Why do I create two skyline sprites? I will tell you that right after. There is a reason for that. Important reason. Now let's define my ground method there. So this is the same thing, right? I generate two sprites, ground.png. Again you might ask why is it creating two sprites? It should create only one. I will tell you that later. Now in my update method I can copy paste this code. And this is why it's important. So if you ever play a flappy bird, you can see that the skyline and the ground are actually moving. There is an illusion that you are actually flying over a city, right? So here I create two separate sprites for each background object and I move them like this. And when the first one is hidden, I put it there. You see? So this is the best way I could find. I know nothing about video game programming, so. But I think it's pretty smart. I was very happy with the result. So I have this and now I can, oh here I'm going to add skyline and add ground. Okay. Now if I type break, oh, no internet. I have my skyline that's moving and my ground that's moving, right? So that's the very basic of the game. Now I can just quit here. What the hell is that, STT? Okay. So let's do something else. Let's add the bird, yeah. Now we are going to add our bird object. So I have my bird here and it's a sprite that we position relatively at the center of the screen and then we have this animate method that we start an animation, the sprite. So you can pass as many files as you want and here we have basically three images for sprite, for bird and we tell the game engine to each 0.5 second to switch to the other sprite. So there's going to be an animation here and we tell the game engine to animate forever. So now if I call add bird, add bird here, like I type break, as you can see each time it's compiling really fine into machine code. So now I have my bird here, oops, let me turn off wifi. So the bird is there and it's animating, right? And from the ripple here, I can actually access my bird. My bird is there, it's a sprite. And you can do actions like let's ask for the position of the bird. It's 100 to something, so I can say move to this position in two seconds. It's going to take two seconds and move to this position, right? And we're back here. Move back here as fast as possible, okay. And you can also make it blink. So there's a blink method, that's a blink three times in 0.5 seconds. So that's useful if your object is colliding with something like in all video games, retro game, you're blinking the sprite. So my bird is there. So let's do some physics. So we have to do some science here. Physics categories first. So the game engine has a physics engine, of course. And first we need to define categories. So I'm going to define two categories. These are actually a bit set. There is a bird and a war category. So here we assume that the bird is its own physics engine, physics type, and everything else is the world. So as soon as the bird contacts with the world, the game is over. So we start with something very simple. So we need to initialize gravity in our scene. So right there I can copy-paste this. And I basically set the gravity to zero and something. I don't know the units there, but it's minus means it's going down. If you do a positive fix, the bird is going up. So I put my gravity there and then I will attach physics properties to the ground. So right there I can copy-paste this. So I will basically say that the ground I know has a physics box. And its category is the world, but it has to contact the bird. And here I will do the same thing for my bird. So the category of the bird is the bird and the contact is the world. Not that I did that. I can actually start the game again. Should make it a default task. So you can see the bird automatically falls, right? So the bird is attracted to the ground. My bird is there. If I change the gravity to zero, something positive, the bird will fall, right? And I can put it back to something and it should fall down. Where's my, oh, here we go, right? So that's basically physics. And as you can see, the bird actually goes on the floor and then doesn't go further down. It's because the floor has actually its own physics category. So my bird is there. No, we're almost done, right? So be patient. Right there, we define an untouched under block. So when the game engine receives a touch event, it's going to call my block. And here I will play some audio file and then I will apply a velocity on my bird. I'll apply a velocity of zero, 200. Zero is x, 200 is y. So basically, the bird will move 200 units in the y position here. So if I type break, I assume it again. I put some sound here. Oh, you can see. I'm actually typing on my touchpad here. So if I type, the bird is going up, right? No, let's finish the game quickly because I'm running out of time. So in my update method here, I want to rotate the bird based on its position. So if the bird is actually going up, I want to rotate the bird this way. And if it's falling down, I want to rotate the bird this way. We're going to initialize. No, we're going to make the pipes appear. So let's go there and let's initialize some variables here and then here I'm going to create my add pipe method. So this method creates pipes. So Flappy Bird is the game where you have a bird and you have pipes appearing. And for each pipe, you basically have two sprites. You have the hub and the bottom part of the pipe. And obviously, since you want the game fun, you want to use some random, you want some randomization here. So we basically generate our pipes and randomly so that the bird has to actually go inside. And the pipe is simple here with, again, a category here. So the pipe is the physics category word and you can contact the bird. And the difference is that as soon as we add a pipe, we actually say the pipe moved by something very left. So as soon as you add the pipe, the pipe is going to move on the left bottom of the screen. So it will be up to the bird to actually figure out a way to not hit the pipe, right? So I do that and now I need to make the pipe appear. So in my update method, I can do that here. I can make a pipe appear every two seconds. So how do I know exactly if we pass two seconds? The argument of our update method is the delta, the number of seconds is the previous frame. So I can just add this into this variable and if it's over two, I know that we actually spend two seconds. So I can just call the add pipe appear and then reset the timer. And finally here, I can detect collisions. So there is an handler here on contact begin. And if the physics engine detects a collision, it will yield this block and then we play another file and we print some message on the terminal. So obviously here, as a real game, you want to show a game over screen, but if I type, break, I guess simulator and my game is here. And the pipe are appearing. So this is working. And if I hit the pipe, this is it. Game over, right? And now I lost, right? So my bird is there. I can put it back actually, but I need to be very, very quickly. Where's my bird? Anyway. Yeah, video game programming is hard, right? So this is a Flappy Bird in Ruby Motion Game and it's 113 lines. And with actually commands. So if you remove the commands because commands are useless, it gets to 100 lines. So let's go back to the slides. Okay, so motion game. You write mobile games in Ruby with Ruby Motion and this one is 100 cross-platform. So I didn't show it, but the same code base runs on Android. So iOS and Android, very nice. So it's fully feature is as a bunch of stuff that I have no idea about, like the scene graph, 2D sprites, actions, events, sensors, physics, particles, that work in APIs. So it's pretty nice. And it's based on well-tested open source component because we are extremely lazy. We are using other people's work for that. And it's going to be released later this year. So the idea is to actually allow Ruby programmers to write very nice mobile games but to write them in Ruby. So conclusion, we motionless to write mobile apps and games very soon. True native apps actually, real native apps. So remember there is a learning curve but no pain, no gain, right? You can use all the platform APIs at no performance expense. It's satirically compiled into machine code so there is no interpreter. You share a command code because it's the same language. There are cross-platform gems, red potion and blue potion. It's only one language, Ruby, and one interface, your favorite editor, and you do the terminal. And just one more thing. We do an annual conference every year. This year it's going to be in Paris first and second of July. Conference at rubyemotion.com. This is a picture of Paris, nice. The conference will actually be in this building not in the Eiffel Tower, but it's nice. And again, conference at rubyemotion.com. Thank you. Thank you so much. That was so cool. We've had a lot of demonstrations today so far. I hope you've enjoyed that as much as I do. We have time for maybe one or two quick questions if you have any for Lawrence. What is your experience in debugging Ruby motion code? Yeah, so the Ruby motion compiler actually generates dwarf metadata and attaches it to the binary. So you can actually connect any debugger like GDB or LLDB in a Ruby motion program and you can set broke points, see back traces, these kind of things. It's all working automatically. You can also connect any profiler like instruments and you will see the back trace of allocations. We really support this metadata dwarf so it's a big deal. When it comes to real debugging, if you want a point and click experience, RubyMind is really the best. RubyMind integrates with LLDB so that you can point and click lines in your projects and it will break right away. So if you're not comfortable with GDB or LLDB, you can use RubyMind. But otherwise, that's more as a debugging story here. So we support C-level debuggers and also abstractions. Thank you. Do we have any other questions? If not, maybe you can find Lawrence afterwards during one of the breaks. Thank you so much. Let's give him another round and invite our next speaker.