Multiplayer in Flash – How to..

5 02 2009

The biggest reason I chose to start up this project at this current date is that before current date it has not been possible to create what I am trying to do , using Flash. In fact, it is not completely possible yet when it comes to some 3D features but I’m an optimist and would like to stay prepared for what both PV3D and Flash has to offer the years to come (yes, I count this project to be in progress for years). Still when it comes to fast paced multiplayer games where two users, sitting by each computer, plays against each other it has just become reality!

Adobe has just opened the (beta)doors to their new protocol (RTMFP) and very shortly it means that.. it can now be done.

If you’re interested right now to try it out wothout reading my oracle guidelines, just head over to Adobes dev. Centre and check out Stratus

Without getting too technical on the subject I want to introduce what the difference is at why we need it, because this article will be about how to think to even be able to create a mp-game using streaming datatransfers client-client.

Netcommunication for dummies

Yes, we have been able to connect 2 (or more) flashclients directly to each other and communicate but until now it has only been available using a TCP-IP like protocol. (if you don’t know what it is, never mind, it is just porn for netfreaks). TCP-IP is very good in the aspect that the same data being sent is actually winding up in the right order and shape that it was sent. So, it is secure and stable. Problem is that the if “recieving client” doesn’t properly get the data sent it will wait until it really really gets it. No other data can be transfered meanwhile and in worst case it can choke up the whole system. In the end TCP/IP assures that the exact data being sent is coming in in the correct order. Maybe great for turnbased games and similar but not for our hot actiongame.

So now, something different has come up.¬† Adobe’s RTMFP is a UDP-based protocol (porn again) and UDP does not really care if all the data comes in in the exact order. It just keeps on sending and recieving data. This means that no “doublechecks” needs to be done clogging up the system and no chokes happenes if one package gets lost along the way. Don’t you worry, there will always come another package ;)

So basically, finally we got fast and uncontrolled data streaming on Flash (good for cam-streaming and such as well). I will not in this article explain codewise how to set up a connection using this technique but it will surely come as this is very much needed for the game. Now how can we use this? What do we need to consider when building a game?

Movement and actions

Actually, without really telling you, I’ve already tried to think multiplayer when it comes to this aspect already in the game. The first approach every mp programmer tries before knowing better (me included) is to just send the transformationdata to the other gamer and believing that just by sending my position and rotation values should be enough to have a great multiplayer game. The problem you will see is that transfers of data does not sometimes sync with the framerate of the game. Sending a package each and every frame will probably get heavy on the system and there is no saying that all those packages will be recieved at the same rate as they were sent.

Also you must consider the fact that the user on the other side might have a worse computer than you with a much lower framerate. Also there is this horrible lag-issue as it takes time for data to be transferred etc etc.

So we can easily say that we could use some tips here.

Predict the future

If we just could predict the actions of the other gamer we could render his unit due to these predictions. Now we at least try, right? First of all, instead of sending coordinates and rotations only we should also send some controls-data.
Actually the controlsdata is more important than the transformdata. Say you recieve some controldata. You loop through all your units on the screen, first your and transform it due to your controls and then the remote unit using the controldata you just recieved. What happens if you dont get any data next frame??? Well if you based the remote units movement only on coordinates it would get stuck on the same position as before now instead you can assume that if he held the forward button in the last millisecond, the best guess is that he/she probably does that now as well, so you continue calculate a new position using his/her last controldata.

Now whenever you recieve new data, use the new data both to control the unit (using unit data) and “tween” towards the absolutely correct positions and rotations. The result will be something similar to these two pictures:

mp_movement1mp_movement2

As you can see, on the top picture, using only transformdata will keep the unit stuttering to new positions on the frames it recieved new data meanwhile using controldata makes the unit move each frame BUT you will have some misplacement on the unit as it continues cusing the same controldata til a new is recieved. Therefor the controldata needs to be mixed with transformationdata so the most realistic movement can be achieved.

Time is relative

