I have to synchronize the movement of multiple players over the Internet, and I'm trying to figure out the safest way to do that.

The game is tile based, you can only move in 4 directions, and every move moves the sprite 32px (over time of course). Now, if I would simply send this move action to the server, which would broadcast it to all players, while the walk key is kept being pressed down, to keep walking, I have to take this next command, send it to the server, and to all clients, in time, or the movement won't be smooth anymore. I saw this in other games, and it can get ugly pretty quick, even without lag. So I'm wondering if this is even a viable option. This seems like a very good method for single player though, since it's easy, straight forward (, just take the next movement action in time and add it to a list), and you can easily add mouse movement (clicking on some tile), to add a path to a queue, that's walked along.

The other thing that came to my mind was sending the information that someone started moving in some direction, and again once he stopped or changed the direction, together with the position, so that the sprite will appear at the correct position, or rather so that the position can be fixed if it's wrong. This should (hopefully) only make problems if someone really is lagging, in which case it's to be expected. For this to work out I'd need some kind of queue though, where incoming direction changes and stuff are saved, so the sprite knows where to go, after the current movement to the next tile is finished. This could actually work, but kinda sounds overcomplicated. Although it might be the only way to do this, without risk of stuttering. If a stop or direction change is received on the client side it's saved in a queue and the char keeps moving to the specified coordinates, before stopping or changing direction. If the new command comes in too late there'll be stuttering as well of course...

I'm having a hard time deciding for a method, and I couldn't really find any examples for this yet. My main problem is keeping the tile movement smooth, which is why other topics regarding synchronization of pixel based movement aren't helping too much.

What is the "standard" way to do this?


I'm assuming you're talking about moving in real time. Trying to interpolate position is probably a lost cause; over a slow connection, your game state could fall further and further behind the actual game state. Unlike the other comment, I would advise against putting much game logic in the server side. When I've implemented these sort of solutions, the client has a TCP socket to the server constantly. When the game state changes, it sends a message to the server, like 'client is at x=10, y=20'. The server pushes the message to the other clients, who try to handle it based on their own internal logic. Using TCP ensures your messages arrive in order.

Unfortunately, even AAA games can't handle extreme lag; players will occasionally move very quickly, because their local and network states are far out of whack. Monitoring the round-trip ping and kicking users who are too far/slow will help with this.

  • 1
    \$\begingroup\$ +1 for 'even AAA games can't handle extreme lag;' Actually No one can handle even small lags perfectly. We can make it look like we can though. \$\endgroup\$ – Valmond Jul 6 '12 at 12:27

Basically this is how you can do it in a simple and secure way (warning, extreme pseudocode):

A) Client (playerid=5) asks server to move 'right' (or better, to tile 73,18)

B) Server checks his big 2D map that contains players (or players ID for example):

 if(map[73][18] == occupied)
     Send back ('Not OK') to client (the case is blocked by another player)
    Set the new position as blocked: map[73][18]=5
    Release the old position: map[72][18]=0;
    Send a 'new position: 5, 73,18' message to all players who are nearby (moving client included)

C) Clients get an 'new position' message (well, or player 5 gets the 'Not Ok' message)

D) clients slowly moves the item which has playerid=5 towards its new position (or creates it if it doesn't have one item with playerid=5)

  • \$\begingroup\$ Well, thanks, but my problem is keeping it smooth on the other clients over multiple continues tile movements, not the tile movement in general^^ \$\endgroup\$ – Mars Jul 3 '12 at 15:59
  • \$\begingroup\$ Set the speed correctly and compensate for the lag with for example dead reckoning or just a 'stupid' 'move towards target at constant speed' (or proportional speed over a certain treashold if you send timestamps along positions) and you should be fine. \$\endgroup\$ – Valmond Jul 3 '12 at 16:31

I think the method you described is pretty good, especially in a simplistic game where only 4 moves are allowed. Here is how I implemented it.

I don't know of any standards, but the first thing that came to mind was to only broadcast "input changes", changes in a player's input, from a player to the others. For example, you could broadcast only messages along the lines of [key pressed, key ID, time], or [key released, key ID, time], and let the players' game act upon these input changes. Including time will help with path correction (if the player has changed direction at time t, then the "going forward" at time t+1 will need to be fixed).

However, with this solution you may encounter the issue of lost messages; suppose the "key released" message was never sent? Something which can help this is periodically polling the game state of a player and return the current position of the player, as well as any key being pressed, or even return the entire game state. Depending on the number of players and commands, you can tweak this in order to balance message passing between clients/server for a good balance.

Another thing you can look into is path planning. For example, if the player has been moving forward for 5s, then in the next millisecond chances are the player will still move forward. In that case, you can create a semblance of path prediction in order to avoid lag. This is essentially what the method above is doing, although this can take into account circular paths.

I hope this helped!

  • 1
    \$\begingroup\$ The problem with just sending inputs is that if you miss a single one or sometimes just interpret them in the wrong order then your gamestate won't be okay any more, ie. two clients will show different 'screens'. \$\endgroup\$ – Valmond Jul 3 '12 at 13:51
  • \$\begingroup\$ @Valmond very good point... in fact, I feel like deleting my answer, since in that light it feels incorrect. \$\endgroup\$ – Jonathan Pitre Jul 3 '12 at 13:52
  • 1
    \$\begingroup\$ You can send the inputs to the server (so up til that it's OK) but the server should (IMO) send exact data or at least verify the data or maybe send the whole gamestate(this has been done in real games for example Blood Bowl), maybe you can tweak your answer instead of deleting it :-) \$\endgroup\$ – Valmond Jul 3 '12 at 13:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.