The Ironism

The Ironism


The lair of Lars J. Nilsson. Contains random musings on beer, writing and this thing we call life.

March 2010
MTWTFSS
« Feb Apr »
1234567
891011121314
15161718192021
22232425262728
293031 

Categories


Asynchronous Games in Firebase; pt II

fungrimfungrim

Note: this post is cross-posted on Cubeia.com.

Last post I looked at the motivation for writing asynchronous multiplayer games on top of Firebase.  This post I’ll sketch an outline on how to actually do it.The first thing to consider is that we now have two notions: The Firebase concept of area (called “table” for legacy reasons) and the overall concept of a “game”. Firebase tables are associated with games, but whereas in a synchronous game the table probably would be the game such that if the table is closed, the game is over, in asynchronous games the table may come and go, but the game itself would survive.Oh by the way, I’ll use Java in this post, but remember you can write it in script languages Ruby, Python and Groovy as well. :-)Let’s step it through:

  1. The game is created. This is probably done on a website somewhere and does not involve Firebase at all.
  2. Client connects. When game client is opened (someone wants to make a move), the client connects to Firebase and does the following:
    1. Search the lobby for any table with the correct “gameId” set in the attributes.
    2. If a table is found, attempt a “join” command.
    3. If a table is not found, or the join fails, send a table creation request and make sure to include the “gameId”.
  3. Activator creates table. When a client cannot find a table for the game, it send a table creation request, the activator then reads the game and its state from database, and creates a new table.
  4. Game play. The player makes its moves and actions normally via Firebase. The game in Firebase either saves the state on each action, or delegates to the time when the table is being closed (see below).
  5. Table closes. When the activator finds  table which has not been accessed for some time. If needed it should also save the game state at this point (see above).

I’ll focus on points no. 3, 4 and 5 above for the rest of this post. And I’ll use code examples from the Kalaha game I’m currently involved in writing.Activator / Table creationThe game activator in Firebase is the components that know how to create and destroy tables in the system. We’ll follow best practises (but we’ll skip the “init” state for now) as it helps us save the state to database.The activator should first make sure to implement RequestAwareActivator to make sure it gets the requests:

When a client wants a table to join for a specific game, it’ll send a table creation request, and the activator should read the game state from the database and create a new table. Somewhat compressed, it may look like this:

The Participant is an inner class for handling the request, like so:

As you can see above the creation participant sets the Game object on the table when it is created. It also sets a lobby attribute with the game ID which is important for the client to find the table. The lobby path above is kept simple for this example and the TABLE_STATE_ATTRIBUTE is a constant you can define yourself.Now we need to close the table when it isn’t used. This is somewhat outside the scope of this post, but I’ll post some pseudo code here to demonstrate table destruction:

The above should be called regularly from a scheduled task. The “get from attributes” method are trivial, for example:

The attributes “last modified” and “seated” are standard attributes and always available. The “table state” attribute is not and you’d have to set and get it yourself. In “check close” we’ll check the table state, destroy it if it is closed and if not, send an action to the table in order to clsoe it:

And finally, the method to send a “close youself” action to the table would look something like this:

Which should be more or less self-explainable. The action is of course whatever type of object and encoding you use in your game, it could be standard Java objects and Serialization for example.Table Play / ClosingThe table should work as usual, the only thing we’ll add is to save the game state on the “close table command”. We need to translate the action byte data to an object, then differ between internal actions and client actions and process. Something like this perhaps (again from my Kalaha game):

In the above all kalaha actions are treated separately as client actions and the “close table” action simple sets the table state attribute to “CLOSED” to mark for the activator that the table is safe to remove, and then saves the game state to database.ConclusionAs you can see, the actual code to manage asynchronous games in Firebase is minimal, you’re going to spend infinitely more time on game logic than state handling. All the code I’ve omitted is trivial. In fact, writing this article took me longer than implementing the feature in my game!Which ends our discussion about asynchronous games in Firebase. Last post we looked at motivation and background, and in this post we’ve seen how to actually program it in Firebase. Now go and try it yourself!

The proprietor of this blog. Lunchtime poet, former opera singer, computer programmer. But not always in that order. Ask me again tomorrow.

    Comments 0
    There are currently no comments.