Making an Asynchronous Multiplayer Game
Hot off the heels of the launch of Pocket Vault, it’s time to start a brand new development. We’re going to develop an asynchronous multiplayer mobile game that supports 2 or more players. At this moment in time we have a spark of an idea for the core gameplay mechanics, and this development blog will serve as a dumping ground of our thoughts as we develop this into a finished, published product.
Building on what we previously learned about web server communication within Unity during the development of Pocket Vault, we are going a few steps further and planning a number of features that require more complex client-server interactions. We will need at least the following databased features:
Users and guest accounts;
- Players should be able to choose "quick game" without the need to log in.
Game finder lobby;
- List of open, joinable games;
- Abilty to create a new game;
- Player's own list of games they're participating in;
- Invite friends via Facebook, Game Center, contacts list;
Game state log;
- Log each player's submitted moves, in sequence;
- Reconstruct the game according to previously submitted moves. In our game, each player submits their move before the round is resolved in turn order. Only when the last player has submitted their turn, will each player be able to see what move everybody else made. Therefore when serving up the game state for reconstruction, we will need to withhold moves from the current round, until each player has been;
- Ability to ban abusive players from chat;
- Log sender, time sent, message;
- Log which players have seen which messages;
- Consider ability to private message another player;
- Consider purging chat log at game end;
When developing Pocket Vault it was essential for content to be delivered with client-server communications. Since the vaults come and go as they are won, new vaults are added all the time and each one is generated with a unique winning code, and hence this information cannot be hard-coded into the application. While the app relies extensively on content served from the cloud, the information that is stored is simple in nature.
What we are proposing with our new game is vastly more complicated because being a multiplayer game, we need to store game state. Everything in the level needs to be initialized exactly the same for each player when they come to make their move. Every action made by each user needs to be logged in the order it was made. There is potentially a huge amount of data to store, and the big question is "How do we structure the database to handle the multitude of game data and object types involved in developing an async multiplayer game?".
It's early days, but I have some immediate points of interest & concerns:
- A simple fact of life is that you can never trust data submitted by the client. If each player is to submit their selected moves to the server, how can we be sure that what they’re submitting is genuine? What stops them sending "cheat" data by hacking the application and manipulating the output sent to the server? In the game, certain moves may have limitations that could potentially be bypassed when the data is sent to the server. The server-side code would therefore need to validate any user-submitted data, rejecting it and returning an error if it doesn’t like what it receives. This may be difficult to validate outside of the game engine.
- It’s currently undecided whether or not the game will utilize the physics engine built into Unity. The game we have in mind involves watching all previous moves play out before the current round’s moves are resolved. If we use the physics engine, will it produce the exact same end result every time and across all devices – Does chaos theory exist within the engine? It would be disastrous if players experienced different outcomes of the physics engine, when it’s critical for the game state to be exactly the same for all players. I suppose this is something to be concerned about regardless of the use of Physics.
Multiplayer game speed. I love async multiplayer games because they allow participants to take part in a game that spans days or even weeks without requiring more than a few minutes of play at a time - Perfect for people who live such a hectic lifestyle that 'live' multiplayer gaming is just not an option.
However, some asyc games have annoying waiting times where players have to wait for the latest moves to be pushed to them from the server - Ticket to Ride on iOS is one good example. There's no refresh button, and sometimes closing and reopening the app is a quicker way to recieve the latest game state.
Our new game must be quick to provide participants with the latest game state, so players can enjoy a 'live' game without annoying wait times. Push notifications are essential, but only for players who haven't yet received the latest data. Our database will therefore need to log which players have been 'updated' with the latest state. We'll also need to remind players that it's their turn if they haven't played their move within a certain timeframe, and these reminders should be limited to just a few times.
What happens if a player opts to leave the game? Should their existance simply be removed from the game? Should they "die" at the point they left, leaving their previous moves in place, so as not to affect the game in any meaningful way? Alternatively the game could end but just writing that gives me bad vibes and I think it would be a cheap and nasty way to handle this issue.
This article has briefly covered some initial thoughts on developing our new, async multiplayer game. As we progress through this project, there will no doubt be many more issues and considerations that we'll blog about as they come up.In the next article (coming soon), we'll discuss the game we're proposing and our initial ideas to get you excited about what's to come.