1
\$\begingroup\$

I've made a little C# server which receives UDP packets and shows me the incoming information. I want to make an authoritative server in C# which simulates character movement and interaction in a 2D real-time world and sends information back to a Unity game client where the information is then represented.

My question is: How does my server know how long a button is pressed in real-time (example: right arrow key to move character right)?

My guess is that the client would send a UDP packet to the server on-key-press saying move-this-direction. The server would then simulate the character moving and new positional information is constantly sent back. When the Client releases the key a new UDP packet is sent to the server saying the movement key has been released thus stop-moving-this-direction. BUT the problem is UDP unreliability and the lag between letting the key press up, and the server knowing that the key press is up; which would make the character keep moving for a period of time after letting go of the key - is this solved with proper movement interpolation?.

Any ideas or information sources how to properly handle sending arrow key movement data to a authoratative server?

\$\endgroup\$
2
\$\begingroup\$

If you're using UDP then, as you say, you don't get reliability from your transport layer, so you'll need to build it into your game layer instead.

In addition to the TCP style of detecting a missed packet and requesting it be re-transmitted, there are two common ways realtime games implement reliability:

  • Don't. Just have every agent spam you with their current state constantly, and if you miss one it's no big deal, the next state update will arrive faster than requesting a re-transmission anyway. Just skip it and move on, using interpolation to cover the gap. This works well for states like position that can be interpolated smoothly.

  • Pack the last few updates together into each packet. That way if one of the past updates was dropped, it can be corrected on the net update without requesting & waiting for re-transmission. This works well for changes that need to be integrated in order, like your keypresses.

You'll of course also want to send some type of time information with the key down/up information: "Key Down at time XX:XX" or "Key Down at Tick XX"

This lets your server compensate for (variability in) latency, and simulate the commands in the right order/timing to get the same result as the client. Two considerations here:

  • To prevent cheating, you should only accept timestamps in a "reasonable" range given the observed network latency to this client.

    If someone says "oh yeah, five seconds ago I totally dodged that bullet" then either the network is way too slow to support realtime play with this client, or they're fudging numbers. Either way, it's a sign you should probably drop this client.

  • Correctly simulating these discrete events can require rewinding the game state to the stamped time, applying the change, then re-simulating forward from there.

    This is more complicated than applying the change at the time of receipt, but it helps you get faithful replication of the simulation, since the net result of a button-down & -up pair is so highly dependent on the timing of & between the events.

    If this is too complicated, you can synchronize positions instead, rather than keypresses, but that can make it harder to detect certain forms of cheating.

\$\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.