2
\$\begingroup\$

I'm making a server/client model for a top-down 2d shooter. Because I need to calculate collisions with walls & other players using a small delta, I want to use the fixed-timestep model like in this example: https://gafferongames.com/post/fix_your_timestep/. Apparently this is a common approach for network games.

Right now my model looks something like this:

  • Client connects and is synced to the current server tick (let's say tick is 50)
  • Client sends its first input + the time pressed (local tick 50) to the server
  • Server receives the message at tick 55. Because the message was for tick 50 which has passed, this request is ignored.

As I understand it, the client and server run at the same rate, but because of latency the client sends messages too late and all get ignored. Am I supposed to let the server run a few ticks behind the client somehow? How do I resolve this?

EDIT: No, this is not a duplicate of that question. What OP is asking in his topic is how to account for lag visually from other players. The answer is mostly you can't, but you can smooth it out with entity interpolation.

My dilemma is that I can't figure out how to process inputs at all server-side using a fixed-timestep model. I assume the client sends timestamps which are processed when the server reaches that same frame, but if client+server are always frame synced, that means all messages are from the past and are ignored. If I allowed the server to accept a past input anyway it would have to implement it immediately instead of the original frame it was meant for, which would result in inaccuracy.

I'll make it real clear: If a client sends an input at tick 4 but it reaches the server at tick 7, how does the server go back and process an input meant for tick 4?

\$\endgroup\$
1

1 Answer 1

1
\$\begingroup\$

You send commands that are post-dated into the future.

  1. Calculate the average-worse (right-ish side N-percentile of the bell curve) ping time in ticks with a small margin (eg: 10 tick ping +2 ticks variation) enter image description here
  2. Client send input/command to the server scheduled for (now_tick + ping_ticks) (eg: now 50 + ping 5 = tick 55)
  3. Server receives the command (ping_ticks / 2) later, relays it to the clients
  4. Clients (hopefully) receive commands before they're due (eg: received on tick 53) and execute command on the tick that was calculated as the post-date (eg: tick 55) so everyone is in sync.

When packets are delayed there is two ways around it:

  1. all clients/servers agree that commands will be received at most every N ticks with a delay of M ticks and will simply wait if no packet is received (use an empty keep-alive packet when no commands are to be sent). More packets can be sent more frequently.
  2. Clients/servers will rewind in time and recalculate (fast-forward) once delayed packets are received. So all clients/servers keep a periodic backup of the entire game state at N ticks granularity for as far back as M (ping-delay) ticks can be accepted.

Usually a mix of both is used.

\$\endgroup\$
2
  • \$\begingroup\$ Very informative, thanks! About delayed packets: #1 is lockstepping, right? I don't want everyone to wait if someone is lagging. #2 I believe is server reconciliation, which I actually had implemented already before switching to a fixed timestep. About ping: When do I calculate ping? Assume the server would send an update at 10hz. Do I calculate then and use the ping for the next update? Should the server add ping to the tick when it's sending it back since I'm already using option 2 for delayed packets? \$\endgroup\$
    – tim
    Nov 18, 2017 at 15:39
  • \$\begingroup\$ You'll need to have your server periodically ping the clients and have the clients reply immediately to estimate the ping time for each clients. Once the game is running and the clients synchronized you can estimate packet travel time using the tick count embedded in the packet you send used to post-date commands. \$\endgroup\$ Nov 18, 2017 at 15:54

You must log in to answer this question.

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