In this lesson, you will learn how to detect state discrepancies between your client’s local simulation and the server’s ground truth to force the client back into alignment.
The Problem: Prediction Drift
When you implement Client-Side Prediction, the client predicts the movement immediately to hide latency. However, because the server is the ultimate authority, the server may arrive at a different location due to floating-point errors, colliding with invisible geometry, or complex physics. If you don’t reconcile, the client will wander off, effectively "de-syncing" from the server's version of reality.
The Reconciliation Loop
Server Reconciliation is the process of the server periodically sending its authoritative state back to the client. The client then compares this authoritative state against its own history of predicted states.
- Tagging Inputs: Every time the client performs a movement, it must assign a unique sequence number to that input packet and store the result in a local buffer (a history of where it thought it was at that time).
- Server Verification: The server processes the movement and returns a "Server State" packet containing the position, velocity, and the ID of the last processed input.
- The Comparison: When the client receives this packet, it checks the position. If the difference between the client’s historical position (at that same input ID) and the server’s reported position exceeds a threshold, a "correction" is required.
Forcing Correction
When a discrepancy is detected, the client must abandon its current position and snap to the server’s authoritative state:
void AMyCharacter::OnClientReconcile(FVector ServerLocation, int32 LastProcessedInputID)
{
// Check if the difference is significant enough to warrant a snap
if (FVector::DistSquared(ClientHistory[LastProcessedInputID].Location, ServerLocation) > KINDA_SMALL_NUMBER)
{
// Force the client to accept the authoritative state
SetActorLocation(ServerLocation);
// Discard old inputs and re-simulate any inputs that occurred after this ID
ReplayInputs(LastProcessedInputID);
}
}
By snapping the position and re-simulating all inputs stored in the buffer that happened after the corrected input, you ensure the client recovers seamlessly without the player feeling a significant "teleport" effect.
Key Takeaway: Server Reconciliation maintains game integrity by forcing clients to discard erroneous local predictions and re-apply pending inputs on top of the server’s authoritative state.