Tuesday, December 31, 2013

My GitHub Game-off 2013 Entry

This past November I participated in the GitHub Game-off 2013. Basically it was a month-long game jam where you created a game that could be played in a web browser on the theme of "change." When I first read about it, it was already November 6th so I was a little behind. But since I had some experience with creating HTML5 games using JavaScript and Canvas I thought I'd give it a try.

The theme was "change" which made me immediately think of frogs. In fact, almost everything makes me immediately think of frogs. I decided to make a game about the life-cycle of frogs. Starting as a tadpole, you have to grab food and avoid being eaten by fish. Other tadpoles are also out to get you. It's a hard life for tadpoles. So in my game, you move your tadpole around in a pond trying to catch falling food and grow into a tadpole with legs, a froglet, and finally a full-grown frog. Once you are a frog you leave the pond, but you have to return to complete the cycle. The game completely changes (see, the "change" thing again) when you are a frog and now it's about jumping back in the water and catching bugs.

I drew some tadpoles and fish and plants and stuff, and found some great music from Incompetech and sound effects on Freesound.org. I can't say enough good things about Kevin MacLeod of Incompetech. The library of extremely high-quality music that he offers royalty-free is just awesome. And his graph paper is pretty cool too.


But what about the code? What did I do? How did I throw something together so fast?

For starters, I didn't use any game development systems. I know some that are very popular and allow you to publish your game as HTML5 and for iOS and Android and a whole bunch of other stuff, but I don't know how to use them. I admit it. I'm not a professional game developer. It's more of a hobby. I am a professional software engineer, and I do know how to write decent JavaScript so I just went with what I knew. I also kept it simple. When the game is simple, the code is simple, and doesn't require a lot of overhead from tools. Here's a quick overview of the basics. You can probably use the outline to make some simple HTML5 games yourself.

There are two absolutely essential packages for making HTML5 games: jQuery and SoundManager2. Well, jQuery might be essential for any type of web development these days. But games aren't much fun without sound and SoundManager2 is the library when you want to do sound from JavaScript. Stop what you're doing, download it, learn it, and love it. Right now.

That being said, making a simple game on an HTML5 canvas element is probably easier than you thought. To begin, create a web page with a canvas element.

<!DOCTYPE html>
<html>
  <head>
    <title>Game</title>
    <style>
     canvas { border: 1px solid #000000; } 
    </style>
  </head>
  <body>

    <div>
      <canvas id="game" width="800" height="450"></canvas>
    </div>
    
  </body>
</html>

You're halfway there! Okay, maybe not halfway. The next thing to do is set up some JavaScript to start working with the canvas. The basic outline of any game is to make a loop that updates the objects on the screen and draws them. In modern browsers, we have a nice utility for that - the window.requestAnimationFrame() function. This method has been added specifically for the purposes of doing animations on web pages, and it is the most efficient way of doing so. The following is a bare-bones version of a game. Note that you have to explicitly call requestAnimationFrame again after each call to your run function (or it will only run once!).

(function(window) {
 
 function Game() {
  
  this.lastTime = null;
  this.paused = false;

  this.canvas = null;
  this.ctx = null;
  
  this.setup = function(options) {
   
   this.canvas = options.canvas;
   this.ctx = this.canvas.getContext("2d");

   var me = this;
   window.requestAnimationFrame(function(e) { me.run(e); });

  };
  
  this.run = function(timestamp) {

   var elapsed;
   if (this.lastTime === null) this.lastTime = timestamp;
   elapsed = timestamp - this.lastTime;
   this.lastTime = timestamp;

   this.gameLoop(elapsed)
   
   var me = this;
   window.requestAnimationFrame(function(e) { me.run(e); });
   
  };
  
  this.gameLoop = function(elapsed) {
   
   // update all your objects here
   
   this.gameDraw();

  };
  
  this.gameDraw = function() {

   // clear your canvas   
   this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);
   
   this.ctx.save();

   // draw all your objects here   
   
   this.ctx.restore();
   
  };

  
 } // Game()
 
 game = new Game();
 
 window.game = game;
 
}(window));

