I am implementing network rollbacker in real-time action game and found out a very strange issue where local (non-master) player is moved a bit forward then back when changing input.

After narrowing it down I found this is a source of the issue:

  1. Non-master player (let say at (0, 5) position) is moving forward via vector (1, 0)
  2. Player decides to stop moving. It immediately stop movement locally (as prediction) and then send message to server that it wants to stop
  3. As it is some time before the packet arrives, the server now thinks the player is at (1, 5) and it broadcast the information to all players
  4. The packet from non-master player arrives. Server immediately goes back a few frames and re-simulates (via rollbacker), and moves character back to position (0, 5). It broadcast the information again.
  5. The non-master player receives information that is should stand at (1, 5). It erroneously corrects its own position to (1, 5)
  6. The second packet arrives. The non-master player goes back to the valid (0, 5)

How can I correct the algorithm so the non-master player won't be doing this leap forward/back on changing input (5th and 6th step above), when receiving incorrect correction from master due to master not knowing its local change of input?

  • 1
    \$\begingroup\$ This page on Valve's solution to this set of problems in the Source Engine may be of interest: developer.valvesoftware.com/wiki/Source_Multiplayer_Networking \$\endgroup\$
    – Basic
    Commented Jun 25, 2023 at 21:54
  • \$\begingroup\$ @Basic Thank you, I know these set of articles pretty well. I couldn't find the answer to my specific problem through \$\endgroup\$
    – PiotrK
    Commented Jun 25, 2023 at 22:08
  • \$\begingroup\$ If I've understood your problem, have a look again at the section on Input prediction. If the prediction is invalid, track the error and smooth to the correct position over a short period of time. ` Prediction error correction can be quite noticeable and may cause the client's view¹ to jump erratically. By gradually correcting this error over a short amount of time, errors can be smoothly corrected.` ¹As you don't appear to be FPS, this would be character model/sprite, rather than viewport. Of course this relies on everyone moving continuously to mask the smoothing \$\endgroup\$
    – Basic
    Commented Jun 25, 2023 at 22:20
  • \$\begingroup\$ @Basic I am doing a smooth correction already. The problem is I shouldn't be doing that correction at all, but I am not quite certain how can I detect the situation and avoid it in the first place \$\endgroup\$
    – PiotrK
    Commented Jun 26, 2023 at 12:19

1 Answer 1


Okay, I found the solution:

  • Non-locally-predicting clients just take server value as requested

  • Non-master character will follow this algorithm:

    1. After change request comes from server and is mis-matching with local prediction, the object will remember current position and schedule position update within next 0.5 second
    2. If new packet arrives it will update position update request, but do not change update timer
    3. If new packet happen to match prediction, the entire correction process is cancelled
    4. When reached position update timeout (after 0.5 second) it takes position requested and add to it local delta movement happen within that 0.5 seconds

Example based on original question:

  1. Packet comes with correction (1, 5). Because it is distant from current position (0, 5), the client schedules update in 0.5 seconds
  2. The client starts moving up to (0, 6)
  3. The new correction comes with (0, 5). The entire correction process is cancelled as the client was at (0, 5) at the moment
  4. The client predicts its new position at (0, 6)

And if there is indeed a mismatch (ie. there was some event that pushed player to (1, 5) that could not be predicted locally):

  1. Packet comes with correction (1, 5). Because it is distant from current position (0, 5), the client schedules update in 0.5 seconds
  2. The client starts moving up to (0, 6)
  3. 0.5 seconds has passed. The clients correct its position to (1, 5) + (0, 6) - (0, 5) = (1, 6)

You must log in to answer this question.

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