 I'm going to be speaking about writing games. If I was there in Patterson, I'd be saying, do you want me to keep games in Ruby? I've got to push, but we're done with this. You can go there and get the code that I'm about to show, and you can follow the progression of the commits. The first thing is we're going to be using Gosu. Gosu is a great, minimalistic game library. It's not really a framework. It's not that opinionated. It's basically the least amount of code that you need in order to write a platform-independent game. It is not that new Gosu language, that JVM abomination thing that just came out. That's completely different. You don't have to get hurt by Google on that. So libgosu.org. You can go there and you can read the R doc. It's a C library that's also got first-class Ruby binings for it. So there's a lot of really great Ruby games that are written in Gosu. So just gem install that, and it should install most of your platforms. So if you're on Linux, there's a wiki page to help you out. Make sure you can install. The first thing we're going to do is we're going to create a hello world application. A couple years ago, there were a lot of game presentations at Ruby conference. I was really excited about them. Each one of them showed a different game library or framework. They didn't really show the process of making games. This was something that I really wanted to know more about. I thought this would be beneficial for people to follow along. If you look at the description of this talk, I said we're going to go from nothing to a working game in 45 minutes. I said a lot of things in that description. I'm not really quite sure if they're going to come true, but that's the goal. So the first thing we're going to do is we're going to... I'm not going to type these skills here. We're going to open up a new file. We're going to require RubyGems and Gosu, and then we're going to create our demo game class. Now we're going to inherit from Gosu window, and this is important because in Gosu, the only thing that can actually draw to the screen is window. So we need to inherit from that. That's pretty much the only thing we need to inherit from. Now, I like to, in my initializer, have width, height, and full screen passed in, then just call super. They don't have to put that anywhere else. That by itself doesn't give us a whole lot. I mean, this is a hell of a world, so let's go ahead and add a caption. This is going to add whatever we write here to the title bar of our game. How do you install Gosu? Gem install Gosu. No, I cannot. So... This is all recorded. I can't do that. It's 15 point. It's a small screen. LibGosu.org has got all the documentation, all the RDoC up there. So here's the documentation for window. If you look at it, Windows got a couple of methods. Windows is one that I care about because I don't like to click the button. It's also got a button up and a button down method, and that's going to be called every time a button is de-pressed or un-pressed. So we're going to go ahead and implement the button down, and it's going to get passed in the ID of the button. There are some constants that's going to help make our code a little more readable. So we're just going to close if the button that was pressed is escaped. I'll finish typing that, and then run it, and then if I hit escape, no more punning and pecking with the mouse. So there you go. So that's our first quote-unquote game. And now you know. It's like if they would have just done that two years ago, I wouldn't be here. So the thing that's different from game development from most other like desktop applications development is the game loop. A lot of the other desktop apps kind of wait on user input and have this kind of message pump that they're going to pull from. But other than that, they try to be really, they don't want to take too many resources. The game, we don't care, right? We want to take as many resources. We want to go full-tall all the time. So Gosu has a game loop. And in this game loop, every time through the loop, it's going to call the update method, and it's going to call the show method. So that's going to be important. The first set of demos we're going to go through, we're just going to worry about draw. But a little later on, we're going to talk a little bit more about update. So to draw, I'm going to draw a rectangle. Now, Gosu has draw quads, which has got a lot of parameters. So Ron Davis actually had this really great helper method draw rectangle. So let's just draw 200 by 200 white box in the middle of the screen. So we did that with our height and width. Now the X and Y coordinate are going to be the coordinates from the top left, right? So here we have our top left, and then we're going to offset that with our height and width. And then we're going to paint this white. And that's what that does. So that's not really too interesting. We want to do something. We'll be wanting this to print out of square. So we're going to animate it. All we're going to do is we're going to change our offset of where we're starting. So we're that originating X and Y coordinate on the upper left of that box. We're just going to be modifying that. There's a couple of ways we can do that. If we take the sign of current time, we get a nice recurring number that's going to come around. We can get some animation. Because the game loop is happening at this point, 60 frames a second, it's going to call, update and draw 60 times each second. And so when we do that, we get the illusion of movement. And unfortunately, the screen capture didn't do a great job. It's less smoother when you see it live. So we can go back and forth. If we change that to sign and cosine, we get a nice little electrical looking animation. If we do, we still have to work. And if we can change that, this is a little animation I kind of like, where you take the sign and the cosine of the current time for the X coordinate, and then you take the tangent for the Y coordinate, and then the box drops off the screen. It's kind of silly, but it's not too bad. And this is early, early stuff. But again, I had a little hard time kind of finding this type of, this type of introduction. All right, we don't care about boxes. Let's add something and make it look a little bit prettier. So what we're going to do is we're going to create an image. We're going to take this background image, it's 800 by 600, which is the size of our window. And we're going to create that as a go-soot image, passing in the window, because the window is the way you're drawing to. We need that reference to that window when we actually create our image object. And then we can just call draw, and again, we're going to do it at the zero X and Y, upper top left. And when we do that, we get a nice picture of the background. We still have our white box blue. So we should probably pick stuff. So we're going to add a ninja, because ninjas are cool, right? That was a few years ago. We're just going to add a little image. Same type of thing, we're going to add it in the initializer. And then when we draw, instead of drawing this box, we're going to draw the image. Instead of keeping the height and width of a box in the draw method, we're just going to grab it from our ninja object. So images have a height, images have a width. And then we just call draw, pass in the X and Y coordinate, and then the Z coordinate, which is the Z layer up and down. How close we are to the player. So we do that, and now we have a nice little animated image floating on the screen. What's nice about GoSu as well is it supports bitmap and PNG, so you have the full alpha blending on all of the images. So you can, even though I'm using kind of crappy developer art, you can come up with some really nice visuals just using standard artwork. Alright, so I think the ninja by itself is not enough. Let's go ahead and inject Andoruby. So let's go ahead and add the ruby image. And I want to have a slightly different animation, so we're going to hammer on this placement just a little bit. Yeah, I think what we're going to do is sign plus cosine over sine, and then sine over tangent. There's something, the other thing too is when we're drawing the ninja they both have the same z-index. If we change that to a y, then it will also pull one image from behind. So if we go back and look at that again, so the ruby is behind the ninja and the ninja is behind the ruby. So that's kind of cool. Alright, that's kind of lovely code. I admit it, but it got a short rest. So let's go ahead and refactor this. So we pull out the ninja to his own class and the ruby into his own class that holds both the x and y coordinate and also is responsible for draw and also the animation. Now our demo game here is pretty simple and it works the same way that it did before. So basically our game is just going to create a background, create a ninja, create a ruby and then we're just going to draw them. So it's pretty simple. Refactoring this logic into its own objects is a good thing. We've got a real-life example. Which one do you say? North. So this is a game, let's see if we've got some sound, that was written by a developer at Ipa. I'm not sure what his real name is. He's somewhat active in the go-sum community working on a framework built on top of go-sum called Tsungu, which this was written in. And this game was written in a weekend by a single developer, including all the artwork and all the code, and we'll talk a little bit about that later on. The game is pretty simple. You are just a little dry, you can kind of hop, you can also squish down and grab things and then throw. You want to kill that key so nervous can put the game. And then it's got 10 levels of difficulty and I haven't yet to beat it. But this was written all in Ruby and the source code is all built up on go. Are they still alive? Like champion? The game? I think it's an artistic thing. It's kind of meant to look like an 8-bit game. Then I have to beat it. So we have kind of our first working graphical kind of display. It's not a complete game. And you saw in the game that we just walked and we just saw the North game and there were a little characters that moved around that had a different type of animation. So that's called a sprite. So we're going to build a sprite next. As we do here, let's take a look at the snake game. So this looks kind of similar to the earlier demo where we were going to create a snake sprite. When we click escape, we're going to close it. When we update it, we're going to keep track of the current time. The only reason I do this is because if we have some of those mathematical calculations it's nice to have the same time, each time for each calculation instead of grabbing time to undo each calculation. And then on draw, we're just going to draw that snake. So hopefully that looks pretty simple. Let me take a look at the sprite here. We're going to initialize it. We're going to get that window because we need that to draw to you. Then we're going to create, instead of creating an image, we're going to create a pile. And this is actually just an array of images. When we do that, we can go to image, load tiles, they're line 11. And we're going to pull up the snake block tile. And I'll show that just a little bit. And then on draw, we're just going to draw the very first one. And again, the center is going to be, the location is going to be the center of the screen. But if we move forward with that, that's it. And I'm kind of telling this to suck the game. I agree. So let's do something a little bit different. I'd like it to change direction. I like to go left and right. So we're going to have a very glitter call direction. Right now it's pointing right. And then when I call move left or move right, this next sprite, I just want it to flip. So when we move right, we're going to set that direction to right. When we move left, we're going to set that direction to left. And then when we draw it, what we're going to do is we're going to check and see if our direction is right, then we're going to draw it the way it is right now. If it's left, then we need to mirror that image. In order to do that, we're going to have to offset the location as well. So the X location is going to be X plus the width. And then these other two parameters that we haven't seen so far on draw, because the default is one, these are the factor or something. But you can adjust how big or small the image is. So the default is one. If you put it at 0.5, it would be half the size. And here's the other thing too. On the button down, in order to tell if we're going to move left or right, it goes for the left arrow or the right arrow. And so our game is going to keep track of the input and then update our sprite for us. So if we do that, now we can switch left and right and our snake changes direction. It's not exciting enough just to change direction while we'll do the movement. The movement's not too bad. We're going to just offset our X position in each frame. Again, because we're doing it so many times a second, it's going to give us the illusion of movement. So here we're setting our movement to four pixels. So once every game loop we're going to move four pixels. Now here I actually have to keep pressing the arrow in order to move because I can't just press down the key. That's because our smoothing is only on button down. So if we change that to our update and we check for button down instead of button pressed, then we can actually hold the key down and it will move for us. So here's a demo of it moving somewhat smoothly. So it needs to do more than just move. Here is the sprite that we loaded. Now so far we've only been drawing the first image on the left. What I like it to do is I like it to cycle about four or five times a second going from the first to the second. So it looks like this snake is kind of slithering on the ground. So we'll go ahead and do that. To do that we need to know how fast to animate that. And then I didn't really go with any industry standard animation techniques. I just kind of did something that I thought worked pretty well. You see, we're just going to change out our frame right now. It's always going to be zero. We're going to give it a different presentation. We're going to take the current time and we're going to divide it by the animation speed and take the modulus of that. That's going to give us a fraction between zero and one. And then I'm going to multiply that times the number of tiles that we have in this case two and that's going to give us our index in our animation array. So if we do that, then it actually animates. We can kind of move around the screen and get the illusion that it's doing more. What's nice about this approach as well is that because these are just variables we can change the animation speed, we can change the movement to two different effects. So we can make like a hyper animated snake or we can make something that's just a little barge. Just by changing those two variables. Do you know any tools for editing sprites and working out the actual individual frames for your animation? There are tools. I intentionally kind of stayed away from them for this because I really wanted to give more about the concepts of building games and kind of show that it really is accessible. You don't need to learn a giant model of the framework in order to build a game. There are literally a couple hundred lines of really good and you have everything that you need. There definitely are tools. I really didn't want to open that chat window's box. So I kind of like the current movement that we have before. Now I like this sprite to do a little more than just kind of move. So we're going to add two different cycles. The first two is going to be like a walk cycle and then the next three are going to be some sort of attack cycle. Now these different cycles can have different frame rates and they can also have different speeds with this approach that I'm doing now. Again some of the other game frameworks probably standardize that. I have a little bit of an opinion on that. So the first two are a walk and then the last three are going to be an attack. So we're going to go ahead and add that. And then we're going to add a new asset to include the attack frames as well. And I'm just going to go ahead and add all of these variables. So we've got a walk movement, a walk speed, and a number of walk frames. We've also got attack speed, a number of attack frames, and then a time. The reason that time is important is I want to know precisely when the attack happened. I don't want to just take any random kind of like to animate it at the cycle time. Otherwise the attack might end at the end of the attack cycle to the beginning. So every time we animate an attack, I want it to start over fresh. So it's important to keep track of that time. So now if we're attacking, we're just going to check to see if our attack time plus the attack speed is greater than now. So if that's greater than what we're attacking, if not, then we'll walk you. So we've got to help them out if it's attacking a walk. And then when we do attack, we're going to call attack bang. And what that's going to do is it's going to set the attack time to the current time, only if we're not already attacking. Now when we move, I only want to move when we're walking. So we're going to add a little bit of what we put here just to only move when we're walking. And that kind of makes me feel the key. But we're also going to add a whole lot of logic to the frame logic here. Because we've got one set of, one piece of logic for walking. One set of logic specifically for attacking. And the reason for that is because I want to make sure that we're always starting the animation from the beginning of the attack going through to the end. So we're going to take the windows time, minus the attack time, and then divide that by the attacks, the modulus one. And then we're going to take the, we're going to take the apparent bang 64. We're going to take the index of that to the attack frames. Now we have to add the walk frames on top of it, right? Because the first two were walk. So if we're in the second attack frame, that's going to be frame zero, one, two, three. Right? And then here in our game code, we're going to go ahead and attack, but we need input to the attack. So we're going to go ahead and check for the space key being pressed. If the space key is pressed, then we're going to go ahead and attack. So now we can kind of move back and forth. And as we attack, our snake stops moving, even though I'm holding down the arrow keys and hitting space at the same time. That's because of a lot of the inner sprite. And that's just kind of how that sprite is written. All right, again, there's a lot about this code I don't like. So let's make this a little prettier. The first thing I want to do is we really got this notion of state. We don't really talk about state machines yet, but state machines are kind of rampant in game development. There's lots of state machines from AI also to characters and sprites. So I'm going to create a walking state that's going to have a movement, a speed, going to have the actual frames of animation and the time, because that time is kind of useful. But if we start a walk cycle, it might be nice to know when that walk cycle started. We're going to do the same thing for the attack. Now, the movement I'm going to have is zero because I don't want the snake to move on attack and get rid of this that code. The only thing we're going to add here is we're going to add a state, and that's going to pull the current state from the hash. That's going to be useful because we're not going to have to check everywhere else what state we're in. To know if we're attacking, we're actually going to have to look at the specific attack state. Instead of just being the instance variables on the object, we're going to look at the hash. When we attack, we're also going to update that hash. Now, our movement actually has gotten a lot better because we're no longer checking to see if we're walking. We just move the x-coordinate by whatever is in the state. So attack has no movement, so it doesn't move. We can also simplify our animation frame logic as well. We don't need to have two separate code paths, one for walking and one for attack because we're just going to pull all of that out of the state. We can even simplify it a little bit further by actually pulling out the frame from the hash. So if we go ahead and look at that, it works the same way that it did before. The code is just a little bit clearer. Let's take a look at another example. This is Zombie Fisticuff Oral. I think it's Deps. This is his name. This is a fun little game. Also created in 48 hours, and all of the assets were created by him himself. So the opening music is him coming up. And the point of this game is just to walk down a stream and beat up some of these. This is pretty cool. So this is the developer. I wish I could take a look at this. Can I dig the monocle? Don't leave me. Y'all, what's happened to me? I hit it with the squirrel. I took it dead. What could you come up with something as good as that? So, like I said, states are really good. They're useful for artificial intelligence. I'm going to do the simplest AI you can possibly think of. What I think we're going to do is we're going to create a sprite. We're going to move it from one location on the screen to the other and then go back. So he's just going to be kind of like a patrol. He's going to go from one side to the next. So let's go ahead and try that. Here is our, again, this is pretty familiar. Here's our patrol game. I separate it onto different files. It looks a lot like our sprite game. We're going to create a patrolling creep. And here I'm going to set the color to red. I don't want the different creeps to have different colors. So I'll go through the logic on how we're going to color these sprites. Same thing, button down. We're going to close if it's escaped. And then we're going to update the creep and draw the creep. So not too unusual from what we've seen before. Here's our creep definition. The difference between what we've done previously and this one is our X and Y coordinate instead of being the upper left-hand corner of the sprite that we're going to draw. I want that to be the dead center of our creep, the lower sprite. And I'll explain why that is as we get into it a little bit further. We're going to create our circle image. And then our default color is going to be white. We set this one to be red in our game loop. We really don't have anything to do on update. And when we draw, we're going to take our center. We're going to offset that by the height of our circle. So we're going to make sure that we're going to draw our circle in the right place. The other thing that we want to do though is we want to add the start and the end locations. So I think by default what we'll do is we'll start at the cycle height and width, so the upper left-hand corner of the screen. And then we want to end at the bottom right-hand corner minus the height and width of the circle. I'm this world's slowest type of, so it's kind of painful for me to watch you run. So we're also going to keep track of the targets. This is kind of more of a state machine aspect of this creep. Then we want to actually get our target, whether that's a start or end. And then when we reverse ourselves, we're just going to change the target if it was pointed at end or even pointed at start. Which is hopefully pretty simple. The next thing we want to do is we want to get a method that's going to take X and Y coordinate and actually set that for us. This is going to be useful so we can set this outside of this class in our game. The other thing we want to do is we want to know if we're near the target. So we're going to talk a little bit here about one of the methods that Gosu gives us, which is a distance calculation. So if you take a set of X and Y coordinates and a set of other X and Y coordinates, it'll give you the distance between those two points. So we're going to know that we're near a target if that distance between where we are now and that target is less than what we are moving at any given loop. So now that we've got our infrastructure here, we're going to take use of the update in our game for the first time. The first thing we're going to do is we're going to get the angle of where our X and Y current center is and where our target is. This is where we want to go on the map. Once we've done that, we're going to take that angle and we're going to offset our X coordinate by our distance plus that angle. And then we're also going to offset our Y coordinate as well. And again, Gosu gives us some really nice helper methods so that we don't have to do all this map ourselves. The next thing we're going to do in our update is we're going to reverse if we're near our target. So that way if we're near N, we're going to turn around and go back to Y to start. And I'm just going to make sure I crack the spell in the window. So here's our run. As you can see, our red circle is now going from the upper left to the bottom right. And that's kind of boring. I think it would be better if we had more creeps than just the one. So we're going to go ahead and add six of them. And we're just going to be basically the same thing. We're going to create a new creep. Instead of having them all start at the same place, let's go ahead and assign them each a random color and a random position for the start and a random position for the end. And once we do this, we can get rid of our previous creep in a sense of variable. And we can change our update draw as well. We have to implement color. This color code comes from some of the Gosu examples. And then a random position, I think we're just going to, let's just pick a random place. A little bit later, I'm going to use a slightly different algorithm for what the random position is and what's an acceptable position. So for now, let's go ahead and update and draw our creeps. And so hopefully we're going to see a bunch of different creeps running on the screen. And in fact, we do. Some of them go very far, some of them go far. So let's just kind of look at the draw. Right. Again, it's kind of what we saw before. Some things are happening on the screen with our involvement for the most part. Let's add something that we can move, something we can control. So I'm going to add a control player. And basically, I'm going to copy this program. So I'm going to take our creep and just make him a player and then remove all the things that I don't need. So the start and end, I really don't need the target, none of that. I don't need for a player. I think our start position, we're going to need that for our X and Y coordinate. Yeah, target, reverse, start, end here. We don't need any of that. And now here on our update, we're getting our angle from our X and Y coordinate and our target. So we need a different algorithm to get our angle that we're going at. So let's just get it from something called current angle. And we'll add that here. I'm just going to add it now. Current angle is going to look at our window and see what buttons are pushed. If we're pushing left, right, up or down in a combination, we're going to get an angle. If none of our buttons are pushed, then our angle's going to be nil. And so here's the logic for that. Again, there may be a built-in way to get this sort to map this out. This is just kind of brute-forced here. But it works, and I think it's pretty understandable. So straight up is angle of zero. Straight to the right is angle of 90. Down is 180. If we're pressing both up and left or up and right, then it's going to be 45 and so on and so forth. So there you can see our logic to determine the angle. If we have an angle, we want to offset our X and Y coordinate. So we're going to move only when we're pressing Y. So here's our control player. We left him Y, and he gets to move around and kind of interact with all of the other circles. Again, we're controlling it, but there's something missing. I expect something to happen as I went around and did that. There's no danger. There's no peril here. The games are supposed to be fun and exciting but I don't see any of that. Okay, so what we're going to do is when we update each of our creeps, we're going to move the creep, and then what we really want to know is is that creep clipping us? Is it touching us? And if that creep is touching us, then we lost. So this will be kind of like a tad. We just want to avoid all of these patrolling creeps. So we're going to take the distance of the current player and the distance of that creep. And we want to make sure that that distance is bigger than its range. And right now we're saying its range is basically the size of the circles. So here in our creep, we need to add our X and Y coordinate because we're using it from our game now. And we're going to add a range. And our range is basically just going to be the width of the circle. We can set that so that this creep can have a bigger range or a smaller range. So now that we've done that, we're going to bring a whole lot of code and just checking to see if the distance is close. If it is, then we're just going to print fail and we're going to close. So here is a game. We kind of wander around and we get touched and it says fail and we're dead. So it's kind of pain-like. Let's try it again. Yeah, it still fails. Okay, so more than just failing, it would be nice if you could actually eat the game and win, have a sense of accomplishment. So I think what we want to do is we're going to start in the upper left-hand corner. Maybe we should go down to the bottom right-hand corner. And once we get to that position, then we'll win the game. So here we have that. If you go back just a little bit. I added this win position right there on line 19. So if players X and Y coordinate equals at 7, 60 and 5, 60, then let's go ahead and say that we won my game. Okay, so after we've updated the player, we're going to say, hey, is your X and your Y, does that equal the win position? And if so, then we should probably put win and then we should close. Now when we do that, let's go fast forward a little bit, we get all the way down, we're untouched, but we get to this bottom, and it's really, really, really difficult to get into that position. So one of the things we can do is we'll probably round off, have a better round for the X and Y coordinate. But our circle is able to go outside of the bounds of the existing level, which is that our level is probably the bounds of the screen. So on our player, we probably need to give our players some bounds and we're just going to go ahead and make that the circle width minus 0.49 just so the rounding evens out. And then we'll take the window height minus the half of the circle height as well. So that way we're starting at 4040 and we're going to 760 and 560. So we got our bounds. Now when we update here we're just going to check and see if we're outside of those bounds. Then we're going to set to be inside of the bounds. And that's basically it. If we pop out at all, we're going to move back down. So let's try that. Now if I kind of move outside of the bounds of the window, I'm not able to. And I'm able to move all the way over. I hit that bottom corner and it says win. So ladies and gentlemen, it's kind of gamey. I'm going to look a little more fancy, I think. So one of the things I'm going to do is I'm going to trick it. What we're going to do is right now we're dealing with a full 800 by 600 X and Y coordinate. What I want to do is I want to fake it out and squish everything. So we're dealing with 800 by 300. So 800 by 600. I'll show you how we're going to accomplish that. That's going to kind of give us the illusion of looking at something from a 45 degree angle. Now again, I think there are better ways to do isomorphic displays, but probably not 45 minutes. So the first thing I want to do is I'm going to pull up a background image. That image is going to show us the bounds of our playing field on the screen. So there's going to be area on the screen that we are not actually able to go to and that is not playable bounds. So we're going to denote that by the background. So there it is. The gray bar is our background. But our creeps are flying all over the place. In order to make sure that our creeps do not fly all over the place and this is going to be really hard to see. We're going to take our X and Y coordinate as they currently are today. Now the Y coordinate, what we want to do is if you're at 500 pixels down, really I want you to be at 250 pixels down offset by whatever that top bar is. So this is what I've done. So we're going to take our existing X out in 2 and then out 20. So we're going to squish the playing field and we're going to drop it down. We're going to do the same thing to the player. So now as we do that, this is the exact same game but it's much more difficult because it's hard to tell as we move up and down. We can move much further left and right than we can up and down and we get caught a lot easier. But the game still works. We've only changed the visual representation on the screen. I think that's a real game. I think I accomplished the goal. Surprisingly enough. You can play it, you can win it, and you can lose it. It kind of does. Yay, real game. So what happens if we skip ahead? So there's a lot more things. We talked about the sprites. We know we've got this oval shaped and what more can we show? I wasn't sure how much time I'd actually have and so are we over? How much time do we have? Five minutes? Alright, so let's skip ahead. Here's the project. Now every step along the way is a different commit within the GiriCo. So you can go and get up and get up and look at each individual step and do the depth and see what was changed. Real game. Real game's got a bunch of different assets. It's got ninjas and snakes and different levels. Let's go ahead and run this. This is live. Alright, so here's my snakes. And as you get close they'll start kissing you. Now if you can hear that, as you run around you win. Now we have four. Let's go ahead and get caught. Now we fail. And we're ready to feed it. We can see on the screen you win. So there's more games than this. Let's take another example. This is for Ryan Davis. This is a zombie apocalyptic simulator. It has white dots that might be difficult to see are normal humans. The green dots are zombies. I think the purple dots are zombies and yellow dots are people that are fleeing and then there's priests that collect people. This is just a simulation. There's not a whole lot of input but it does kind of show the spread of the zombie-ness in a population of random people. There's kind of a lot of screensaver out of this. This is pretty cool. I'm trying to convince them to release the code so everyone can see. That's pretty sweet. Also there's also a Frogger example that you can see. So this is Frogger. This is about 200 lines of root code but it's more difficult than you would think. Over here it says win. There's more to this as well. There's a really fantastic physics library called Chipmunk. So if you see like the Angry Birds game where you're throwing stuff at a structure you can build something like that. One of my original goals was to build an Angry Birds clone. I don't think I had enough time. But it's all there. It's a lot like Gosu. It's written in C and it's got first-class Ruby bindings. So there's a lot of games. There's some examples that are using Chipmunk as well. There's another really great library called Textplay. If you've ever had a problem with getting R Magic installed, Textplay is also a very lightweight C or C++ library that's got great Ruby bindings drawing circles and trying to build it's a lot easier. There's a site called Ludham Dare. This is what it was talking about before where these developers will sit down and over the course of a week and over the course of 45 hours or 48 hours they'll create a game completely from scratch. So any existing library or framework code you can use but all of the art assets all of the sounds all of the music has to be created and like your game code has to be created by you and 48 dollars. The most good strengths have delivered some really interesting types of games. Here's something that I'm kind of this is an idea that I really, really like. I want to see a lot of games as genres. I would love to see like Dave Thomas talked about going out inspiring people not like yourself. Teaching kids how to program games in Ruby and distributing those games as genres. Just gem, install, game and play. It seems like that's an idea that this time should come. Again, my name is Mike Moore. I'm Blomage or Blomage. That doesn't matter how you say it. Twitter and pretty much everywhere else. Here's my email address. Again, I'm GitHub ZOMG Games. Again, it's November so if there are games with balls you can have them both. Questions? Yeah? Is there a hand up? Over here. Yeah, Gosu actually will integrate with RubyGL and so you can do all of your OpenGL programming in Ruby and call them directly to it and then also gives you the rendering display so you can print it and stuff. If you look at the Gosu examples there's an actual example that shows a rotating map as you're like a ship flying over but it's a full 3D through OpenGL. For executable packaging? The name of the of the app that scares me but there is if you go to Gosu forums there is a Ruby to executable package manager that will take a Ruby interpreter, all of your code all of your gems to a single EXE this is how the Ruby guys deploy their games you can also take Gosu and package it up as a Mac application and deploy it that way. I kind of like the idea of gems I kind of think games should be gems. Anything else? Sure? Yeah, I think Confreaks is recording it and we'll put it up. Yes sir. Yeah, see Confreaks here? Yeah, hopefully soon. I'll do it soon. Did any of the other Ruby game frameworks besides Gosu? I like Gosu just because it was so minimalistic I didn't want to get lost in dealing with the library I really wanted to do the concepts I kind of looked at it and I don't know what to play with I'm more of a minimalistic kind of guy I like It's really, really clean. It is pretty clean. Is there another question in the hand of the winner? I'm sorry, what's that? Oh, Mac Ruby? It's a C++ library and so they've got bindings but they've got a version of the Gosu gem that runs on the Mac I don't really seem anything with Mac Ruby I think if you're dealing with Mac Ruby you're already so specific to that platform that you just go ahead and use the C++ libraries to do your drawing Thank you Alright, thank you guys