After saving this code (I saved it as "main.js") you can fire it up by adding the following scripts into your HTML file with the canvas element:

<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="js/main.js"></script>
<script type="text/javascript">

    $(function() {

        game.setup({
         canvas: document.getElementById("game")
        });
        
    });
      
</script>

Now as soon as your page is loaded, your setup function is called. It is passed the canvas element and starts looping and drawing. To complete your game, just add some objects to be moved around and drawn!

If you'd like to see my completed code, it's here on GitHub: cwleonard / game-off-2013.

If you'd like to play the completed game, you can find it here: The Frog Lifecycle Game.

Leave a comment below with your scores! A really good time for becoming a frog is about 135 seconds.

Friday, August 23, 2013

We're Kickstartering

Great news! My wife's company, Syslark, Inc., has decided to use Kickstarter to raise the funds to take my FFZ game from amusing prototype to finished game on the OUYA!

She's participating in OUYA's Free the Games Fund, which provides matching funds for games that will be OUYA exclusives for 6 months after launch.



So everyone please have a look and back her if you like what you see.


Monday, August 5, 2013

The Science of Fun

Let's Do Science!

Well, let's at least consider why some games are fun and you want to play them more and more...while other games don't hold your attention for 3 minutes.

Two games that I really think get it right are Minecraft and The Amazing Frog. On the surface, these games have absolutely nothing in common. Punching trees to collect wood in one and throwing a rag-doll frog off the top of a parking garage in the other. So what makes them fun?

First, both are immediately playable. There's no complex story you have to sit through. In fact, I don't know that there's a story at all. There doesn't need to be. And there's no tutorial. You just start doing stuff. You pick it up as you go. You have nothing to lose, except your currently mundane existence in which you are not playing these games.

Second, both create environments of open-ended creativity. Obviously in Minecraft you can build yourself houses or roller-coasters or chicken farms or whatever you want. You can play with friends - one of you digging in holes while the other rigs traps for zombies. Or not. You can really do whatever you want. There are no rules. But The Amazing Frog is not all that different. Okay, so it's more about blowing up cars in Swindon than it is about building things, but there aren't really a lot of rules. You get points for falling, but you don't have to care about that. My kids have also turned the game into hide-and-seek, soccer (well maybe football since it's British), and capture the flag (or crown in this case). Sometimes they just bounce in the bounce house. For like 37 minutes! And there's always something unknown on the horizon. None of us have been able to get in that cargo container hanging from the blimp yet, but it fills our imaginations with ways to maybe get there - all of which end with us blowing something up instead. What's up with that crown anyway?

Third, and this one is maybe odd, but neither game is finished. Huh? Really. Minecraft updates all the time. Do you remember how exciting it was to get carrots on fishing poles so you could finally steer pigs? You'd had pigs to ride for months, and that was fun, but now you can steer them! It's like you just got a whole new game! My daughter gets really excited when Minecraft PE updates on her iPod. New stuff! Even if she's already had that stuff in the PC version, it's still exciting. It's like when you were a kid and you loved checking the mailbox every day...some days you would get something and it would be great! Other days you would get nothing but it just made you more excited about the possibility of getting something tomorrow. These "unfinished" games give you the same feelings. Maybe "unfinished" isn't the right word. Maybe the games are complete in their state of constant change. I can't wait to see the next iteration of Amazing Frog...and if you follow Fayju on Twitter you get to see little hints of things to come that make you even more anxious. Will we get a few more stages? New outfits for the frogs? New things to grab and throw? Or whole new game mechanics? No matter what, I'm sure it will be great - and it keeps players coming back for more.

So now I will summarize.

  1. Stories. Keep them short.
  2. Rules. Keep them few.
  3. Updates. Keep them coming.
And that is how you make a great game. In theory, anyway. If we're going to be scientific about it we have to test this theory by making games according to these rules and see if they become awesome.



Thursday, July 4, 2013

Facebookified and Zyngaficated

