/** How the simulation is stepped: a fixed rate with a catch-up cap, or once per frame with the frame's dt. */ export interface SimulationConfig { /** * Fixed simulation rate in steps per second, or `"variable"` to run one step per frame with the frame's * clamped dt. Default `"variable"` (the historical behavior). A fixed rate makes every step's dt identical, * which is what determinism, replay, rollback, and a stable physics solver need; renderers read * `ctx.sim.renderPose` to interpolate between steps. */ hz?: number | "variable"; /** Fixed steps run per advance before the loop drops the remaining time instead of spiralling. Default 5. */ maxCatchUpSteps?: number; /** Entities that move farther than this in one step snap instead of interpolating (teleports, respawns). Default 8 world units. */ snapDistance?: number; } /** Serializable loop position: the tick count and the real seconds accumulated toward the next fixed step. */ export interface SimLoopState { tick: number; accumulator: number; } /** What one {@link SimLoop.advance} did. */ export interface SimAdvanceResult { /** Steps run this advance. */ steps: number; /** Fraction of a step accumulated but not yet simulated, 0..1; always 1 on a variable loop. */ alpha: number; /** Tick count after this advance. */ tick: number; /** Steps discarded because the catch-up cap was hit. */ dropped: number; } /** The stepper handle: advance with real time, read the tick and interpolation alpha, retune the rate, snapshot and restore. */ export interface SimLoop { /** Feed real elapsed seconds; runs `step(dt, tick)` zero or more times and returns what happened. */ advance(realDt: number, step: (dt: number, tick: number) => void): SimAdvanceResult; tick(): number; alpha(): number; /** Seconds per fixed step, `null` on a variable loop. */ stepSeconds(): number | null; isFixed(): boolean; retune(config: SimulationConfig): void; config(): Readonly>; snapshot(): SimLoopState; restore(state: SimLoopState): void; } /** * The simulation stepper every driver (shell frame, headless runner, authoritative host) advances through, so * the sim sees the same dt sequence regardless of who drives it. Fixed mode accumulates real time and steps in * equal slices with a catch-up cap; variable mode steps once per advance. * * @capability sim-loop fixed-step or variable simulation stepping with tick count, catch-up cap, and interpolation alpha */ export declare function createSimLoop(initial?: SimulationConfig): SimLoop;