Vixen
02b45cc4
csharp
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 History

    What was predicted for each of the last few ticks.

  • public IReadOnlyList<PredictionCorrection> Corrections

    How far each predicted object moved in the last reconciliation, if any did.

  • public Tick Current

    The newest tick simulated.

  • public bool HasSimulated

    Whether anything has been simulated.

  • public long PredictedTickCount

    Ticks simulated forward, which is once each.

  • public long ConfirmedCount

    Snapshots that agreed with what was predicted, and cost nothing to reconcile.

  • public long MispredictionCount

    Snapshots that disagreed, each of which cost a replay.

  • public long ResimulatedTickCount

    Ticks simulated a second time. The price of the feature.

  • public long LostHistoryCount

    Snapshots 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