I've decided that to truly succeed as a game developer I have to change the way I design things. I have to design for revenue. I have to put revenue before gameplay. Here's my plan...

  1. Limit how long people can play. I know this sound crazy, but just wait. I'll limit my players to 20 minutes of play and then make them wait an hour to play for another 20 minutes - UNLESS they give me another dollar. Then I'll let them play as much as they want, but only for 24 hours. Tomorrow they'll have to give me another dollar.
  2. Start out easy, then make it impossible. Will people quit playing when it gets too difficult? No, they'll already have too much of an emotional investment in the game to walk away. They'll just have to buy a power-up that will enable them to continue. It will cost another $1. Then after that really hard level it will get easier for a little while, you know, to get them back into it before I throw in another impossible level and charge another dollar.
  3. Make you bring friends if you want to keep playing. At first you can play by yourself and multiplayer will be optional. But after a certain point, you have to play with other people if you want to continue. Something in the level won't be possible without a second player. And that second player has to buy the game too! She might not want to at first, but you'll keep twisting her arm until she does. And she will because you're friends. Then BAM! I start getting dollars here and there from her too. Brilliant!
Oh, wait. I forgot. I just want to make things that are fun. But this plan sounds strangely familiar. It sounds like the outline of every Zynga and/or Facebook game ever made.

Is this all the world has to offer? I get to choose between another pointless first-person shooter that costs me $70 up front, or an addictive puzzler that is designed to take my money one dollar at a time?

This is why I'm developing for OUYA.

Saturday, June 15, 2013

Hack It, then Refactor It

I've spent the last several days refactoring my OUYA game. It seems strange to spend so many hours working on the code and the great accomplishment is that it still works. I just felt the need to explain why I do this and how it works for me.

I believe that I am a very results-oriented person. Not to say that the ends always justify the means, but I recognized many years ago that getting a product working is much more important that making sure that all the T's are dotted and the I's are crossed. I've also been known to get forgiveness instead of permission on many occasions.

You can be writing the most elegant, perfect, optimized code in all the world but if no one ever sees or uses the product then what have you really accomplished? This is true for everything, not just software products. Once (1998) I decided to replace the stock 3.8L V6 engine in my 1989 Mercury Cougar with a 5.8L small-block V8. I had 3 months until I needed the car to run again so I could go back to college. As far as we could tell, this feat of automotive engineering had never before been accomplished. The engine did not physically fit in the car. But I wasn't building it to put on display, so we hacked and bent and cut and torched and pounded with a hammer. It wasn't pretty, but it ran. I drove it back to college and almost every day while I was there. I also spent the next 3 years fine-tuning it. Parts were replaced with new ones as they were fabricated. The more powerful engine totally blew out the rest of the drive-train in time, but that got fixed as well. I could have spent those 3 years making it perfect before it ever left the garage, but it was much better to be driving it all that time.

Basically, I learned that success means shipping a product. So how does this relate to hacking and refactoring software? It's pretty much the same thing.

I wanted to get stuff on the screen of the OUYA and get things moving around with the controller as quickly as I could. I needed to see it working, even if the code was less than perfect. I needed to see those results so that I could continue. Letting it "sit in the garage" for too long would just discourage me and I would lose interest.

However, I know better than to leave the code that way for too long. If I am going to build a complete game, my code has to be structured such that it can be built on. It can't be brittle. It has to use the proper design patterns. So every few weeks, I stop adding new features and refactor. I clean up the ugly code and make sure I have a solid foundation before building more. But in the mean time I also have something that my kids and I can play (You don't have to release your product to everyone to count it as a release. My Cougar only had one user, after all).

It's just what works for me. And it works for other people as well. Check out the works of Kent Beck and Martin Fowler. They've written lots of stuff on design patterns and refactoring code.

Also, read this paper.

And as for my Cougar, I no longer drive it but it taught me a lot about successful engineering projects.

Friday, March 22, 2013

Virtual D-Pad Killed by Geometry

