public sealed class ClientPrediction<T> where T : struct, IPredictedInput<T>Guesses the local player's future, and takes it back when the server disagrees.
No guide page documents this yet — the page shows what the code says about itself.
Remarks
The loop is three lines and the subtlety is entirely in what they mean. Each tick, the client records its input, simulates forward with it, and records the result. When a snapshot arrives describing tick T — which is some ticks in the past, because it travelled — the world is holding the server's word for T and the client's guesses for everything after. Comparing the server's T against the guess for T is what decides whether those guesses survive.
Agreement is the common case and it must be the cheap one. A comparison of encoded bytes and a restore of the already-recorded present, with no simulation at all. If reconciliation cost a replay every snapshot, prediction would be a constant multiple on the simulation budget rather than an occasional one — which is what ResimulatedTickCount is for: it is the price of the feature, and it should be near zero on a connection that is behaving.
Disagreement replays, and replays from the server's state rather than from the guess. That is what makes the correction converge: the snapshot has already put the predicted entities where the server says they were, so simulating T+1 onwards with the inputs that were used the first time reaches a present built on truth. Correcting the present directly — nudging it toward the server's value — is the tempting alternative and it does not converge, because the error it is correcting was produced by ticks it is not redoing.
What it does not do is hide the correction. A rollback moves things, sometimes visibly, and smoothing that is a presentation problem with its own answer — OwnerSmoothing, which gives the error to the camera as an offset that decays while the simulation takes it at once.
Fields and properties (9)
public PredictionHistory HistoryWhat was predicted for each of the last few ticks.
public IReadOnlyList<PredictionCorrection> CorrectionsHow far each predicted object moved in the last reconciliation, if any did.
public Tick CurrentThe newest tick simulated.
public bool HasSimulatedWhether anything has been simulated.
public long PredictedTickCountTicks simulated forward, which is once each.
public long ConfirmedCountSnapshots that agreed with what was predicted, and cost nothing to reconcile.
public long MispredictionCountSnapshots that disagreed, each of which cost a replay.
public long ResimulatedTickCountTicks simulated a second time. The price of the feature.
public long LostHistoryCountSnapshots describing a tick the history no longer holds.
Methods (4)
public ClientPrediction(ReplicationRegistry registry, InputLog<T> log, PredictedStep<T> step, int depth = 32)Creates a predictor.
public void Step(World world, Tick tick, in T input)Simulates one tick forward with the local player's input.
public int Reconcile(World world, Tick confirmed)Reconciles what the server said with what was guessed.
public void Clear()Forgets everything, for a client that is reconnecting into a fresh world.
Used by (2)
- ClientPredictionTestsVixen.Net.Tests
- PredictedPlayerMovementTestsVixen.Net.Physics.Tests