Advertisement

Server Authoritative Movement Questions

Started by April 12, 2020 01:41 PM
4 comments, last by hplus0603 4 years, 6 months ago

Hello everyone,

I am running into a problem while implementing client-side prediction in my multiplayer FPS. I'm not entirely sure if I've completely and correctly understood the concepts. I have read the articles from Gambetta and from Valve, as well as several others.

What I'm currently doing is sending client input as key presses and key releases; the client sends when it presses 'W', for instance, and sends a packet once it has stopped pressing 'W'. The client then predicts the movement in a fully-deterministic way. The server then sends a position packets to all of the clients and the client checks if there is any divergence and corrects for it.

I am now running into the issue if the time between the input packets on departure differs from the time of the input packets on arrival, it will inevitably lead to small errors and massive divergence over time as the server will think the client will have pressed a key for longer or less time than it actually has. I haven't seen anyone mention this, so I'm questioning if what I'm doing is right.

Another issue I am seeing with this approach is that the client sends rotation updates to the server at 64hz (my tick-rate). This will, of course, lead to small differences in rotation from the server and client at specific times. Given that the movement is dependent on the orientation/rotation of the player, client-side prediction errors will inevitably ensue.

One way I was thinking that could fix the first problem, would be to send timestamps along with the input packets and have the server rewind positions and compensate for the delay imprecisions. Before I follow through with that, I am seeking some confirmation as to what I'm doing is right.

Any help would be appreciated! Thanks!

Yes: You need to send the timestamp for each command that you forward to the server.

Thus, if you say “at timestamp X, I started moving, and at timestamp Y, I stopped moving,” then everyone (server, other clients,) know that you moved for a total of (Y-X) frames.

Also, it's generally a good idea to send the semantic events ("move forward") not the physical keys ("W") because players may re-map their keyboards, may use a gamepad, etc.

Whether the server “rewinds,” or whether you delay playing the action on the client until the server has received it and echoed it back to you, depends on what “feel” you want in your game.

enum Bool { True, False, FileNotFound };
Advertisement

This article is useful too for understanding of client prediction: http://buildnewgames.com/real-time-multiplayer/

@undefined Thank you for your reply! What exactly do I send as timestamps? Do I send actual timestamps or ticks? If I send actual timestamps such as the client moved forward at 50ms, then how does the server know where the client was at 50ms so it can rewind the client to where it was at 50ms and apply the new input? I hope that makes sense. Let me know if I need to rephrase my question.

For games that use a fixed timestep, the best measure of “game time” is “tick number since game start.”

For games that don't use a fixed timestamp, you typically establish a server clock (milliseconds or microseconds or frames or whatever,) and use some kind of lightweight synchronization protocol in the headers of your packets to keep them in sync.

The most important part is to make events “happen in the same order” – the exact wall-clock time they happen at will be slightly different, if nothing else then because of relativity, but as long as the client and the server agrees that “the event happened at game-time T” then you can sort it out.

Typically, the client will send something like “at my wallclock time T1, my estimate of game time was T2.” When the server receives it, it will compare T2 to its estimated game time. When it sends the next packet back, it will send something like “I spent Dt amount of time between receiving and responding to your packet you sent at time T1, and my game time when I sent this response was T3.” The client will record the local time T4 when it receives that response from the server, and can calculate an average round-trip time and an average game-time-offset to its local wallclock time from that.

Typically, games will keep running this protocol for the duration of the connection, to be able to adjust to slight shifts in round trip latencies and clock skew.

enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement