0
\$\begingroup\$

I've implemented Client-Side prediction into my game, where when input is received by the client, it first sends it to the server and then acts upon it just as the server will, to reduce the appearance of lag. The problem is, the server is authoritative, so when the server sends back the position of the Entity to the client, it undo's the effect of the interpolation and creates a rubber-banding effect.

For example: Client sends input to server -> Client reacts on input -> Server receives and reacts on input - > Server sends back response -> Client reaction is undone due to latency between server and client

To solve this, I've decided to store the game state and input every tick in the client, and then when I receive a packet from the server, get the game state from when the packet was sent and simulate the game up to the current point.

My questions:

Won't this cause lag? If I'm receiving 20/30 EntityPositionPackets a second, that means I have to run 20-30 simulations of the game state.

How do I sync the client and server tick? Currently, I'm sending the milli-second the packet was sent by the server, but I think it's adding too much complexity instead of just sending the tick. The problem with converting it to sending the tick is that I have no guarantee that the client and server are ticking at the same rate, for example if the client is an old-end PC.

\$\endgroup\$
  • \$\begingroup\$ To solve this, I've decided to store the game state and input every tick in the client, and then when I receive a packet from the server, get the game state from when the packet was sent and simulate the game up to the current point. Sounds like prediction to me. I may be misunderstanding but sounds like you trying to solve your prediction causing rubber banding by adding prediction? \$\endgroup\$ – ClassicThunder Aug 22 '14 at 23:59
1
\$\begingroup\$

First of all, use tick counts instead of time. There's no good way to synchronize the client and server clocks.

You will also have to set a minimum tick rate, if a client fails to match this rate there's not much you can do. Note that this tick rate doesn't have to match the FPS rendered, it could be lower or higher. In order to make sure the client and server tick at the same rate, read this article on Fixing Your Timestep.

Getting corrections from the server will result in rubber banding if your predictions are off, you can make this less obvious by not switching positions instantaneously, but rather correct over time. The amount of states you can store and re-simulate depends on how computationally intensive your simulation is, but you can draw a line and force a re-sync of position/velocity if the client has fallen behind too much.

An alternative solution is to make your simulation deterministic and have the server respect client movement, but still remain authoritative. When the server receives input from the client on a tick that has already passed, it can rewind and simulate forward again(within a certain tick frame, otherwise correct the client). This results in clients being able to move freely without being corrected all the time. The drawback is that you'll see other clients rubber band, but this can be smoothed over time as well.

\$\endgroup\$

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.