0
\$\begingroup\$

I am building a very tiny first-person multiplayer game. I'm just aiming to get the basic rights: client-side prediction and reconciliation + entity interpolation. I have read many articles on these topics but I have a question that I can't find answer for. Consider the following problem:

  • There's a queue on the server where the client inputs are stored (movement keys + camera vectors)
  • Server runs the physics simulation 60 times per second. This means that each input from a client will be simulated for 16.6 ms.

Now, consider that I have two clients: one with a beefy computer able to run the game loop 100 times per second, and a slower one that is only able to run it 30 times per second.

My game will send the 'client inputs' packet to the server on every iteration of the game loop. This means that the 100 fps client will send 100 packets, while the 30 fps client only 30.

What this means is that the fast client will get more simulation time on the server, since each input is simulated for 16ms. So the fast client will move significantly more than the slower client.

What is the appropriate way to design the 'client input' packet send rate? What is a solution that ensures that fast clients and slow clients receive an equal or roughly equal amount of simulation time?

Thanks for your time!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ You might want to consider decoupling your rendering framerate from your simulation tickrate, so the beefy computer still gets smooth 100 fps rendering, but runs the same underlying simulation rate, so the game feel and fairness are preserved consistently between different devices, and your netcode stays simple. See this Q&A for more details on why games often do this \$\endgroup\$
    – DMGregory
    Feb 4 at 15:51
  • \$\begingroup\$ Thanks a lot for the answer. I didn't really think this could be a problem with my game loop. I'll go over those resources. \$\endgroup\$
    – user115675
    Feb 4 at 16:42
  • \$\begingroup\$ @DMGregory I fixed my game loop! Thanks a lot for the tip. But I'm still confused as to how my server is supposed to apply the user inputs. I have read some comments where 'collating' the user actions is an option. Do you recommend any resources on this topic? Thanks a lot for the help. \$\endgroup\$
    – user115675
    Feb 6 at 14:11
  • \$\begingroup\$ Sounds like you can edit your question to ask about your new area of interest. \$\endgroup\$
    – DMGregory
    Feb 6 at 14:26
1
\$\begingroup\$

I had this exact same issue with my multiplayer game engine. As others have pointed out you could decouple the rendering and simulation on the client side to keep the client side simulation at a consistent tick rate, but I still wanted my system to be resilient against fluctuating tick rate on both the server and clients.

My solution was to include the tick-duration of the client on each input message that was sent to the server. The server will then make sure to simulate the clients input message for the time specified in the message.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Just note that you shouldn't give unlimited trust to a client-provided timestamp, otherwise a cheater could forge the timestamp to send their moves "back in time" to get an unfair advantage. You might want to establish an expected time horizon, and consider dropping players who keep sending messages too old for that cutoff - they're either cheaters or badly lagged, and both can contribute to a bad play experience. \$\endgroup\$
    – DMGregory
    Feb 17 at 15:38
  • 1
    \$\begingroup\$ @DMGregory I updated my answer to reflect the fact that durations (and not timestamps) should be sent from the clients to the server. \$\endgroup\$
    – Expliced
    Feb 17 at 15:42
  • \$\begingroup\$ Thanks for the answer. I spent the last week reading Quake's source code and they do exactly what you describe. The 'tick duration' from the client packet is capped on the server to prevent physics from breaking or cheating. \$\endgroup\$
    – user115675
    Feb 17 at 16:44

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.