Vixen
02b45cc4
csharp
public sealed class LagCompensator

The world as a client plausibly saw it, for as long as it takes to ask one question.

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

Remarks

The problem. A player with an 80 ms round trip aims at a running target, fires, and the packet reaches the server 40 ms later — by which time the target has moved a third of a metre and the shot misses something the shooter watched themselves hit. Snapshot interpolation makes it worse rather than better: the client was not even rendering the newest state it held, it was rendering behind it. Without compensation, hitting anything moving requires leading it by an amount that depends on your own latency, which players experience as the game being broken.

The answer, and its cost. The server keeps a short history of where every compensated body was, moves those bodies back to where the shooter saw them, asks physics the question, and puts them back. The cost is paid by the person who was shot: they had already moved, and from their side they were killed after reaching cover. That trade is not avoidable — it is the one every server-authoritative shooter makes — and the settings are where it is decided rather than assumed.

Only tracked bodies move. Static geometry did not go anywhere, so rewinding it would be work with no effect; the tracked set is the players and the vehicles, which is tens of bodies rather than thousands. It also means the walls stay where they are during a rewound query, which is what makes a shot through a doorway resolve against the doorway as it is now — and doorways do not move.

Nothing here believes the client. A hit claim names a tick, and the client chooses that number. ClampFor is the rule that decides what it is allowed to mean, and it is public and separately testable because it is the anti-cheat surface: a player cannot rewind further than their measured round trip makes plausible, however far back they say they were looking.

Single-threaded frame code, like everything else in the tick. Capture runs once a tick beside the replication capture; a rewind happens inside the handling of one remote call and is over before the next thing runs.

Fields and properties (7)

  • public LagCompensationSettings Settings

    How far back it is willing to look.

  • public int TrackedCount

    How many bodies are having their history kept.

  • public Tick NewestTick

    The newest tick captured.

  • public bool HasCaptured

    Whether anything has been captured at all.

  • public long RewindCount

    How many rewinds have been performed.

  • public long ClampedCount

    How many claims were clamped to the window rather than honoured as asked.

  • public bool IsRewound

    Whether a rewind is in progress. Bodies are not where the simulation left them.

Methods (10)

  • public LagCompensator(PhysicsWorld world, TickRate rate, LagCompensationSettings? settings = null)

    Creates a compensator over a physics world.

  • public void Track(BodyHandle body)

    Starts keeping history for a body.

  • public bool Forget(BodyHandle body)

    Stops keeping history for a body, and forgets what it had.

  • public bool IsTracked(BodyHandle body)

    Whether a body is having its history kept.

  • public bool TryGetHistory(BodyHandle body, out BodyHistory? history)

    The history kept for a body, for a diagnostic that wants to draw it.

  • public void Capture(Tick at)

    Records where every tracked body is, once, for this tick.

  • public Tick ClampFor(Tick claimed, TimeSpan roundTrip)

    What a claimed tick is allowed to mean, given what the server measured.

  • public RewindScope Rewind(Tick at, float fraction = 0)

    Moves every tracked body to where it was, until the scope is disposed.

  • public RewindScope RewindFor(Tick claimed, TimeSpan roundTrip, float fraction = 0)

    Rewinds to what a player's claim is allowed to mean.

  • public void Clear()

    Forgets every history, for a match that is starting again.

Used by (2)

  • LagCompensationTestsVixen.Net.Physics.Tests
  • RewindScopeVixen.Net.Physics