Here at Bocoup I’ve been building a lot of multiplayer HTML5 games using Node.js and Socket.io. This stack has been working great for us! We’ve used Socket.io in our work with Game Show Network, PBS and MIT, and we build all kinds of stuff on Node.
My experience on these projects has led me to identify multiple chunks of code that I write again and again. If only there was a software library that did the exact things I needed! Well, thanks to Open Source Time at Bocoup, now there is!
Cloak is a library for multiplayer HTML5 games that handles client/server messaging, room/lobby management, and the fiddly edge cases that you don’t want to think about. It’s the plumbing you don’t want to fret over when you’re too busy designing your game. It has both a server and a client library and handles all the communication between them. It’s a lot like writing Socket.io code, but with added features specific to game development.
When making a game with Socket.io, one of the first things you’ll do is write some server code to handle incoming connections. It might look something like this:
Now, what happens if the user’s connection drops for a moment? With this code, a new game would be started. Let’s use a global
games map and socket IDs to try to resume games:
This is a start. But this highlights a bunch of edge cases we haven’t considered yet. What happens to the game if the user never reconnects? How long do they have to reconnect? What happens when a player reconnects after it’s been too long?
Even if we solved all those problems, we wouldn’t even have multiplayer yet! Let’s skip those problems for now and modify this code for a two-player game.
This may work, but now we have a whole slew of new questions. How does the client know if they’re waiting or in a game? How long might they be waiting? Will someone end up in the waiting state again when their game is done? Should
waiting be a queue?
And of course, when you do all this yourself, there will be bugs. Did you notice the rather serious bugs in the above code? First, the
game variable is never set for users that go into
socket.id is different on a new connection, so the client would have to save an id and use it to resume.
It goes on and on. Who wants to do that stuff, wouldn’t you rather be making the game itself? That’s why Cloak handles users, reconnection, lobbies, and rooms.
Let’s look at how you might start writing the same game in Cloak:
As you can see, Cloak already handles a lot of the concerns that were brought up as we started writing our server code.
You probably noticed that this server code sends a few messages to users. Specifically, it sends
gameStart. Let’s look at the Cloak client code that would run in the browser and handle those messages:
And of course communication is two-way. You may remember that the server handles a
move message from the client. The client could send this message simply with
It stands to reason that as I make more games I’ll add more cool stuff to Cloak. I hope it’s useful for you too, and I hope you send a pull request on GitHub if you add anything nifty!