Multiplayer Family Dots is still fresh in the App Store, but Famigo was already hard at work polishing the next app during its launch. Hot Potato takes everyone’s barely-contained desire to launch scorching hot tubers at their friends’ faces and turns it into socially acceptable family fun (guaranteed less mess and fewer hospital visits).
Hot Potato presented a completely different set of challenges from Family Dots. The Famigo API is designed with asynchronous gaming in mind, and Family Dots is a great example of this. Play happens at the user’s leisure, so games can run for weeks, with hours (or even days) between turns. After each move, Famigo updates the game state for the other players, acting as the game’s primary mechanism for synchronization. Performance is important, but not critical to the gameplay.
On the other hand, Hot Potato is fast and local. Users don’t play “through” Famigo. Instead, a single device acts as the server and communicates with the other devices via WiFi. Also a round of gameplay completes within seconds, and score during the game is less important than how the game ends (namely which poor sap was left holding the tater), so there’s really no need to keep track of game state while the game is in progress.
Thus the Famigo server has a slightly different purpose. It tallies up the final scores for players who choose to log into their Famigo accounts (giving them Family/Member Points when appropriate), but not requiring players to use the service. Here Famigo is an added bonus, a little icing on the potato if you will, rather than the central mechanism of gameplay.
But never fear. This in no way hurts the Famigo API’s feelings, and no matter a game’s needs, it’s happy to help in any way, big or small. Famigo is all about flexibility, so our service has methods allowing developers to send information unobtrusively to and from the Famigo server at any point in the game. So I’m happy to report that integration with Famigo was not the major challenge.
Instead, we got to work directly on the problem of quickly synchronizing devices via message passing, anticipating and preventing race conditions, and generally having the pleasure of fighting with concurrency. Note that I am not a masochist, so it was not actually a pleasure.
But I certainly did learn a lot! Networking gurus can skip on by, but for people who just want to dabble in it or on occasion work with them as a necessity, these few lessons may be of interest.
1. Keep the network as much of a dictatorship as possible
Especially for a small network like in a Hot Potato game (with a maximum of nine players), I found it better to let the server do most of the broadcasting and all of the game state tracking. Only the server needs to run the potato timer, track the potato state graphics etc, so also let the server decide if other clients need that information, and pass messages accordingly.
2. The order in which messages arrive is unpredictable so plan for all cases
Like with parallel programming, synchronization across a network is rife with race conditions. Keeping a dictatorship helps mitigate this, but it’s important to consider how different orders of execution affect the program. What happens when the game has ended but a client receives a game update? Who knows? There might be a spectacular explosion, or, worse, there might not be. It might manifest in some small, seemingly unrelated way. So always consider concurrency problems no matter the bug.
3. Keep messages succinct and to a minimum but know what the minimum is
This is obvious in theory, but sometimes hard in practice to know what that means. First you need to determine what the minimum amount of information is, and that by itself is not necessarily trivial. And of course the actual implementation can explode into something inefficient and unwieldy in no time. So there’s a lot that can go wrong for a relatively small part of the game. The solution to this really comes down to having good design and good implementation, which is important for all areas of coding, but absolutely critical in this area.
Feel free to contribute your own thoughts and experiences, as I’m well aware that there’s more subtlety to networks than just the aforementioned issues!