Networking · class
RewindLoop
Explained in Networking and rollback.
class RewindLoop<S>import { RewindLoop } from '@driftengine/network';Constructor
new
constructor(options: RewindOptions<S>)| Parameter | Type | Description |
|---|---|---|
options | RewindOptions<S> |
Properties
| Name | Type | Description |
|---|---|---|
depthreadonly | number | |
fixedDtreadonly | number | |
inputsreadonly | InputLog |
Accessors
| Name | Type | Description |
|---|---|---|
tickget | number | The last tick that was stepped. -1 before anything has run. |
isReplayingget | boolean | Whether step is being called by a replay. See isReplaying for why a consumer may care. |
statsget | { readonly replays: number; readonly replayedTicks: number; } | How many rewinds have happened, and how many ticks they re-ran. For a consumer's diagnostics. |
earliestget | number | The oldest tick a rewind can still reach, or -1 when nothing is retained. |
Methods
advance
advance(dt: number, tick: number): voidTake one tick: settle any pending rewind, save the world as this tick begins, then step.
| Parameter | Type | Description |
|---|---|---|
dt | number | |
tick | number |
More
The tick comes from the loop rather than being counted here, so there is one source of truth for it. Handing back a tick already stepped is refused, because it would overwrite a snapshot a rewind may still need and there is no reading of it that is not a caller's bug.
supply
supply(participant: number, tick: number, payload: Uint8Array): booleanAn input arrived. false when it is for a tick this loop can no longer reach.
| Parameter | Type | Description |
|---|---|---|
participant | number | |
tick | number | |
payload | Uint8Array |
More
A refusal rather than a silent drop, because an input outside the rewind window means the session has diverged from this peer's world and nothing local can repair it — which is information a consumer needs, and is the point at which a lockstep session should stall rather than continue.
reconcileSnapshot
reconcileSnapshot(tick: number, apply: () => void): booleanAn authoritative state for tick arrived: put the world back there, let apply overwrite what
the authority owns, and replay the local ticks since.
| Parameter | Type | Description |
|---|---|---|
tick | number | |
apply | () => void |
More
This is the operation a late input is not. A late input means the ticks since were computed from a wrong input; an authoritative state means they were computed from a wrong world. So the snapshot for that tick is corrected and re-saved before the replay, and the local inputs are kept, which is what makes a correction converge instead of erasing what the player did.
false when the tick is outside the window, which for a client means the correction is older
than its own history and the honest response is to accept the authority's state whole.
rewindTo
rewindTo(tick: number): booleanPut the world back to the beginning of tick and replay to where it was.
| Parameter | Type | Description |
|---|---|---|
tick | number |
More
Public because lag compensation needs it — an authority rewinding to a shooter's view of the past is a real technique and a fairness policy an engine should not choose. The design refuses to implement that policy and exposes the machinery for it, with the reason in §16.
digestOf
digestOf(tick: number): string | nullA hash of the state as tick began, or null when that tick is not retained or the snapshotter
offers no digest.
| Parameter | Type | Description |
|---|---|---|
tick | number |
More
A slot rather than the live world, and that distinction is the whole of it. The live world is at the newest tick and is speculative: it was computed from predictions for inputs that have not arrived. Two peers comparing their live worlds disagree constantly and correctly, because each has predicted what the other already knows. A slot at a confirmed tick was computed from inputs both of them have, which is the only state worth comparing — and getting this wrong halted a healthy session at tick 32 during development.