I'm working on an authoritative multiplayer fps in Unity.
The client is sending commands to the server designated for specific ticks and the server sends back an offset to control how far ahead/behind the client's command clock should be based on how late/early the commands are arriving.
I found a GDC talk that describes adding server-side client command extrapolation and reconciliation.
In other words, when the server goes to execute tick 100 if the client's command for tick 100 has not arrived the server will reuse the last received command from the client assuming their input has not changed much. This is pretty normal from my understanding, but it goes further by rewinding/resimulating server ticks that had used old/extrapolated input when the actual (previously missing) command from the client does arrive. The period of time that they allow to be reconciled like this is limited to 50ms. Once it exceeds 50ms the ‘extrapolated’ commands become authoritative and will not be resimulated if they do later arrive.
https://www.gdcvault.com/play/1026833/Handling-Network-Latency-Variation-in (timestamp 9:10)
we want to avoid running out of input to simulate
there are several options the server can use
the server can extrapolate client input by taking the last known input from that client and executing it and taking the position and orientation and committing that to the world state and the antilag buffers that when clients are looking at that client moving around they see and can shoot at the client effectively. it is not committed in this case to the player's view of themselves, because committing that extrapolated state to the player's view and then sending that back to the player would result in the player's own view of themselves hitching because they would not have simulated that extrapolated movement. they are not experiencing their own network issue. and when the actual input does arrive from the player with extrapolation you unwind or discard that extrapolation and you apply the real input
They imply in the presentation that they even extrapolation/prediction over buffering to keep the latency low and the tick offset always on the bleeding edge. But what they don't cover is what limits are imposed during the extrapolation/reconciliation periods.
Approach A:
Limit extrapolation to movement only. Could result in other players being killed during the reconciliation which might feel bad? But should favor the shooter apply here?
extrapolate:
- move (last received move input)
reconcile:
- move (actual move input)
- fire (actual fire input)
Approach B:
Allow movement + gunfire during extrapolation. Reconcile move input but ignore actual fire input. Keep fire latency down for remote players.
extrapolate:
- move (last received move input)
- fire (last received fire input)
reconcile:
- move (actual move input)
Issues
And that's not to mention the other issues that could arise from the reconciliation (e.g. delta compression against snapshots that were already sent but have now been resimulated… possibly bringing dead players back to life if the resimulated input would have moved the extrapolated player out of the way of danger, etc.)
I'm deep into this rabbit hole and looking for any feedback/thoughts about the practicalities of implementing something like this and what/if any limits should be imposed.