{"version":3,"file":"reconciler.mjs","sources":["../../src/predict/reconciler.ts"],"sourcesContent":["/**\n * Reconciler — server-reconciled rollback for a locally-controlled entity whose\n * authoritative truth is a flat list of scalar `fields` on ONE schema instance.\n *\n * The active counterpart to {@link Predict}: where Predict passively smooths the\n * server stream for entities you DON'T control (lerp/reckon), the Reconciler\n * owns the predicted simulation of the entity you DO control. It applies your\n * inputs immediately (zero-latency local feel), buffers the unacknowledged ones,\n * and when the server's authoritative state arrives rewinds to that truth and\n * replays the still-unacked inputs — the standard rewind-and-replay rollback loop\n * (shared with `SimReconciler` via {@link RollbackController}), with the *server*\n * as the authority that provides the restore point.\n *\n * This is the flat-`fields` face of the shared engine: it mirrors a declared\n * `fields` list off one authoritative schema instance (adopt = copy those fields;\n * pose = read them back). For composite state across several instances, or an\n * opaque physics-engine handle, reach for `SimReconciler` (`predict.sim`).\n *\n * `fields` is OPTIONAL and defaults to EVERY scalar field the instance's schema\n * declares (numbers / booleans / strings, declaration order — the same metadata\n * walk as `predict.sim`'s auto-bind; child schemas, collections and `.noSync()`\n * fields are excluded). Pass an explicit list only to subset deliberately: hot\n * server-driven scalars (hp regen, timers) defeat the wire-precision reconcile\n * skip and surface as drift-telemetry corrections when they move; a string field\n * disables the history ring; adopt-only fields become mirrored into `.state` at\n * ack cadence (read them off the raw instance for decode cadence). With an\n * explicit subset, a dev-only diagnostic (debug overlay loaded) warns once per\n * schema field `step` touches that the list doesn't mirror.\n *\n * The acknowledgement lives on the INPUT HANDLE, not a clock: you send inputs\n * through `room.input(...)`, so that handle knows the server ack\n * (`input.lastProcessed`) and the seq you've sent (`input.sentCount`).\n *\n * Smooth error correction: a misprediction is absorbed into a per-field visual\n * offset that decays to 0 over a few frames, so corrections never pop.\n *\n * Input is FIXED-TIMESTEP and the reconciler is a pure OBSERVER: you mutate + send\n * through the input handle directly, and `predict.tick(now)` returns how many fixed\n * steps are due this frame. The reconciler watches the handle's `sentCount` and\n * predicts each new send (see {@link RollbackController}); render reads\n * ({@link value}) interpolate between the two latest steps so motion stays smooth\n * above the step rate.\n *\n *     // Every send() transmits one input (body-less when unchanged), so each\n *     // predicted step is delivered — predicted set == server-applied set.\n *     const input = room.input({ type: MoveInput, mode: \"reliable\" });\n *     const me = predict.reconciler(player, {\n *         input,\n *         step: (ctx, state, command) => applyInput(state, command, LEVEL, ctx.dt), // ctx.dt shared w/ server\n *         smoothMs: 65,\n *         // fields: defaults to every scalar field of `player`'s schema.\n *         // stepMs / stepSeconds default from `input`'s server-advertised rate.\n *     });\n *\n *     // per frame: predict.tick returns how many fixed input steps are due; mutate\n *     // + send each through the handle — the reconciler observes and predicts them:\n *     const n = predict.tick(now);\n *     for (let i = 0; i < n; i++) {\n *         input.data.moveX = moveX; input.data.jump = jump; // stage the wire input\n *         input.send();                                     // transmit + buffer for replay\n *     }\n *     draw(predict.value(player, \"x\"), predict.value(player, \"y\")); // one read idiom\n *\n * The reconciler registers its numeric `fields` into the owning Predict's\n * `predict.value(instance, field)` — the SAME render read as every passively-\n * smoothed entity (raw fallback before spawn / after dispose). `me.value(f)`\n * remains for direct handle reads.\n *\n * Hot path (`value`) is plain-number only; reconcile (cold, ~server-tick rate)\n * reads the authoritative instance.\n */\n\nimport { RollbackController, type RollbackOptions, type StepContext } from \"./rollback.ts\";\nimport { wireQuantizerOf, scalarFieldsOf } from \"../core/schema-reflect.ts\";\nimport { diagnosticsActive } from \"./divergence.ts\";\n\n/** Ring/compare encoding of a predicted field value: numbers pass through,\n *  booleans become 0/1, anything else NaN (never matches → safe adopt). The\n *  recording and comparing sides MUST encode identically — hence one helper. */\nconst asScalar = (v: unknown): number =>\n    typeof v === \"number\" ? v : typeof v === \"boolean\" ? (v ? 1 : 0) : NaN;\n\n// Re-export StepContext (+ the sink shape its `predict` emits into) so the\n// `@colyseus/sdk/predict` barrel resolves them here.\nexport type { StepContext, PredictSink } from \"./rollback.ts\";\n\nexport interface ReconcilerOptions<S extends object, I> extends RollbackOptions<I> {\n    /**\n     * Deterministic input-application step, SHARED with the server. Mutates\n     * `state` in place by applying `command` over `ctx.dt`. `ctx` leads (the\n     * step-context-first argument convention): it carries the fixed `dt`\n     * (matches the server's, so replay reproduces the server's result),\n     * `ctx.memo` (freeze a value replay can't re-derive) and `ctx.predict`\n     * (declare an optimistic event — live steps only, replay-safe).\n     *\n     * `command` is the buffered wire input the handle recorded at `send()`\n     * (`input.at(seq)`) — the exact value the server decodes, read the same way on\n     * the live catch-up step and on rollback replay, so lossy wire fields (a\n     * `t.quantized` angle) reconcile by construction. Keep everything the step\n     * reads on the input schema; anything you don't stage on `input.data` before\n     * `send()` won't reach `step`.\n     */\n    step: (ctx: StepContext, state: S, command: I) => void;\n    /**\n     * Fields to mirror from the server on reconcile (everything the step reads\n     * or writes). Numeric fields additionally get smooth error correction;\n     * non-numeric fields (e.g. `grounded`) are copied verbatim.\n     *\n     * OPTIONAL — when omitted, defaults to EVERY scalar field the instance's\n     * schema declares (numbers / booleans / strings, declaration order; child\n     * schemas, collections and `.noSync()` fields excluded — the same metadata\n     * walk as `predict.sim`'s auto-bind).\n     *\n     * List explicitly only to SUBSET deliberately: hot server-driven scalars\n     * (hp regen, timers) defeat the wire-precision reconcile skip and register\n     * as drift-telemetry corrections when they move; string fields disable the\n     * history ring; adopt-only fields become mirrored at ack cadence (read them\n     * off the raw instance for decode cadence). With an explicit subset, a\n     * dev-only diagnostic (debug overlay active) warns once per schema field\n     * `step` touches that the list doesn't mirror.\n     */\n    fields?: readonly (keyof S & string)[];\n}\n\nexport class Reconciler<S extends object = any, I = any> extends RollbackController<I> {\n    /** The current predicted step state (the \"true\" state, advanced one fixed\n     *  step per input). Read raw for logic; rendered via interpolation. */\n    private local: Record<string, number | boolean> = {};\n\n    private readonly fields: readonly string[];\n    private readonly numericFields: string[] = [];\n    private readonly step: (ctx: StepContext, state: S, command: I) => void;\n    private readonly instance: any;\n\n    // --- Wire-precision-aware reconcile (see RollbackController.truthMatchesAt) --\n    /** Per-field wire quantizer, parallel to `fields`: maps a predicted float64\n     *  to the exact value the wire would deliver (fround for `float32`, the\n     *  codec's dynamic rule for auto `number`, identity for exact types). */\n    private readonly wireRound: Array<(v: number) => number> = [];\n    /** Per-seq predicted-state ring (values via {@link asScalar}): slot\n     *  `seq % size` holds the post-step field values for that seq; `historySeq`\n     *  validates the slot (-1 = empty). Written on every applied step — live AND\n     *  replay, so after a rollback the ring tracks the post-rollback trajectory.\n     *  Sized to the input handle's replay ring: same seq window, ages out together. */\n    private readonly history: Float64Array;\n    private readonly historySeq: Float64Array;\n    private readonly historySize: number;\n    /** False when a declared field isn't a number/boolean at construction (the\n     *  ring can't represent it) — the short-circuit is then disabled and every\n     *  reconcile adopts, exactly the pre-history behavior. */\n    private readonly historyOn: boolean;\n\n    /** Schema scalars absent from an EXPLICIT `fields` list — the dev\n     *  diagnostic's watch set. null ⇒ diagnostic off (derived list, complete\n     *  list, or no metadata): applyStep's check is then one null compare. */\n    private undeclared: Set<string> | null = null;\n    /** Cached dev proxy over `local` handed to `step` while the debug overlay\n     *  is active (see {@link stepView}). */\n    private devView: S | null = null;\n\n    constructor(instance: object, opts: ReconcilerOptions<S, I>) {\n        super(opts);\n        this.instance = instance;\n        const explicit = opts.fields;\n        // Omitted fields ⇒ mirror every schema scalar (sim's auto-bind rule).\n        const fields = explicit ?? scalarFieldsOf(instance).fields;\n        if (explicit === undefined && fields.length === 0) {\n            throw new Error(\n                \"predict.reconciler(): no `fields` given and none derivable — the \" +\n                \"instance has no schema metadata (a plain object, or a schema with no \" +\n                \"scalar fields). Pass the decoded instance from room.state, or list \" +\n                \"`fields` explicitly.\",\n            );\n        }\n        this.fields = fields as readonly string[];\n        this.step = opts.step;\n        let scalarOnly = this.fields.length > 0;\n        for (const f of this.fields) {\n            const v = (instance as Record<string, unknown>)[f];\n            this.local[f] = v as number | boolean;\n            if (typeof v === \"number\") { this.numericFields.push(f); this.prev[f] = v; this.error[f] = 0; }\n            else if (typeof v !== \"boolean\") scalarOnly = false;\n            this.wireRound.push(wireQuantizerOf(instance, f));\n        }\n        this.historyOn = scalarOnly;\n        // The 64 fallback covers bare test fakes without a ring.\n        this.historySize = this.input_.replayBufferSize ?? 64;\n        this.history = new Float64Array(this.historyOn ? this.historySize * this.fields.length : 0);\n        this.historySeq = new Float64Array(this.historyOn ? this.historySize : 0).fill(-1);\n        if (explicit !== undefined) {\n            const declared = new Set<string>(this.fields);\n            const rest = scalarFieldsOf(instance).fields.filter((f) => !declared.has(f));\n            if (rest.length > 0) this.undeclared = new Set(rest);\n        }\n    }\n\n    /**\n     * The TRUE predicted state — read it for game logic, and mutate it directly\n     * to apply a per-step side-effect (e.g. a collision bounce). It carries no\n     * interpolation / smooth-correction offset (that's what {@link value} adds\n     * for rendering). To survive a reconcile, a mutation must be reproducible by\n     * `step` during replay — record it per-seq and re-apply it inside `step`.\n     *\n     * Always current — inputs are stepped eagerly as you `send()` them (the\n     * reconciler observes the handle). Plain object access — no string-keyed\n     * get/set, no mutator closure. The reconciler tracks ONE entity, so its state\n     * is naturally a single struct; this ports to `state.vy = …` in C# / Lua and\n     * `state->vy = …` in C.\n     */\n    get state(): S {\n        return this.local as S;\n    }\n\n    /** @internal Bound registrations for the owning Predict's `value()` overlay:\n     *  this reconciler's numeric fields on its one instance, pose key = field\n     *  name ({@link value} already reads by field). Empty source refId (plain\n     *  test fixtures) is skipped by the overlay installer. */\n    get boundRegistrations(): ReadonlyArray<{ source: object; fields: readonly string[]; poseKeys: readonly string[] }> {\n        return [{ source: this.instance as object, fields: this.numericFields, poseKeys: this.numericFields }];\n    }\n\n    /**\n     * Rendered value: the predicted state interpolated between the previous and\n     * current fixed step by {@link renderAlpha}, plus the decaying correction\n     * offset. Smooth above the step rate (at ~one step of render latency). Numeric\n     * fields only; non-numeric fields return the current value verbatim.\n     */\n    value(field: keyof S & string): number {\n        this.noteRenderRead();\n        const c = this.local[field as string];\n        if (typeof c !== \"number\") return c as unknown as number;\n        const smoothed = c + (this.error[field as string] ?? 0);\n        const p = this.prev[field as string] ?? smoothed;\n        return p + (smoothed - p) * this.renderAlpha();\n    }\n\n    // --- RollbackController hooks ----------------------------------------------\n\n    protected smoothedFields(): readonly string[] { return this.numericFields; }\n    protected readCurrent(field: string): number { return this.local[field] as number; }\n\n    protected applyStep(input: I): void {\n        // Explicit-subset dev diagnostic: hand `step` a proxied view that warns\n        // on undeclared-schema-field touches. Overlay checked per step (its\n        // dynamic import races construction). Raw local otherwise.\n        const state = this.undeclared !== null && diagnosticsActive()\n            ? this.stepView() : (this.local as S);\n        this.step(this.stepCtx, state, input);\n        // Record this seq's predicted state (live and replay alike — after a\n        // rollback the replayed values are the canonical prediction).\n        if (this.historyOn) {\n            const seq = this.stepCtx.tick;\n            const slot = seq % this.historySize;\n            const base = slot * this.fields.length;\n            for (let i = 0; i < this.fields.length; i++) {\n                this.history[base + i] = asScalar(this.local[this.fields[i]]);\n            }\n            this.historySeq[slot] = seq;\n        }\n    }\n\n    /** Dev-only view of `local` for `step`: warns ONCE per schema scalar missing\n     *  from the explicit `fields` list on first read/write — the \"step touched a\n     *  field the reconciler doesn't mirror\" hazard (prediction integrates on a\n     *  stale value; rubber-bands only under latency). String keys only: symbols\n     *  (runtime probes) and non-schema scratch keys forward untouched. Built\n     *  lazily on the first overlay-active step, then cached — identity is stable\n     *  across live and replay steps. Non-semantic by construction (forwards\n     *  everything unchanged) — ports substitute a native check or skip it, see\n     *  PORTING.md. */\n    private stepView(): S {\n        if (this.devView !== null) return this.devView;\n        const undeclared = this.undeclared!;\n        const warned = new Set<string>();\n        const check = (verb: string, prop: string | symbol): void => {\n            if (typeof prop !== \"string\" || !undeclared.has(prop) || warned.has(prop)) return;\n            warned.add(prop);\n            console.warn(\n                `@colyseus/sdk predict: step ${verb} \"${prop}\" — a schema field NOT in this ` +\n                `reconciler's \\`fields\\` list, so it is never mirrored or replayed: prediction ` +\n                `integrates on top of a stale value and rubber-bands under latency. Add \"${prop}\" ` +\n                `to \\`fields\\`, or omit \\`fields\\` to mirror every scalar field. Read adopt-only ` +\n                `fields off the raw instance instead of the predicted state.`,\n            );\n        };\n        this.devView = new Proxy(this.local, {\n            get(t, prop, recv) { check(\"read\", prop); return Reflect.get(t, prop, recv); },\n            set(t, prop, v, recv) { check(\"wrote\", prop); return Reflect.set(t, prop, v, recv); },\n        }) as S;\n        return this.devView;\n    }\n\n    /**\n     * Wire-precision compare: the prediction at `acked` (from the history ring)\n     * against the decoded truth on the instance, each predicted value passed\n     * through its field's wire quantizer. All fields indistinguishable ⇒ the\n     * wire could not have told the server anything different ⇒ skip adopt+replay\n     * (see {@link RollbackController.reconcile}). Any miss — ring slot aged out\n     * or pre-reset, NaN, a genuine mismatch — falls back to a full adopt.\n     */\n    protected truthMatchesAt(acked: number): boolean {\n        if (!this.historyOn) return false;\n        const slot = acked % this.historySize;\n        if (this.historySeq[slot] !== acked) return false;\n        const base = slot * this.fields.length;\n        const inst = this.instance as Record<string, unknown>;\n        for (let i = 0; i < this.fields.length; i++) {\n            if (this.wireRound[i](this.history[base + i]) !== asScalar(inst[this.fields[i]])) return false;\n        }\n        return true;\n    }\n\n    protected snapshotPrev(): void {\n        for (const f of this.numericFields) this.prev[f] = (this.local[f] as number) + this.error[f];\n    }\n\n    protected adoptTruth(): void {\n        const inst = this.instance as Record<string, number | boolean>;\n        for (const f of this.fields) this.local[f] = inst[f];\n    }\n\n    protected reseedState(): void {\n        const inst = this.instance as Record<string, number | boolean>;\n        for (const f of this.fields) this.local[f] = inst[f];\n        for (const f of this.numericFields) { this.prev[f] = this.local[f] as number; this.error[f] = 0; }\n        // Prior life's predictions must not certify a post-reset ack as matching.\n        this.historySeq.fill(-1);\n    }\n}\n"],"names":[],"mappings":"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"}