Until now, we have updated the speed and rotation each frame equally. Fine, this might work well in a singleplayer game as you are the only one competing against yourself but what if two players have different capacity on their computers? One computer is an ultramachine updating the game at 35 fps meanwhile the other one is going slow on 5 fps. This means that the fast comp will update the frame 35 times = moving it’s vehicle 7 times more often than the other one. Result is that the guy on the fast computer will have a faster moving unit. Also will he see the other unit move very strange as his computer will calculate the movements on the remote unit faster than it is actually being calculated on the slow computer.

Well you hear where this is leading… people will yell “CHEATERS” at each other and we will not have that cozy, nice and social game that we want. There are a few different solutions to this but the one I really recommend is called Delta Timing.

Move by time, not by frame

Delta Timing is to calculate how much the unit is transforming through time, and not static through each frametick. To achieve this you need to check the timespan between each movement. Let me give you some theory (yes, Ive done that this whole article)…

Assume you want the unit to move 10 pixels each frame. That is if your framerate is 30 FPS constantly. Then we have two good variables to start with, now lets calculate the time it really takes between one movement to the other. My pseudocode would look something like this:


{

//...here goes a lot of gamecode and nice stuff ...

currentTime  = currentTimeInMilliSeconds

timeItTookSinceLastTime = currentTime - lastTime

timeItShouldTake = 1000 / 30  // this gives how many milliSeconds it takes for one frame in 30FPS

timeScaler = timeItTookSinceLastTime / timeItShouldTake // give you a number that should be close to 1 if FPS is good.

lastTime = currentTime

}

With above code (no it’s not working if you try it, it’s just pseudo-mumbo-jumbo) you will get a variable timeScaler that will be lower than 1 if the FPS is actually going higher than 30 and higher than 1 if the FPS is dropping so this exact timeScaler must be used to compensate all speeddrops or speedboosts a FPS could get. So whenever you update, say a movement, each frame. instead of

unit.x += speed

with deltatiming you will now always use

unit.x += speed*timeScaler

Same goes with rotation, weapons, animations, cameramovement and everything that is speeded up or slowed down with your current fps.

Yes I know I haven’t given you a real line of code but the theory needs to be there before we actually create something with it. Now, swap your browser with your favourite AS3 IDE and start playing around with these things. I will soon implent it in the game code.

Cya

/Andreas


Actions

Information

6 responses

6 02 2009
Golden

Interesting from where you are taking your knowledge, just from your head, master? ;)

6 02 2009
ajirenius

:) All is a mixture of trial and error, reading articles and try some more.
Always been interested in trying out every aspect of this kind of development as it really triggers my creativity.
To read more about these things I recommend sites like http://www.gamasutra.com , http://www.gamedev.net and http://www.gdmag.com.
But yes, I admit that a lot of this is more built from scratch and experiencebased rather than studied.

8 02 2009
theflashmonkey

Andreas, i’ve been working on multiplayer techniques and flash for a while now. Glenn Fiedler’s blog at http://www.gaffer.org has a lot of information about techniques aimed at fast-twitch games that can be comfortably ported to use over RTMP(TCP). I’ve been hammering away on a multiplayer library for flash for some time now so if you’re interested in comparing notes let me know!

8 02 2009
ajirenius

theflashmonkey: I would love to hear and learn more about this. I’ve just started reading and learning and am (as mentioned in comments above) experimenting my way forward. The blog you mention really seems competent and I will dive into it as soon as possible.
Do you know of any good examples of flash multiplayer communication on the net using RTMP that I could look at as well? It seems like networking in flashgames is really an unexplored area but I might be dead wrong.

oh, and you can contact me via andreas@ (my company found in section About)

19 02 2009
Rob McCardle

Your blog is mega, thanks Andreas. I found this really useful, esepcially the stuff on delta timing. You may find a book by Dr Bill Sanders from http://www.as3dp.com good, his Programming Flash Communication server covers loads of RTMP stuff well

Regards from London,

Rob

17 08 2009
Understanding Lag « c# to javascript, actionscript

[…] Update: Read about prediction. […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




Follow

Get every new post delivered to your Inbox.

%d bloggers like this: