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

Network architectures

Peer-to-peer architecture

In this setup, each client has control over the game data and the server is used only to connect the clients together and allow them to share their data with each other,

Our first problem is with security. This kind of setup is a hacker's delight! A gold mine of places to exploit and cheat. Even worse, you have limited tools to block him, and almost no tools that can stop him completely.

Let us pretend that player 1 and player 2 are playing a simple turn-based game where each must attack the other in turn. Let us also say that player 1 is a hacker.

It is player 1's turn and he attacks player 2 for random damage. Of course, player 1 must compute then send this value, so theoretically he can make it whatever he wants! Suddenly, player 2 is hit by a 9999 damage attack and is vaporized. The cheater has succeeded.

Of course, your natural reaction might be to have player 2 check to see if it was within acceptable bounds and reject it if it is too high. But imagine that player 2 is attacking player 1 now. Player 1 has set up his machine so that it abuses this veto power you just gave him and rejects all attacks, he becomes invincible and crushes his enemy. It should be evident that neither client should be responsible for making these decisions as neither can be trusted to be truthful about it.

In addition to security, there are other more fundamental problems when each player controls their own game. Weird contradictions can pop up due to the transfer time between computers.

Let us say that both player 1 and player 2 issue commands to move onto the same tile at the same time. Each player's game shows that to be a valid move (because they do not yet know of each other's movements) and they both move onto the same square.

We can safely say that peer-to-peer is not the preferable option for most every game you would want to create. The only circumstance where I would suggest you use peer-to-peer is if you cannot (or do not wish to) code on the server. As unfortunate as it is, this is a main reason the peer-to-peer model has so heavily been embraced in the flash community.

Thankfully enough, you can completely avoid writing anything for the server if you wish. Simply make you game connect to the "bounce" server in your connection code. Using this setup causes all messages sent to the server to be simply echoed or "bounced" back to all clients. Using this setup, we have a method of communicating all information to every other player connected. To use the bounce/echo server use the following code when creating a room:<

2-tiered system

Getting back to the matter of security, if we cannot trust either of the clients with our data and decisions, who CAN we trust?

The server of course! If you have the server make all the decisions and take away the executive power from the clients, you have removed destructive power from the hacker's grasp. This brings us to our second architecture, where the server acts as more then just a message boy and instead runs our game and computes all game-critical information. Because we now have code in two places, the client AND the server, we must visualize how this is going to work.

Note that only the server layer and the user are truly important to the proper functioning of our game. This give interesting consequences...

Our client layer is sandwiched between our server layer (where the game actually takes place) and the user (who decides what actions to perform). The flash application we have running on the client truly serves no other purpose then to connect the two other layers together and give the user visual feedback. Our flash game is no more then a fancy input-output machine for the server! It has two purposes:

1. Get the required information (mainly input) to the server so that it can run the game properly
2. Receive game information from the server and with that, show the player what he needs to know in order to play (output)

Obviously, this changes -fundamentally- how the flash part of our game operates. In many ways, however, it is made even simpler. Looking at it from the client's perspective, you only actually do anything when the server tells you to do it! Otherwise, you are mainly just sitting around doing nothing and sending input when the user presses the proper buttons.

Server-Client architecture

Of course, it is better to look at this setup from the server's perspective. It is the head honcho here; the big cheese. The server will accept input from all users and run the game on it's internal systems. When something changes (someone makes a move, etc.) the server sends out a message to inform all players of this to ensure that they are all sharing the same state. As pictured below:

Earlier, we hinted that this setup is much more secure. Indeed, it immediately makes hackers frown. You just made their lives a whole lot harder, and perhaps impossible. Of course, I only refer to the real hackers in that statement. The script kiddies will have no idea what's going on and try their programs anyway; load up their speedgear and their message sniffers, only to find they don't work! Since there are many more script kiddies then actual hackers out there who are going to be trying to cheat at your game, you have just instantly waved away a major problem.

Why is this more secure? It is because we took all the power away from the client, which is the only thing the player has any actual power over. The worst they can do now is change the inputs they give to the server. There is, of course, still room for exploitation such as aim bots and other, similar methods of cheating.

Thankfully, in a turn-based game you generally don't have to worry about programs designed to perfect input. That is a concern more oriented towards real time games.

The problem caused by same-time input is solved immediately and naturally as well. The problem was that both clients acted before they could possibly know each other's input. The server, on the other hand, does not act on two different things at the same time because it is a single entity. As such, it will act on the first command it gets and the second one will be blocked as an invalid move.

This brings up an important point in defensive coding. ALWAYS check to make sure a move is valid. Even if you think you are protected elsewhere and you think you've prevented any such contradiction to be sent from the clients, you never know when something unpredictable and tricky like this will rear it's ugly head.

To uncover the proper workings of this system, an example is in order. For continuity's sake we will use that same chess example.

The player wishes to move from C2 to E4. Just as before, he must send the following message out to the server to show his intentions:

connection.Send("Move",3,2,5,4);

Then, (and this part is really easy!) you do nothing! You don't move the piece as according to the player's wishes because in reality, the piece hasn't moved yet. We must wait for confirmation from the server in order to move the piece.

On the server, we receive this message and check to make sure the move is valid. If it is, then we perform the move and send back a message to every player INCLUDING the person who sent it to us.

Broadcast("Move",3,2,5,4);

Back on the client, we have received this message from the server. It is telling us to move the piece located at co-ordinate (3,2) to position (5,4). Happily, we oblige and so does every other player. Turn complete successfully.

You should follow this same format for every single move. Send-wait-act on server decision. It is good practice to give the user feedback during he wait period as well. Turning the cursor into an hourglass or using other, similar effects to show the user that their input has been accepted and they should wait to see the result.



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).