PlayerIO

The fastest way to build online games without breaking a sweat.

Building Flash Multiplayer Games

This tutorial is also available in a pure flash version..

Table of contents
1 - Introduction 8 - Synchronization
2 - Game Basics 9 - Interpolation
3 - Turn Based Games 10 - Latency
4 - Network Architectures 11 - Tips & Tricks
5 - Security 12 - Game: Turn Based
6 - Example Game 13 - Game: Realtime uninterpolated
7 - Real Time Games 14 - Game: Realtime interpolated

Example game

Often an example is required before these sorts of concepts can properly sink in. I have prepared a VERY simple sample game.

multiplayer game grid

You can play it here

You can download the source here

This game uses the server-client setup and cannot be hacked by conventional means. (it is easy to prove a game is secure when it is so simple)

The objective of the game is to take control of as much of a 10x10 grid as is possible. To do so, each player places a piece anywhere on the board. Once all players have moved, each piece grows.

You will notice that this game is very stripped down and contains none of the features that you would find in a commercial game. For example, players should get kicked or skipped if they take too long to move, (if you only skip AFK players, beware. It means they will drag the turn to timeout for every turn afterwards, ruining the experience) the user should be given more information (such as the colors of his opponents, etc.

While all of these features are nice and are necessary in a final game, they are also superficial and un-needed in this example.

The code is too long (300 lines total) to go over inside this tutorial, but I will go over the general control flow and it will be easy for you to follow along from the comments inside the code itself. (download it and open it if you haven't already.)

empty multiplayer game grid

First, we look at what happens when the game starts and users join. On the server and the clients, we have declared a 2-dimensional array to store the board and the server computes a color for each player and informs them of their color through the "assign" message (see UserJoined() method)

The server will then wait for user input. On the client side, we send out a message when the user clicks on the grid (see clicky() function). Note that this is the only message that the client sends out, as it is the only input that we have as players.

The server then receives this information in it's GotMessage() function and begins to act. First, it performs the move, then it sends a message out to all clients informing them of this event. Note that the server must append the player color to the message so that all players can know who moved.

On the client side again, we act on the move once we get the server message in the classic send-wait-move setup. The details of this can be seen in the client's gotMessage() function.

Finally, when all players have moved, the server will send out yet another message, "nextTurn". Both the client and the server will then let the pieces on the board grow. Notice that we did not need to send the updated board to each player. Each player is able to compute this for himself. This computation is fully deterministic. But beware, there is a scenario where you must send the whole board to players in this game.

When a player joins in, they do not know what moves have been made already. As such, the server must inform them of the game's current state.

More often then not, if you allow a player to join in mid-game you will have to send them a large amount of information. If possible, you will want to do this with a single message (multiple messages are wasteful). In this example, we send a message with all 100 squares appended on to the end. This is the "grid" message (see UserJoined() method on the server)

The final message we send out from the server is the "newGame" message. This is sent when all squares are filled and we must start the game again to keep on playing. (note that each client knows the game is over, but the server waits 5 seconds before broadcasting this message and restarting the game. Because we want to keep synced, we broadcast a message to tell the clients when they can refresh)

That covers just about all of this game's functionality. Take a good look at the gotMessage() function in the client code. Make sure you understand how the reception of messages works and you can understand everything that this function does.

Finally, we talked about security and we made the very strong claim that this game could not be hacked by conventional means. This is true.

Let us take a look at the possible vulnerabilities in this game:

First, would be the client application. It would be easy enough for the hacker to wave his hands and turn all squares into his color, rendering him the winner on his screen. But to what end? This will still not effect other players. All that he accomplishes is messing up his own game.

Secondly, he could try to modify messages so that if benefited him. The server will only act on 1 message type ("place") thus he must use that. Unfortunately for him, the server will check if he is allowed to move and if the co-ordinates he gives are accurate. The worst he can do is take his turn normally!

When games get more complex it becomes harder to make 100% claims such as this one. But, as long as you make sure to program defensively, perfect security is within arm's reach.



Table of contents
1 - Introduction 8 - Synchronization
2 - Game Basics 9 - Interpolation
3 - Turn Based Games 10 - Latency
4 - Network Architectures 11 - Tips & Tricks
5 - Security 12 - Game: Turn Based
6 - Example Game 13 - Game: Realtime uninterpolated
7 - Real Time Games 14 - Game: Realtime interpolated


About the author

Ryan Brady is a Canadian developer who is currently going to the university of Waterloo. When he isn't fooling around with friends or dealing with an ungodly amount of course work, he likes to design and build games.

Two of the things Ryan likes most above all else are sarcasm and irony. Thus, he likes other people when they have a sense of humor and don't take offence at playful stabs and teasing. Otherwise, people tend to think Ryan hates them and/or the entire universe.

Subscribing to the "Work hard, Play hard" mindset, Ryan is always on the move. There are not enough hours in the day to do everything he wants to do (which is quite a bit). As a habit, Ryan designs more things then he has time to make. Alphas and proofs of concepts are his bread and butter though he always wishes he could make them into full games.

Every so often, you will see Ryan with a full beard on his chin. This commonly refereed to as Schrodinger's beard as you never know if Ryan will have it when you see him next. He re-grows it in under a week.

Every 4 months, Ryan has a co-op term so he moves around quite a bit. He might be living in Canada one month then be living in San Fran the next. You will never know when Ryan will be at large in your area next (until it is too late).