I hate virtual D-pads in mobile games. The D-pad was great on my Nintendo Entertainment System, but trying to play Mega Man II on my iPhone with the standard touch-screen replacement for tactile control made me regret spending $2.99 on the game. With nothing to stop my thumb from sliding right off the control zone, Mega Man plunged needlessly to his death so many times. So many times. Oh, the humanity! Well, in this case, the android...ity? Androidity? Is that a word? Feel free to substitute another word in your head when you read this. A word that you would use to express anguish over the massacre of heroic humanoid robots.

So let's just say I hate virtual D-pads. In the Android version of my FFZ game, I was not about to use one. There are a few alternatives that people have come up with, but here I'm going to talk about my current favorite and how I implemented it. It just took a little geometry.

What I wanted was a system where I could swipe my finger anywhere on the screen, and then my frog would move in a similar way. I swipe down and to the right, the frog moves down and to the right by the same distance. I don't have to start my swipe on the frog, so I don't have to block anything on the screen that I don't want to. I basically just want to create a vector with my finger that is then applied to the frog.

Doing this seemed fairly simple. I would just need a class that could represent the line segment created by the finger swipe, and then create a parallel line segment for the frog to move along.

Formula for a Line


Remember back to high school geometry class. The standard equation for a line is
y = mx + b
where m is the slope and b is the y-intercept (where the line will cross the y-axis). Slope is really important in this case, since that's basically what I want to duplicate in a second line for the frog's movement. Remember, lines with the same slope are parallel.

How, then, does one calculate slope? If you have a line, take any two points on it. Let's represent these two points as (x1, y1) and (x2, y2). Subtract y2 from y1 and divide that by the value of x1 minus x2.
m = (y1 - y2) / (x1 - x2)
The two points I'll use are the positions of the start of the touch event and the end of the touch event. So here's what my FrogPath class looks like so far.

public class FrogPath {

  private float x1;
  private float x2;
  private float y1;
  private float y2;
  private float slope;
  private boolean vertical;
 
  public void setStart(float x, float y) {
    this.x1 = x;
    this.y1 = y;
  }
 
  public void setEnd(float x, float y) {
  
    this.x2 = x;
    this.y2 = y;
    this.calculateSlope();
  
  }
 
  private void calculateSlope() {
    if (x1 - x2 == 0) { // don't divide by 0! no!
      slope = 0;
      vertical = true;
    } else {
      slope = (y1 - y2) / (x1 - x2);
      vertical = false;
    }
  }

}

Note the special handling for lines that go straight up and down. If there was no change in the x values for the two points, you'll divide by zero if you're not careful to check for that. Instead, a vertical line is said to have no slope. The formula for a line with no slope looks a little different, it's just x = n. The y value can be anything, but x will always be the same and there's no y-intercept. It's a little different than a horizontal line, which has a slope of 0. You can use the standard formula for those types of lines, but the value for m is 0 which essentially eliminates x from the equation. You're left with just y = n where n is always equal to b, because the line will cross the y-axis at the same value as every other point on the line! Consider the horizontal line y = 2, for example. Anyway, the point is that we have to perform special handling for vertical lines but not horizontal ones.

Thanks to Garrett Bartley for the Virtual Graph Paper I used here! 

So in my Android app, when I get an ACTION_DOWN MotionEvent I create a new FrogPath object and set the start coordinates. I hold on to that object until I get an ACTION_UP event, at which time I set the end coordinates. The FrogPath object calculates the slope of the line. That was the easy part!

Can We Get There from Here?


Now I have a slope and I have the current coordinates of my frog. I calculate the distance I want the frog to move, based on his speed and how much time passes between animation frames. What now? To calculate his new position, I have to figure out new coordinates that are on a line with the calculated slope that passes through the current coordinates. These new coordinates have to be the calculated distance from the current coordinates. Sound easy? Let's look at the picture...


Here we can say that c represents the distance we want to move the frog along the line. We know where the frog is now. Your first thought might be to call on your old friend Pythagoras and do that whole a2 + b2 thing. Sorry, but Pythagoras can't help you here. There's just not enough information. We need to find both a and b, and we can't do that with just c. This is where it get's tricky. You need to look at the problem in a different way. What if instead of seeing a triangle, you see a circle?

