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

Interpolation

The wonderful world of deception

There is one very freeing fact that you realize when you start to program multiplayer games. It doesn't actually matter if everything on the screen is actually accurate, so long as it seems like it's accurate to the player. What I mean by this is, you can pull a fast one on the player, as long as they don't catch on to the fact that all is not as it seems.

For example, we all know about the wonderful world of simplified hit-tests. You should test against a circle or rectangle instead of a 6382 pointed object that would lag your game to kingdom come. This is a common example of player deception for the greater good.

In a game, the most important thing is to give the player the illusion that he is playing a game with no problems due to latency, bad synchronization, etc. In general, seeing an object teleport from one position to another will give a player all the reason he needs to hate your game and vote 0 on it.

So what do we do? WE PRETEND!! We use sleight of hand to make it seem to the player as if they are seeing accurate, continuous movement when it is most assuredly not the case.

Smoothing

We will cover more advanced usages and implementations of interpolation in our tips and tricks section. Right now, we shall talk about smoothing.

The goal is to simply turn something that could be as bad as this:

Into something that resembles this:

By far, the easiest method of interpolation is linear easing. This simply means that you take the difference between where you are and where you should be then divide by how many frames you want to use in order to ease into the correct position. Remember that your position does not need to be exactly accurate, this only has to be a good representation of what might be happening in order to preserve the illusion for the player.

Other, more powerful methods of interpolation exist such as cubic splines, which we will discuss in the "Tips and tricks" portion, But linear easing will suffice for this gentle introduction to real time.

The recommended interpolation time is simply the time between state updates. The length of time you take to correct from error should be as long as you can get away with, so the correction is smooth and discrete but not too long as it can look strange or even cause synchronization problems because the player never truly gets pulled to his proper position. Slow correction can easily cause problems around objects such as walls, where the slow-correcting entity cuts it too short and gets stuck on the wall.

With proper tweaking, this simple form of interpolation can serve well for most applications.

Chapter 11

Extrapolation (Movement prediction)

Knowing what you can predict

"Prediction" is a deceptive word in this scenario. Most events in a game, you simply cannot predict. For example, you can't predict another player will move left before he actually does so. Your game cannot read a player's mind. Thus the rules surrounding prediction, especially concerning movement are simple:

You can only "predict" what you already know.

As useless as it sounds, this actually does have it's uses in the crazed world of latencies and synchronization, where what you see is not actually exactly what is happening.

Remember our old friend the client-server architecture?

Let us revisit this topic in more detail, to see what very important pieces we are currently missing.

The true instance of every object is contained on the server. Or, put more simply, the server contains the master copy of all data. An event does not happen in actuality until the server says that it happened. Your character does not begin to move in actuality until the server verifies that you are moving.

As you can easily see there is a problem buried in here. Every time you press a key, you do not actually move until the server sends a message back to confirm it. This creates a VERY noticeable delay on the responsiveness of your game and leads to a very sluggish feel for your controls.

So, what do we do?

We predict our own movement so that the player gets immediate feedback when he presses a key. We know exactly how our player should act, so we can show the player exactly what he wants to see, the illusion that things happen immediately when he presses the keys. Remember, the illusion is the most important thing to uphold when dealing with latencies.

Once the message has made the round trip, you can ensure that your prediction was correct and discreetly account for any differences by using interpolation. Alternately, you can simply wait for the next state update to ensure that there is no error. This requires a small calculation involving ping..

The ping approximation

Ping is a the time it takes for a message to go from your computer, to the server and back. This is referred to as the round-trip time. This number is useful in a large variety of latency-related calculations and so knowing your ping is very useful.

To calculate this, we simultaneously send a simple message to the server and record the current game time by calling Date.getTime(). The server, when it receives this message, should send it right back. When you receive the message back on the client, you sample getTime() again and the difference will be your ping. A sample implementation will be available in the source at the end of this chapter.

You should do this at regular intervals (5 seconds is good) to ensure you have an updated number (the ping fluctuates quite a bit.)

To check our position using ping we can simply add the position given to us by the server with the estimated difference caused by latency (ping time in frames)x(player velocity) to get the proper predicted position of our player.

Extrapolation works great on all objects who's paths we can predict. Objects such as bullets and other objects that follow a linear path are very easy to extrapolate on.

Why you should never try to predict another player

Quite simply, when you try to predict the movement of something which can change direction or velocity without your knowledge, very bad things happen.

Take this simple example: Another player moves forward then backward. The filled circle represents the player's actual position, the outline represents the information you receive from the server.

Here is your lovely prediction:

The light blue outline is the prediction.

As you can see, the penalty for being incorrect is UGLY. The prediction far overshoots because you have no idea that the player has reversed direction until it is much too late and then it must snap back across a giant gap that even interpolation can't fix smoothly..

Thus, you should only extrapolate on data when you can be confident your prediction will be correct (or at least a good approximation).

Summery

  • Utilize both state and event synchronization in tandem to give a good approximation of the other player's position
  • Keep the number of messages you send to a minimum while also still keeping good synchronization.
  • Use interpolation to cover up the great multitude of mistakes that your game is making due to terrible network conditions
  • Use extrapolation to predict the movement of object who's speed and position you can already know.
  • AT ALL COSTS, maintain the illusion of a perfectly functioning game.

At this point in time you may want to take a breather. These concepts are notorious for making your head hurt. It would be worthwhile to look through the sample code on the next page in the meanwhile. When you feel ready, we will move on to our next topic:

How to deal with latency

The following is a full implementation of event and state synchronization with interpolation and extrapolation added. Read the comments for even more techniques that I used.


View game

Download the source



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