{"version":3,"file":"Predictor.mjs","sources":["../../src/predict/Predictor.ts"],"sourcesContent":["/**\n * Predict — drop-in prediction layer for Colyseus 0.18+ clients.\n *\n * Combines two prediction strategies behind a single ergonomic class:\n *   - Field smoothing (lerp / extrapolate / damped)\n *   - Dead-reckoning (forward-simulate via a shared step function)\n *\n * THE PREDICTION FAMILY — pick by what you're predicting:\n *   - `Predict` (this class) — PASSIVE smoothing of the server stream for\n *     entities you DON'T control (remote players → lerp, AI → reckon). Read\n *     with `predict.value(instance, field)`.\n *   - `predict.reconciler(self, …)` → a {@link Reconciler} — ACTIVE server-\n *     reconciled rollback for the entity you DO control: apply input now,\n *     rewind to server truth + replay, smoothly correcting. Read state for\n *     logic via `controller.state` (exact, mutable).\n *   - `predict.sim(…)` → a {@link SimReconciler} — the same rollback over a\n *     COMPOSITE or engine-backed world. Decoded schema instances placed in\n *     its `world` are AUTO-BOUND (seeding/adopt/pose derive from the schema).\n *   - `predict.defineEvent(…)` → a {@link PredictedEventChannel} — a typed\n *     optimistic DISCRETE event (a goal, a kill, a pickup): predicted from the\n *     sim via `ctx.predict(channel, payload)` (replay-safe) or from UI, with\n *     confirm / auto-reject / TTL settlement against server truth.\n *\n * ONE READ IDIOM for rendering: `predict.value(instance, field)` covers every\n * entity — passively-smoothed remotes AND the instances a reconciler/sim\n * binds (the controllers register their bound fields here, overlaying any\n * passive slot while they live and restoring it on dispose). Consumers get\n * the full lifecycle for free: raw state before the controller spawns →\n * reconciled pose while it's alive → raw again after `dispose()`. Game logic\n * (hit-reg, zone checks) keeps reading EXACT state via `controller.state` /\n * `controller.world` — never the smoothed render read.\n * One `predict.tick(now)` per frame drives all three — controllers and event\n * channels spawned here are ticked/pruned automatically (see {@link tick}).\n *\n * Mirrors `Callbacks.get(room)` from `@colyseus/schema` — construct via the\n * static factory and attach prediction to schemas as they appear. The\n * server's `room.clock` (delivered via the TIMED protocol prefix when the\n * room called `defineInput()`) is consumed automatically — RTT / server\n * time arrive without any setup.\n *\n *     import { Client } from \"colyseus.js\";\n *     import { Predict } from \"./Predictor\";\n *\n *     const room = await client.joinOrCreate(\"arena\");\n *     const predict = Predict.get(room, { mode: \"lerp\", delay: 80 });\n *\n *     // Smoothing on a single schema instance:\n *     predict.attach(room.state.boss, { x: \"lerp\", y: \"lerp\" });\n *\n *     // Dead-reckoning on every child of a collection. Pass the parent\n *     // (e.g. `room.state`) only for nested collections — root-level\n *     // collections take just the key:\n *     predict.attachAll(\"enemies\", {\n *         mode: \"reckon\", step: stepEnemy, fields: [\"x\",\"y\",\"vx\"], smoothMs: 40,\n *     });\n *\n *     // Once per render frame:\n *     function renderLoop(t: number) {\n *         predict.tick(t);\n *         drawPlayer(predict.value(room.state.boss, \"x\"), predict.value(room.state.boss, \"y\"));\n *         requestAnimationFrame(renderLoop);\n *     }\n *\n * For side-by-side mode comparison, spin up multiple Predicts:\n *\n *     const lerp   = Predict.get(room, { mode: \"lerp\",   delay: 80 });\n *     const damped = Predict.get(room, { mode: \"damped\", smoothMs: 65 });\n *\n * The exact public surface an SDK port implements is recorded in the port\n * manifest (`PORTING.md`, repo root); everything else in this module is\n * internal machinery or a JS-only dev affordance.\n *\n * NOTE: call `attach` AFTER the instance has been delivered by the\n * server (e.g. inside `onAdd`). Attaching to an instance that hasn't been\n * decoded yet throws `Can't addCallback (refId is undefined)`.\n */\n\nimport { Callbacks, type Data } from \"@colyseus/schema\";\nimport { PredictedEventChannel, type PredictedEventChannelOptions } from \"./predictedEventChannel.ts\";\nimport { PredictedSpawns, type PredictedSpawnsOptions } from \"./predictedSpawns.ts\";\nimport { Reconciler, type ReconcilerOptions } from \"./reconciler.ts\";\nimport { SimReconciler, type SimReconcilerOptions } from \"./simReconciler.ts\";\nimport { InputHandleImpl, type InputHandle } from \"../input/InputHandle.ts\";\nimport { classifyDrift, type Drift, type DriftStatus } from \"./drift.ts\";\nimport { NULL_CLOCK, type RoomClockLike } from \"../RoomClock.ts\";\nimport { publishDebug } from \"../debug-channel.ts\";\nimport {\n    $VALUES,\n    refIdOf, metadataOf, fieldIndexOf, scalarFieldNamesOf, makeUnrolledSnapshot,\n    type CollectionKeys, type ChildOf,\n} from \"../core/schema-reflect.ts\";\nimport { wireConfirmOn, type ConfirmOn } from \"./confirmOn.ts\";\n\n// -----------------------------------------------------------------------------\n// Type helpers for narrow inference on Predict.{attach,attachAll,value}.\n// -----------------------------------------------------------------------------\n\n/** Keys of T whose value type is `number`. We only smooth numeric fields. */\ntype NumericKeys<T> = {\n    [K in keyof T]-?: T[K] extends number ? K : never;\n}[keyof T] & string;\n\nexport type PredictMode = \"lerp\" | \"extrapolate\" | \"damped\" | \"reckon\" | \"raw\";\n\n/**\n * Field-level smoothing options for `lerp` / `extrapolate` / `damped`.\n *\n * `lerp`        — canonical entity interpolation. Buffers recent snapshots\n *                 and renders at `renderTime - delay`, interpolating between\n *                 the bracketing pair. Smooth, lagged, sample-faithful.\n *                 The primary knob is `delay`; size it so jitter rarely\n *                 makes the buffer underrun (1–2 server tick intervals).\n *                 An optional `smoothMs` output spring (default off) keeps\n *                 rendered velocity continuous when the snapshot stream\n *                 itself is imperfect.\n * `extrapolate` — linear forecast from the two most recent samples.\n *                 Live, can overshoot.\n * `damped`      — exponential smoothing toward the latest value.\n *                 Never exact, never jittery.\n */\nexport interface SmoothingOptions {\n    mode?: \"lerp\" | \"extrapolate\" | \"damped\";\n    /** Render-time lag in ms for `lerp` (default 100). Ignored by other modes. */\n    delay?: number;\n    /**\n     * Output-smoothing time constant, in milliseconds. 0 disables.\n     *\n     * The smoothed value closes ~63% of any gap to its target per `smoothMs`\n     * (~95% after 3×). The practical reading: `smoothMs` is roughly the extra\n     * display latency the smoothing adds — during steady motion the display\n     * trails its target by ≈ `speed × smoothMs` (260 px/s at `smoothMs: 65`\n     * → ~17 px).\n     *\n     * `damped` uses it as the chase rate toward the latest value, and\n     * `extrapolate` as its predict-then-smooth blend (default 50 for both;\n     * 0 snaps — raw latest value / raw forward-projection).\n     *\n     * `lerp` uses it as an optional output spring on the interpolated result\n     * — default 0 (off, exact interpolation). Turn it on to keep rendered\n     * velocity CONTINUOUS when the snapshot stream itself is imperfect\n     * (server stamp jitter, uneven per-patch motion): the eye punishes\n     * discrete velocity jumps far harder than smooth, bounded error. ~25\n     * removes the discontinuities at minimal added lag; ~65 renders rough\n     * streams buttery at the cost of that much more lag. DISPLAY-ONLY:\n     * server-side rewind (lag compensation) reconstructs the UNSMOOTHED\n     * interpolation, so the drawn position trails the hit position by the\n     * `speed × smoothMs` bound above — leave at 0 where draw == hit\n     * precision matters.\n     */\n    smoothMs?: number;\n    /** Maximum extrapolation overshoot in ms past the latest sample for `extrapolate` (default 200). Ignored by other modes. */\n    maxExtrapolate?: number;\n    /**\n     * Snap incoming sample arrival times to a regular grid of this many ms,\n     * relative to the previous sample. 0 disables (default).\n     *\n     * Useful when the server emits state at a known fixed cadence (e.g.\n     * 33.33 ms for a 30 Hz `setSimulationInterval`) and you want lerp /\n     * extrapolate to render at a uniform playback velocity regardless of\n     * network arrival jitter. Each new sample is timestamped at\n     * `lastT + round(elapsed / tickInterval) * tickInterval`, bounded\n     * to never overshoot wall-clock `now` by more than one interval.\n     *\n     * Has no effect on `damped` (which is keyed to render frames, not\n     * sample arrivals).\n     */\n    tickInterval?: number;\n    /**\n     * Value-space discontinuity threshold. When a new sample's value differs\n     * from the previous one by MORE than this, the change is treated as a\n     * TELEPORT (respawn, blink, warp) instead of motion: the smoothing state\n     * resets to the new value and every mode renders it immediately — no\n     * glide across the gap. 0 disables (default).\n     *\n     * Deliberately time-free: latency/jitter shift when samples arrive, not\n     * what they carry, so bursty delivery can't false-trigger it. Size it\n     * well above `maxSpeed × patchInterval` (per-sample motion) and below the\n     * smallest legitimate teleport. Note the server encodes only the LATEST\n     * value per patch — a long server stall coalesces real movement into one\n     * sample, so leave headroom for the stalls you'd rather glide through.\n     * For `angle` fields the delta is measured after the shortest-arc fold\n     * (≤ π), so thresholds above π never trip.\n     */\n    snap?: number;\n    /**\n     * Treat the field as an ANGLE in radians. Samples are stored unwrapped\n     * (continuous) — each new value is folded onto the previous over the\n     * SHORTEST arc — so `lerp` / `damped` / `extrapolate` interpolate correctly\n     * across the ±π seam instead of spinning the long way round. Applies to every\n     * field in the attach config, so attach angular fields (yaw, pitch) in a\n     * SEPARATE call from linear ones (x, y, z). Default false.\n     */\n    angle?: boolean;\n}\n\n/**\n * Entity-level dead-reckoning options. The `step` function advances a scratch\n * copy of the entity forward by `forwardMs` (drawn from the Predict's clock)\n * in fixed substeps; the result is predict-then-smoothed.\n *\n * For Predict constructor defaults `step` is required. For per-`attach` /\n * `attachAll` overrides `step` is optional — if omitted it falls back to the\n * Predict's constructor-time default. Missing on both ⇒ throw with a clear\n * pointer at the call site.\n */\nexport interface ReckonOptions<T = any> {\n    mode: \"reckon\";\n    /** The pure step function. Mutates the provided scratch object in place. */\n    step?: (state: T, dt: number, elapsedMs: number) => void;\n    /** Predict-then-smooth time constant in ms — see {@link SmoothingOptions.smoothMs}. Default 50. 0 = snap. */\n    smoothMs?: number;\n    /** Substep length in ms. Smaller = more accurate bounces / collisions. Default 16. */\n    substep?: number;\n    /** Rebase discontinuities larger than this pop instead of decaying out —\n     *  see {@link SmoothingOptions.snap}. 0 disables (default). */\n    snap?: number;\n}\n\n/**\n * \"Off\" mode — `value()` returns the latest schema field as-is, with no\n * smoothing or prediction. Useful as a baseline in the SDK debug panel so\n * the visual difference each mode contributes can be A/B-compared against\n * the raw server stream.\n */\nexport type RawOptions = { mode: \"raw\" };\n\n/**\n * Discriminated union of mode-specific options. The `mode` field discriminates\n * — TS catches mistakes like `{ mode: \"lerp\", step: fn }` at compile time.\n */\nexport type PredictOptions<T = any> = SmoothingOptions | ReckonOptions<T> | RawOptions;\n\n// -----------------------------------------------------------------------------\n// SoA slot storage — a single Float64Array holds every tracked slot's runtime\n// state, including lerp's snapshot ring. Indexed by slot id (assigned at\n// track-time, recycled via a free-list).\n//\n// Config (mode/delay/smoothMs/maxExtrapolate/tickInterval) is *not* stored\n// per slot — it lives in a separate `profileBuf` and the slot only carries a\n// `profileIdx`. Many slots that share the same config share one profile, so\n// homogeneous attachAll groups collapse to a single packed record. Mutating\n// the defaults profile in place is enough for `setDefaults` to take effect —\n// no retrack-all walk.\n//\n// Layout per slot: stride = SLOT_STRIDE floats.\n//   [0]  v1                 latest server value (damped target; fallback when ring empty)\n//   [1]  auxV               mode-multiplexed smoothing state:\n//                              damped       → current EMA value\n//                              extrapolate  → predict-then-smooth output\n//                              lerp         → output-spring value (smoothMs > 0)\n//   [2]  auxT               timestamp of the last frame that advanced auxV\n//   [3]  profileIdx         index into `profileBuf` for this slot's config\n//   [4]  refId              schema refId this slot belongs to (self-describing)\n//   [5]  fieldId            schema field index this slot predicts\n//   [6]  ringHead           next write index into the snapshot ring (0..RING_CAP-1)\n//   [7]  ringCount          number of valid entries (0..RING_CAP)\n//   [8]  lerpPrev           previous frame's RAW lerp output — the target slope\n//                              for the output spring's first-order-hold step\n//   [9..]                   RING_CAP × (t, v) interleaved snapshots\n//                              (used by both lerp and extrapolate)\n//\n// refId / fieldId make the slot self-describing: given only a slot id, the\n// engine can recover its (refId, fieldId) without touching any JS object. This\n// is what lets every mode's read collapse to a pure `(slotId) -> number`\n// computer — reckon reads `simByRef[refId]` and `raw` reads SLOT_V1, neither\n// needing the instance handed in.\n//\n// Sample updates write a few floats in place — zero allocation on the hot\n// path. The ring is a fixed circular buffer; pushing past capacity overwrites\n// the oldest entry via head wrap, so there is no O(n) shift like Array.shift.\n//\n// Damped and extrapolate are mutually exclusive per slot (the profile picks\n// the mode), so they share auxV / auxT instead of carrying separate fields.\nconst RING_CAP = 16;\nconst SLOT_V1 = 0;\nconst SLOT_AUX_V = 1;\nconst SLOT_AUX_T = 2;\nconst SLOT_PROFILE = 3;\nconst SLOT_REF = 4;\nconst SLOT_FIELD = 5;\nconst SLOT_RING_HEAD = 6;\nconst SLOT_RING_COUNT = 7;\nconst SLOT_LERP_PREV = 8;\nconst SLOT_RING_BASE = 9;\nconst SLOT_STRIDE = SLOT_RING_BASE + RING_CAP * 2; // 9 + 32 = 41\n\n// Idle-resume gap collapse (see the listener). Colyseus delta-encodes, so a\n// field that stops changing (a player standing still, y while grounded) emits\n// NO samples — the ring goes stale. When samples resume there's a huge time\n// gap between the last idle sample and the first motion sample; left alone,\n// lerp/extrapolate interpolate across it and the entity crawls for ~delay ms\n// (\"starts, pauses, then walks\") before snapping to real speed. We detect the\n// gap RELATIVE to the most recent normal inter-arrival interval (so genuinely\n// sparse-but-regular streams are NOT collapsed) and pull the previous sample's\n// timestamp forward to one normal interval before the resume, so playback\n// continues at the real cadence with no crawl.\nconst GAP_RESUME_MULT = 3;      // collapse when gap > MULT × recent interval (cadence unknown)\n// When the server's patch cadence is known (clock.patchInterval), collapse a\n// gap past ~1.5 patches: on the jitter-free server-time axis a moving field\n// gets a sample EVERY patch, so a longer gap means it went idle. This catches\n// short pauses that MULT × the (rate-scaled) measured interval misses when\n// patchRate ≠ tickRate — the rewind records every patch, so the client must\n// HOLD across an idle gap to match it (lag-comp \"what you see is what you hit\").\nconst GAP_RESUME_PATCH_MULT = 1.5;\nconst GAP_RESUME_MAX_MS = 250;  // cap the synthesized resume span (safety)\n\n// Profile table — packed Float64Array, PROFILE_STRIDE floats. Profile 0 is the Predict's\n// *defaults* (mutable; setDefaults edits it in place). Profiles 1..N are\n// *frozen* per-call configs, allocated when an attach overrides any defaults.\n// Frozen profiles are value-deduplicated via `profileKeys` so that an\n// attachAll on a thousand entities sharing the same override still allocates\n// just one extra profile, not a thousand.\nconst PROFILE_STRIDE = 7;\nconst P_MODE = 0;\nconst P_DELAY = 1;\nconst P_SMOOTH_MS = 2;\nconst P_MAX_EXTRAPOLATE = 3;\nconst P_TICK_INTERVAL = 4;\nconst P_SNAP = 5;\n// Lerp's output-spring time constant, stored SEPARATELY from P_SMOOTH_MS:\n// the same `smoothMs` option defaults 0 on lerp (spring off) but 50 on\n// damped/extrapolate, and a profile can mode-flip at runtime — one float\n// can't carry both defaults. An explicit `smoothMs` writes both fields.\nconst P_LERP_SMOOTH_MS = 6;\nconst DEFAULTS_PROFILE = 0;\n\nconst MODE_LERP = 0;\nconst MODE_EXTRAPOLATE = 1;\nconst MODE_DAMPED = 2;\nconst MODE_RECKON = 3;\nconst MODE_RAW = 4;\n/** Internal-only: the slot's value is a rollback controller's pose read (the\n *  bound overlay `predict.sim`/`predict.reconciler` install for their bound\n *  instances). Not a user-selectable {@link PredictMode} — absent from\n *  MODE_CODES; profiles carrying it are allocated by `installBoundOverlay`. */\nconst MODE_BOUND = 5;\n/** Subset that's purely slot-driven (vs. reckon which also reads `simByRef`). */\ntype SmoothingMode = \"lerp\" | \"extrapolate\" | \"damped\";\nconst MODE_CODES: Record<PredictMode, number> = {\n    lerp: MODE_LERP,\n    extrapolate: MODE_EXTRAPOLATE,\n    damped: MODE_DAMPED,\n    reckon: MODE_RECKON,\n    raw: MODE_RAW,\n};\n\n/**\n * @internal Stepped-prediction options behind the reckon attach path.\n *\n * You already have a pure `step(state, dt, elapsedMs)` function that runs on\n * the server tick. Pass the *same* function via\n * `attach({ kind: \"reckon\", step, ... })` and the client advances a\n * scratch copy of the entity forward by `forwardMs` in small substeps, then\n * predict-then-smooths the result.\n *\n * `forwardMs` / `elapsedMs` default to reading from the Predict's clock —\n * most callers never touch them.\n */\nexport interface SteppedOptions<T = any> {\n    /** Fields that `value(instance, field)` should return predicted values for. */\n    fields: readonly (keyof T & string)[];\n    /** The pure step function. Mutates the provided scratch object in place. */\n    step: (state: T, dt: number, elapsedMs: number) => void;\n    /** How far past the snapshot to predict, in ms. Defaults to the snapshot\n     *  AGE (`serverNow() − clock.lastServerTime()`) — forwards a remote entity\n     *  to its current server position. Override for a different horizon. */\n    forwardMs?: () => number;\n    /** Server time for time-keyed formulas (sinusoids etc). Defaults to `clock.serverNow()`. */\n    elapsedMs?: () => number;\n    /** Predict-then-smooth time constant in ms — see {@link SmoothingOptions.smoothMs}. Default 50. 0 = snap. */\n    smoothMs?: number;\n    /** Substep length in ms. Smaller = more accurate bounces / collisions. Default 16. */\n    substep?: number;\n    /** Rebase discontinuities larger than this pop instead of decaying out —\n     *  see {@link SmoothingOptions.snap}. 0 disables (default). */\n    snap?: number;\n    /** Override how the per-frame scratch is built. Defaults to copying every\n     *  schema field through its accessor (or a plain spread for non-schema\n     *  objects). Override only for exotic instances the default can't clone. */\n    snapshot?: (instance: T) => T;\n}\n\n/**\n * Options for {@link Predict.spawns} — the {@link PredictedSpawnsOptions}\n * store options plus optional dead-reckoning of the collection's confirmed\n * entities, replacing a separate `attachAll(key, { mode: \"reckon\", … })` for\n * spawn-style collections.\n */\nexport interface SpawnsOptions<S = unknown, L = Partial<S>, D = undefined>\n    extends PredictedSpawnsOptions<S, L, D> {\n    /**\n     * Dead-reckon confirmed entities on these fields, using the same `step`\n     * that advances pending locals. Each confirmed entity gets a reckon slot\n     * (readable via `predict.value()` or, uniformly across the handoff, the\n     * store's `value()`): foreign entities forward to server-present\n     * (snapshot age); owned ones additionally forward by the entry's measured\n     * input lead when {@link PredictedSpawnsOptions.spawnTime} is set.\n     */\n    fields?: readonly (keyof S & string)[];\n    /** Reckon smoothing time constant in ms for confirmed entities. Default 0\n     *  — a deterministic constant-step projectile rebases exactly, so smoothing\n     *  only adds lag. */\n    smoothMs?: number;\n    /** Reckon substep in ms. Smaller = more accurate bounces / collisions. Default 16. */\n    substep?: number;\n}\n\n/**\n * @internal Low-level entity-level forward prediction. Used when the motion\n * doesn't fit the `step(state, dt, elapsed)` shape — e.g. a closed-form\n * formula or a non-temporal query. For the usual case prefer\n * {@link SteppedOptions}.\n */\nexport interface SimulateOptions<T = any> {\n    /** Fields on `instance` that `advance` forecasts and `value()` reads. */\n    fields: readonly (keyof T & string)[];\n    /** How far past `now` to predict, in ms. Called every frame. Typical: client RTT (or a smoothed RTT). */\n    forwardMs: () => number;\n    /**\n     * Forecast function. Reads current values off `instance`, writes the\n     * predicted value of `fields[k]` into `out[k]` (SoA — indexed by field\n     * position, NOT keyed by name, so the predict-then-smooth path stays\n     * monomorphic). `out` is a reused buffer; fill every slot each call.\n     *\n     * `endElapsed` is the absolute server-time (ms) the prediction window ends\n     * at (`serverNow()` for the per-frame reckon; an arbitrary instant when read\n     * via {@link Predictor.valueAt}); the window spans `[endElapsed − forwardMs,\n     * endElapsed]`. Ignore it for purely forward, time-independent motion.\n     */\n    advance: (instance: T, forwardMs: number, out: Float64Array, endElapsed: number) => void;\n    /**\n     * Absolute server-time (ms) provider for the prediction window end. Defaults\n     * to `clock.serverNow()`. Only matters for `valueAt` / time-sampled motion.\n     */\n    elapsedMs?: () => number;\n    /**\n     * Predict-then-smooth time constant in ms — see\n     * {@link SmoothingOptions.smoothMs}. Default 50. Set to 0 to snap directly\n     * to the `advance` output every frame.\n     */\n    smoothMs?: number;\n    /** Rebase discontinuities larger than this pop instead of decaying out —\n     *  see {@link SmoothingOptions.snap}. 0 disables (default). */\n    snap?: number;\n}\n\ninterface SimState {\n    /** Live schema instance — held so `computeReckon` can run `advance` from\n     *  a slot id alone (the read path no longer receives the instance). Cleared\n     *  on detach, so its lifetime tracks the entity's tracked window. */\n    instance: any;\n    /** Field indices, parallel to the SoA buffers below (position k ↔ field). */\n    fieldIds: number[];\n    /** fieldId → position in the SoA buffers (or -1). Sized to max fieldId + 1\n     *  so `computeReckon` maps a slot's SLOT_FIELD to its position with one\n     *  array index instead of `fieldIds.indexOf(...)`. */\n    posOf: Int8Array;\n    forwardMs: () => number;\n    /** Absolute server-time (ms) the prediction window ENDS at — `serverNow()`\n     *  for the per-frame render reckon, an arbitrary instant for `valueAt`. */\n    elapsedMs: () => number;\n    /** `endElapsed` is the absolute time of the window end (the last substep\n     *  lands on it) so time-sampled step fns read the right instant; the window\n     *  spans `[endElapsed − forwardMs, endElapsed]`. */\n    advance: (instance: any, forwardMs: number, out: Float64Array, endElapsed: number) => void;\n    smoothMs: number;\n    /** Value-space discontinuity threshold — rebase jumps beyond it skip the\n     *  offset capture (pop, don't glide). 0 = off. */\n    snap: number;\n    /** Displayed values (= `out + offset`), indexed by field position. */\n    smoothed: Float64Array;\n    /** Reused per-frame `advance` output, indexed by field position. */\n    out: Float64Array;\n    /** Reused scratch for `valueAt` — a one-off reckon to an arbitrary instant\n     *  that must NOT clobber the per-frame render reckon in `out`/`smoothed`. */\n    valueOut: Float64Array;\n    /** Pop-hiding correction offset, decaying toward 0 (see applySimulation). */\n    offset: Float64Array;\n    /** Previous frame's `out` — lets a clean frame measure per-field motion so a\n     *  rebase can subtract the expected motion from its offset capture. */\n    outPrev: Float64Array;\n    /** Per-ms field velocity from the last CLEAN (non-rebase) frame — the\n     *  expected-motion term a rebase multiplies by the frame dt so one frame of\n     *  genuine motion isn't mis-captured as a discontinuity. */\n    frameVel: Float64Array;\n    /** Snapshot identity (`clock.lastServerTime()`) at the last apply — a\n     *  change marks a REBASE: the forward sim now starts from new data, so any\n     *  discontinuity is captured into `offset`. NaN = no clock → EMA fallback. */\n    lastBaseT: number;\n    lastApplyTime: number;   // -Infinity until first `value()` call\n}\n\n/** Smoothing-mode defaults applied when callers omit specific fields. */\nconst SMOOTHING_DEFAULTS: Required<SmoothingOptions> = {\n    mode: \"lerp\",\n    delay: 100,\n    smoothMs: 50,\n    maxExtrapolate: 200,\n    tickInterval: 0,\n    snap: 0,\n    angle: false,\n};\n\n/** Reckon-mode defaults. `step` stays undefined — must be supplied at construct time\n *  or per-attach; otherwise `attach`/`attachAll` throws. */\ninterface ReckonDefaults {\n    step: ((state: any, dt: number, elapsedMs: number) => void) | undefined;\n    smoothMs: number;\n    substep: number;\n    snap: number;\n}\nconst RECKON_DEFAULTS: ReckonDefaults = {\n    step: undefined,\n    smoothMs: 50,\n    substep: 16,\n    snap: 0,\n};\n\n\n// Loose typing: accept anything `Callbacks.get` accepts (Room, Decoder, etc.)\ntype CallbacksInput = Parameters<typeof Callbacks.get>[0];\n\n/**\n * Extract the root state type from a Room / Decoder / Callbacks input.\n * Used by `Predict.get(room)` so the returned `Predict<TState>` can offer\n * a root-level `attachAll(key, config)` overload narrowed to `TState`'s\n * collection-valued keys.\n */\ntype StateOf<R> = R extends { state: infer S } ? S : any;\n\n// -----------------------------------------------------------------------------\n// Attach config — declarative shape consumed by Predict.attach / attachAll.\n// -----------------------------------------------------------------------------\n\n/** Per-field smoothing: either a mode shorthand or full {@link SmoothingOptions}. */\nexport type FieldSmoothing = \"lerp\" | \"extrapolate\" | \"damped\" | SmoothingOptions;\n\n/**\n * Smoothing config — flat per-field map: `{ x: \"lerp\", y: { mode: \"damped\" } }`.\n * Field names are checked against `T`'s numeric keys, so a typo or non-numeric\n * field is a compile error.\n */\nexport type SmoothingConfig<T = any> = Partial<Record<NumericKeys<T>, FieldSmoothing>>;\n\n/**\n * Reckon attach config — apply dead-reckoning to `fields` using a step\n * function. `step` can be omitted if the parent Predict was constructed\n * with `mode: \"reckon\"` + a `step` default (it falls back); when missing on\n * both, `attach` / `attachAll` throws.\n */\nexport interface ReckonAttachConfig<T = any> {\n    /**\n     * Per-attach mode. Falls back to the Predict's `defaultMode` when omitted.\n     * The client's display mode is declared HERE, independently of the server's\n     * rewind `mode` — keep them aligned (\"what you see is what you hit\"): render\n     * targets the server rewinds `mode:\"reckon\"` with `mode:\"reckon\"` here, and\n     * those it rewinds `mode:\"snapshot\"` with an interpolating mode (`lerp` /\n     * `damped`). Common patterns:\n     *   - `mode: \"lerp\"` → smoothing-only attach (no sim state allocated).\n     *   - `mode: \"reckon\"` → reckon attach (requires `step` here or in Predict).\n     *   - omitted → the Predict's `defaultMode`.\n     * Per-attach overrides go through the same profile system as the defaults\n     * (the slot's `SLOT_PROFILE` points at a frozen profile encoding the\n     * mode + opts), so dispatch is uniform and the panel sub-card can tune\n     * the override at runtime.\n     */\n    mode?: PredictMode;\n    /** Numeric fields of `T` to predict. */\n    fields: readonly NumericKeys<T>[];\n    /** Step function. Falls back to the Predict's constructor-time default. */\n    step?: (state: T, dt: number, elapsedMs: number) => void;\n    /** Substep length in ms. Defaults to the Predict's setting (or 16). */\n    substep?: number;\n    /** Value-space discontinuity threshold, applied to every field here — a\n     *  per-sample jump beyond it snaps instead of smoothing (teleports:\n     *  respawn, blink, warp). See {@link SmoothingOptions.snap}. Default 0 (off). */\n    snap?: number;\n    /** Output-smoothing time constant in ms, applied to every field here —\n     *  see {@link SmoothingOptions.smoothMs}. On a reckon group it is the\n     *  predict-then-smooth window (default the Predict's setting, or 50); on\n     *  a `lerp` group the display-only output spring (default 0 = off). */\n    smoothMs?: number;\n    /** Treat every field here as a radian ANGLE — see {@link SmoothingOptions.angle}.\n     *  Use only on smoothing-mode attaches (lerp/damped/extrapolate), not reckon. */\n    angle?: boolean;\n    /**\n     * Override how the per-frame reckon scratch is built. Leave unset for the\n     * default fast path (a pooled schema instance refilled via `$values` by\n     * index — monomorphic, zero-alloc). Provide one only for non-schema\n     * instances or to copy a custom field subset; a custom snapshot uses the\n     * generic (slower, dynamic-key) advance path.\n     */\n    snapshot?: (state: T) => T;\n}\n\nexport type AttachConfig<T = any> = SmoothingConfig<T> | ReckonAttachConfig<T>;\n\n/** One MODE_BOUND overlay slot's backing: the controller pose read\n *  (`ctrl.value(key)`) plus the stashed passive slot it displaced (-1 = none),\n *  restored when the controller disposes. */\ninterface BoundSlotEntry {\n    ctrl: { value(field: string): number };\n    key: string;\n    stash: number;\n}\n\n/** The controller face the bound overlay consumes — implemented by both\n *  {@link Reconciler} and {@link SimReconciler}. `boundRegistrations` lists the\n *  decoded instances the controller predicts (one entry per bound world part;\n *  `fields`/`poseKeys` parallel — the overlay maps `predict.value(source,\n *  fields[i])` to `ctrl.value(poseKeys[i])`). */\ninterface BoundController {\n    value(field: string): number;\n    onDisposed(hook: () => void): void;\n    readonly boundRegistrations: ReadonlyArray<{\n        source: object; fields: readonly string[]; poseKeys: readonly string[];\n    }>;\n}\n\nfunction isReckonAttachConfig<T>(cfg: AttachConfig<T>): cfg is ReckonAttachConfig<T> {\n    if (cfg === null || typeof cfg !== \"object\") return false;\n    return Array.isArray((cfg as Partial<ReckonAttachConfig<T>>).fields);\n}\n\n/**\n * Resolved attach config for one group. Built ONCE per `attachAll` (profiles\n * allocated up front, labeled by the collection key) and reused for every\n * child, so a 1000-item collection allocates one profile, not 1000 — and the\n * profile is the group's own, never the mutable default #0 that the panel\n * mutates. Each child just references the pre-resolved profile ids.\n */\ninterface GroupPlan {\n    label: string;\n    /** True when the group runs dead-reckoning (allocates a SimState per child). */\n    isReckon: boolean;\n    reckonFields?: readonly string[];\n    reckonStep?: (state: any, dt: number, elapsedMs: number) => void;\n    reckonSmoothMs?: number;\n    reckonSubstep?: number;\n    reckonSnap?: number;\n    reckonSnapshot?: (state: any) => any;\n    /** Field → profile id (+ angle flag). All children of the group share these. */\n    fieldProfiles: Array<{ field: string; profileIdx: number; angle?: boolean }>;\n}\n\n/**\n * One attach()/attachAll() group. The base plan (today's one-plan-per-group)\n * is built eagerly; children whose TYPE resolves identically reuse it, so\n * homogeneous collections behave exactly as before. A child type whose field\n * set differs (missing some configured fields) gets its own lazily-built\n * sub-plan/profile labeled `label:TypeName` — mixed-type collections resolve\n * per constructor, and each type surfaces as its own debug-panel card.\n */\ninterface AttachGroup {\n    label: string;\n    config: AttachConfig<any>;\n    basePlan: GroupPlan;\n    /** Resolved plan per child constructor (lazily filled). */\n    planByCtor: Map<Function, GroupPlan>;\n}\n\n// -----------------------------------------------------------------------------\n// Predict — the single per-room prediction class.\n// -----------------------------------------------------------------------------\n\n/**\n * Options passed to {@link Predict.get}. Intersects {@link PredictOptions}\n * with extra construction-time fields. The common case — picking the\n * default mode — is a flat one-liner:\n *\n *     Predict.get(room, { mode: \"lerp\",   delay: 80 });\n *     Predict.get(room, { mode: \"reckon\", step: stepEnemy, smoothMs: 40 });\n *\n * Type alias (not interface) because PredictOptions is a discriminated union\n * and interface-extends-union isn't permitted in TS.\n */\nexport type PredictGetOptions<T = any> = PredictOptions<T> & {\n    /**\n     * Clock used as the default for the reckon attaches' `forwardMs` /\n     * `elapsedMs`. Falls back to `room.clock` (allocated by the SDK when the\n     * server called `defineInput()`). When neither is available, reckon\n     * attaches must pass explicit `forwardMs` / `elapsedMs`.\n     */\n    clock?: RoomClockLike;\n    /**\n     * Draw dead-reckoned (`mode:\"reckon\"`) entities on the clock's SLEW-LIMITED\n     * **render** timeline ({@link RoomClockLike.renderNow}) instead of the raw\n     * {@link RoomClockLike.serverNow}. Both the reckon horizon (snapshot age)\n     * and the time-sampled absolute clock (`elapsedMs`, for closed-form motion\n     * like sinusoids) then read `renderNow()`, so the per-patch offset-EMA\n     * wobble stops showing as `v·Δclock` stutter on remote entities.\n     *\n     * **ON by default** (when the clock implements `renderNow()`; falls back to\n     * `serverNow()` otherwise). It affects ONLY what you SEE: the lag-comp hit\n     * path (`valueAt(when)` with an explicit instant) bypasses it and keeps\n     * stamping on accurate `serverNow()`, so \"what you see is what you hit\"\n     * holds in steady state — the render timeline just smooths the draw.\n     *\n     * Pass `false` to force the raw `serverNow()` horizon. The one reason to:\n     * strict draw==hit WYSIWYG on a fast twitch game, where you want the drawn\n     * position to equal the hit position even DURING an offset correction (the\n     * slew briefly lags the draw behind the `serverNow()`-stamped hit; racing /\n     * platformer don't care, a competitive shooter might).\n     */\n    renderPresent?: boolean;\n    /**\n     * Human-friendly identifier shown in `@colyseus/sdk/debug` panels and\n     * useful for logging. Falls back to `predict#N` (incremented per process).\n     */\n    name?: string;\n};\n\n// -----------------------------------------------------------------------------\n// Introspection registry — `@colyseus/sdk/debug` installs a tiny\n// `globalThis.__colyseusDebug.publish()` receiver. Predict publishes a stable,\n// engine-level *core* handle to it at construction so the debug layer can build\n// its panel from OUTSIDE the engine. The handle exposes only portable engine\n// state (profiles, defaults, attached count) plus an `onTrack` subscription —\n// NO panel-shaped data (e.g. \"which fields use a profile\") lives here; the\n// debug bridge in `@colyseus/sdk/debug` derives that itself. When the registry\n// is absent (prod build, debug not imported), publishing is a no-op and Predict\n// carries no debug state at all.\n// -----------------------------------------------------------------------------\n\n/**\n * Stable engine-introspection contract Predict publishes. Deliberately scoped\n * to portable engine state so a future C# / C port can expose the same surface;\n * the debug *panel* shape (per-profile field labels etc.) is assembled in\n * `@colyseus/sdk/debug` from this core, not here.\n */\n/** Per-reconciler drift snapshot published to the debug panel. */\nexport interface ReconcilerStat {\n    /** Display label (index-based — most games drive a single reconciler). */\n    readonly label: string;\n    /** The actionable read: matched / jitter / diverging (see classifyDrift). */\n    readonly status: DriftStatus;\n    /** `ema / tolerance` when a `warnOnDivergence` tolerance is set — how far past\n     *  the dev's own threshold the persistent drift sits. `undefined` otherwise. */\n    readonly severity?: number;\n    /** Rolling drift EMA — the persistent/divergence component. */\n    readonly ema: number;\n    /** Rolling drift peak — recent jitter spikes. */\n    readonly peak: number;\n    /** Most recent reconcile's max |correction| (world/pose units). */\n    readonly lastCorrectionMag: number;\n    /** Reconcile counter — advances once per reconcile. */\n    readonly reconcileSeq: number;\n}\n\nexport interface PredictCore {\n    readonly name: string;\n    readonly mode: () => PredictMode;\n    readonly smoothingDefaults: () => {\n        mode: PredictMode;\n        delay: number;\n        smoothMs: number;\n        maxExtrapolate: number;\n        tickInterval: number;\n    };\n    readonly reckonDefaults: () => Readonly<ReckonDefaults>;\n    /** Number of instances currently attached. */\n    readonly attachedCount: () => number;\n    /** Drift telemetry for each driven reconciler/sim — the panel renders a\n     *  per-reconciler divergence-vs-jitter readout. Empty when this Predict\n     *  drives only passive smoothing. */\n    readonly reconcilers: () => ReconcilerStat[];\n    /** Mutate defaults. Mode flips across families freely. */\n    readonly setDefaults: (opts: PredictOptions) => void;\n    /**\n     * Snapshot every profile currently registered with this Predict. The debug\n     * panel renders one sub-card per non-default profile so per-field overrides\n     * (e.g. `{ vx: { mode: \"extrapolate\" } }`) become tunable without code edits.\n     */\n    readonly profiles: () => ProfileCore[];\n    /**\n     * Mutate a specific profile in place. Slots whose `SLOT_PROFILE` points\n     * at `id` pick up the change next frame. Setting `mode` swaps the\n     * `profileComputers[id]` function pointer in lock-step. Mode accepts any\n     * of the five `PredictMode` values.\n     */\n    readonly setProfile: (id: number, opts: { mode?: PredictMode } & SmoothingOptions) => void;\n    /**\n     * Subscribe to track events: fires `(profileIdx, field)` each time a field\n     * is tracked under a profile. The debug bridge uses this to build the\n     * profile → field-names mapping it displays, so that panel-only mapping\n     * never has to live in the engine. Returns an unsubscribe fn.\n     */\n    readonly onTrack: (cb: (profileIdx: number, field: string) => void) => () => void;\n    /** Unsubscribe when the Predict is disposed. */\n    readonly onDispose: (cb: () => void) => () => void;\n}\n\n/** Read-only snapshot of one profile (engine state; no panel-only fields). */\nexport interface ProfileCore {\n    readonly id: number;\n    readonly isDefault: boolean;\n    /** Attach-group label this profile belongs to (the collection key passed to\n     *  `attachAll`, or \"(attach)\" for standalone attaches). The panel renders\n     *  one card per (label, mode) so each group is tuned independently. */\n    readonly label: string | undefined;\n    readonly mode: PredictMode;\n    readonly delay: number;\n    readonly smoothMs: number;\n    readonly maxExtrapolate: number;\n    readonly tickInterval: number;\n    readonly snap: number;\n}\n\nlet __predictAutoId = 0;\n\nlet __warnedNoInputClock = false;\n/** Warn once when a {@link Predict} inherits the inert {@link NULL_CLOCK} — the\n *  server room never called `defineInput()`, so server-time interpolation and\n *  lag compensation silently fall back to local time. */\nfunction warnNoInputClock(): void {\n    if (__warnedNoInputClock) { return; }\n    __warnedNoInputClock = true;\n    console.warn(\n        \"@colyseus/sdk Predict: room.clock isn't server-synced because the server \" +\n        \"room didn't call defineInput(). Server-time interpolation and lag \" +\n        \"compensation fall back to local time. Add defineInput() on the server \" +\n        \"room to enable them — or ignore this if you only need local smoothing.\",\n    );\n}\n\nexport class Predict<TState = any> {\n    /**\n     * Factory mirroring `Callbacks.get(room)`. Each call returns a fresh\n     * Predict — instantiate multiple for side-by-side comparison overlays.\n     * `TState` is inferred from `room.state` so `attachAll(key, config)` can\n     * narrow `key` to the root state's collection-valued properties.\n     */\n    static get<R extends CallbacksInput>(room: R, opts: PredictGetOptions = {}): Predict<StateOf<R>> {\n        return new Predict<StateOf<R>>(room, opts);\n    }\n\n    // Loose-typed callbacks wrapper. Forwards to `Callbacks.get(room)` whose\n    // own overloads accept either `(key, cb)` for root state or\n    // `(parent, key, cb)` for nested collections.\n    private callbacks: {\n        onAdd: (...args: any[]) => () => void;\n        onRemove: (...args: any[]) => () => void;\n        listen: (instance: any, field: string, cb: (v: any) => void, immediate?: boolean) => () => void;\n    };\n    /** The construction input, kept for `sessionId` (a Room has one, a raw\n     *  Decoder doesn't) — `confirmOn.mine` resolves against it. */\n    private sessionSource: { sessionId?: string };\n    // SoA storage for smoothing slots. `slotBuf` holds all slots packed at\n    // `slotIdx * SLOT_STRIDE`. `slotByRef` maps refId → (field NAME → slot idx).\n    // Keying the inner map by field name (not index) means the hot `value()`\n    // read resolves a slot with two plain Map.gets and NEVER touches schema\n    // metadata — no per-frame name→index resolution (that was a megamorphic\n    // keyed load). `slotDetach[idx]` holds the listen()-returned unsubscribe\n    // (parallel array, not packed in `slotBuf` since closures aren't numbers).\n    // Recycled indices live in `freeSlots`; the buffer doubles when `slotCount`\n    // outgrows capacity.\n    //\n    // Keyed on the schema's integer refId, not JS object identity — the same\n    // key the wire protocol and a C / C# port would use. Entries are removed on\n    // detach (which fires from onRemove before the decoder can recycle a\n    // refId), so a reused refId never collides with a stale entry.\n    private slotBuf: Float64Array = new Float64Array(64 * SLOT_STRIDE);\n    private slotCount: number = 0;\n    private slotDetach: Array<(() => void) | undefined> = [];\n    // Per-slot angle flag (parallel to slotDetach). Marks slots whose samples are\n    // stored unwrapped so the interpolators handle the ±π seam — see `angle` option.\n    private slotAngle: boolean[] = [];\n    private freeSlots: number[] = [];\n    private slotByRef = new Map<number, Map<string, number>>();\n    private simByRef = new Map<number, SimState>();\n    /** MODE_BOUND side table: overlay slot → its {@link BoundSlotEntry}. An\n     *  entry here marks the slot as a controller overlay; teardown paths branch\n     *  on membership (see untrackSlot / detachByRef / registerBound). */\n    private boundBySlot = new Map<number, BoundSlotEntry>();\n    /** The one shared MODE_BOUND profile (lazily allocated). Bound slots carry\n     *  no tunable params and the panel's per-controller cards come from\n     *  {@link snapshotReconcilers}, so per-controller profiles would only\n     *  accumulate (profiles are never freed — a respawn loop would leak them). */\n    private boundProfileIdx = -1;\n    private renderTime = 0;\n    private defaultMode: PredictMode;\n    private reckonDefaults: ReckonDefaults;\n    private clock: RoomClockLike | undefined;\n    /** Draw reckon entities on the clock's render timeline — see the\n     *  `renderPresent` option on {@link PredictGetOptions}. */\n    private useRenderClock = false;\n\n    // --- Room-wide fixed-step accumulator (drives reconciler input pacing) ------\n    // The server's tick rate is one value per room, so one accumulator here is the\n    // single source of truth: `tick(now)` converts elapsed render time into the\n    // whole number of fixed input ticks due (returned to the caller's send loop).\n    // `stepMs` is adopted from the first reconciler spawned (its input handle\n    // advertises the server rate); until then no fixed step is known and `tick`\n    // returns 0. (Render interpolation is NOT derived here — each reconciler eases\n    // it off its own last-step time, so it holds correctly when that entity's input\n    // pauses; see RollbackController.renderAlpha.)\n    private fixedStepMs: number | undefined;\n    private stepAcc = 0;\n    private lastFrameNow = -1;\n    /** Spiral-of-death guard: cap fixed steps emitted per frame (after a hitch,\n     *  drop the backlog rather than chase it). */\n    private static readonly MAX_STEPS_PER_FRAME = 5;\n\n    // Profile table. Profile 0 is the defaults (mutable via setDefaults).\n    // Subsequent indices are frozen, value-deduped via `profileKeys`.\n    private profileBuf: Float64Array = new Float64Array(8 * PROFILE_STRIDE);\n    private profileCount: number = 0;\n    private profileKeys = new Map<string, number>();\n    /**\n     * Human label per profile, indexed by profile id. Set from the attach\n     * group's key (collection name) so the debug panel can render one card per\n     * group (\"enemies\", \"players\") instead of an anonymous, cross-wired\n     * per-Predict mode toggle. The label is also part of the dedup key, so two\n     * different groups never share a profile even if their params match —\n     * tuning one group's card can't bleed into another's.\n     */\n    private profileLabels: Array<string | undefined> = [];\n    /**\n     * Per-profile read function — resolved once at profile allocation (or\n     * when `setDefaults`/`setProfile` flips a profile's mode) and stored\n     * here. Slot reads dispatch via `profileComputers[profileIdx](slotIdx)`\n     * instead of an `if (mode === ...)` chain at each `value()` call.\n     *\n     * Every mode reads purely from the slot: the slot's SLOT_REF / SLOT_FIELD\n     * let `reckon` find its SimState and `raw` read SLOT_V1, so no instance or\n     * field-name is threaded through. This pure `(slotId) -> number` shape is\n     * exactly a C function-pointer table / C# delegate array.\n     */\n    private profileComputers: Array<(slotIdx: number) => number> = [];\n    /**\n     * Track-event listeners. The debug bridge subscribes via the published\n     * core's `onTrack`; on the cold attach path each `trackWithProfile` notifies\n     * them with `(profileIdx, field)` so the bridge can build its profile→fields\n     * view WITHOUT the engine holding any panel-shaped state. Empty in prod (no\n     * debug registry ⇒ never subscribed), so the per-track notify is a length\n     * check on a cold path.\n     */\n    private trackListeners: Array<(profileIdx: number, field: string) => void> = [];\n\n    /** Public name (shown in the debug panel and useful for logs). */\n    readonly name: string;\n    private disposeListeners: Array<() => void> = [];\n    /**\n     * Child primitives spawned by {@link defineEvent} / {@link spawns} /\n     * {@link reconciler} / {@link sim} that this Predict drives from its own\n     * {@link tick}. The Predict is the single\n     * per-frame driver for the whole prediction stack — one `predict.tick(now)`\n     * advances smoothing AND every controller AND prunes every event store, so\n     * callers can't forget to tick/prune a child (a forgotten drive is a silent\n     * visual bug). Children expose their own `tick`/`prune` for standalone use;\n     * a `dead` child is dropped on the next tick.\n     */\n    private driven: Array<{ tick?(now: number): void; prune?(): void; dead?: boolean }> = [];\n\n    private constructor(room: CallbacksInput, opts: PredictGetOptions) {\n        this.callbacks = Callbacks.get(room as any) as any;\n        this.sessionSource = room as { sessionId?: string };\n        const { clock, ...rest } = opts as PredictGetOptions & Record<string, any>;\n        // Determine the predictor's *default* prediction style. Per-attach\n        // overrides can still switch to a different mode.\n        this.defaultMode = (rest.mode ?? \"lerp\") as PredictMode;\n        // Always materialize a defaults profile at index 0 — even on a\n        // reckon-default or raw-default Predict, callers may flip the mode\n        // back to a smoothing mode later and the profile needs to exist.\n        const isSmoothingDefault =\n            this.defaultMode !== \"reckon\" && this.defaultMode !== \"raw\";\n        const initial: Required<SmoothingOptions> = isSmoothingDefault\n            ? (() => {\n                const s = rest as SmoothingOptions;\n                return {\n                    mode: (s.mode ?? SMOOTHING_DEFAULTS.mode) as SmoothingMode,\n                    delay: s.delay ?? SMOOTHING_DEFAULTS.delay,\n                    smoothMs: s.smoothMs ?? SMOOTHING_DEFAULTS.smoothMs,\n                    maxExtrapolate: s.maxExtrapolate ?? SMOOTHING_DEFAULTS.maxExtrapolate,\n                    tickInterval: s.tickInterval ?? SMOOTHING_DEFAULTS.tickInterval,\n                    snap: s.snap ?? SMOOTHING_DEFAULTS.snap,\n                    angle: s.angle ?? SMOOTHING_DEFAULTS.angle,\n                };\n            })()\n            : { ...SMOOTHING_DEFAULTS };\n        // Allocate profile 0 (defaults). Its MODE is the Predict's actual\n        // `defaultMode` (reckon/raw included) — NOT lerp. Seeding it as lerp was\n        // the quirk that let a lerp group silently collapse onto the default\n        // profile. The smoothing PARAMS are still seeded from defaults so a\n        // later flip to a smoothing mode (via setDefaults) has sane values.\n        // `dedup: false` because we mutate this profile in place via setDefaults;\n        // deduping would conflate it with a frozen profile of the same values.\n        // Lerp's output spring defaults OFF — only an explicit `smoothMs` arms\n        // it (initial.smoothMs's 50 fallback serves damped/extrapolate).\n        const lerpSmoothMs = isSmoothingDefault ? ((rest as SmoothingOptions).smoothMs ?? 0) : 0;\n        const dIdx = this.allocProfile(\n            this.defaultMode,\n            initial.delay,\n            initial.smoothMs,\n            lerpSmoothMs,\n            initial.maxExtrapolate,\n            initial.tickInterval,\n            initial.snap,\n            false,\n        );\n        // The first allocProfile is guaranteed to land at index 0 — invariant\n        // relied on by SLOT_PROFILE writes that fall back to \"use defaults\".\n        if (dIdx !== DEFAULTS_PROFILE) {\n            throw new Error(\"Predict: defaults profile must be at index 0\");\n        }\n        if (this.defaultMode === \"reckon\") {\n            const r = rest as ReckonOptions;\n            this.reckonDefaults = {\n                step: r.step,\n                smoothMs: r.smoothMs ?? RECKON_DEFAULTS.smoothMs,\n                substep: r.substep ?? RECKON_DEFAULTS.substep,\n                snap: r.snap ?? RECKON_DEFAULTS.snap,\n            };\n        } else {\n            this.reckonDefaults = { ...RECKON_DEFAULTS };\n        }\n        // Prefer caller-supplied clock; otherwise inherit `room.clock` (set\n        // by the SDK when the server called `defineInput()`). Stays undefined\n        // for rooms without a clock — `trackStepped` then requires explicit\n        // forwardMs/elapsedMs.\n        this.clock = clock ?? (room as { clock?: RoomClockLike | null }).clock ?? undefined;\n        // Default ON: reckon draws on renderNow() when the clock offers it\n        // (presentFn falls back to serverNow otherwise). `false` forces raw.\n        this.useRenderClock = (rest as { renderPresent?: boolean }).renderPresent !== false;\n        // Prediction wants a server-synced clock (server-time interpolation,\n        // lag-comp render stamps). It only exists once the room called\n        // defineInput(); inheriting the inert stub means that didn't happen.\n        if (this.clock === NULL_CLOCK) { warnNoInputClock(); }\n\n        this.name = (rest as { name?: string }).name ?? `predict#${++__predictAutoId}`;\n\n        // Publish a core handle to the debug channel. `publishDebug` renders it\n        // now if `@colyseus/sdk/debug` is loaded, else BUFFERS it for replay when\n        // the overlay's (dev-only, dynamic) import lands — so a Predict created\n        // before that import still shows up. Prod pays nothing: no overlay ⇒ a\n        // bounded WeakRef buffer nothing ever reads (and `trackWithProfile`'s\n        // notify stays a length check, `attachedCount` an already-maintained map).\n        publishDebug(\"predict\", this.makeCoreHandle());\n    }\n\n    /**\n     * Predictor's current default mode. Reflects mutations via {@link setDefaults}\n     * (and therefore the SDK debug panel), so consumers that need to react to\n     * mode changes can read this each frame.\n     */\n    get mode(): PredictMode {\n        return this.defaultMode;\n    }\n\n    /**\n     * The \"present\" instant provider for reckon horizons + time-sampling (the\n     * `forwardMs` snapshot-age and the `elapsedMs` absolute clock). Unless\n     * {@link PredictGetOptions.renderPresent} was set `false`, and when the clock\n     * implements {@link RoomClockLike.renderNow}, it's the slew-smoothed render\n     * timeline; otherwise the raw {@link RoomClockLike.serverNow}. `undefined`\n     * with no clock — reckon attaches then require explicit\n     * forwardMs/elapsedMs. Resolved once on the cold attach path.\n     *\n     * The lag-comp read (`valueAt` with an explicit `when`) never goes through\n     * here, so hit stamps stay on `serverNow()` even with render-present on.\n     */\n    private presentFn(): (() => number) | undefined {\n        const clock = this.clock;\n        if (!clock) { return undefined; }\n        return this.useRenderClock && clock.renderNow\n            ? clock.renderNow.bind(clock)\n            : clock.serverNow.bind(clock);\n    }\n\n    // --- Core introspection handle ---------------------------------------------\n\n    private makeCoreHandle(): PredictCore {\n        return {\n            name: this.name,\n            mode: () => this.defaultMode,\n            smoothingDefaults: () => this.readSmoothingDefaults(),\n            reckonDefaults: () => ({ ...this.reckonDefaults }),\n            reconcilers: () => this.snapshotReconcilers(),\n            // Every attached instance owns ≥1 smoothing slot, so the slot map's key\n            // count IS the attached-instance count — no separate bookkeeping needed.\n            attachedCount: () => this.slotByRef.size,\n            setDefaults: (opts) => this.setDefaults(opts),\n            profiles: () => this.snapshotProfiles(),\n            setProfile: (id, opts) => this.setProfile(id, opts),\n            onTrack: (cb) => {\n                this.trackListeners.push(cb);\n                return () => {\n                    const i = this.trackListeners.indexOf(cb);\n                    if (i >= 0) this.trackListeners.splice(i, 1);\n                };\n            },\n            onDispose: (cb) => {\n                this.disposeListeners.push(cb);\n                return () => {\n                    const i = this.disposeListeners.indexOf(cb);\n                    if (i >= 0) this.disposeListeners.splice(i, 1);\n                };\n            },\n        };\n    }\n\n    /** Drift telemetry for each driven Reconciler/SimReconciler (duck-typed by\n     *  the presence of `drift`), for the debug panel. Event/spawn stores in the\n     *  same `driven` list have no `drift` and are skipped. */\n    private snapshotReconcilers(): ReconcilerStat[] {\n        const out: ReconcilerStat[] = [];\n        let i = 0;\n        for (const d of this.driven) {\n            const r = d as Partial<{ drift: Drift; lastCorrectionMag: number; reconcileSeq: number; warnTolerance?: number }>;\n            if (!r.drift) { continue; }\n            const tol = r.warnTolerance;\n            out.push({\n                label: `reconciler #${i++}`,\n                status: classifyDrift(r.drift, tol),\n                severity: tol !== undefined && tol > 0 ? r.drift.ema / tol : undefined,\n                ema: r.drift.ema,\n                peak: r.drift.peak,\n                lastCorrectionMag: r.lastCorrectionMag ?? 0,\n                reconcileSeq: r.reconcileSeq ?? 0,\n            });\n        }\n        return out;\n    }\n\n    private readSmoothingDefaults(): { mode: PredictMode; delay: number; smoothMs: number; lerpSmoothMs: number; maxExtrapolate: number; tickInterval: number; snap: number } {\n        const p = this.profileBuf;\n        const b = DEFAULTS_PROFILE * PROFILE_STRIDE;\n        const m = p[b + P_MODE] | 0;\n        const mode: PredictMode =\n            m === MODE_LERP ? \"lerp\" :\n            m === MODE_EXTRAPOLATE ? \"extrapolate\" :\n            m === MODE_DAMPED ? \"damped\" :\n            m === MODE_RECKON ? \"reckon\" : \"raw\";\n        return {\n            mode,\n            delay: p[b + P_DELAY],\n            smoothMs: p[b + P_SMOOTH_MS],\n            lerpSmoothMs: p[b + P_LERP_SMOOTH_MS],\n            maxExtrapolate: p[b + P_MAX_EXTRAPOLATE],\n            tickInterval: p[b + P_TICK_INTERVAL],\n            snap: p[b + P_SNAP],\n        };\n    }\n\n    /**\n     * Look up or allocate a profile matching the given values. With\n     * `dedup=true`, an identical existing profile is reused — so an attachAll\n     * over 1000 entities with the same per-field config still allocates one\n     * profile, not 1000.\n     */\n    private allocProfile(\n        mode: PredictMode | number,\n        delay: number,\n        smoothMs: number,\n        lerpSmoothMs: number,\n        maxExtrapolate: number,\n        tickInterval: number,\n        snap: number,\n        dedup: boolean,\n        label?: string,\n    ): number {\n        // A numeric mode is an internal code (MODE_BOUND) with no PredictMode name.\n        const modeCode = typeof mode === \"number\" ? mode : MODE_CODES[mode];\n        let key = \"\";\n        if (dedup) {\n            // Label is part of the key: two groups never share a profile, so\n            // their panel cards stay independent.\n            key = `${label ?? \"\"}|${modeCode}|${delay}|${smoothMs}|${lerpSmoothMs}|${maxExtrapolate}|${tickInterval}|${snap}`;\n            const existing = this.profileKeys.get(key);\n            if (existing !== undefined) return existing;\n        }\n        const idx = this.profileCount++;\n        const needed = (idx + 1) * PROFILE_STRIDE;\n        if (needed > this.profileBuf.length) {\n            const grown = new Float64Array(this.profileBuf.length * 2);\n            grown.set(this.profileBuf);\n            this.profileBuf = grown;\n        }\n        const base = idx * PROFILE_STRIDE;\n        this.profileBuf[base + P_MODE] = modeCode;\n        this.profileBuf[base + P_DELAY] = delay;\n        this.profileBuf[base + P_SMOOTH_MS] = smoothMs;\n        this.profileBuf[base + P_LERP_SMOOTH_MS] = lerpSmoothMs;\n        this.profileBuf[base + P_MAX_EXTRAPOLATE] = maxExtrapolate;\n        this.profileBuf[base + P_TICK_INTERVAL] = tickInterval;\n        this.profileBuf[base + P_SNAP] = snap;\n        this.profileLabels[idx] = label;\n        // Resolve the compute function once, here at registration — slot\n        // reads then invoke it directly instead of branching on mode.\n        this.profileComputers[idx] = this.computerForMode(modeCode);\n        if (dedup) this.profileKeys.set(key, idx);\n        return idx;\n    }\n\n    private computerForMode(modeCode: number): (slotIdx: number) => number {\n        if (modeCode === MODE_LERP) return this.computeLerp;\n        if (modeCode === MODE_EXTRAPOLATE) return this.computeExtrapolate;\n        if (modeCode === MODE_DAMPED) return this.computeDamped;\n        if (modeCode === MODE_RECKON) return this.computeReckon;\n        if (modeCode === MODE_BOUND) return this.computeBound;\n        return this.computeRaw; // MODE_RAW\n    }\n\n    /**\n     * Resolve a per-track opts shape to a profile index.\n     *   - empty opts (no own keys) → defaults profile (0). The slot follows\n     *     setDefaults mutations.\n     *   - non-empty opts that, after merging with current defaults, match\n     *     defaults exactly → defaults profile (0). Equivalent intent, same\n     *     internal state.\n     *   - non-empty opts that differ from defaults → frozen profile, value-\n     *     deduped via `profileKeys`. The slot does NOT follow later\n     *     setDefaults mutations (the override is \"frozen\").\n     */\n    private profileFromOpts(opts: { mode?: PredictMode } & SmoothingOptions): number {\n        if (\n            opts.mode === undefined &&\n            opts.delay === undefined &&\n            opts.smoothMs === undefined &&\n            opts.maxExtrapolate === undefined &&\n            opts.tickInterval === undefined &&\n            opts.snap === undefined\n        ) {\n            return DEFAULTS_PROFILE;\n        }\n        const d = this.readSmoothingDefaults();\n        const mode = (opts.mode ?? d.mode) as PredictMode;\n        const delay = opts.delay ?? d.delay;\n        const smoothMs = opts.smoothMs ?? d.smoothMs;\n        const lerpSmoothMs = opts.smoothMs ?? d.lerpSmoothMs;\n        const maxExtrapolate = opts.maxExtrapolate ?? d.maxExtrapolate;\n        const tickInterval = opts.tickInterval ?? d.tickInterval;\n        const snap = opts.snap ?? d.snap;\n        // Collapse to defaults profile when the merged values match it. This\n        // unifies homogeneous per-attach configs (e.g. `{ mode: \"lerp\" }` on\n        // a Predict already at lerp) with the implicit no-override case —\n        // ensuring there's exactly one internal state for any given intent.\n        if (\n            mode === d.mode && delay === d.delay && smoothMs === d.smoothMs &&\n            lerpSmoothMs === d.lerpSmoothMs &&\n            maxExtrapolate === d.maxExtrapolate && tickInterval === d.tickInterval &&\n            snap === d.snap\n        ) {\n            return DEFAULTS_PROFILE;\n        }\n        return this.allocProfile(mode, delay, smoothMs, lerpSmoothMs, maxExtrapolate, tickInterval, snap, true);\n    }\n\n    /**\n     * Allocate (or reuse, within the same `label`) the profile for an attach\n     * group. Unlike {@link profileFromOpts}, this NEVER collapses onto the\n     * mutable default profile #0 — each labeled group owns its own profile so\n     * the debug panel can tune it in isolation (the fix for the \"changing the\n     * enemies card moved the players\" cross-wire). All children of one\n     * `attachAll` share the profile (same label + params ⇒ deduped); different\n     * groups never do.\n     */\n    private groupProfile(\n        opts: { mode?: PredictMode; delay?: number; smoothMs?: number; maxExtrapolate?: number; tickInterval?: number; snap?: number },\n        label: string,\n    ): number {\n        const d = this.readSmoothingDefaults();\n        const mode = (opts.mode ?? this.defaultMode) as PredictMode;\n        return this.allocProfile(\n            mode,\n            opts.delay ?? d.delay,\n            opts.smoothMs ?? d.smoothMs,\n            opts.smoothMs ?? d.lerpSmoothMs,\n            opts.maxExtrapolate ?? d.maxExtrapolate,\n            opts.tickInterval ?? d.tickInterval,\n            opts.snap ?? d.snap,\n            true,\n            label,\n        );\n    }\n\n    /**\n     * Mutate the Predict's default options. Within the same mode family\n     * (smoothing modes are interchangeable; reckon is its own family). Throws\n     * on cross-family switches — create a new Predict instead.\n     *\n     * Mutations take effect on the next frame for every slot that attached\n     * with a default-shaped config (e.g. `{ x: {}, y: {} }`); attaches that\n     * explicitly overrode a field (e.g. `{ x: { delay: 50 } }`) snapshot\n     * their settings at attach time and are unaffected.\n     *\n     * Mode flips can cross families freely. The defaults profile (id 0)\n     * always encodes the current mode (any of the five), and its computer is\n     * swapped in lock-step so `value()` dispatches correctly without further\n     * branching.\n     */\n    setDefaults(opts: PredictOptions): void {\n        // Mode handling first — it's the only field that affects routing.\n        const newMode = (opts as { mode?: PredictMode }).mode;\n        if (newMode !== undefined) {\n            this.defaultMode = newMode;\n            // Profile 0 always stores the current mode — uniform encoding\n            // means slot dispatch follows automatically.\n            const base = DEFAULTS_PROFILE * PROFILE_STRIDE;\n            const code = MODE_CODES[newMode];\n            this.profileBuf[base + P_MODE] = code;\n            this.profileComputers[DEFAULTS_PROFILE] = this.computerForMode(code);\n        }\n\n        // Smoothing-mode fields → profile 0 (slots sharing it follow).\n        const s = opts as SmoothingOptions;\n        const base = DEFAULTS_PROFILE * PROFILE_STRIDE;\n        const p = this.profileBuf;\n        if (s.delay !== undefined) p[base + P_DELAY] = s.delay;\n        // Explicit smoothMs arms both fields — lerp's spring and damped/\n        // extrapolate's rate — so the value survives runtime mode flips.\n        if (s.smoothMs !== undefined) { p[base + P_SMOOTH_MS] = s.smoothMs; p[base + P_LERP_SMOOTH_MS] = s.smoothMs; }\n        if (s.maxExtrapolate !== undefined) p[base + P_MAX_EXTRAPOLATE] = s.maxExtrapolate;\n        if (s.tickInterval !== undefined) p[base + P_TICK_INTERVAL] = s.tickInterval;\n        if (s.snap !== undefined) { p[base + P_SNAP] = s.snap; this.reckonDefaults.snap = s.snap; }\n\n        // Reckon-mode fields → reckonDefaults.\n        const r = opts as ReckonOptions;\n        if (r.step !== undefined) this.reckonDefaults.step = r.step;\n        if (r.smoothMs !== undefined) this.reckonDefaults.smoothMs = r.smoothMs;\n        if (r.substep !== undefined) this.reckonDefaults.substep = r.substep;\n    }\n\n    /**\n     * Snapshot every profile currently registered with this Predict. Profiles\n     * include the defaults (id 0) plus one per unique `(mode, opts)` tuple that's\n     * been frozen by per-field attach overrides. Returns engine state only — the\n     * profile → field-names mapping the panel shows is derived by the debug\n     * bridge from the `onTrack` stream, not here.\n     */\n    private snapshotProfiles(): ProfileCore[] {\n        const out: ProfileCore[] = [];\n        for (let i = 0; i < this.profileCount; i++) {\n            const base = i * PROFILE_STRIDE;\n            const m = this.profileBuf[base + P_MODE] | 0;\n            if (m === MODE_BOUND) continue;   // controller-owned — nothing tunable\n\n            const mode: PredictMode =\n                m === MODE_LERP ? \"lerp\" :\n                m === MODE_EXTRAPOLATE ? \"extrapolate\" :\n                m === MODE_DAMPED ? \"damped\" :\n                m === MODE_RECKON ? \"reckon\" : \"raw\";\n            out.push({\n                id: i,\n                isDefault: i === DEFAULTS_PROFILE,\n                label: this.profileLabels[i],\n                mode,\n                delay: this.profileBuf[base + P_DELAY],\n                // Report the smoothMs the ACTIVE mode reads (lerp's spring vs\n                // damped/extrapolate's rate) — the panel slider round-trips it.\n                smoothMs: this.profileBuf[base + (m === MODE_LERP ? P_LERP_SMOOTH_MS : P_SMOOTH_MS)],\n                maxExtrapolate: this.profileBuf[base + P_MAX_EXTRAPOLATE],\n                tickInterval: this.profileBuf[base + P_TICK_INTERVAL],\n                snap: this.profileBuf[base + P_SNAP],\n            });\n        }\n        return out;\n    }\n\n    /**\n     * Mutate one profile in place. Used by the debug panel's per-profile\n     * controls. Setting `mode` swaps the cached `profileComputers[id]` in\n     * lock-step so slot reads pick the new dispatch immediately.\n     */\n    private setProfile(id: number, opts: { mode?: PredictMode } & SmoothingOptions): void {\n        if (id < 0 || id >= this.profileCount) return;\n        const base = id * PROFILE_STRIDE;\n        const p = this.profileBuf;\n        if ((p[base + P_MODE] | 0) === MODE_BOUND) return;   // controller-owned — not tunable\n        if (opts.mode !== undefined) {\n            const code = MODE_CODES[opts.mode];\n            p[base + P_MODE] = code;\n            this.profileComputers[id] = this.computerForMode(code);\n            // Defaults profile's mode also drives the outer routing's\n            // smoothing-mode encoding, keep them aligned.\n            if (id === DEFAULTS_PROFILE) this.defaultMode = opts.mode;\n        }\n        if (opts.delay !== undefined) p[base + P_DELAY] = opts.delay;\n        if (opts.smoothMs !== undefined) { p[base + P_SMOOTH_MS] = opts.smoothMs; p[base + P_LERP_SMOOTH_MS] = opts.smoothMs; }\n        if (opts.maxExtrapolate !== undefined) p[base + P_MAX_EXTRAPOLATE] = opts.maxExtrapolate;\n        if (opts.tickInterval !== undefined) p[base + P_TICK_INTERVAL] = opts.tickInterval;\n        if (opts.snap !== undefined) p[base + P_SNAP] = opts.snap;\n    }\n\n    /**\n     * Tear down all subscriptions. Detaches every attached instance, frees\n     * smoothing slots, removes the Predict from the debug registry, and\n     * invokes onDispose listeners.\n     */\n    dispose(): void {\n        for (const refId of new Set([...this.slotByRef.keys(), ...this.simByRef.keys()])) this.detachByRef(refId);\n        this.trackListeners.length = 0;\n        for (const d of this.driven.splice(0)) (d as { dispose?(): void }).dispose?.();\n        for (const cb of this.disposeListeners.splice(0)) cb();\n    }\n\n\n    // --- Low-level smoothing primitives ----------------------------------------\n\n    /**\n     * @internal Low-level primitive — track one numeric field for smoothing.\n     * Most consumers should use {@link attach} / {@link attachAll}; this is\n     * the underlying mechanism the high-level paths build on, exposed for\n     * advanced per-field control or when integrating with frameworks that\n     * already manage their own attach lifecycle.\n     */\n    track<T extends object>(\n        instance: T,\n        field: NumericKeys<T>,\n        opts: SmoothingOptions = {},\n    ): () => void {\n        // Resolve to a shared profile (empty opts → defaults profile;\n        // non-empty → frozen, value-deduped). The mode encoded in the\n        // profile drives dispatch — including reckon and raw — so this\n        // primitive accepts any `PredictMode` in `opts.mode`.\n        return this.trackWithProfile(instance, field, this.profileFromOpts(opts), opts.angle ?? false);\n    }\n\n    /**\n     * @internal Track `field` under an explicit, pre-resolved profile. The\n     * attach path uses this so a whole group shares ONE labeled profile\n     * instead of each field re-resolving (and possibly collapsing onto the\n     * mutable default #0). The read/sample hot path is identical either way —\n     * the slot just stores whichever profile id it's given.\n     */\n    private trackWithProfile<T extends object>(\n        instance: T,\n        field: NumericKeys<T>,\n        profileIdx: number,\n        angle: boolean = false,\n    ): () => void {\n        // Resolve the schema-native identity once, here at the API boundary.\n        // The hot path (samples + reads) operates purely on these integers.\n        const refId = refIdOf(instance);\n        if (refId === undefined) {\n            throw new Error(\n                \"Predict.track(): instance has no refId — track/attach must run \" +\n                \"AFTER the decoder delivers the instance (e.g. inside onAdd).\",\n            );\n        }\n        const fieldId = fieldIndexOf(instance, field);\n\n        // `field: NumericKeys<T>` guarantees `instance[field]` is `number`;\n        // the `?? 0` only covers the case where the schema field hasn't\n        // been hydrated by the decoder yet.\n        const initial: number = (instance[field] as number) ?? 0;\n\n        // Idempotent per field: re-tracking the SAME field frees + replaces its slot,\n        // leaving OTHER fields on the instance untouched — so a 2nd attach()/attachAll()\n        // COMPOSES additively instead of leaking the old slot. This is what lets\n        // attachWithPlan skip the blanket detach that used to clobber sibling attaches.\n        // When the current mapping is a controller overlay (MODE_BOUND), the overlay\n        // wins: the new passive slot installs UNDERNEATH it as the stash (replacing\n        // any previous understudy) and keeps sampling until the controller disposes.\n        let boundOver: BoundSlotEntry | undefined;\n        const existingIdx = this.slotByRef.get(refId)?.get(field);\n        if (existingIdx !== undefined) {\n            boundOver = this.boundBySlot.get(existingIdx);\n            if (boundOver !== undefined) this.freeStash(boundOver);\n            else this.untrackSlot(refId, field);\n        }\n\n        const slotIdx = this.allocSlot();\n        const buf = this.slotBuf;\n        const base = slotIdx * SLOT_STRIDE;\n        buf[base + SLOT_V1] = initial;\n        buf[base + SLOT_AUX_V] = initial;\n        buf[base + SLOT_AUX_T] = performance.now();\n        buf[base + SLOT_LERP_PREV] = initial;\n        buf[base + SLOT_PROFILE] = profileIdx;\n        buf[base + SLOT_REF] = refId;\n        buf[base + SLOT_FIELD] = fieldId;\n        // Reset the snapshot ring. Slot reuse via the free-list means stale\n        // ring state could survive across attach lifetimes — head=count=0\n        // makes the ring logically empty (entry floats are masked by count).\n        buf[base + SLOT_RING_HEAD] = 0;\n        buf[base + SLOT_RING_COUNT] = 0;\n        this.slotAngle[slotIdx] = angle;\n\n        if (boundOver !== undefined) {\n            boundOver.stash = slotIdx;\n        } else {\n            let perRef = this.slotByRef.get(refId);\n            if (perRef === undefined) { perRef = new Map(); this.slotByRef.set(refId, perRef); }\n            perRef.set(field, slotIdx);\n        }\n\n        // Notify track listeners (the debug bridge, when present) so it can\n        // build its profile → field-names view outside the engine. Empty in\n        // prod — this is a length check on the cold attach path.\n        for (let li = 0; li < this.trackListeners.length; li++) {\n            this.trackListeners[li](profileIdx, field);\n        }\n\n        // Sample-update hot path: push to ring + update v1. Capture `slotIdx`\n        // by value; `this.slotBuf` is re-read each call to pick up grown\n        // buffers transparently.\n        const detach = this.callbacks.listen(\n            instance,\n            field,\n            (current: number) => {\n                // Server-time axis: stamp samples with the patch's server-encode time\n                // (jitter-free, server-stamped) when a clock is present, so interpolation\n                // is immune to network arrival jitter. No clock → client arrival (perf.now).\n                const now = (this.clock && this.clock.lastServerTime() > 0) ? this.clock.lastServerTime() : performance.now();\n                const b = this.slotBuf;\n                const i = slotIdx * SLOT_STRIDE;\n                // Angle field: fold the new wrapped value onto the last stored (continuous)\n                // one over the shortest arc, so the ring stays monotonic across ±π and the\n                // interpolators never spin the long way. sin/cos make the delta period-2π.\n                if (angle) { const prev = b[i + SLOT_V1]; current = prev + Math.atan2(Math.sin(current - prev), Math.cos(current - prev)); }\n                const pBase = (b[i + SLOT_PROFILE] | 0) * PROFILE_STRIDE;\n                const tickInterval = this.profileBuf[pBase + P_TICK_INTERVAL];\n\n                let head = b[i + SLOT_RING_HEAD] | 0;\n                let count = b[i + SLOT_RING_COUNT] | 0;\n\n                // Value-space discontinuity (`snap` option): a per-sample jump\n                // beyond the threshold is a TELEPORT, not motion — empty the\n                // ring and snap the damped/extrapolate output state, so every\n                // mode renders the new value immediately instead of gliding\n                // across the gap. SLOT_V1 still holds the PREVIOUS sample here\n                // (mirrored below). The zeroed count also disables the\n                // gap-collapse inject for this sample (count >= 2 guard).\n                const snapDelta = this.profileBuf[pBase + P_SNAP];\n                if (snapDelta > 0 && count > 0 && Math.abs(current - b[i + SLOT_V1]) > snapDelta) {\n                    head = 0;\n                    count = 0;\n                    b[i + SLOT_AUX_V] = current;\n                    b[i + SLOT_LERP_PREV] = current;   // lerp's output spring pops too\n                }\n\n                // Derive lastT1 (timestamp of the previous newest snapshot)\n                // straight from the ring — no per-slot t1 field needed.\n                const lastT1 = count === 0\n                    ? Number.NEGATIVE_INFINITY\n                    : b[i + SLOT_RING_BASE + (head === 0 ? RING_CAP - 1 : head - 1) * 2];\n\n                // Tick-snap incoming sample times to a regular grid so the\n                // snapshot ring's bracketing lookup walks uniformly even when\n                // packets arrive with jitter. Skipped for the first sample.\n                // Bounded at +1 interval past `now` so the grid can't drift\n                // into the future.\n                let snapT = now;\n                if (tickInterval > 0 && isFinite(lastT1)) {\n                    const elapsed = now - lastT1;\n                    const ticks = elapsed > 0 ? Math.max(1, Math.round(elapsed / tickInterval)) : 1;\n                    snapT = lastT1 + ticks * tickInterval;\n                    const cap = now + tickInterval;\n                    if (snapT > cap) snapT = cap;\n                }\n\n                // Mirror the latest value into SLOT_V1 — damped reads it as\n                // its EMA target without having to walk the ring.\n                b[i + SLOT_V1] = current;\n\n                // Idle-resume gap collapse. If this sample lands far after the\n                // previous one RELATIVE to the recent inter-arrival cadence, the\n                // field was idle (delta encoding sent nothing). INJECT a\n                // synthetic \"held\" sample carrying the previous value at\n                // `snapT - resumeSpan`, so the stale anchor stays put (the\n                // entity reads as held during idle) and motion resumes over one\n                // normal interval instead of crawling across the whole gap.\n                // Compared against the last *normal* interval (ring[head-2]→\n                // ring[head-1]) so a genuinely sparse-but-regular stream\n                // (gap ≈ its own cadence) is left untouched.\n                const ringBase = i + SLOT_RING_BASE;\n                if (count >= 2 && isFinite(lastT1)) {\n                    const h1 = head === 0 ? RING_CAP - 1 : head - 1;       // previous newest\n                    const h2 = h1 === 0 ? RING_CAP - 1 : h1 - 1;           // one before it\n                    const lastInterval = lastT1 - b[ringBase + h2 * 2];\n                    // Prefer the server-advertised patch cadence (stable, immune to\n                    // the measured interval drifting after a prior collapse); fall\n                    // back to MULT × the measured interval when it's unknown.\n                    const patchMs = this.clock?.patchInterval ? this.clock.patchInterval() : 0;\n                    const span = patchMs > 0 ? patchMs : lastInterval;\n                    const trigger = patchMs > 0 ? GAP_RESUME_PATCH_MULT * patchMs : GAP_RESUME_MULT * lastInterval;\n                    if (span > 0 && (snapT - lastT1) > trigger) {\n                        const resumeSpan = span < GAP_RESUME_MAX_MS ? span : GAP_RESUME_MAX_MS;\n                        const sOff = ringBase + head * 2;\n                        b[sOff] = snapT - resumeSpan;\n                        b[sOff + 1] = b[ringBase + h1 * 2 + 1]; // previous (held) value\n                        head = head + 1 >= RING_CAP ? 0 : head + 1;\n                        if (count < RING_CAP) count++;\n                    }\n                }\n\n                // Push onto the snapshot ring. Head wraps at RING_CAP, count\n                // saturates — past capacity, new writes overwrite the oldest\n                // entry in place (no shift, no allocation).\n                const off = ringBase + head * 2;\n                b[off] = snapT;\n                b[off + 1] = current;\n                b[i + SLOT_RING_HEAD] = head + 1 >= RING_CAP ? 0 : head + 1;\n                if (count < RING_CAP) b[i + SLOT_RING_COUNT] = count + 1;\n            },\n            /* immediate */ true,\n        );\n        this.slotDetach[slotIdx] = detach;\n\n        return () => this.untrackSlot(refId, field);\n    }\n\n    /**\n     * @internal Counterpart to {@link track}. Most consumers should use\n     * {@link detach} / {@link attachAll}'s onRemove subscription instead.\n     */\n    untrack<T extends object>(instance: T, field: NumericKeys<T>): void {\n        const refId = refIdOf(instance);\n        if (refId === undefined) return;\n        this.untrackSlot(refId, field);\n    }\n\n    private untrackSlot(refId: number, field: string): void {\n        const perRef = this.slotByRef.get(refId);\n        const slotIdx = perRef?.get(field);\n        if (slotIdx === undefined) return;\n        const bound = this.boundBySlot.get(slotIdx);\n        if (bound !== undefined) {\n            // The mapping is a controller overlay: untrack removes the PASSIVE\n            // registration underneath (the stash). The overlay itself is torn\n            // down only by its controller's dispose (or by detachByRef when the\n            // entity itself is removed).\n            this.freeStash(bound);\n            return;\n        }\n        this.slotDetach[slotIdx]?.();\n        this.slotDetach[slotIdx] = undefined;\n        this.freeSlots.push(slotIdx);\n        perRef!.delete(field);\n        if (perRef!.size === 0) this.slotByRef.delete(refId);\n    }\n\n    /** Free a bound entry's stashed passive slot (detach its listener). */\n    private freeStash(entry: BoundSlotEntry): void {\n        if (entry.stash < 0) return;\n        this.slotDetach[entry.stash]?.();\n        this.slotDetach[entry.stash] = undefined;\n        this.freeSlots.push(entry.stash);\n        entry.stash = -1;\n    }\n\n    private allocSlot(): number {\n        if (this.freeSlots.length > 0) return this.freeSlots.pop()!;\n        const idx = this.slotCount++;\n        const needed = (idx + 1) * SLOT_STRIDE;\n        if (needed > this.slotBuf.length) {\n            const grown = new Float64Array(this.slotBuf.length * 2);\n            grown.set(this.slotBuf);\n            this.slotBuf = grown;\n        }\n        return idx;\n    }\n\n    // --- Bound overlay (predict.value ← rollback controllers) -------------------\n\n    /**\n     * Install a MODE_BOUND overlay slot for each (source, numeric field) a\n     * rollback controller predicts, so `predict.value(source, field)` reads the\n     * controller's interpolated + smooth-corrected pose — the same idiom as\n     * every passively-smoothed entity. A pre-existing passive slot (e.g. the\n     * local player inside an `attachAll` lerp group) is STASHED — its field\n     * listener stays subscribed and samples keep landing in its ring — and\n     * restored when the controller disposes, so lerp resumes seamlessly.\n     *\n     * Returns the unregister (run on the controller's dispose): frees the\n     * overlay slots and restores (or deletes) each mapping.\n     */\n    private registerBound(\n        ctrl: { value(field: string): number },\n        source: object,\n        fields: readonly string[],\n        poseKeys: readonly string[],\n        profileIdx: number,\n    ): () => void {\n        const refId = refIdOf(source)!;   // callers pre-check (bound sources are decoded)\n        let perRef = this.slotByRef.get(refId);\n        if (perRef === undefined) { perRef = new Map(); this.slotByRef.set(refId, perRef); }\n        const slots: number[] = [];\n        for (let k = 0; k < fields.length; k++) {\n            const field = fields[k];\n            const existing = perRef.get(field);\n            let stash = -1;\n            if (existing !== undefined) {\n                const prior = this.boundBySlot.get(existing);\n                if (prior !== undefined) {\n                    // Same (instance, field) claimed twice (two controllers, or one\n                    // instance in two world parts): last registration wins — mirrors\n                    // the \"one accumulator can't pace two rates\" posture. The\n                    // ORIGINAL passive stash is inherited by the winner.\n                    console.warn(\n                        `@colyseus/sdk Predict: \"${field}\" (refId ${refId}) is already bound ` +\n                        \"to a controller — the newer registration wins.\",\n                    );\n                    stash = prior.stash;\n                    this.boundBySlot.delete(existing);\n                    this.freeSlots.push(existing);\n                } else {\n                    stash = existing;   // passive slot: stashed, its listener keeps sampling\n                }\n            }\n            const slotIdx = this.allocSlot();\n            const buf = this.slotBuf;\n            const base = slotIdx * SLOT_STRIDE;\n            // Self-describing like any slot, but NO listener — the computer reads\n            // the controller, not the sample ring (slotDetach stays undefined;\n            // teardown paths use `?.()`).\n            const initial = (source as Record<string, number>)[field] ?? 0;\n            buf[base + SLOT_V1] = initial;\n            buf[base + SLOT_AUX_V] = initial;\n            buf[base + SLOT_AUX_T] = 0;\n            buf[base + SLOT_LERP_PREV] = initial;\n            buf[base + SLOT_PROFILE] = profileIdx;\n            buf[base + SLOT_REF] = refId;\n            buf[base + SLOT_FIELD] = fieldIndexOf(source, field);\n            buf[base + SLOT_RING_HEAD] = 0;\n            buf[base + SLOT_RING_COUNT] = 0;\n            this.slotAngle[slotIdx] = false;\n            this.boundBySlot.set(slotIdx, { ctrl, key: poseKeys[k], stash });\n            perRef.set(field, slotIdx);\n            slots.push(slotIdx);\n            for (let li = 0; li < this.trackListeners.length; li++) {\n                this.trackListeners[li](profileIdx, field);\n            }\n        }\n        return () => {\n            for (let k = 0; k < slots.length; k++) {\n                const slotIdx = slots[k];\n                const entry = this.boundBySlot.get(slotIdx);\n                // Identity check, not just presence: a freed slot index is recycled\n                // by the free-list, so after a duplicate-claim (or entity removal)\n                // this index may now back ANOTHER controller's overlay — which this\n                // stale unregister must not tear down.\n                if (entry === undefined || entry.ctrl !== ctrl) continue;\n                this.boundBySlot.delete(slotIdx);\n                this.freeSlots.push(slotIdx);\n                const pr = this.slotByRef.get(refId);\n                if (pr?.get(fields[k]) === slotIdx) {\n                    if (entry.stash >= 0) {\n                        pr.set(fields[k], entry.stash);   // resume the passive slot\n                    } else {\n                        pr.delete(fields[k]);\n                        if (pr.size === 0) this.slotByRef.delete(refId);\n                    }\n                }\n            }\n        };\n    }\n\n    /** Wire a just-spawned controller's bound instances into the `value()`\n     *  overlay (all controllers share the one MODE_BOUND profile — the side\n     *  table, not the profile, carries the per-slot backing) and arrange the\n     *  restore on its dispose. No-op for controllers with nothing bound (opaque\n     *  sim worlds, plain-fixture reconcilers). */\n    private installBoundOverlay(ctrl: BoundController): void {\n        const offs: Array<() => void> = [];\n        for (const reg of ctrl.boundRegistrations) {\n            if (reg.fields.length === 0 || refIdOf(reg.source) === undefined) continue;\n            if (this.boundProfileIdx < 0) {\n                this.boundProfileIdx = this.allocProfile(MODE_BOUND, 0, 0, 0, 0, 0, 0, false, \"bound\");\n            }\n            offs.push(this.registerBound(ctrl, reg.source, reg.fields, reg.poseKeys, this.boundProfileIdx));\n        }\n        if (offs.length > 0) ctrl.onDisposed(() => { for (const off of offs) off(); });\n    }\n\n    /**\n     * @internal Low-level dead-reckoning primitive — forward-simulates\n     * `instance` using a step function with scratch-snapshot + substep loop +\n     * predict-then-smooth on read. Most consumers should pass a reckon\n     * attach config to {@link attach} / {@link attachAll}; this is the\n     * underlying implementation, exposed for cases where the declarative\n     * config shape doesn't fit.\n     */\n    trackStepped<T extends object>(instance: T, opts: SteppedOptions<T>): () => void {\n        const substep = opts.substep ?? 16;\n        const fields = opts.fields;\n        const fieldIds = fields.map((f) => fieldIndexOf(instance, f as string));\n        const step = opts.step;\n        const clock = this.clock;\n\n        // Default forward horizon = SNAPSHOT AGE, exactly.\n        //\n        // Age = `serverNow() − lastServerTime()` (current server time minus the\n        // server-encode time of the latest patch) — the exact amount to forward\n        // a remote entity to its CURRENT server position. Unlike a fixed RTT\n        // proxy it's the true downstream age (~RTT/2 + buffering, not the full\n        // round trip) and GROWS between patches (continuous, not\n        // freeze-then-step).\n        //\n        // No lag compensation on top: offset-decay smoothing is steady-state\n        // EXACT (only rebase discontinuities decay), so the displayed instant\n        // IS serverNow — which is exactly what the input prefix stamps as\n        // reckonTime. Any extra lead here desyncs display from stamp and the\n        // server's lag-comp reads mis-aim by lead × velocity (enough to flip\n        // knife-edge hit calls). Override `forwardMs` for a different\n        // horizon (e.g. a collision read wanting extra look-ahead).\n        const present = this.presentFn(); // serverNow(), or renderNow() under renderPresent\n        const forwardMs = opts.forwardMs ?? (present\n            ? () => { const stamp = clock!.lastServerTime(); return stamp > 0 ? Math.max(0, present() - stamp) : 0; }\n            : () => 0);\n        const elapsedMs = opts.elapsedMs ?? (present ?? (() => performance.now()));\n\n        // Build `advance` once. It writes predicted fields into the SoA `out`\n        // buffer (indexed by field position) — never a name-keyed object.\n        const liveValues = (instance as Record<symbol, unknown>)[$VALUES];\n        // The SoA fast path is only valid when the instance actually stores its\n        // field values in a dense `$values` array indexed by field index. Some\n        // @colyseus/schema versions expose values ONLY through prototype getters\n        // and leave `$values` empty (length 0) — `Array.isArray([])` is still\n        // true, but reading `sv[fieldId]` then yields `undefined`, which a\n        // Float64Array coerces to NaN (entity vanishes). Require the array to\n        // actually cover every field we read; otherwise fall through to the\n        // generic accessor-based snapshot, which reads via the getters.\n        const fastPathOk =\n            opts.snapshot === undefined &&\n            Array.isArray(liveValues) &&\n            fieldIds.every((id) => id >= 0 && id < (liveValues as unknown[]).length);\n        let advance: (live: T, fwd: number, out: Float64Array, endElapsed: number) => void;\n        if (fastPathOk) {\n            // SoA fast path (decoded schema instances). The scratch is a pooled\n            // instance of the same type; each frame we refill its `$values`\n            // array BY INDEX from the live instance (no dynamic-key object\n            // building → no V8 dictionary mode, no megamorphic keyed store),\n            // let `step` mutate it through its accessors, then extract the\n            // predicted fields BY INDEX. Fully monomorphic + zero allocation.\n            const scratch = new (instance.constructor as new () => T)();\n            const sv = (scratch as Record<symbol, number[]>)[$VALUES];\n            advance = (live, fwd, out, endElapsed) => {\n                const lv = (live as Record<symbol, number[]>)[$VALUES];\n                for (let i = 0; i < lv.length; i++) sv[i] = lv[i];\n                let remaining = fwd;\n                // The scratch is the SNAPSHOT state (age `fwd` ago), so absolute\n                // time runs from `endElapsed − fwd` and the LAST substep lands\n                // exactly on `endElapsed` — time-SAMPLED fields (sinusoids,\n                // cooldown snaps) then read the same instant the input stamp\n                // claims. Starting at `endElapsed` instead would evaluate them\n                // `fwd` ms (≈ one-way latency) in the future — a latency-scaled\n                // desync the server's lag-comp read can't cancel.\n                let elapsed = endElapsed - fwd;\n                while (remaining > 0) {\n                    const stepMs = remaining < substep ? remaining : substep;\n                    elapsed += stepMs;\n                    // elapsed at the END of the substep: equivalent for\n                    // integrated quantities, correct for time-sampled ones.\n                    step(scratch, stepMs / 1000, elapsed);\n                    remaining -= stepMs;\n                }\n                for (let k = 0; k < fieldIds.length; k++) out[k] = sv[fieldIds[k]];\n            };\n        } else {\n            // Generic path: non-schema instance, a caller-supplied snapshot, or\n            // (the common browser case) a decoded instance whose `$values` SoA is\n            // empty so the fast path above didn't apply. Builds a fresh named\n            // scratch each frame and extracts by name. When metadata is available\n            // the per-field copy is UNROLLED (monomorphic, no eval — see\n            // makeUnrolledSnapshot); otherwise a plain `{...instance}` spread\n            // covers non-schema objects.\n            const fieldNames = scalarFieldNamesOf(instance);\n            const snapshotFn: (e: T) => T = opts.snapshot ?? (fieldNames.length > 0\n                ? (makeUnrolledSnapshot(fieldNames) as (e: T) => T)\n                : (e: T) => ({ ...e } as T));\n            const names = [...fields] as string[];\n            advance = (live, fwd, out, endElapsed) => {\n                const scratch = snapshotFn(live) as Record<string, unknown>;\n                let remaining = fwd;\n                // Snapshot-relative absolute time — see the fast path above.\n                let elapsed = endElapsed - fwd;\n                while (remaining > 0) {\n                    const stepMs = remaining < substep ? remaining : substep;\n                    elapsed += stepMs;\n                    step(scratch as T, stepMs / 1000, elapsed);\n                    remaining -= stepMs;\n                }\n                for (let k = 0; k < names.length; k++) out[k] = scratch[names[k]] as number;\n            };\n        }\n\n        return this.trackSimulated(instance, {\n            fields,\n            forwardMs,\n            elapsedMs,\n            smoothMs: opts.smoothMs,\n            snap: opts.snap,\n            advance,\n        });\n    }\n\n    private trackSimulated<T extends object>(instance: T, opts: SimulateOptions<T>): () => void {\n        const refId = refIdOf(instance);\n        if (refId === undefined) {\n            throw new Error(\n                \"Predict.trackStepped(): instance has no refId — must run AFTER \" +\n                \"the decoder delivers the instance (e.g. inside onAdd).\",\n            );\n        }\n        const fields = opts.fields;\n        const n = fields.length;\n        const fieldIds = fields.map((f) => fieldIndexOf(instance, f as string));\n        let maxId = 0;\n        for (const id of fieldIds) if (id > maxId) maxId = id;\n        const posOf = new Int8Array(maxId + 1).fill(-1);\n        for (let k = 0; k < n; k++) if (fieldIds[k] >= 0) posOf[fieldIds[k]] = k;\n        const smoothed = new Float64Array(n);\n        for (let k = 0; k < n; k++) smoothed[k] = (instance as any)[fields[k]] ?? 0;\n        // Default the absolute-time provider to the reckon present — serverNow,\n        // or renderNow under renderPresent (matches the per-frame reckon).\n        // `valueAt` overrides the end instant per call, so hit reads stay exact.\n        const present = this.presentFn();\n        const elapsedMs = opts.elapsedMs ?? (present ?? (() => performance.now()));\n        const state: SimState = {\n            instance,\n            fieldIds,\n            posOf,\n            forwardMs: opts.forwardMs,\n            elapsedMs,\n            advance: opts.advance as SimState[\"advance\"],\n            smoothMs: opts.smoothMs ?? 50,\n            snap: opts.snap ?? 0,\n            smoothed,\n            out: new Float64Array(n),\n            valueOut: new Float64Array(n),\n            offset: new Float64Array(n),\n            outPrev: new Float64Array(n),\n            frameVel: new Float64Array(n),\n            lastBaseT: NaN,\n            lastApplyTime: -Infinity,\n        };\n        this.simByRef.set(refId, state);\n        return () => this.untrackSimulated(refId);\n    }\n\n    private untrackSimulated(refId: number): void {\n        this.simByRef.delete(refId);\n    }\n\n    // --- High-level orchestration ----------------------------------------------\n\n    /**\n     * Attach prediction to a single schema instance via a declarative config.\n     *\n     * For collections, prefer {@link attachAll}. For a root-level instance\n     * that arrives lazily, wrap this call in\n     * `Callbacks.get(room).listen(state, \"field\", ..., true)`.\n     */\n    attach<T extends object>(instance: T, config: AttachConfig<T>): () => void {\n        // A standalone attach is its own one-off group, labeled \"(attach)\".\n        // Identical configs dedup under that label (so a hand-rolled loop over\n        // many instances doesn't explode the profile table); for per-collection\n        // isolation use attachAll, which labels the group by its key.\n        const group = this.makeGroup(\"(attach)\", config);\n        return this.attachWithPlan(instance, this.planFor(group, instance));\n    }\n\n    /** One group per attach()/attachAll(): base plan built eagerly (so config\n     *  errors throw at the call site, like before); per-type sub-plans lazy. */\n    private makeGroup(label: string, config: AttachConfig<any>): AttachGroup {\n        return {\n            label,\n            config,\n            basePlan: this.buildGroupPlan(config, label),\n            planByCtor: new Map(),\n        };\n    }\n\n    /** The plan for one child — the group's base plan unless the child's TYPE\n     *  lacks some of the configured fields (those are dropped). Cached per\n     *  constructor: homogeneous collections hit one entry. */\n    private planFor(group: AttachGroup, child: object): GroupPlan {\n        const ctor = child.constructor as Function;\n        let plan = group.planByCtor.get(ctor);\n        if (plan === undefined) {\n            plan = this.resolveCtorPlan(group, child);\n            group.planByCtor.set(ctor, plan);\n        }\n        return plan;\n    }\n\n    /**\n     * Once per (group, constructor): drop fields the child type doesn't declare\n     * (they'd subscribe to nothing and, in reckon scratch, read garbage). Mode\n     * is the group's — the client's prediction mode is explicit, never inferred\n     * from the schema. Returns the base plan when every field is present;\n     * otherwise builds a `label:TypeName` sub-plan with its own profile.\n     */\n    private resolveCtorPlan(group: AttachGroup, child: object): GroupPlan {\n        const md = metadataOf(child);\n        const typeName = (child.constructor as Function | undefined)?.name || \"?\";\n        const config = group.config;\n\n        if (!isReckonAttachConfig(config)) {\n            // Per-field smoothing map.\n            if (md === undefined) return group.basePlan;   // non-schema fixture\n            const keys = Object.keys(config).filter((k) => (config as Record<string, unknown>)[k] !== undefined);\n            if (keys.every((k) => typeof md[k] === \"number\")) return group.basePlan;\n            const filtered: Record<string, unknown> = {};\n            for (const k of keys) if (typeof md[k] === \"number\") filtered[k] = (config as Record<string, unknown>)[k];\n            return this.buildGroupPlan(filtered as AttachConfig<any>, `${group.label}:${typeName}`);\n        }\n\n        const rcfg = config as ReckonAttachConfig<any>;\n        let fields = rcfg.fields as readonly string[];\n        if (md !== undefined) {\n            const filtered = fields.filter((f) => typeof md[f] === \"number\");\n            if (filtered.length !== fields.length) fields = filtered;\n        }\n        if (fields === rcfg.fields) return group.basePlan;   // all fields present\n        return this.buildGroupPlan({ ...rcfg, fields } as AttachConfig<any>, `${group.label}:${typeName}`);\n    }\n\n    /**\n     * Resolve a group's profiles ONCE. Profiles are allocated via\n     * {@link groupProfile} (labeled, never the mutable default #0), so every\n     * child of the group shares the group's own profile and the panel can tune\n     * it without bleeding into other groups.\n     */\n    private buildGroupPlan<T extends object>(config: AttachConfig<T>, label: string): GroupPlan {\n        const fieldProfiles: Array<{ field: string; profileIdx: number; angle?: boolean }> = [];\n        if (isReckonAttachConfig(config)) {\n            const rcfg = config as ReckonAttachConfig<T>;\n            if (!Array.isArray(rcfg.fields)) {\n                throw new Error(\"Predict.attach(): `fields` must be a numeric-key array.\");\n            }\n            const effectiveMode: PredictMode = rcfg.mode ?? this.defaultMode;\n            const step = rcfg.step ?? this.reckonDefaults.step;\n            const isReckon = effectiveMode === \"reckon\";\n            if (isReckon && typeof step !== \"function\") {\n                throw new Error(\n                    \"Predict.attach(): reckon mode requires a 'step' function. \" +\n                    \"Either pass `step` in the attach config OR construct the Predict with \" +\n                    \"`Predict.get(room, { mode: 'reckon', step: yourStepFn })` so it can be inherited.\",\n                );\n            }\n            // One profile for the whole group (all fields share it).\n            const profileIdx = this.groupProfile({ mode: effectiveMode, snap: rcfg.snap, smoothMs: rcfg.smoothMs }, label);\n            for (const f of rcfg.fields) fieldProfiles.push({ field: f as string, profileIdx, angle: rcfg.angle });\n            return {\n                label,\n                isReckon,\n                reckonFields: isReckon ? (rcfg.fields as readonly string[]) : undefined,\n                reckonStep: isReckon ? step : undefined,\n                reckonSmoothMs: rcfg.smoothMs ?? this.reckonDefaults.smoothMs,\n                reckonSubstep: rcfg.substep ?? this.reckonDefaults.substep,\n                reckonSnap: rcfg.snap ?? this.reckonDefaults.snap,\n                reckonSnapshot: rcfg.snapshot,\n                fieldProfiles,\n            };\n        }\n        // Smoothing-only per-field map. Each field gets a profile (deduped\n        // within the group by params), so `{ x:\"lerp\", vx:\"extrapolate\" }`\n        // yields two group-labeled profiles → two panel sub-cards.\n        const smoothing = config as SmoothingConfig<T>;\n        for (const key of Object.keys(smoothing) as unknown as ReadonlyArray<NumericKeys<T>>) {\n            const value = smoothing[key];\n            if (value === undefined) continue;\n            const o: SmoothingOptions = typeof value === \"string\" ? { mode: value } : value;\n            fieldProfiles.push({ field: key as string, profileIdx: this.groupProfile(o, label), angle: o.angle });\n        }\n        return { label, isReckon: false, fieldProfiles };\n    }\n\n    /** Attach one child using a pre-resolved {@link GroupPlan}. `forwardMs`\n     *  overrides the reckon horizon for THIS instance only (e.g. the spawns\n     *  store's per-entity input lead); omitted → snapshot age, as usual. */\n    private attachToGroup<T extends object>(instance: T, plan: GroupPlan, forwardMs?: () => number): () => void {\n        const offs: Array<() => void> = [];\n        if (plan.isReckon) {\n            offs.push(this.trackStepped<T>(instance, {\n                fields: plan.reckonFields as readonly (keyof T & string)[],\n                step: plan.reckonStep as (s: T, dt: number, e: number) => void,\n                smoothMs: plan.reckonSmoothMs,\n                substep: plan.reckonSubstep,\n                snap: plan.reckonSnap,\n                snapshot: plan.reckonSnapshot as ((s: T) => T) | undefined,\n                forwardMs,\n            }));\n        }\n        for (const { field, profileIdx, angle } of plan.fieldProfiles) {\n            offs.push(this.trackWithProfile(instance, field as NumericKeys<T>, profileIdx, !!angle));\n        }\n        return () => { for (const f of offs) f(); };\n    }\n\n    private attachWithPlan<T extends object>(instance: T, plan: GroupPlan): () => void {\n        const refId = refIdOf(instance);\n        if (refId === undefined) {\n            throw new Error(\n                \"Predict.attach(): instance has no refId — attach must run AFTER \" +\n                \"the decoder delivers the instance (e.g. inside onAdd).\",\n            );\n        }\n        // No blanket detach: attachToGroup tracks each field idempotently (see\n        // trackWithProfile), so this ADDS to whatever is already tracked on the\n        // instance — a 2nd attachAll for other fields composes instead of clobbering.\n        this.attachToGroup(instance, plan);\n        return () => this.detachByRef(refId);\n    }\n\n    /** Detach a previously {@link attach}'d instance. No-op if not attached. */\n    detach(instance: object): void {\n        const refId = refIdOf(instance);\n        if (refId !== undefined) this.detachByRef(refId);\n    }\n\n    private detachByRef(refId: number): void {\n        // Data-driven teardown — no stored closures. slotByRef already maps the\n        // instance to every field tracked on it (across however many attach calls),\n        // so walk it and free each slot, then drop any reckon SimState. Snapshot the\n        // keys: untrackSlot mutates perRef (and deletes the slotByRef entry when empty).\n        const perRef = this.slotByRef.get(refId);\n        if (perRef) {\n            for (const field of [...perRef.keys()]) {\n                const slotIdx = perRef.get(field);\n                if (slotIdx === undefined) continue;\n                const bound = this.boundBySlot.get(slotIdx);\n                if (bound !== undefined) {\n                    // The ENTITY died while a controller overlay was live: tear down\n                    // the overlay AND its stash — a recycled refId must not collide\n                    // with a stale mapping. The controller's own dispose then finds\n                    // the side entry gone and skips (its logic reads keep working\n                    // off `me.world` until it's disposed).\n                    this.freeStash(bound);\n                    this.boundBySlot.delete(slotIdx);\n                    this.freeSlots.push(slotIdx);\n                    perRef.delete(field);\n                } else {\n                    this.untrackSlot(refId, field);\n                }\n            }\n            if (perRef.size === 0) this.slotByRef.delete(refId);\n        }\n        this.simByRef.delete(refId);\n    }\n\n    /**\n     * Attach prediction to every child of a collection on the root state.\n     * Mirrors `callbacks.onAdd(\"enemies\", cb)`'s shape — when the collection\n     * lives on `room.state` you can omit the parent.\n     */\n    attachAll<K extends CollectionKeys<TState>>(\n        key: K,\n        config: AttachConfig<ChildOf<TState[K]>>,\n    ): () => void;\n    /**\n     * Attach prediction to every child of a nested collection at `parent[key]`.\n     * Wires `onAdd` to {@link attach} the child and `onRemove` to detach it.\n     * Works for MapSchema / ArraySchema / SetSchema.\n     *\n     * @returns A detacher that unsubscribes add/remove AND detaches every\n     *   child still tracked.\n     */\n    attachAll<P extends object, K extends CollectionKeys<P>>(\n        parent: P,\n        key: K,\n        config: AttachConfig<ChildOf<P[K]>>,\n    ): () => void;\n    attachAll(...args: any[]): () => void {\n        // Mirror Callbacks: `typeof args[0] === 'string'` ⇒ root variant.\n        const rootForm = typeof args[0] === \"string\";\n        const parent: object | undefined = rootForm ? undefined : args[0];\n        const key: string = rootForm ? args[0] : args[1];\n        const config: AttachConfig<any> = rootForm ? args[1] : args[2];\n\n        // Resolve the group's base profile(s) ONCE — labeled by the collection\n        // key so this group owns its profile and the panel tunes it in\n        // isolation. Each child resolves through planFor: homogeneous\n        // collections reuse the base plan; a type whose field set differs\n        // (missing some configured fields) gets its own per-type sub-plan.\n        const group = this.makeGroup(key, config);\n\n        const tracked = new Set<object>();\n        const onAdd = (child: object) => {\n            this.attachWithPlan(child, this.planFor(group, child));\n            tracked.add(child);\n        };\n        const onRemove = (child: object) => {\n            tracked.delete(child);\n            this.detach(child);\n        };\n        const addOff = rootForm\n            ? this.callbacks.onAdd(key, onAdd)\n            : this.callbacks.onAdd(parent, key, onAdd);\n        const removeOff = rootForm\n            ? this.callbacks.onRemove(key, onRemove)\n            : this.callbacks.onRemove(parent, key, onRemove);\n        return () => {\n            addOff?.();\n            removeOff?.();\n            for (const child of tracked) this.detach(child);\n            tracked.clear();\n        };\n    }\n\n    // --- Per-frame driver ------------------------------------------------------\n\n    /**\n     * Call once per render frame — the single per-frame driver for the whole\n     * prediction stack. Returns your SEND BUDGET: how many fixed input steps are\n     * due this frame — mutate + send exactly that many inputs through your input\n     * handle (`for (n) { input.data.x = …; input.send(); }`), and the reconcilers\n     * observe + predict each send. Besides pacing, the call reconciles + steps +\n     * decays every {@link reconciler}/{@link sim} spawned here, advances\n     * smoothing, and prunes every event channel/spawn store.\n     *\n     * Returns 0 while the fixed step is UNKNOWN: the rate is adopted from the\n     * first {@link reconciler}/{@link sim} spawned here, so pre-spawn frames —\n     * and passive smoothing-only Predicts — pace nothing. That is the send loop\n     * self-gating before the local player exists, not an error; keep calling\n     * `tick()` and the budget starts flowing the frame the controller spawns.\n     *\n     * ORDER WITHIN THE FRAME MATTERS: send the returned steps FIRST, then read\n     * render values (`value()`/`pose()`). A read between this call and the frame's\n     * sends is one fixed step stale — the interpolation clamps at the latest\n     * applied step (never extrapolates), so late frames flat-top and fast objects\n     * visibly stutter. The reconciler warns once when it detects that pattern.\n     * Game logic that wants the exact predicted state (hit-reg, zone checks)\n     * should read `.state`/`.world` instead, which this ordering doesn't affect.\n     * In engines that run per-object update callbacks (rather than one frame\n     * function), tick AND pump in the earliest registered callback — the frame\n     * driver owns input; objects only read. `room.input()` returns the same\n     * handle everywhere, so the driver and the entity that predicts through it\n     * don't need to share plumbing.\n     *\n     * `now` defaults to `performance.now()`. When you drive from\n     * `requestAnimationFrame`, pass ITS timestamp argument — not `performance.now()`\n     * (or `room.clock.now()`) sampled inside the callback: the rAF timestamp is\n     * vsync-aligned and evenly spaced, whereas an in-callback reading folds JS\n     * scheduling jitter into the frame `dt`, which makes render interpolation advance\n     * unevenly (motion looks \"not smooth\" though it never stutters). Pass it\n     * explicitly, too, when ticking multiple Predicts in one frame so they share one\n     * frame-time reference.\n     */\n    tick(now: number = performance.now()): number {\n        this.renderTime = now;\n\n        // Advance the room-wide fixed-step accumulator: elapsed render time → the\n        // whole number of fixed input steps due this frame (returned to the caller).\n        let steps = 0;\n        const stepMs = this.fixedStepMs;\n        if (stepMs !== undefined && stepMs > 0) {\n            const dt = this.lastFrameNow < 0 ? 0 : now - this.lastFrameNow;\n            this.stepAcc += dt;\n            steps = Math.floor(this.stepAcc / stepMs);\n            if (steps > Predict.MAX_STEPS_PER_FRAME) {\n                this.stepAcc = 0;   // hitch: emit a bounded count, drop the backlog\n                steps = Predict.MAX_STEPS_PER_FRAME;\n            } else {\n                this.stepAcc -= steps * stepMs;\n            }\n        }\n        this.lastFrameNow = now;\n\n        // Drive children (reconcile + decay); each derives its own render\n        // interpolation from `now`. Compact out any disposed ones in the same pass.\n        const driven = this.driven;\n        let live = 0;\n        for (let i = 0; i < driven.length; i++) {\n            const d = driven[i];\n            if (d.dead) continue;\n            d.tick?.(now);\n            d.prune?.();\n            if (live !== i) driven[live] = d;\n            live++;\n        }\n        if (live !== driven.length) driven.length = live;\n\n        return steps;\n    }\n\n    // --- Event channels --------------------------------------------------------\n\n    /**\n     * Declare a typed optimistic-event CHANNEL — one logical event type\n     * (a goal, a kill, a pickup) owned end-to-end: predicted from the sim\n     * (`ctx.predict(channel, payload)` inside a reconciler `step`, replay-safe\n     * by construction) or from UI (`channel.predict(payload)`), optimistic\n     * feedback via `onPredict`, and settlement against the server:\n     * `channel.confirm()` on the authoritative signal, or auto-reject once\n     * the server has processed past the prediction without confirming (see\n     * the channel header's SETTLEMENT notes).\n     *\n     * The channel OBJECT is the identity — no string key; call sites hold the\n     * binding. Auto-driven by this Predict's {@link tick} — no manual\n     * `prune()`.\n     *\n     *     const goals = predict.defineEvent<Team>({\n     *         onPredict: (team) => { celebrate(team); hidePuck(); },\n     *         onReject:  ()     => showPuck(),\n     *     });\n     *     // in the reconciler step:      if (crossed) ctx.predict(goals, team);\n     *     // on the server's broadcast:   room.onMessage(\"score\", () => goals.confirm());\n     *\n     * When the authoritative signal is a STATE change rather than a broadcast,\n     * declare it with `confirmOn` and skip the hand-wired listener entirely —\n     * the Predict subscribes it for you and tears it down with the channel:\n     *\n     *     const breaks = predict.defineEvent<string>({\n     *         label: \"break\",\n     *         // when a crate's `alive` flips false, confirm the entry keyed\n     *         // by that crate's collection key\n     *         confirmOn: { collection: \"crates\", field: \"alive\", equals: false },\n     *     });\n     *\n     * Also `{ collection, event: \"add\" | \"remove\" }` when membership itself is\n     * the signal (`add` settles keyless, optionally gated by `mine`). The\n     * field/remove forms require channel entry keys (the `uniqueBy` output) to\n     * BE collection keys; root-level collections only — mismatched schemes\n     * confirm manually (see the `confirmOn` module header).\n     */\n    defineEvent<T>(\n        opts: PredictedEventChannelOptions<T> & { confirmOn?: ConfirmOn<TState> },\n    ): PredictedEventChannel<T> {\n        const { confirmOn, ...channelOpts } = opts;\n        const channel = new PredictedEventChannel<T>(channelOpts, this.clock ?? null);\n        if (confirmOn !== undefined) {\n            if (confirmOn.mine !== undefined && typeof this.sessionSource.sessionId !== \"string\") {\n                throw new Error(\n                    `Predict.defineEvent: confirmOn.mine (\"${confirmOn.mine}\") requires a Predict ` +\n                    `built from a Room (it compares against room.sessionId); confirm manually instead.`,\n                );\n            }\n            channel._addTeardown(wireConfirmOn(\n                this.callbacks, channel, confirmOn,\n                () => this.sessionSource.sessionId,\n            ));\n        }\n        this.driven.push(channel);\n        return channel;\n    }\n\n    /**\n     * Spawn a {@link PredictedSpawns} store for a collection of optimistically-\n     * spawned entities (bullets, grenades, dropped items) at `state[key]`.\n     *\n     * Predicted locals (added via the store's `spawn(...)`) render instantly;\n     * when the authoritative entity arrives in the collection it's correlated\n     * to the matching prediction and the two collapse onto one logical entry\n     * with a stable `id`. Wires the collection's `onAdd`/`onRemove` and is\n     * auto-ticked + pruned by this Predict's {@link tick} — no separate drive.\n     *\n     * With `fields`, the store also owns the collection's **motion** (no\n     * separate `attachAll` needed): confirmed entities are dead-reckoned with\n     * the same `step` that advances pending locals, and `store.value(entry,\n     * field)` is one read path across the whole life of the entity. Foreign\n     * entities reckon to server-present; with `spawnTime`, owned ones reckon\n     * to server-present *plus the measured input lead*, so the authoritative\n     * entity continues the prediction's flight on the shooter's timeline —\n     * no snap-back at the handoff, and the rendered trajectory is the one a\n     * favor-the-shooter lag-comp hit test actually judges.\n     *\n     * The server element type `S` is inferred from `key`; the predicted-local\n     * shape defaults to `Partial<S>`, so `spawn()` is type-checked against the\n     * server fields with no annotations. To carry client-only fields, annotate\n     * a callback param (e.g. `step: (b: { x: number; speed: number }, dt) => …`)\n     * and `L` is inferred from it. An optional `data` factory gives each entry\n     * an auto-cleaned render-scratch slot (`entry.data: D`), inferred from its\n     * return.\n     *\n     * ```ts\n     * const rockets = predict.spawns(\"rockets\", {\n     *   owned:     r => r.owner === room.sessionId,      // r: Rocket\n     *   spawnTime: r => r.bornMs,                        // exact per-shot lead\n     *   step:      stepRocket,                           // shared client/server sim\n     *   fields:    [\"x\", \"z\"],                           // reckon confirmed entities\n     * });\n     * // on the predicted fire (live input step):\n     * rockets.spawn({ x, z, heading });\n     * // render — one path, handoff-invisible, keyed on the stable entry id:\n     * for (const e of rockets.entries()) {\n     *   draw(e.id, rockets.value(e, \"x\"), rockets.value(e, \"z\"));\n     * }\n     * ```\n     */\n    spawns<K extends CollectionKeys<TState>, L = Partial<ChildOf<TState[K]>>, D = undefined>(\n        key: K,\n        opts: SpawnsOptions<ChildOf<TState[K]>, L, D> = {},\n    ): PredictedSpawns<ChildOf<TState[K]>, L, D> {\n        type S = ChildOf<TState[K]>;\n        const store = new PredictedSpawns<S, L, D>(opts, this.clock ?? null);\n\n        // Reckon wiring (`fields` + `step`): every confirmed entity gets a\n        // regular reckon attach (group-labeled by the collection key, like\n        // attachAll) whose forward horizon is snapshot age plus the entry's\n        // measured input lead — 0 for foreign entities (server-present, same\n        // as an attachAll reckon), the exact per-spawn uplink for owned ones\n        // (see PredictedSpawnsOptions.spawnTime). An owned projectile thus\n        // keeps flying the shooter's timeline through the handoff — the view\n        // the server's lag-comp rewind judges.\n        const fields = opts.fields as readonly NumericKeys<S>[] | undefined;\n        const step = opts.step;\n        const group = fields !== undefined && step !== undefined\n            ? this.makeGroup(String(key), {\n                mode: \"reckon\",\n                fields,\n                step: step as unknown as (state: S, dt: number, elapsedMs: number) => void,\n                smoothMs: opts.smoothMs ?? 0,\n                substep: opts.substep,\n            } as ReckonAttachConfig<S>)\n            : undefined;\n        const untrack = group !== undefined ? new Map<S, () => void>() : undefined;\n        const clock = this.clock;\n\n        store.attach((onAdd, onRemove) => {\n            const addOff = this.callbacks.onAdd(key, (server: S, k: string | number) => {\n                onAdd(server, k);\n                if (group === undefined || untrack!.has(server)) return; // decoder re-fire\n                const lead = store.entryFor(server)?.leadMs ?? 0;\n                const forwardMs = clock\n                    ? () => {\n                        const stamp = clock.lastServerTime();\n                        const age = stamp > 0 ? Math.max(0, clock.serverNow() - stamp) : 0;\n                        return Math.max(0, age + lead);\n                    }\n                    : () => Math.max(0, lead);\n                untrack!.set(server, this.attachToGroup(server as object, this.planFor(group, server as object), forwardMs));\n            });\n            const removeOff = this.callbacks.onRemove(key, (server: S, k: string | number) => {\n                untrack?.get(server)?.();\n                untrack?.delete(server);\n                onRemove(server, k);\n            });\n            return () => {\n                addOff?.(); removeOff?.();\n                if (untrack !== undefined) {\n                    for (const off of untrack.values()) off();\n                    untrack.clear();\n                }\n            };\n        });\n        if (group !== undefined) {\n            // route store.value() confirmed reads through the reckon slots\n            store.bindReader((server, field) => this.value(server as object, field as never));\n        }\n        this.driven.push(store as { tick?(now: number): void; prune?(): void; dead?: boolean });\n        return store;\n    }\n\n    /**\n     * The canonical interpolation `delay` (the default profile's `delay`, from\n     * `Predict.get(room, { delay })` / {@link setDefaults}). Lag compensation's\n     * `renderDelay` is bound to this by {@link reconciler}/{@link sim} so the\n     * interp buffer the remotes render at and the server's rewind instant are\n     * derived from ONE number — they can't drift out of sync.\n     */\n    private canonicalDelay(): number {\n        return this.profileBuf[DEFAULTS_PROFILE * PROFILE_STRIDE + P_DELAY];\n    }\n\n    /**\n     * Bind lag-comp's `renderDelay` on the input handle to this Predict's lerp\n     * `delay` (the impl's `bindRenderDelay`) so the remote interp\n     * buffer and the server's rewind instant stay one value — no \"keep the two\n     * delays equal\" footgun. `instanceof`-narrowed (not cast), so a non-impl\n     * input (a test mock) is a no-op; an explicit `room.input({ renderDelay })`\n     * still wins inside `bindRenderDelay`.\n     */\n    private bindInputRenderDelay(input: InputHandle<any>): void {\n        if (input instanceof InputHandleImpl) {\n            input.bindRenderDelay(() => this.canonicalDelay());\n        }\n    }\n\n    /**\n     * Spawn a {@link Reconciler} for a locally-controlled entity — server-\n     * reconciled rollback (predict your inputs immediately, rewind to the server's\n     * authoritative state + replay unacked inputs, smoothly correcting\n     * mispredictions). The active counterpart to this Predict's passive modes: use\n     * `reconciler()` for the entity you control, lerp/reckon for the rest.\n     *\n     * A pure OBSERVER of `opts.input` (`room.input(...)`): you mutate + send through\n     * the handle (`input.data.x = …; input.send()`) and the reconciler steps each\n     * send + reads the server ack (`input.lastProcessed`) off it — the channel you\n     * send on is the channel that knows what's acked. `predict.tick(now)` returns\n     * how many fixed input steps are due this frame.\n     *\n     * Auto-ticked by this Predict's {@link tick} each frame (reconcile + smooth-\n     * correction decay) — no separate `tick()` call to forget.\n     *\n     * `opts.fields` defaults to every scalar field of `instance`'s schema — see\n     * {@link Reconciler} for the derivation and when to subset explicitly.\n     */\n    reconciler<S extends object, W>(\n        instance: S,\n        opts: Omit<ReconcilerOptions<S, Data<W>>, \"input\"> & { input: InputHandle<W> },\n    ): Reconciler<S, Data<W>> {\n        // `S` is inferred from `instance`; the wire input type `W` from\n        // `opts.input` (the SDK's `InputHandle<W>` — e.g. `room.input<MoveInput>()`).\n        // The command type is then `Data<W>` (the input's data fields), so neither\n        // type argument needs to be written at the call site, and `step`'s `cmd`\n        // is contextually typed.\n        // Inject this Predict's clock so ctx.reckonTime resolves its unstamped\n        // fallback (serverNow) inside the library; an explicit opts.clock wins.\n        const recon = new Reconciler<S, Data<W>>(instance, { ...opts, clock: opts.clock ?? this.clock });\n        this.adoptFixedStep(recon.stepMs);\n        this.bindInputRenderDelay(opts.input);\n        // One read idiom: predict.value(instance, field) reads THIS controller's\n        // pose while it's alive (raw fallback before spawn / after dispose).\n        this.installBoundOverlay(recon as unknown as BoundController);\n        this.driven.push(recon as { tick?(now: number): void; dead?: boolean });\n        return recon;\n    }\n\n    /**\n     * Spawn a {@link SimReconciler} for the entity (or entities) your inputs\n     * control — server-reconciled rollback (predict immediately, rewind to the\n     * server's authoritative state + replay unacked inputs, smoothly correcting\n     * mispredictions) — when their truth isn't a single flat scalar `fields` list:\n     * composite scalar state across several schema instances (a paddle + the puck\n     * it strikes, reconciled together), or an opaque physics-engine handle. Your\n     * `world` owns the state via `step` / `adopt` / `pose` callbacks; the controller\n     * runs the rollback loop and passes the world handle to each.\n     *\n     * Like {@link reconciler}, it OBSERVES `opts.input` (you mutate + send through\n     * the handle; `predict.tick(now)` returns the fixed-step count) and is\n     * auto-ticked by this Predict's {@link tick} each frame (reconcile + decay).\n     */\n    sim<W, P extends Record<string, number> = {}, E = any>(\n        opts: Omit<SimReconcilerOptions<Data<W>, P, E>, \"input\"> & { input: InputHandle<W> },\n    ): SimReconciler<Data<W>, P, E> {\n        // wire input `W` from `opts.input`, pose `P` from `opts.pose` ({} when the\n        // world is fully bound and no custom pose exists), world handle `E` from\n        // `opts.world` — none written at the call site, and `step`'s `cmd` is\n        // contextually typed `Data<W>`.\n        // Clock injection: same as reconciler() — resolves ctx.reckonTime's fallback.\n        const ctl = new SimReconciler<Data<W>, P, E>({\n            ...(opts as SimReconcilerOptions<Data<W>, P, E>),\n            clock: opts.clock ?? this.clock,\n        });\n        this.adoptFixedStep(ctl.stepMs);\n        this.bindInputRenderDelay(opts.input);\n        // One read idiom: bound world entries register into predict.value(instance,\n        // field) — the render layer stops caring which strategy backs an entity.\n        this.installBoundOverlay(ctl as unknown as BoundController);\n        this.driven.push(ctl as { tick?(now: number): void; dead?: boolean });\n        return ctl;\n    }\n\n    /**\n     * Adopt a spawned reconciler's fixed step as this Predict's room-wide pacing\n     * rate (the first one wins — the server has a single tick rate). Warns if a\n     * later reconciler advertises a different step, since one accumulator can't\n     * pace two rates.\n     */\n    private adoptFixedStep(stepMs: number): void {\n        if (this.fixedStepMs === undefined) {\n            this.fixedStepMs = stepMs;\n            // Start the count accumulator fresh with the reconciler just created:\n            // if this accumulator had been advancing since Predict.get, the first\n            // tick after spawn would emit a BURST of steps (all the time elapsed\n            // before there was anything to predict), which the app would send at\n            // once. (The render clock itself self-corrects any phase offset — see\n            // RollbackController.catchUp — so this is about the burst, not smoothness.)\n            this.stepAcc = 0;\n            this.lastFrameNow = -1;\n            return;\n        }\n        if (Math.abs(this.fixedStepMs - stepMs) > 1e-6) {\n            console.warn(\n                `@colyseus/sdk Predict: a reconciler's fixed step (${stepMs}ms) differs from ` +\n                `this Predict's (${this.fixedStepMs}ms). tick() paces one rate for the whole room; ` +\n                `use a separate Predict per rate.`,\n            );\n        }\n    }\n\n    // --- Reads -----------------------------------------------------------------\n\n    /**\n     * Smoothed/predicted RENDER value for a numeric field — the one read idiom:\n     * passively-smoothed entities (lerp/reckon/…) and instances bound by a\n     * live `reconciler()`/`sim()` controller all resolve here (the controller\n     * overlays the slot while it lives; dispose restores the passive slot or\n     * the raw fallback). Falls through to raw `instance[field]` if the field\n     * isn't being tracked — so the read is valid across the entity's whole\n     * lifecycle. For game logic on a controlled entity read the controller's\n     * `.state`/`.world` instead (exact, no smoothing offset).\n     */\n    value<T extends object>(instance: T, field: NumericKeys<T>): number {\n        // Hot read: refId (one symbol load) + two Map.gets (refId → field name →\n        // slot). No schema metadata, no name→index resolution. Dispatch is then\n        // a pure `(slotId) -> number` computer; the slot is self-describing via\n        // SLOT_REF / SLOT_FIELD so the instance/string never reach the computer.\n        const refId = refIdOf(instance);\n        const slotIdx = refId === undefined ? undefined : this.slotByRef.get(refId)?.get(field);\n        // `field: NumericKeys<T>` proves `instance[field]` is `number`.\n        if (slotIdx === undefined) return instance[field] as number;\n        const profileIdx = this.slotBuf[slotIdx * SLOT_STRIDE + SLOT_PROFILE] | 0;\n        return this.profileComputers[profileIdx](slotIdx);\n    }\n\n    /**\n     * RAW reckoned value at an ARBITRARY server-time instant `time`\n     * (server-clock ms) — the reckoned position WITHOUT the decaying\n     * smooth-correction offset that {@link value} adds for rendering.\n     *\n     * Use this for GAME LOGIC (collision / hit tests), and {@link value} for\n     * RENDERING. The offset exists only to hide snapshot-rebase pops on screen;\n     * feeding it into a hit test makes the client judge an overlap against a\n     * position a few cm off the physical prediction, which flips knife-edge\n     * stomp/hit calls vs the server (the server reads the exact timeline, no\n     * offset). Controller-bound fields' exact predicted state lives on the\n     * controller (`me.state` / `me.world`), not behind this read.\n     *\n     * For client-side collision/hit prediction, sample remote entities at the\n     * input's `ctx.reckonTime` (the instant the server rewinds to) so the client's\n     * hit call matches the server's lag-comp read BY CONSTRUCTION — on the live\n     * step AND deterministically on rollback replay (same `time` per seq). For\n     * logic reads at the present instant outside a step, pass\n     * `room.clock.serverNow()`.\n     *\n     * Perf: the render read's per-frame reckon is cached; `valueAt` re-runs the\n     * forward projection on EVERY call. Hot per-frame consumers should batch\n     * with {@link readAt} — one projection per instance instead of one per field.\n     *\n     * Reckons FORWARD from the latest server snapshot to `time`: integrates the\n     * tracked `step` from `lastServerTime()` to `time`, evaluating time-sampled\n     * formulas (sinusoids, cooldown snaps) at `time`. The SDK keeps no per-entity\n     * history, so `time ≤ lastServerTime()` CLAMPS to the snapshot (reckoning\n     * into the past is the server rewind buffer's job — a non-reckonable discrete\n     * motion you replay backward must be reconstructed from its own schedule). On\n     * the live step `time = reckonTime ≈ serverNow() > lastServerTime()`, so it's\n     * exact. Non-reckon / untracked fields ignore `time` and return {@link value}.\n     */\n    valueAt<T extends object>(instance: T, field: NumericKeys<T>, time: number): number {\n        const refId = refIdOf(instance);\n        const slotIdx = refId === undefined ? undefined : this.slotByRef.get(refId)?.get(field);\n        if (slotIdx === undefined) return instance[field] as number;\n        const i = slotIdx * SLOT_STRIDE;\n        const profileIdx = this.slotBuf[i + SLOT_PROFILE] | 0;\n        // Only reckon depends on the instant; lerp/damped/extrapolate/raw don't.\n        if (this.profileComputers[profileIdx] !== this.computeReckon) {\n            return this.profileComputers[profileIdx](slotIdx);\n        }\n        const sim = this.simByRef.get(this.slotBuf[i + SLOT_REF]);\n        if (sim !== undefined) {\n            const fieldId = this.slotBuf[i + SLOT_FIELD] | 0;\n            const pos = fieldId < sim.posOf.length ? sim.posOf[fieldId] : -1;\n            if (pos >= 0) {\n                // Forward from the latest snapshot to `time` (clamped ≥ 0), absolute\n                // end = `time`. Into `valueOut` so the per-frame render reckon\n                // (out/smoothed/offset) is untouched. Raw — no smooth offset.\n                const base = this.clock?.lastServerTime?.() ?? NaN;\n                const fwd = Number.isNaN(base) ? 0 : Math.max(0, time - base);\n                sim.advance(sim.instance, fwd, sim.valueOut, time);\n                return sim.valueOut[pos];\n            }\n        }\n        return this.slotBuf[i + SLOT_V1];\n    }\n\n    /**\n     * Batch {@link value} reads — the render value of each listed field written\n     * into one object. The `fields` YOU list define the result's shape\n     * (`Record<field, number>`). Pass `out` to fill (and return) a reused\n     * scratch instead of allocating — its properties beyond `fields` are left\n     * untouched, so a scratch can carry extra context (an `alive` flag, say).\n     * Mirrors the server's `seen.read` — the same batch-read concept on both\n     * sides of the wire.\n     *\n     * Hot-path guidance (per-frame loops): hoist `fields` as a module-level\n     * const and reuse the scratch — a fresh array or object literal per frame\n     * allocates. The batch resolves the instance's ref once for the whole\n     * group, then reads each field through the same computers as {@link value}.\n     */\n    read<T extends object, F extends NumericKeys<T>, O extends Record<F, number> = Record<F, number>>(\n        instance: T,\n        fields: readonly F[],\n        out?: O,\n    ): O {\n        const o = (out ?? {}) as Record<F, number>;\n        const refId = refIdOf(instance);\n        const fieldMap = refId === undefined ? undefined : this.slotByRef.get(refId);\n        for (let i = 0; i < fields.length; i++) {\n            const field = fields[i];\n            const slotIdx = fieldMap?.get(field);\n            o[field] = slotIdx === undefined\n                ? instance[field] as number   // untracked → live, as value()\n                : this.profileComputers[this.slotBuf[slotIdx * SLOT_STRIDE + SLOT_PROFILE] | 0](slotIdx);\n        }\n        return o as O;\n    }\n\n    /**\n     * Batch {@link valueAt} reads — every listed field sampled at the same\n     * server-time instant `time`, with {@link read}'s scratch contract.\n     *\n     * For client-side hit prediction, sample a remote's pose at the input's\n     * `ctx.reckonTime` in one call: the batch runs the forward reckon\n     * integration ONCE per instance instead of once per field, so a\n     * four-field pose read costs one `step` walk, not four. Non-reckon and\n     * untracked fields ignore `time`, exactly like {@link valueAt}.\n     */\n    readAt<T extends object, F extends NumericKeys<T>, O extends Record<F, number> = Record<F, number>>(\n        instance: T,\n        fields: readonly F[],\n        time: number,\n        out?: O,\n    ): O {\n        const o = (out ?? {}) as Record<F, number>;\n        const refId = refIdOf(instance);\n        const fieldMap = refId === undefined ? undefined : this.slotByRef.get(refId);\n        let sim: SimState | undefined;\n        let advanced = false;   // one advance per batch — the instance has one sim\n        for (let i = 0; i < fields.length; i++) {\n            const field = fields[i];\n            const slotIdx = fieldMap?.get(field);\n            if (slotIdx === undefined) { o[field] = instance[field] as number; continue; }\n            const s = slotIdx * SLOT_STRIDE;\n            const profileIdx = this.slotBuf[s + SLOT_PROFILE] | 0;\n            // Only reckon depends on the instant; other modes read as value().\n            if (this.profileComputers[profileIdx] !== this.computeReckon) {\n                o[field] = this.profileComputers[profileIdx](slotIdx);\n                continue;\n            }\n            if (!advanced) {\n                advanced = true;\n                sim = this.simByRef.get(this.slotBuf[s + SLOT_REF]);\n                if (sim !== undefined) {\n                    // Same window as valueAt: forward from the snapshot (clamped ≥ 0)\n                    // into `valueOut`, leaving the per-frame render reckon untouched.\n                    const base = this.clock?.lastServerTime?.() ?? NaN;\n                    const fwd = Number.isNaN(base) ? 0 : Math.max(0, time - base);\n                    sim.advance(sim.instance, fwd, sim.valueOut, time);\n                }\n            }\n            if (sim !== undefined) {\n                const fieldId = this.slotBuf[s + SLOT_FIELD] | 0;\n                const pos = fieldId < sim.posOf.length ? sim.posOf[fieldId] : -1;\n                if (pos >= 0) { o[field] = sim.valueOut[pos]; continue; }\n            }\n            o[field] = this.slotBuf[s + SLOT_V1];\n        }\n        return o as O;\n    }\n\n\n    /**\n     * Exponential smoothing toward the latest server value (`v1`). Reads\n     * `smoothMs` from the slot's profile.\n     */\n    private computeDamped = (slotIdx: number): number => {\n        const buf = this.slotBuf;\n        const i = slotIdx * SLOT_STRIDE;\n        const pBuf = this.profileBuf;\n        const pBase = (buf[i + SLOT_PROFILE] | 0) * PROFILE_STRIDE;\n        const now = this.renderTime;\n        const v1 = buf[i + SLOT_V1];\n\n        const lastT = buf[i + SLOT_AUX_T];\n        const dtFrame = now - lastT;\n        buf[i + SLOT_AUX_T] = now;\n        let damped = buf[i + SLOT_AUX_V];\n        if (dtFrame > 0) {\n            const tau = pBuf[pBase + P_SMOOTH_MS];\n            const k = tau > 0 ? 1 - Math.exp(-dtFrame / tau) : 1;   // 0 = snap\n            damped += (v1 - damped) * k;\n            buf[i + SLOT_AUX_V] = damped;\n        }\n        return damped;\n    };\n\n    /**\n     * Canonical entity interpolation:\n     *   1. Render at `target = now - delay` (delay sized so the snapshot\n     *      ring almost always brackets the target).\n     *   2. Find the latest pair (k, k+1) with ts(k) <= target.\n     *   3. Lerp between them. On underrun (target past newest snapshot) or\n     *      warmup (only one snapshot), hold at the newest sample — *don't*\n     *      extrapolate. Extrapolation here is what produced the \"flickery\"\n     *      feel; bracketing changes happen at predictable render-time\n     *      crossings, not at jittered packet arrivals.\n     *   4. Optionally chase the result with an output spring (`smoothMs`,\n     *      default 0 = off) — display-side velocity continuity for imperfect\n     *      snapshot streams; see {@link SmoothingOptions.smoothMs}.\n     */\n    private computeLerp = (slotIdx: number): number => {\n        const raw = this.computeLerpRaw(slotIdx);\n        const buf = this.slotBuf;\n        const i = slotIdx * SLOT_STRIDE;\n        const tau = this.profileBuf[(buf[i + SLOT_PROFILE] | 0) * PROFILE_STRIDE + P_LERP_SMOOTH_MS];\n        const now = this.renderTime;\n        if (tau <= 0) {\n            // Spring off (the default) — pin the state to the raw output so a\n            // runtime smoothMs enable starts from here instead of gliding in\n            // from wherever the spring last rested.\n            buf[i + SLOT_AUX_V] = raw;\n            buf[i + SLOT_LERP_PREV] = raw;\n            buf[i + SLOT_AUX_T] = now;\n            return raw;\n        }\n        const lastT = buf[i + SLOT_AUX_T];\n        const dt = now - lastT;\n        if (dt <= 0) return buf[i + SLOT_AUX_V];   // same-frame re-read\n        // Exact first-order-hold step for a linearly-varying target (τ = smoothMs):\n        //   y(dt) = u1 − s·τ + (y0 − u0 + s·τ)·e^(−dt/τ),  s = (u1 − u0)/dt\n        // Frame-rate independent: a steady mover renders with a constant s·τ\n        // trail at any fps (a per-frame EMA's trail varies with frame rate),\n        // which also lets a rewind-side reproduction match it in closed form.\n        const u0 = buf[i + SLOT_LERP_PREV];\n        const y0 = buf[i + SLOT_AUX_V];\n        const kdt = dt / tau;\n        const trail = (raw - u0) / kdt;\n        const y = raw - trail + (y0 - u0 + trail) * Math.exp(-kdt);\n        buf[i + SLOT_AUX_V] = y;\n        buf[i + SLOT_LERP_PREV] = raw;\n        buf[i + SLOT_AUX_T] = now;\n        return y;\n    };\n\n    /** Steps 1–3 of {@link computeLerp} — the undamped interpolant. */\n    private computeLerpRaw(slotIdx: number): number {\n        const buf = this.slotBuf;\n        const i = slotIdx * SLOT_STRIDE;\n        const pBuf = this.profileBuf;\n        const pBase = (buf[i + SLOT_PROFILE] | 0) * PROFILE_STRIDE;\n        const now = this.renderTime;\n\n        const count = buf[i + SLOT_RING_COUNT] | 0;\n        if (count === 0) return buf[i + SLOT_V1];\n        const head = buf[i + SLOT_RING_HEAD] | 0;\n        const ringBase = i + SLOT_RING_BASE;\n        const start = (head - count + RING_CAP) % RING_CAP;\n\n        const newestPhys = (start + count - 1) % RING_CAP;\n        const newestOff = ringBase + newestPhys * 2;\n        if (count === 1) return buf[newestOff + 1];\n\n        // Render at the SAME instant the server's lag-comp rewinds to — the input's\n        // renderTime = serverNow − renderDelay − rtt/2. On the server-time axis (clock\n        // present) that `− rtt/2` must be explicit; the arrival axis got it implicitly from\n        // transit. delay == renderDelay, so display == rewind → exact \"what you see is what\n        // you hit\", AND jitter-immune (off the jitter-free server-stamped sample times).\n        const delay = pBuf[pBase + P_DELAY];\n        const target = (this.clock && this.clock.lastServerTime() > 0)\n            ? this.clock.serverNow() - delay - this.clock.smoothedRtt() / 2\n            : now - delay;\n        const oldestOff = ringBase + start * 2;\n        if (target <= buf[oldestOff]) return buf[oldestOff + 1];\n        if (target >= buf[newestOff]) return buf[newestOff + 1];\n\n        // Walk backwards from second-newest. Typical k is `count - 2` ⇒ O(1).\n        let k = count - 2;\n        let phys = (start + k) % RING_CAP;\n        while (k > 0) {\n            const tk = buf[ringBase + phys * 2];\n            if (tk <= target) break;\n            k--;\n            phys = phys === 0 ? RING_CAP - 1 : phys - 1;\n        }\n        const aOff = ringBase + phys * 2;\n        const bPhys = phys + 1 >= RING_CAP ? 0 : phys + 1;\n        const bOff = ringBase + bPhys * 2;\n        const tA = buf[aOff], tB = buf[bOff];\n        const span = tB - tA;\n        if (span <= 0) return buf[bOff + 1];\n        const u = (target - tA) / span;\n        const vA = buf[aOff + 1], vB = buf[bOff + 1];\n        return vA + (vB - vA) * u;\n    }\n\n    /**\n     * Ring-driven forward projection with predict-then-smooth output EMA.\n     *   1. Anchor on the ring's newest snapshot.\n     *   2. Slope from a 2-step lookback in the ring (~2 tick intervals)\n     *      when available, else last-2 fallback.\n     *   3. raw = anchor + slope · clamp(now − anchor.t, 0, maxExtrapolate).\n     *   4. EMA-blend raw → smoothed using `smoothMs` (0 disables → return raw).\n     */\n    private computeExtrapolate = (slotIdx: number): number => {\n        const buf = this.slotBuf;\n        const i = slotIdx * SLOT_STRIDE;\n        const pBuf = this.profileBuf;\n        const pBase = (buf[i + SLOT_PROFILE] | 0) * PROFILE_STRIDE;\n        const now = this.renderTime;\n\n        const count = buf[i + SLOT_RING_COUNT] | 0;\n        if (count === 0) return buf[i + SLOT_V1];\n\n        const head = buf[i + SLOT_RING_HEAD] | 0;\n        const ringBase = i + SLOT_RING_BASE;\n        const start = (head - count + RING_CAP) % RING_CAP;\n        const newestPhys = (start + count - 1) % RING_CAP;\n        const newestOff = ringBase + newestPhys * 2;\n        const newestT = buf[newestOff];\n        const newestV = buf[newestOff + 1];\n\n        let raw: number;\n        if (count === 1) {\n            raw = newestV;\n        } else {\n            const steps = count >= 3 ? 2 : 1;\n            const lbPhys = (start + count - 1 - steps + RING_CAP) % RING_CAP;\n            const lbOff = ringBase + lbPhys * 2;\n            const lbT = buf[lbOff];\n            const lbV = buf[lbOff + 1];\n            const dt = newestT - lbT;\n            if (dt <= 0) {\n                raw = newestV;\n            } else {\n                const slope = (newestV - lbV) / dt;\n                const maxExt = pBuf[pBase + P_MAX_EXTRAPOLATE];\n                let ahead = now - newestT;\n                if (ahead < 0) ahead = 0;\n                else if (ahead > maxExt) ahead = maxExt;\n                raw = newestV + slope * ahead;\n            }\n        }\n\n        // Predict-then-smooth. Reuses SLOT_AUX_V / SLOT_AUX_T (damped is the\n        // other consumer; the two modes can't share a slot).\n        const lastT = buf[i + SLOT_AUX_T];\n        buf[i + SLOT_AUX_T] = now;\n        const tau = pBuf[pBase + P_SMOOTH_MS];\n        if (tau <= 0) {\n            buf[i + SLOT_AUX_V] = raw;\n            return raw;\n        }\n        const dtFrame = now - lastT;\n        let smoothed = buf[i + SLOT_AUX_V];\n        if (dtFrame > 0) {\n            const k = 1 - Math.exp(-dtFrame / tau);\n            smoothed += (raw - smoothed) * k;\n            buf[i + SLOT_AUX_V] = smoothed;\n        }\n        return smoothed;\n    };\n\n    /**\n     * Dead-reckoning dispatch. Recovers (refId, fieldId) from the slot, finds\n     * the `SimState` registered by `trackStepped`, and runs predict-then-smooth.\n     * If the slot's profile flipped to reckon at runtime but no SimState was\n     * ever allocated (e.g. attach was smoothing-only), falls back to the latest\n     * server value mirrored in SLOT_V1 — degraded but functional, no object\n     * access.\n     */\n    private computeReckon = (slotIdx: number): number => {\n        const buf = this.slotBuf;\n        const i = slotIdx * SLOT_STRIDE;\n        const refId = buf[i + SLOT_REF];\n        const fieldId = buf[i + SLOT_FIELD] | 0;\n        const sim = this.simByRef.get(refId);\n        if (sim !== undefined) {\n            // posOf maps fieldId → SoA position in one array index (no indexOf).\n            const pos = fieldId < sim.posOf.length ? sim.posOf[fieldId] : -1;\n            if (pos >= 0) return this.applySimulation(sim, pos);\n        }\n        return buf[i + SLOT_V1];\n    };\n\n    /**\n     * Raw dispatch — return the latest server value as-is, no smoothing/\n     * prediction. SLOT_V1 mirrors the latest sample on every update, so this\n     * needs no object access. The slot ring still receives samples from the\n     * listener (so a panel flip back to a smoothing mode works without\n     * re-attach), but they're unused while raw is active.\n     */\n    private computeRaw = (slotIdx: number): number => {\n        return this.slotBuf[slotIdx * SLOT_STRIDE + SLOT_V1];\n    };\n\n    /**\n     * Bound-overlay dispatch — the slot's value is a rollback controller's\n     * interpolated + smooth-corrected pose read (`ctrl.value(poseKey)`). Same\n     * dispatch class as reckon's `simByRef` read: one side-table lookup, then\n     * the controller read — which also runs the read-before-pump bookkeeping,\n     * so `predict.value(entity, f)` and `me.value(f)` warn identically.\n     */\n    private computeBound = (slotIdx: number): number => {\n        const e = this.boundBySlot.get(slotIdx);\n        return e !== undefined ? e.ctrl.value(e.key) : this.slotBuf[slotIdx * SLOT_STRIDE + SLOT_V1];\n    };\n\n\n    // --- Internal smoothing math -----------------------------------------------\n\n    /** `pos` indexes the SoA buffers (`sim.smoothed` / `sim.out`).\n     *\n     * Predict + OFFSET-DECAY smoothing (not an EMA chase): the display is\n     * `out + offset`. Between snapshots the forward sim is continuous, so the\n     * display moves at the target's full velocity — STEADY-STATE EXACT, no\n     * systematic lag on a moving entity (an EMA chasing a mover lags it by\n     * ~v × smoothMs forever — enough to flip knife-edge hit calls vs the\n     * server, which always reads the exact timeline). When a new SNAPSHOT\n     * rebases the sim and the trajectory jumps (a real misprediction), the\n     * discontinuity is captured into `offset` and decays out — the pop-hiding\n     * the smoothing exists for. Same construction as the Reconciler's\n     * error-decay for the local player.\n     *\n     * Without a clock (`lastBaseT` stays NaN — rebase undetectable), falls\n     * back to the EMA chase. */\n    private applySimulation(sim: SimState, pos: number): number {\n        const now = this.renderTime;\n        // Run `advance` once per render frame per instance, even if value() is\n        // called for several fields. All math is indexed Float64Array access —\n        // monomorphic, no per-frame allocation, no dynamic-key (megamorphic) hits.\n        if (sim.lastApplyTime !== now) {\n            const out = sim.out;\n            const sm = sim.smoothed;\n            const off = sim.offset;\n            const n = sm.length;\n            const baseT = this.clock?.lastServerTime?.() ?? NaN;\n            sim.advance(sim.instance, sim.forwardMs(), out, sim.elapsedMs());\n            const first = sim.lastApplyTime === -Infinity;\n            if (first || sim.smoothMs <= 0) {\n                for (let k = 0; k < n; k++) { off[k] = 0; sm[k] = out[k]; }\n            } else if (!Number.isNaN(baseT)) {\n                const dtMs = Math.max(0, Math.min(now - sim.lastApplyTime, 100));\n                if (baseT !== sim.lastBaseT && !Number.isNaN(sim.lastBaseT)) {\n                    // REBASE: a new snapshot re-seeded the forward sim. `out`\n                    // forwards by SNAPSHOT AGE, so across a clean patch it's\n                    // already continuous — it just advanced one frame of REAL\n                    // motion (≈ frameVel·dt). Subtract that expected motion so\n                    // ONLY a genuine snapshot correction lands in the offset;\n                    // without it every patch mis-reads v·dt of motion as a\n                    // discontinuity (a per-patch sawtooth, amplitude independent\n                    // of the decay rate). Past `snap` it's a teleport: pop.\n                    const snap = sim.snap;\n                    const vel = sim.frameVel;\n                    for (let k = 0; k < n; k++) {\n                        const d = sm[k] + vel[k] * dtMs - out[k];\n                        off[k] = (snap > 0 && Math.abs(d) > snap) ? 0 : d;\n                    }\n                } else if (dtMs > 0) {\n                    // Clean frame: record per-ms motion for the next rebase's\n                    // expected-motion term.\n                    const outPrev = sim.outPrev, vel = sim.frameVel;\n                    for (let k = 0; k < n; k++) vel[k] = (out[k] - outPrev[k]) / dtMs;\n                }\n                const decay = Math.exp(-dtMs / sim.smoothMs);\n                for (let k = 0; k < n; k++) { off[k] *= decay; sm[k] = out[k] + off[k]; }\n            } else {\n                // No clock → no rebase signal: legacy predict-then-smooth EMA.\n                const dtMs = Math.max(0, Math.min(now - sim.lastApplyTime, 100));\n                const kk = 1 - Math.exp(-dtMs / sim.smoothMs);\n                for (let k = 0; k < n; k++) sm[k] += (out[k] - sm[k]) * kk;\n            }\n            const outPrev = sim.outPrev;\n            for (let k = 0; k < n; k++) outPrev[k] = out[k];\n            sim.lastBaseT = baseT;\n            sim.lastApplyTime = now;\n        }\n        return sim.smoothed[pos];\n    }\n}\n"],"names":[],"mappings":"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"}