We can figure out the next position of the frog using the formula for a circle and determining where a circle centered at the frog's current coordinates and with radius r will intersect with the line. You may not be as familiar with the formula for a circle as you were with the formula for a line, but here it is. If the coordinates for the center of the circle are represented as (c, d) and a point on the circle is represented as (x, y) and r is the radius, the standard form circle equation is
(x - c)2 + (y - d)2 = r2
It might look crazy, but if you think about it, we have enough information to solve the problem if we combine the equation of our line with the equation of our circle. We know c and d, because those are the current coordinates of the frog. We know r because that is the distance we want the frog to move. And we know y (in terms of x anyway) because the line formula is y = mx + b. We know m because that is the slope. We can find b because we have a point on the line (the frog's current coordinates) and the slope. That's everything. Just plug it all in and solve for x! If you factored it all out, you'd come up with an equation like this for x:
x = c ± r / √(1 + m2)
Now you might notice that plus/minus thing in there, and rightly so - if you look at the picture above it clearly shows that the circle intersects the line in two places. How do you know which x value you want? Simple. You go back to your original two points that you used to calculate the slope in the first place. If the x value for the end point is greater than the x value for the start point, do a plus in the equation above. If not, do a minus. This basically means that if the user moved their finger from left to right you want to pick the intersection point on the right to keep the frog moving in the right direction. Pun intended.

We're almost done now. We can solve for x. But we still need a y value for the frog's new coordinates. Back to the line formula! Take our newly acquired value for x and plug it into our line equation y = mx + b along with the known values for m and b. You'll easily get y and now you've got a coordinate pair!

Just one more minor note before we get to the code. Remember that whole vertical line thing? Yeah, we need to handle that. But, good news! If we have a vertical line we don't need to mess with any circles or triangles or dodecahedrons or anything. Just add or subtract the distance moved from the current y coordinate (again, depending on if the original swipe was up or down) and return that paired with the current x coordinate.

Here's the two new methods that should be added to the FrogPath class shown above:

private float yIntercept(float x, float y, float m) {
  return (y - (m * x));
}
 
public float[] getNextPoint(float c, float d, float dist) {
  
  if (vertical) {
 
    float yp = d;
    if (this.y2 < this.y1) {
      yp -= dist;
    } else {
      yp += dist;
    }
    return new float[] {c, yp};
   
  } else {

    float b = yIntercept(c, d, this.slope);

    float xp = 0f;
    if (this.x2 < this.x1) {
      xp = (float) (c - (dist / (Math.sqrt(1+Math.pow(this.slope, 2)))));
    } else {
      xp = (float) (c + (dist / (Math.sqrt(1+Math.pow(this.slope, 2)))));
    }
    float yp = (this.slope * xp) + b;
    return new float[] {xp, yp};

  }
  
}

Just note that I return the new coordinates as an array of floats where the x coordinate is at position 0 and the y coordinate is at position 1. You could easily substitute some kind of object that represents a point if you prefer.

The only thing left to do is to figure out when to stop moving. That task is relatively simple, you just have to keep track of the total distance moved and stop when it equals the distance moved in the original screen swipe.

So that's it. That's how I used geometry that I probably should have learned in high school to defeat the dreaded virtual D-pad in a mobile game. And speaking of defeating something, who do you think would win in a fight between Pythagoras and Archimedes? Leave your comments below. My money's on Archy. Yeah, that's right. I called him Archy. Archimedes had a nickname. That's what his friends called him.

Sunday, March 17, 2013

It would appear that I've made an error

Back in 2011 I implemented the Separating Axis Theorem in JavaScript to help detect polygon collisions in HTML5 games. Now that I've started implementing similar games in Java to play on my OUYA, it has come to my attention that my algorithm had a slight mistake in it.

The problem had to do with calculating the Minimum Translation Vector, which tells you how to move one of the polygons to get them out of collision. If you were just using the algorithm to detect collision with a true/false you wouldn't notice any problem.

Here's what I did wrong...

After projecting both shapes' vertices onto the normal axis, you will have two line segments and you are supposed to determine how big the overlap (if any) is between the them. You can read a great explanation of the whole algorithm on the Code Zealot blog.

So let's say you end up with two line segments, A and B. Both sit on the X axis, so you can ignore any Y value. A runs from 1.5 to 4.4 while B runs from -2.8 to 2. What would you say the overlap is? The correct answer would be 0.5, but my implementation of the algorithm was coming up with 7.2.

Here was my calculation of the overlap:
o = (maxA > minB ? maxA - minB : maxB - minA);
See anything wrong there? In the case I outlined above, maxA was 4.4, obviously greater than minB which was -2.8. So I calculated the overlap as 4.4 + 2.8. Wrong! What was I thinking? Try it yourself with other line segments...you'll see that it sometimes gives you a correct value but often does not. If only I had created a good unit test for this code years ago. Fortunately, I did create such a test for my Java version using JUnit, and found my mistake. Here is the correct calculation of overlap:
o = (maxA > maxB ? maxB - minA : maxA - minB);
I've updated my JavaScript version, so people who find it on my previous blog entry won't be led astray. Sorry about that. I'll post my Java version soon, along with what is (hopefully) a good explanation of how it works.

Saturday, February 23, 2013

Node.js and Socket.io Allow Frogs to Play Together

It can be lonely out there for frogs. They need to interact with other frogs, and not just on Facebook. In the real world. But this isn't the real world, it's a virtual world that is supposed to be sorta like the real world. For frogs. Let's just say that if you want to connect multiple client browsers together to create some sort of online frog collaboration environment, there is no better way than with Node.js and Socket.io.

FFZ is where I play around with browser tech like WebSockets, Canvas, and HTML5 Audio. I like to make things with frogs in them. In this application, you can move a frog around a small world filled with trees, flowers, rocks, and streams. But it's even more fun when another person is on the site at the same time you are - you'll play in a collaborative environment. You will see their frog move in real-time and they'll see yours. It amuses my young children for hours. Just press "R" to ribbit.

How do I hook everybody's browser up together? Well first of all, don't expect it to work with Internet Explorer. Seriously. IE, how can you even show your face in public anymore? Chrome and Firefox work like browsers should. I'm talking WebSockets. Sure, you can do WebSockets the old-fashioned way...but Socket.io is a great utility that abstracts much of the complexity away from you. It's built for Node.js, the awesome server-side Javascript engine. Node allows you to hook up tons of clients together with very little overhead because of its event-driven IO model.

My FFZ "server" is a Node.js program that listens for events from the client browsers running the application and publishes events out to the clients as well. When one frog moves, it publishes its changed position to the server, which turns around the publishes it to all the other browsers so they can update the positions of that frog on their screens. And thanks to Socket.io, it's extremely simple.

Here's my Node server code:


var http = require("http");
var sockio = require("socket.io");

var frogs = [];

var io = sockio.listen(8080);
io.configure(function() {
    io.set('log level', 2);
    io.set('transports', [
      'websocket'
    ]);
});

io.sockets.on("connection", function(socket) {
      
    socket.on("frogmove", function(fdata) {
        socket.broadcast.emit("fm", fdata);
    });

    socket.on("objmove", function(odata) {
        socket.broadcast.emit('sm', odata);
    });
      
    socket.on("ribbit", function(fdata) {
        socket.broadcast.emit("rbbt", fdata);
    });
      
    socket.on("startup", function(msg) {
        console.log("frog " + msg.fid + " connected");
        socket.broadcast.emit("newfrog", msg.fid);
 socket.set("frog id", msg.fid);
 frogs.forEach(function(i) {
            socket.emit("newfrog", i);
 });
 frogs.push(msg.fid);
    });
      
    socket.on("disconnect", function() {
        socket.get("frog id", function(err, fid) {
            console.log("frog " + fid + " disconnected");
     socket.broadcast.emit("byefrog", fid);
         if (frogs.indexOf(fid) != -1) {
                frogs.splice(frogs.indexOf(fid), 1);
            }
 });
    });

});


So hopefully the first part of the code is fairly self-explanatory. In the configuration of the socket listener, I set the "transports" to be just "websocket" because I don't want it to automatically downgrade to Flash or long-polling. Those things are fine I suppose but I wanted to use FFZ to try out WebSockets. (I actually did try Flash and long-polling with FFZ. Flash is ok but long-polling just doesn't work with an application like this - there was just too much data being transmitted and the user experience was poor.)

