6
\$\begingroup\$

I've read several articles published on gambrielgambetta.com, gafferongames.com plus some pages about how Valve handles multiplayer networking in its games but I still can't get it how to implement the client-side prediction for my game where the player's always moving and he controls the speed by pressing the spacebar. When the client input has arrived the server already had simulated the world using the old velocity values. So we get a stretch in time.

Let's imagine that the player is moving between the 0.0 and 1.0 values. The current position is 0.2. The normal speed is 0.1. The "crawling" speed is 0.05.

Let's assume the server and the client have framerates both fixed and the latency is two steps high.

STEP 0
server 0.2
client 0.2

STEP 1
server 0.3 (+0.1)
client 0.3 (+0.1)

STEP 2
server 0.4 (+0.1)
client 0.4 (+0.1)

STEP 3 (Spacebar's pressed)
server 0.5 (+0.1)
client 0.45 (+0.05)

STEP 4 (Spacebar's still pressed)
server 0.6 (+0.1)
client 0.5 (+0.05)

STEP 5 (Spacebar's still pressed. Finally, the input has arrived)
server 0.65 (+0.05)
client 0.55 (+0.05)

STEP 6 (Spacebar's still pressed)
server 0.7 (+0.05)
client 0.6 (+0.05)

STEP 7 (Spacebar's released. Input was sent)
server 0.7 (+0.05)
client 0.7 (+0.1)

STEP 8
server 0.75 (+0.05)
client 0.8 (+0.1)

STEP 9 (Input has arrived)
server 0.85 (+0.1)
client 0.9 (+0.1)

It looks like nothing's wrong with this data while every multiplayer game's trying to hide the latency. But what if the periods of pressing the spacebar are different and the latency is different and the server and client have different framerates. I can't use the input duration when updating the player position because it allows the player to cheat (just lower the duration and you will start moving slower). And the server reconciliation works not very good since I'm getting the effects derived in the statistics above. When pressing the spacebar the player just jumps back and starts moving slower. So I need to compensate that somehow.

The core of the problem is how to handle the player input when the user can only decrease the speed of the character while the character's moving with the predefined speed.

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

To do server reconciliation, you not only need to know what the client inputs are, but when they were made. That means when the player sends "pressed space", you need to know when that input was actually made. An easy way to do that would be for the client to send it, i.e. "pressed space on step 3". You could also guess on the server side, "the client is approximately 2 steps behind, so when I receive a press space on step 5, it actually happened on step 3". Each method has its merits but the important part is that you figure out when the commands happened.

Once you have that, the server needs to be able to apply commands that happened in the past. When this happens, movement will become discontinuous for the server and other clients, but at least the positions will be synchronised most of the time. When you have multiple clients, you also need to deal with the possibility of paradoxes, i.e. if two clients both want to travel to the same position, but due to the effects of latency, none of them think they are running into each other. As the server you'll need to decide what happens, one way or the other, and tell the client(s) "nope, due to a collision in the past, your current position is actually here".

But without going too deep (and it goes pretty deep), here's what things would look like, in a table:

    Space (C)   Position (C)   Position (S)   Space (S)                                        Notes                                        
--- ----------- -------------- -------------- ----------- ---------------------------------------------------------------------------------- 
0   N           0.2            0.2            N                                                                                             
1   -           0.3            0.3            -                                                                                             
2   -           0.4            0.4            -                                                                                             
3   Y           0.45           0.5            -                                                                                             
4   -           0.5            0.6            -                                                                                             
5   -           0.55           0.55           Y           Server rewinds to step 3, reapplies movement using the slow speed for frames 3-5  
6   -           0.6            0.6            -                                                                                             
7   N           0.7            0.65           -                                                                                             
8   -           0.8            0.7            -                                                                                             
9   -           0.9            0.9            N           Server rewinds to step 7, reapplies movement using the fast speed for frames 7-9  

Note that on step 5, it would appear that the client moves backwards, and on step 9 the client jumps forwards. To make this look nicer, some games will interpolate the jump over a number of frames.

\$\endgroup\$
2
  • \$\begingroup\$ congusbongus, thank you so much for your answer! For some reason I was about to do that but there was a doubt that allowing the player to change the world state from the past makes the game very vulnerable to the hackers since they are able to change the time values they are sending to the server. But actually the server can just check if the timing values are correct and that's all. Thank you once again. \$\endgroup\$
    – nmindiedev
    Oct 6, 2015 at 17:18
  • \$\begingroup\$ I know this is old, but anyone knows how does this system work with rewinding actions that effect other players? Position is pretty simple to sync, but I don't understand how to resolve all the various conflicts with more advanced actions \$\endgroup\$
    – Ron
    May 24, 2017 at 20:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .