/** * Rolling reconcile-drift telemetry, shared by {@link Reconciler} and * {@link SimReconciler} so both report it identically. * * Each reconcile feeds the max |correction| (world/pose units) into a pair: * * - **ema** — EMA of the magnitude: the *persistent* component. A steady * nonzero `ema` means the prediction is genuinely *diverging* from the * server (wrong `dt`, a non-shared `step`, a skipped input) — the * rubber-banding you otherwise can't tell apart from jitter. * - **peak** — a decaying max: *recent* spikes. A `peak` well above a low * `ema` is network *jitter* (occasional rollbacks), not divergence. * * Both ~0 ⇒ the prediction matched the server. Fed once per reconcile (patch * rate, not per render frame), so the cost is two flops. */ export interface Drift { /** EMA of reconcile-correction magnitude — the persistent/divergence component. */ ema: number; /** Decaying max of reconcile-correction magnitude — recent jitter spikes. */ peak: number; } /** A fresh zeroed {@link Drift}. */ export declare function newDrift(): Drift; /** Fold one reconcile's max |correction| (`mag`, world/pose units) into `d`. */ export declare function updateDrift(d: Drift, mag: number): void; /** Zero `d` — call on a hard resync (respawn) so a deliberate pose jump doesn't * inflate the telemetry into looking like divergence. */ export declare function resetDrift(d: Drift): void; /** The actionable read of the rolling drift — see {@link classifyDrift}. */ export type DriftStatus = "matched" | "jitter" | "diverging"; /** * Turn the rolling {@link Drift} into an actionable status. The debug panel and * the `warnOnDivergence` warning both classify through here, so they can never * disagree about what the numbers mean: * * - **matched** — `ema` and `peak` both within the floor: the prediction * reproduces the server. Nothing to do. * - **jitter** — `ema` within the floor but `peak` above it: corrections * happen yet DON'T persist (they decay out of the EMA) → transient network * jitter (packet loss / reorder), not a bug; smoothing absorbs it. * - **diverging** — `ema` above the floor: the *persistent* correction is real * → the client and server simulations disagree (a determinism bug). * * The EMA's smoothing IS the persistence test — a one-off spike barely moves it, * so only sustained corrections read as `diverging`. The floor is the caller's * `tolerance` (`warnOnDivergence`) when set — so the matched/diverging cut needs * no game-specific magic number — and falls back to {@link FLOAT_NOISE} ("is it * ~0") when it isn't. */ export declare function classifyDrift(d: Drift, tolerance?: number): DriftStatus;