Vixen
02b45cc4
csharp
public sealed class TickManager

The clock everything else is stated in: turns frame deltas into whole ticks, and on a client, keeps those ticks lined up with the server's.

No guide page documents this yet — the page shows what the code says about itself.

Remarks

On a server this is an accumulator and nothing more — time in, whole ticks out, the same shape as the engine's fixed step. On a client it is also the clock-sync loop, and that is where the interesting decision is.

Drift, do not jump. A client that discovers it is three ticks behind could set its tick counter three higher, and everything keyed by tick — input, interpolation, the history the server rewinds — would jump with it. Instead the tick length is scaled by up to MaxDriftRatio, so the client runs a few percent fast until it has caught up and then goes back to normal. Nobody sees a correction that takes a second and moves nothing.

Jump anyway when drifting would take too long. Joining, resuming from a breakpoint or coming back from a suspended app leaves an error that a 10 % correction would take minutes to work off. Past SnapThresholdTicks the clock snaps, and says so through SnapCount rather than doing it quietly.

The client runs ahead, the renderer runs behind. Current is aimed at the server's tick plus a lead of half the round trip and a jitter margin, so input sent now arrives just before the server needs it. InterpolationTick is the opposite: the server's tick minus the same margin, which is the tick the motion layer should be drawing, because the snapshot for it has already arrived.

Fields and properties (19)

  • public TickRate Rate

    How often this clock ticks.

  • public Tick Current

    The tick the simulation is on.

  • public int MaxTicksPerAdvance

    The most ticks one Advance may run before the rest of the debt is dropped.

  • public double MaxDriftRatio

    How far the tick length may be scaled to correct drift, as a fraction.

  • public int SnapThresholdTicks

    How large an error stops being corrected by drifting and is snapped instead.

  • public RoundTripEstimator RoundTrip

    Round trip and jitter, measured from the samples handed to Synchronize.

  • public bool IsSynchronized

    Whether this clock has ever been told what the server's tick is.

  • public long TotalTicks

    Ticks run since this clock was made.

  • public long DroppedTicks

    Ticks dropped to the catch-up clamp — a stall, visibly rather than quietly.

  • public long SnapCount

    How many times the clock has given up on drifting and snapped.

  • public Tick EstimatedServerTick

    What the server's tick is believed to be right now.

  • public int LeadTicks

    How far ahead of the server this clock aims to be, so that input sent now arrives in time: half a round trip, plus a margin for jitter, plus one.

  • public int LeadBias

    An adjustment to the lead, in ticks, for something that measured better than a guess.

  • public Tick InterpolationTick

    The tick the renderer should be interpolating towards — behind the server, not ahead.

  • public int InterpolationDelayTicks

    How far behind the server the interpolation target sits.

  • public Tick TargetTick

    Where Current is trying to be.

  • public int TickError

    How far Current is from where it should be. Positive means behind.

  • public double DriftScale

    What the tick length is currently being multiplied by. One when there is nothing to correct, below one while catching up, above one while waiting for the server to catch up.

  • public float Alpha

    How far through the current tick the last Advance left us, from 0 to 1.

Methods (4)

  • public TickManager(TickRate rate, int maxTicksPerAdvance = 8, double maxDriftRatio = 0.1, int? snapThresholdTicks = null)

    Creates a clock.

  • public int Advance(TimeSpan elapsed)

    Banks elapsed time and reports how many ticks to run.

  • public void Synchronize(Tick serverTick, TimeSpan roundTrip)

    Tells the clock what tick the server was on when it sent something, and how long the round trip took.

  • public void Reset(Tick tick)

    Sets the tick directly and forgets any drift correction in progress.

Used by (8)

  • GameClientMultiplayer
  • LocalMatchMultiplayer
  • NetworkMatchMultiplayer
  • NetworkSessionVixen.Net
  • PredictionWiringTestsVixen.Net.Tests
  • SessionTestsVixen.Net.Tests
  • TickLeadControllerVixen.Net
  • TickManagerTestsVixen.Net.Tests