The second block is where the real magic happens. On a "connection" event, we set up the event listeners for that socket. The first three events are very simple. When a socket, which represents a connection to a client, gets a "frogmove" event, for example, it just turns around and broadcasts it out again. The "broadcast" method sends a message to all known sockets except oneself - so the sender isn't going to get the message back but every other socket that Socket.io knows about will get it. This is how I handle the simple events - moving frogs and objects and making frogs ribbit.

The "startup" event gets a little more complicated. When a new client connects, they need to let all the other clients know to add them to their screens, but the new client also needs to know where all the existing frogs are so they can be added to their screen. So here I use the "socket.broadcast.emit" method again to tell everyone else about the new frog - and then I use "socket.emit" to send a "newfrog" event back to the socket that just joined. This is a bit of a trick because these aren't exactly new frogs (they existed before the new client joined) but the client will behave the same way as if a new frog joined - by adding the other frog(s) to the screen and tracking them for future updates. Finally, I add the new client id to the frogs array so the server knows about this frog in the future, at least until it disconnects.

That brings me to the "disconnect" event. Again, I use the broadcast to tell everyone else to stop displaying and tracking the frog that just left. I also then remove it from the frogs array.

So there you have it. A server in Node.js that keeps all the frogs playing nicely together. Easy peasy lemon squeezy. Now let's take a gander at the client code too. It's almost as simple.

