 All right, let's get started So today we're gonna talk about two-day video game with Mac Ruby on the OS 10 But before we get started, I have a few questions for you just so I can know you better So I like to know who does Ruby for a living Okay, so who does not do Ruby for a living? All right, so what do you what do you do? Python for living good Who does Ruby but not rails for living? Now so we have a few people Pretty cool Who does Ruby have to work or just for fun? Okay, most people that's pretty good Who owns a Mac? Okay, who doesn't own a Mac? Okay, so a few people that's cool Who knows Coco already and uses it from time to time? All right, not too many That's actually pretty good because when I started this project, I didn't know much about Coco so it's pretty good All right before we start I want to test your memory I want to see what you know about video games So I'm gonna show you some video games and I want to hear the name of the game and then we're gonna move on really quickly So this one Bong everybody knows it this one Asteroid this one This one Many I mentioned very good Donkey Kong This one digger This one what different names there were a lot of tons. So that's right This is when I played a lot, but I don't know if you guys knew it. So I like that So that's I love this one Dark hands. All right Here easy Topper this was pretty good Ah Prince of Persia Nobody knows this one Rick dangerous. I heard it over there. Very good California games very good This one I heard it over there. Very good legend of Korea. Yeah, very good City F zero Double Dragon All right, so everybody knows his video games I think we all spent a lot of time playing video games video games are fun Especially all these I think we all spent a lot of time playing video games But we also spent a lot of time writing Ruby and Ruby is also a lot of fun And as we saw most of you guys have a Mac and the few who did not well that might want to Consider getting one pretty soon Anyway, this talk is about a video game and we're talking about all school video games from scratch We're not talking about using any type of fancy libraries with Physics and all the stuff you can also do that But for this talk what I wanted to do is spend a couple of hours and just write a simple code a simple game That's fun to play So the truth about this talk is that your game at the end of the day probably won't be legendary It won't be a super game that everybody's gonna play and he won't make you really rich like mr. Burns The truth is you're just gonna be the same geek. You've always been and a really nice guy but Hopefully it's gonna feed you curiosity. You're gonna learn a lot of cool stuff and you're gonna provide hours of fun for other people So let's quickly look at the very popular games what what people are playing nowadays A lot of people play MMORPGs. So we're talking about games like Second life world of Warcraft Eve online a lot of really cool games But the problem is that it takes too much time to actually code something like that for fun You need a team of people working on that Then you have another type of games which are the first-person shooters Games like aflife. Hello three far cry These are cool games. You can actually do them pretty easily if you want something very simple a good example Would be Rubinstein that were that was written by the Fusion guys they used a library called go-sue and It's it's cool But what I wanted to do was actually do something even simpler than that So I looked at different type of games new stuff that appeared in the last few years We saw a lot of we games and that's pretty cool because you just interact with the hardware And now with Mac Ruby we can actually do that very easily because you just you just reuse the device You have on your console or whatever you use and just connect it to the computer. So you have all this cool game We could write Then you also have a lot of online games I know my wife plays a lot this kind of game She has on Facebook and you know different stuff and we have them also on the iPhone and a lot of very tiny games Where you find the fun you used to have when you were a kid You also have the iPhone games. I'm sure a lot of you guys played this game Do you guys know the name of this game fly control? I we spent way too much time playing this game other games like tap tap and Basically, these are very simple games and what's important is just the idea behind the game The way you do the game is not very simple if you look at I fly control. It's actually a very very simple game But it's an awesome game anyways What I did was actually I wrote a code I wrote a small example and I want to show you the game before we actually look at how to write the code So I'm actually gonna demo the game So I'm opening Xcode. I wrote it in Xcode, but You don't actually have to it's just easier. So I'm just gonna build a game live for you So it's a very simple game you can switch full screen So it will scale up and down And For that I just used some vectors all the design was done by Stephanie. Stephanie. Can you can you just stand up? So Stephanie actually helped me So I just wanted to write this demo for the demo was just written for this talk and Stephanie was really nice She did a lot of design stuff. She even did the music. I think we're gonna hear the music So anyway, I'm gonna put it full screen Play the game. The concept of the game is very simple You you have to grab the rubies to go to the next level and you need to avoid the bombs So I made it really easy for the demo because I'm not that good So as you can see we're switching levels and you can pause the game So and then when you die actually give myself a lot of lives there you go you have a game over So The game is is very simple If you look actually at the CPU performance is really good right now. We're actually using only 3% of my CPU And when you play it doesn't go much higher. We're like in the 10 15 percent. So it's it's very optimized The screen. Yeah, I actually messed up. I see with the resolution of the The video projector, but anyway, that's that's the game. It's very simple and I will show you how it was written So let me just go back to the presentation All right, so it was written with Mac Ruby Mac Ruby is not Ruby for Scottish people. It was actually written by a Belgium guy So now I have to say Lauren can you just stand up so people can actually see you No, he's over there It doesn't quite look like that, but I never saw him in his postures. Anyway It was written also by a lot of other people working for this guy the man that's Apple and so Apple is actually Leading the project Mac Ruby is an open source project and it's basically a Ruby implementation on top of the objective See runtime and garbage collector The major the major advantage for us today this morning is that now you don't have a bridge You can actually access Coco directly and Coco is a suite of frameworks or libraries that you have to write Any type of applications and for this video game I actually kind of hacked Coco because in Coco when you want to write video games You were probably gonna use open GL and some really low-level See APIs, but in this case what I did is I use core animation which is meant for Desktop application when you do simple animation when you have like the scroll bar moving or the the menu bar moving up and down And I basically use that to create the game So the way it works is with snow leopard. They actually Built a core animation on top of open GL and they use a GCD which is the grand central dispatchers So the way it works is they handle all the threads for you And you have a poor threads and the system handles all of that So I did a lot of tests and it turns out that it was fast enough for simple game like mine And it's much much easier because we end up doing something like flash where you have layers and on the layers You just move the layers with the object So it's actually much much easier than having to deal with the sprites and all this stuff So anyway, let's talk about how you write a video game a video game Is a bit different than an application what we have is we have a user in this case Patrick and Patrick is gonna use his keyboard and it's gonna press the buttons And it's gonna send a key event and the key event is gonna get stored in memory. I Will explain it on why we do that So it goes into the memory, which is a game data that would say the user pressed a button and then we have a Game loop so a game loop is something that's gonna run in our case 30 times a second And we will do a lot of things the first thing is it will go and Find all the layers that were created previously that are available on The game and we'll tell them to update and the layer is basically just a core animation layer It's a very simple layer that doesn't know much about anything apart from his position So he knows his size and his position and the layer has a game item So when you say a date the layer goes and and talks to the game item like our user or the other player And says update and the player knows about it's on position And he will go and check with the game data if for instance in the case of the player if the user pressed right The the game item needs to change is coordinates to move to the right or to the left Once the the user change when the player the game item changed his position What it does is sense It basically gets read again by the layer and the layer will reposition itself based on the item So if you press right you want in the memory The layer gets updated course the game update the game item the game item said oh you press the right button I'm gonna move five pixel to the right and then the layer would say oh you move five pixels I'm gonna move five pixel and the layer just moves Once that's done the game loop comes back and says okay. Let's check on collisions So on a simple game like I did it's it's really easy You have the player and you will check on collisions between a ruby and the player and A bomb and the player so at this time the game loop checks on the collisions, and if there are any collisions We're gonna update the amount of lies the amount of points, and we're gonna eventually play your sound so A game is divided in three parts, so we have the game data the game loop and the game play Okay, this game is done like that so the game play The game play is what you use when you play the game, and it's basically the different controls going left and right The way you're gonna do that in in cocoa with with my who build in cocoa in general is in interface builder where you build the UI We add a new view On top in the window so that's gonna be at the top so we're gonna be able to catch all the keyboard events and What do we do is we add this view which is just a drag-and-drop I didn't do a video But it's basically you bring the view in interface builder in the window, and then you click on The parameters so you can see what's going on in the inspector and we say okay We actually want a subclass of a normal view so we can interact with it And we're gonna give you the name called keyboard control view In reality what you do is you create a view first the you create a class first And then you will show up here in the list of class But we go back to our code and we create our NS view Subclass so for people who don't know cocoa cocoa has a lot of different classes and the NS view is Basically what you need to use that I'm not gonna explain all the details here but what we want is to have a subclass of NS view so we can add new methods and NS view as a callback on key down so what happens is every time people will click on a key Up or down it will call a method a method and it will pass events which is an object So now we can catch this event and we can do something and as in usual Ruby You can call super which will bring will send back the control to the next Class in the chain So what do we do is the user press the button sends to events to the method and then we deal with it Now it's actually not that simple because here we just accessing the key But when you play a video game you need to deal with Acceleration so for instance if I was a player and you press the button the game loops comes and it will move me once To the right and then once to the right So if you leave the button pressed I'm just gonna go move and like that the premise in reality when you play a video game When you leave the button pressed the the the player will actually accelerate and it will move faster So you want to actually deal with that and what we do is we take care of that in the game item You the game item class when you press the button and the button was the button was already pressed instead of music Moving the user for like five pixels. We're gonna accelerate the movement and push it a bit further So you need to think so basically you don't want to end up with issues like that Where you didn't scale scale up properly So when we change resolution if you have a small window and you just go up You need to make sure that when before you were saying the player needs to move five pixels to the right You need to multiply multiply this dimension by the new screen resolution So you need to think about the ratio of the screen and all of that So that's what I did in the cut. It's actually not really hard You just need to do a bit of math and you're good, but that's that's basically the gameplay for you And then you can find other keys for instance a pose and X and the space bar and different things that work So the gameplay is pretty easy Most of the code is actually written in a game loop So the game loop if you remember it's what's running in the background 30 times a second So the usual workflow that we used to when Oops, sorry The usual workflow when we write Web applications or desktop application is that you have an action jump on the ball and you have a reaction That's that's the usual thing we used to so the user click on the button and we do something now in the video game It's likely different Wait, we basically don't the user doesn't need to interact with you It would just you have a lot of stuff moving on all to around you And the game needs to be able to run without the user being involved So everything is to run smoothly regardless of the user's inputs or lack thereof The cat actually goes for the wife. So I'm just gonna jump all right so the game loop 30 times per second the game loop does something and this is what it does It will move the player which is the main object Then it will move the other objects around and then it would check and resolve all the collisions It was it will date all the score and the levels Redraw the graphics and then play a sound if needed So that's the job of the the game loop and a game loop In cocoa you could you can do it different ways. This is the way I did it, which is pretty simple and This is basically my game loop or how the game loop gets triggered All right, so let me explain the cut a little bit So we create we have an instance of a cocoa class called NS timer So it's just a timer and then we pass this long method That's that basically says we're gonna run on a time interval and every time we reach this time interval We're gonna do something and the time interval here is 0.03 and then the target is who we're gonna call once this interval is Is up and then we call a selector so a selector in cocoa is basically a method you call The only thing you need to be careful with when you write a cocoa with my cookies you need to put the colon at the end so we know it's really a method to call and Then we pass all the stuff that we actually don't care about So this is just a hash by the way Don't don't be scared. It's just a ruby 1 9 hash. You could do it's do ruby 1 8 hash But the way it works is in Mac ruby When you want to call a selector in cocoa, which is a method that texts written named arguments You just pass a hash and it would work and here. I just use the ruby 1 9 syntax because it looks just much better on screen So as you can see the selector refresh screen is the method we're gonna call on the target which is here on the bottom and This method text and arguments You could also wrap this class into something like that. That's much cleaner And interval timer would be the class you would write that would just do exactly the same thing and just pass Through the thing is you only use the timer once so I didn't think it was very useful to do it And here is the entire game loop Which is you know quite a lot of code, but it's actually not that hard. So we're gonna go through it What we do is we ask the game data data all the layers. So these are all the core animation layers There are just simple layers than other positions and then we go through each of them and we say update If you remember what I said at the beginning when the layer updates what it does it calls the item itself and the item goes and Move is X and Y and then based on that the layer will move Once that's done what do we do is we check on the collisions So I have a class. I have a method called the collisions on game data And it will return two arrays one for the collided bombs and one for the collided rubies And to check on the collision. I basically implemented this small method called collide with Which I put on the game item itself and the way it works is in self doing all the math itself Ourselves we're using an essential Intersect wrecked which is a C method that we call transparently So it's really really fast and what it does is it takes a rectangle of a wrecked version of our object And then it takes another rectangle version of a different object and it will tell us if there is a collision or not and So what I did and I'll show you all the code is open source and you'll be able to see it But basically each object has a wrecked version So this is the only thing we do to check on collision and we return true or false Next We checked if we have collided with any bombs If we did we're gonna lose a life, which is a method called I would just remove one to the amount of lives And if you add zero then it's a game offer. So we're switching to game offer then we check on every single collided bomb and What do we do is we take the item and we reset it and when you reset the item? What that means is we bring it back up at the top of the game and We're telling it to just start again to fall to fall down How very simple now if we did not collide with any bombs We're gonna check if we had any if we collided with any rubies and if we did we increase the amount of points by the value of the item and We update that we update the display and finally we bring back the ruby at the top And the next what we do is if we touch any rubies We're gonna play a sound effect. That's just a tiny sound you were hearing when I was touching a ruby and I'll show you that in a second, but just before we move to the sound What do we do is if we should change the level which is a simple method that checks on the amount of points Then I call the method level change exclamation mark So playing a sound It's actually very very simple. I was almost disappointed This is actually all the code I did you can actually make it even easier than that But I just wanted to make it a bit fancy So often when you write a video game, you actually don't need to use object oriented Programming so in this case, I just created a module with module function and I have sound effects and at the beginning of My module I define different sounds so you can load different sounds you can ship with different sounds Or you can use a system sound like I did here and then I have a method called deaf frog and then I pass a delay So you might want to add a delay to the sound. That's why I made it a bit more complicated So then what do we do is we take the sound and you say perform selector Which is the same as send in ruby, but in objective system perform selector and then we pass it play We don't pass it any object, but we say after delay delay You could just also do frog that play and it would work, but you will not have the delay You could also do frog that there's another one that lets you run in a loop And that's what I use for the music in the background. So music just loops So that's actually that's it for the sound So let's look at the game data So if you remember the game data is the memory of you game. That's where you store all the different states Of the game so again module game data is just a module function Actually, it's just a module that we use Not really as a class so we don't create an instance of them of game data And the challenge is we need to be able to connect The game controller, which is an instance of game controller With the game data so we can talk with each other and what we do is we use a hook called awake from nib so in cocoa When the nib which is the interface That you created yourself so you basically drag and drop that's what we saw at the beginning of NS view all of this Details get loaded this method gets called so we call awake from nib and here what we do is say, okay We're gonna register ourselves, which is the game controller with game data, which is just a module so now game data knows about The controller and since game we just use game data directly. We don't need to go the other way Once we have this connection made we can actually go use game data all layers But I didn't show you how to create a layer yet So a layer is actually created this way We call a method called display item and we pass an item we want to display and I'm not gonna show you the game game item, but it's basically your x y and then an image you want to use all the Images that Stephanie design and we're just PDF images so they can scale up and down and they're just shipped with the game and We create a new layer and This new layer is called using image layer, which is a class I created which inherits from core animation So you just need to do core animation layer What's CL layer and you're in here it's from that and then we use so that's actually a bit weird for rubies But that's the way in objective. See you initiate An instance you do a lock that in it with something so I need to explain a bit more about that once again So you could do image dot new, but the problem is the way Some of the cocoa classes work. They actually don't do the proper a lock and in it So you might have some issues. So it's usually better to actually use the cocoa syntax and say a lock Dot in it and here what I wanted to do is to actually initialize with some specific params and I could just Overwrite or just define initialize But because of the issues with the cocoa classes It's better to just stick to the cocoa approach and say a lock in it in it with item Which is a method I defined and then we pass the item and basically what it does is we get the item We take the the file puts it in and we're good to go Once the layer is created. We just add it to the array of all the layers and that's about it You had a question If you have questions you can just stop me All right, so Then that's actually all the config for the game. So we have another module That defines the data for the game and this is basically where you have all the stuff for your game So we have an array where we have a hash with an array of all the levels and then we define the settings for each level So this is how I got the game to be much easier for me because I Basically gave myself a lot of lives and then I didn't put a lot of bombs But in this example you can see we're gonna have three rubies that are gonna be created and fall down and 12 bombs We're gonna have a score limit of 30, which means that after 30 we're gonna move on to the next level For the vehicle that we use so, you know, the little player is on something on some levels So we just define the name of the file and something for the bomb And then you have the different ratios that we use so you can have different file size for the player and the bomb So I just want to show you a tiny thing about cocoa hacks so Often you might be surprised when you arrive in cocoa and you like this API just this API looks weird and you don't like it So what you need to realize is the cocoa class is actually a ruby class. It's exactly the same thing So you can do what you would do to a ruby class. So if you don't like an API What you can do is you can just wrap it and this is kind of the concept of Hot cocoa, which I'm not gonna talk about but basically you can you can wrap you can reopen any cocoa class and do whatever you want with them So this is a quick example of what I did for NS button so NS button is Just a simple button that you click on and it does something so it calls a method the problem is the NS button is It inherits from a lot of different classes and when you want to change just the color of the font You actually need to do all of that. Well, actually, there's an easier way But for my example that worked pretty well So what you need to do is you need to get the attributed title And then you need to get the attributed string and then you need to modify it And you need to risk to resend it back to the object. It's kind of a pain So what I just did is I did that once and then I just created my method called title color equal and pass a color and Then now I can take my button instance and just call that So whenever you you're struggling with ugly code, you can actually refactor that and have a small folder Where you just load all these classes that would just wrap stuff for you The last thing I wanted to show you about writing the game is actually compilation So we're all used to using Ruby and it's great. The problem is if you write a Real game and you want to sell it you probably don't want to ship the source code with your app Especially because people could cheat people could reuse your code on different things. So That's one reason why you wouldn't want to use compilation. The other reason is because you want the boot time to be faster Instead of having to cheat all the files every time when you start what would happen is everything will be done beforehand So the load time would actually be a bit much faster So the way you do it is actually very simple. You just need to go in your objectives in your Xcode interface and you say add a new Template a new target and then you choose embed Mac Ruby and what it does in the background is actually just that it's just calling a simple script that's called Mac Ruby deploy and then it passes the target which is the the target builder which is where the The application was compiler was put and then pass a different string So here what I do is I embed Mac Ruby. So basically the game ships with Mac Ruby So nobody needs to have Mac Ruby And then I say well actually don't load the Ruby stand libraries because we don't need them So we're gonna make the game a bit Smaller and then compile it. So instead of having All the RB files. We're gonna have some compiled files So let me just show you what it does Should have the same thing now very good So going back to my game. So just since we're looking at it here. It's a bit tiny I don't know if we can zoom in probably not so if you see that's the Swiss code of the game And it's organized by folders. So here we have the different sounds So we have level one two three four Then we have all the graphics, which is just different PDFs files Just the backgrounds and stuff like that Here is the cocoa hacks. I was telling you about so we're just wrapping By the way, if you guys don't like Xcode you can also just set up to use text mate when you edit so All right So then we have all the classes and I was explaining here. We have the control view That just binds to different code Anyway, this was his online. I'll just show it to you And here I defined the target and to define it to add a new targets You just go to what's that new target here and You add embed Mac Ruby. So I already did it. We have it here So, let me just show you what we add. So let me build the game a first time Also when you do a putz, which I guess now I should try to do G See if that works, but when you when you play you can see how it puts here on the side So you can kind of debug and see what's what's going on All right, so you can actually see in your logs. What's going on? So I compile the game what actually I did not compile it. I created dot app file, which would be in my projects your products It's not So we have a build folder should be somewhere here and I mean So my game and I can just show you the content of the game. So we have a contents folder Source, that's me now. So basically we're shipping with all the different Files, we also have a custom font that we ship and if you look at the source card I just show you how you can load the font and ship with your own fonts And then you can see we have these different Ruby files are just Ruby files that I could open and preview And you actually don't want to do that. So what we're gonna do is compile all of that running Running Running the target. So here we switch switching to using the ambit target and We just build and run. I could just build it and he runs the script here says building the custom Running the custom shell So it's taking a little while and it's taking every single Ruby file and compile it down ahead of time So once it's done, which we should be soon All right, there you go It's not totally done But you can see all the RB files were replaced by RBO files. So they're all compiled files And you just cannot see what's going on in the game, which is cool, especially for the settings So I only have two minutes of what I wanted to show you. Oh, there you go the game finished What I wanted to do is just show you how you add a new level So to add a new level here, I prepared some some graphics that Stephanie did for me I'm gonna go into my graphics here. I'm just gonna drag and drop all this stuff here And I'm not gonna copy it just put it here and then I'm oh this one I forgot and Then I'm just adding the sound All right. Now what I do is I just need to go to my game config and I will just add a new Just a new hash for this level, which I actually did somewhere here. They go So I'm just gonna copy it Stupid excuse. Let's just run the game and see if that works. Oh, I'm just I'm in the wrong So I need to switch back my target to the game. So I don't compile it. It will be much faster. There you go Yes So when you compile it actually the RBOs fight don't get deleted So I'm just gonna delete them myself so they don't get reloaded. Also. Here is the framework. So he ships with my ruby directly All right deleting that All right, and we're compiling game linking. There you go Let's try to see the last level so I need to actually beat all the levels level two It's a motivation High level three All right level four one more to go. I actually don't remember the limit we put on the level Hopefully it's one of it. I think I'm gonna cheat I'm gonna game over I guess it is the water. I really suck one of the two. All right. Let me just cheat quickly We're gonna hack the game and just say we're gonna switch here to That was the problem Let's put this guy at 90. All right, we run the game All right, full screen Yeah, I need to like left left right right and All right level two level three I just need one ruby. There you go All right, so I could play for hours so we probably should stop now So there was one thing I didn't show you is you can actually use instruments I'm not gonna show it But you can just use instruments a lot of the the X code tools to actually monitor and see what's going on with cocoa So anyway, thank you very much