Tony Polinelli
Tarwin Stroh-Spijer

contact [at]
touchmypixel.com

6/25 Easey Street
Collingwood, 3066
Vic, Australia

+61 3 8060 5321

Multiplayer Games in Flash

gorillaz

I’ve been having a little play with creating multiplayer games in flash. Its kinda like that basic game – Gorilla, or was that Bannanas? hmm… not as chunky gfx yet tho ;P

It sounds pretty easy at first – but is getting a little complicated – even with my small test. The haxe mailinglist has been helpful in getting me started with some good advice.

One approach is to use an authoritative server – where the server runs a simulation of the game. Clients then connect & post their user input to the server. The server will make changes to the simulation and then post back updates to the client(s) about what has changed/is relevant to the user. This is a solid way to ensure that each client is getting the same experience. A major downside to this approach is the greater server load associated with running a game simulation. Especially if the game is planned to run a physics simulation (eg box2d), then the processing would be far too great – especially if a game only supports 2 players, and therefore the number of simulations/players will be extreme.  A great upside of using haxe is that the game logic required to run the simulation on the clientside, can easily be compiled to the serverside target (neko, c++) to run the server. This will prove a MASSIVE bonus for creating authoritative multiplayer flash games.

The approach i’ve taken is to only run updates on the client side. There are 3 different systems running in the test:

Rotating a cannon

The keypress event is sent to the server with the new roataion, this new roataion is broadcast to all clients (including yourself) then the rotation is applied. This means that you should experience similar latency to the opposition. Which isnt great – but it is very simple. As it is linked to the ‘cannon’ update loop – events are fired to the server at the tick rate (60fps) which isnt great either – a ‘rate’ should be capped for updates.

Creating CannonBalls

The event to create a CannonBall is send to the server. This is so that the server can increment a ‘count’ of cannonballs. It is important the each client can identify each cannonball – for later destruction. This is the only authoritative part of the simulation. Each cannonball is also ‘owned’ by a certain player – meaning that that players simulation controls its motion. This is fine for the simple test, but i can see that if cannonballs ‘owned’ by one player needed to interact with balls owned by the other, then problems could arise.

Updating CannonBalls

So, each client updates the motion of ‘its’ balls, and boardcasts this to the other clients (via the server). This means that you have smooth motion of your own objects.

In a turn based game (what i’m looking at making) this switching of ‘ownership’ of the simulated objects should work reasonably well – the non dominant client will have a more latent, jittery simulation (as inaccuracies are fixed). Another option would be to run one of the clients as the ‘dominant’ or ‘server’ client all of the time. This would be similar to how quake runs when you run it on a local network (atleast how use used to run quakeworld – hah memories).

So now i’m loking at ways to reduce/account for latency – as i think that over the internet the test would run a little jumpy.

Running the test

compile the hxml file (install haxe/neko from www.haxe.org)

run the server.bat

open 2 instances of the bin/Gorillaz.swf

Download the game test

cheers Tony

5 comments

  1. robo

    wow!,great!,
    I want to ask is this support video?or phone steam?


  2. I actually started playing around w/ Project Darkstar and got about this far, too. How do you update the clients? It sounds like you send any changes at a certain interval, does that mean the clients are totally dumb? Or do they run their own simulations, too (e.g. they control their cannon ball)? If so how do you plan on reconciling the latency issues in each client? For example, if I fire a cannon ball and it takes 100ms to reach the server then 200ms to reach my client how do you ensure that it’s in the correct position across all clients?

    Sorry to blast you with questions! I’m just interested in hearing how others are working through these problems.


  3. Yeah, turn-based seems to be the wait to do it. Although I guess another way to support multiplayer physics flash games is to not let the players interact with each other and put them in separate simulations.

    Just in case it’s not clear: While Box2D is as deterministic as possible, the Flash player does not guarantee consistent floating point math across architectures. It might seem deterministic if you repeat a simulation on one machine, but if you try hard enough you can find a machine that will produce a different outcome. This has been a source of contention for some people trying network-y stuff in the past. So don’t rely on determinism. :)


  4. Hi Tony,

    What do you use when you are debugging and profiling these HaXe applications?

    -Tim


  5. Alex >
    The clients arnt totally dumb – they are running the simulation and updating positions, but then adjusting when the information from the server comes – making sure they are accurate. I havent looked into latency issues yet – it’ll be a whole lot of fun it seems (reading up on it). This test is my first 4 hours of looking at multiplayer stuff- so very basic ;P I’ll look at how to adjust for latency soon, maybe make a post on it next. I might not need to worry in this game however- as its turn based.

    John>
    Yeah – i wont be trusting box2d – will have to refresh all objects at the end of a turn, to make sure they are in correct positions.

    Tim>
    you can use the -debug option, which gives linenumbers on the stacktrace of runtime errors. Besides this I just output my traces to the FlashDevelop output window by redefining the haxe.Log.trace

    haxe.Log.trace = function(v, ?pos:PosInfos)
    {
    if (v == null) v = “null”;
    flash.Lib.fscommand(“trace”, traceCount1++ + ” ” + pos.fileName+”:”+pos.lineNumber+”: ” +v);
    }

    and/or i outup to Firebug with and ExternalInterface to console.log
    i dont think there is a way to debug with breakpoints, i seeyour talking about it on the list anyway ;P

 

Leave a Reply

Our Friends:

Powered by haXe / poko cms | Copyright 2008-09 TouchMyPixel