The first thing to do in the client is to load the Socket.io code. But it serves itself! That's right, when Socket.io wants a sandwich it makes it and brings it to itself. You just source the JavaScript right from your Node.js server. So for example, if you look at the server code above you will notice that I'm running on port 8080 and I serve everything from amphibian.com. So I have this in my HTML:

<script type="text/javascript" src="http://www.amphibian.com:8080/socket.io/socket.io.js"></script>

Bam! You've got the Socket.io client now! By the way, you can actually serve the client manually if you need to for some obscure reason. See https://github.com/LearnBoost/socket.io-client

This is what I do to get the socket connected and set up the client's frog to publish events:


<script type="text/javascript">

sckt = io.connect("http://www.amphibian.com:8080");

sckt.on("connect", function() {

    console.log("socket connected");
    frog.bind('move', function(fdata) {
        // fdata will have the frog's id and position info
        sckt.emit("frogmove", fdata);
    });

    frog.bind('ribbit', function(fdata) {
        // fdata will have the frog's id and position info
        sckt.emit("ribbit", fdata);
    });

});

</script>


The "connect" call is fairly simple, you just give it the URL. Then you get up your connect event callback. When the "connect" event occurs, I bind some events on the client's frog to functions which will emit data over the socket. (I use MicroEvent.js to do this. You can read more about that here. It is awesome.) This works pretty much the same way as on the server side. Calling "emit" with an event name and some data sends that event+data to the server where (hopefully) there is a callback set up listening for that event. So in the code above, I emit the "frogmove" event and the "ribbit" event, both of which are listened for in the server code shown previously.

Remember that the server essentially rebroadcasts events from one client to all the other clients using custom event names. I'll just show you one here, the "rbbt" event, but the others are all very similar.


<script type="text/javascript">

sckt.on("rbbt", function(fdata) {
    for (var f = 0; f < otherfrogs.length; f++) {
        if (otherfrogs[f].uid == fdata.id) {
            otherfrogs[f].ribbit();
        }
    }
});

</script>

If you look at the server code and the first part of the client setup, you'll see that when a client's frog ribbits the event is published over the socket as the "ribbit" event. The server gets that and republishes to all other clients as a "rbbt" event. I removed the vowels. Servers don't like to broadcast vowels. No, that statement is completely false. Really I just wanted a slightly different event name so I could tell the client and server events apart. Anyway, this is an example of the client listening for the "rbbt" custom event. If this client gets such an event it means that some other client's frog is making a sound and so we should show that frog opening his mouth and play the sound as well. The data that comes in will have the other frog's id in it so we just look for which frog it should be and then call the "ribbit" method on that frog.

