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

Turn-based Games

The importance of sharing state

We have 2 computers, linked together by what could be thought of as only a wire. A flimsy cable of no consequence. They have no other means of communication and no other way to know what is going on other then what passes through that wire.

Imagine, if you will, that one client did not send a vital piece of information to it's technological counterpart through that wire. What would happen then? To put it lightly, nothing good would come of it.

Say player 1 and player 2 are playing a simple game of checkers. Player 2 decides to jump one of player 1's pieces but fails to send a message that informs player 1 of this event.

Because player 1 has no way of knowing that he has just been jumped (the only way to know would be if he was sent a message) his screen stays the same. Player 2, meanwhile sees his piece jump black's piece.

But the trouble has only just begun.

Player 1 will take his turn now and jump player 2's piece. Watch player 2's screen.

Player 2 sees half of his army get killed seemingly out of nowhere and will likely suspect cheating. As we can see, once a single mistake is made it breeds even more mistakes until the game becomes a farce of it's former self.

Thus, we MUST insure that both players have up to date information about the game at all times. A single mistake can mean no possible recovery.

But what to send? And when? Surely you cannot send everything, or broadcast non-changing information non-stop! That would be a waste!

What you send is:
EXACTLY (not more for it is inefficient, not less for it could spell disaster) what the other player(s) do not know about the current game state.

For example, If you a click a button that makes your piece jump another, you must send that information out, because otherwise he has no way of knowing that it occurred. You do not, however, need to send a message to tell him where you landed or if you were kinged! From the information you gave him, he knows all of that already!

Of course, it's often better to be safe then sorry and the consequences for sending too much info to make sure (extra bandwidth) far outweigh the costs of missing information (ruined game)

But we still have not answered the question to a level where it really helps up when creating our games. What exactly quantifies what another player does not know? We need a better method of analysis then simply staring blankly at our code and thinking "Well.. I think they wouldn't know this... I'd better send it."

Looking back at our checkers example, there was a whole host of information that we did not need to send because the other player could deduce it from our move. Putting the scenario in more general terms, the other player is able to deduce the results from the decision we made.

In general, a game's rules are deterministic and not open to interpretation. Given the decision of a player, the results of that action can easily be computed to one and only one result. Of course, there is also the non-deterministic case where you cannot know the outcome from just the player's decisions (most often due to a random factor) and we must be able to deal with this as well.

So, knowing the general case and with room to handle the case where more information is required, we can firmly state that information must be received in two cases: where a decision is made or where an event occurs that cannot be predicted/evaluated according to game logic alone.

This simplifies even further because what is a "decision"? It's just user input! The computer can't make decisions by itself! (unless you've invented a self-aware computer)

So, the two reasons to send data in order to keep the same game state on both machines are the following:

It is important to note that while messages are intimately tied to user input, you don't need to send a message for EVERY input. If the user presses the quality button, you don't need to broadcast that fact! You only need to send info when a player causes an event to happen in the game; when they cause something to change. It is healthy to think of this not from the perspective of the entity sending the data, but rather from the perspective of the person who needs the data.

To make thing crystal clear with regards to the code that underlies all this, here is an example message. Imagine we are playing chess and player 1 wants to move a piece from C2 to E4.

To inform another player of this event, we must send two pieces of data along, which piece moved and where it moved to. The easiest way to do this is by sending the co-ordinates of the start and ending points which are (3,2) and (5,4) respectively. This results in 4 pieces of information being tacked onto our message and the code to send it would look something like:

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

This is simple enough, but now we must think about the cases where sending just the move is not enough.

Random is the most obvious, (and trivial) example of this. If you deal a random amount of damage and the outcome you get is a 6, you must inform the other player of this. Otherwise, they would have to compute a random number as well, and they might get a 7 or an 8 which is disastrous. Of course, random is only the simplest example of how this problem manifests...

If you plan of having a real-time part to your turn-based game (a moving ball, such as in pool, for example) there are several factors that causes error to creep into our game and we must send more information to compensate. It is recommended that you look over the real-time part of this tutorial in this case. Thankfully there is a simplified solution to this sort of scenario which you can find in the tips and tricks section of this tutorial.

There are still a multitude of various, less common special situations where more information is required that we have left untouched, use your better judgment and you should be able to find all of them that apply to your game.

Now, we must tackle a more interesting problem. Where does the actual game take place? You might be inclined to say that it will be taking place on all player's computer's simultaneously, but this can cause security problems as well as other assorted issues. As you will see, our other option is to make the game reside on the server and have the players play the game through the server.

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