import type { CommandResult } from "../commands/commandRegistry.js"; import type { ModelAssetRef } from "../scene/assetCatalog.js"; import type { GameContext, GameContextContent, GameContextModels } from "./gameContext.js"; import type { GameDefinition, LoopPlayer } from "../game/defineGame.js"; import { type HostedGameRunner, type InputFrame } from "./hostedGameRunner.js"; import type { WorldDiff } from "./worldReplication.js"; import type { SnapshotViewer, WorldSnapshot } from "./worldSnapshot.js"; import type { HostedWorldRecord, HostedWorldStore, SyncHostedWorldStore } from "./hostedWorldStore.js"; export type { HostedWorldRecord, HostedWorldStore, SyncHostedWorldStore } from "./hostedWorldStore.js"; /** @internal Decode the retry envelope shared by authoritative hosts. */ export declare function unwrapOpEnvelope(input: unknown): { opId: string; input: unknown; } | null; /** Detached in-process {@link SyncHostedWorldStore} for tests, local play, and the browser-tab P2P host. * @internal */ export declare function memoryWorldStore(seed?: HostedWorldRecord): SyncHostedWorldStore; /** Async in-process store for callers exercising the production persistence contract. */ export declare function asyncMemoryWorldStore(seed?: HostedWorldRecord): HostedWorldStore; /** A client replication pull: a full baseline (first sync / fell behind) or a diff since the client's cursor. */ export type HostedWorldSync = { kind: "baseline"; revision: number; snapshot: WorldSnapshot; } | { kind: "diff"; diff: WorldDiff; }; /** Config for {@link createHostedWorldSession}: the game, its persistence store, and the auto-save cadence. */ export interface HostedWorldSessionOptions { definition: GameDefinition; content: GameContextContent; host?: LoopPlayer; now?: () => number; /** Where the authoritative snapshot persists; defaults to {@link memoryWorldStore}. */ store?: SyncHostedWorldStore; /** Minimum elapsed ms between automatic saves, measured against `now` (default `Date.now`). Default `0`; private clock/simulation changes also count. A pending write defers automatic capture until a later tick. */ saveIntervalMs?: number; /** Retained retry receipts per player. Default `64`; retries after eviction are new operations. */ operationHistoryLimit?: number; /** Render-model lookup for collider auto-fit, forwarded to the runner — see {@link HostedGameRunnerOptions.models}. */ models?: GameContextModels; } /** * The stateful host substrate a long-lived backend binds (ws server, browser P2P host): a live * {@link HostedGameRunner} loaded from a {@link HostedWorldStore}, auto-persisted on tick, serving each client a * baseline then diffs. The stateless Convex path doesn't use this — it reconstructs a runner from the same store * per invocation and diffs with `diffSnapshots`. Either way the store seam and the game code are identical. */ export interface HostedWorldSession { join(userId: string, isNew: boolean): void; /** Whether this identity has joined before, including across leave/restart. */ hasPlayer(userId: string): boolean; leave(userId: string): void; input(userId: string, frame: InputFrame): void; /** Optional stable operation id deduplicates retries across reconnect/restart; the receipt persists atomically with state. */ command(userId: string, name: string, input: unknown, operationId?: string): CommandResult; tick(dt: number): number; /** Replication pull: a fresh, pre-restart or future cursor receives a baseline; an in-session revision receives a diff. */ sync(sinceRevision: number | null): HostedWorldSync; /** Alias used by host transports when pulling the next baseline or diff for a subscriber. */ pull(sinceRevision: number | null): HostedWorldSync; /** The full world baseline projected for one viewer (private/AOI). Identity when no replication policy is set. */ snapshotFor(viewer: SnapshotViewer): WorldSnapshot; /** True when {@link snapshotFor} is viewer-dependent — a host must serve each connection its own projected frame instead of a shared diff. */ projectsViewers(): boolean; revision(): number; members(): readonly string[]; /** Force-persist the current world to the store. */ save(): void | Promise; /** Most recent automatic save failure; cleared by a successful write. Explicit `save()` also rejects. */ persistenceError(): unknown | null; runner(): HostedGameRunner; } /** Build a {@link HostedWorldSession} — a live runner loaded from a {@link HostedWorldStore} and auto-persisted on tick. * @internal */ export declare function createHostedWorldSession(options: HostedWorldSessionOptions): HostedWorldSession; /** Build a hosted session from an asynchronous persistence backend. */ export declare function createHostedWorldSessionAsync(options: Omit, "store"> & { store: HostedWorldStore; }): Promise;