Couldn't be easier, right?

And there's even better news! What if you wanted to hook up your OUYA game to a Node.js server using Socket.io? I know I do! There is a Java client available for Socket.io that works on Android. So technically you could hook up web browsers, mobile phones, game consoles, and possibly even refrigerators all to the same server to share data in real-time. Yes, Node.js most assuredly rocks.


Thursday, January 10, 2013

Getting Started with my OUYA

So now I have my OUYA Dev kit all unboxed and hooked up to the TV and everything. The screens and welcome video look nice, but to load anything on it I needed to get it hooked up to the computer and detected as a valid Android device.

I like to do my development in Eclipse on Windows. I know, I'm crazy. I like my Mac and all, but when I write software (except for iOS of course) I've always been in a Microsoft environment. Maybe it's because my first introduction to programming was BASIC in DOS. Maybe? But from BASIC to Turbo Pascal to C to Java, I've always used a DOS or Windows PC. I'm now on Windows 7 64-bit and of course the OUYA wasn't detected as a valid device when I plugged it in.

The Windows section of the setup information for OUYA devs is a little sparse right now (ok, it's empty) but the forums did provide me with a solution, which I will now share. Hopefully they'll provide some kind of driver with the OUYA when it is released to the general public in a few months, but if not this trick will probably still work.

First, find the Android device driver file provided by Google in your Android SDK. Mine was

C:\Users\User Name\AppData\Local\Android\android-sdk\extras\google\android_winusb.inf

and yours is probably somewhere similar. Open that file up in Nodepad and add these two lines in the [Google.NTx86] section:


%SingleAdbInterface% = USB_Install, USB\VID_0955&PID_7100&MI_01
%CompositeAdbInterface% = USB_Install, USB\VID_0955&PID_7100&REV_0232&MI_01


Then you go to your Device Manager and find the unknown device. It is probably calling itself "Cardhu" or something. I don't know what that's about, but just open that up and click the "Update Driver" button. Choose "Browse my computer for driver software" and then "Let me pick from a list of device drivers on my computer". On the next screen, click on the "Have Disk" button and then browse for the .INF file you edited earlier. Then when asked to pick a model, select "Android ADB Interface". You'll probably get warnings about the driver not being signed. Tell the Windows nanny to take a hike and install the driver anyway.

That's what worked for me.

Tuesday, January 1, 2013

Unboxing my OUYA Dev Kit

I received my OUYA development kit yesterday! They really shipped them to us when they said they would. These early dev models are special - they have clear casing and say "OUYA DEVS" on them. Here's what was in the box.


Here's a close-up of the back of the console. Power is on the top. Below it is a mini-USB for connecting it to your PC and an Ethernet port. The bottom two ports are the HDMI output and a USB input. I used that one to connect a mouse to navigate the settings screens before I paired the controllers. I actually had trouble getting the controllers paired with the console, and here's why. To put the controller in pairing mode, you hold in the power button for 5 seconds. To shut down the controller, you hold in the button for 7 seconds. I guess I'm not good at counting in my head, so when I would keep the button down just a little too long it would shut down in the middle of pairing. I would like to see a different button used to pair the devices.


Here's a picture of one of the controllers beside the console. They say that the controller design is not final yet, so if you get one in the spring they might look a little different.

OUYA Console and Controller

They even supplied Duracell batteries for the controllers! That was nice, since I don't really have enough batteries in my house right now. And when I was writing this, my wireless mouse needed new batteries.


You put one battery in each side of the controller. I thought that the panels came off a little too easily, and they've already warned us that shaking the controller too hard can pop the batteries out. Hope they address those issues before the final production.


Here's a close-up of a controller. The buttons are labeled O, U, Y, and A. Both sticks are buttons if you push them straight down as well. There's two triggers and two bumpers along the top. My initial impression is that the triggers might be a little hard for me to use but I like the bumper locations.

OUYA Controller