import type { EntityPosition, SceneEntity } from "../scene/entityStore.js"; import type { SnapshotViewer, WorldSnapshot } from "./worldSnapshot.js"; /** * Host-side interest/privacy policy — how the authoritative world projects to each viewer over the * wire. Unset (the default) means every client receives the whole world, exactly as before. Enabling a * field changes only what each client *sees*, never how the host simulates: the game plays identically. * The core replication modules read this to attach a {@link SnapshotModule.project} without the engine * growing a per-feature branch. */ export interface ReplicationPolicy { /** Decimal places used for replicated positions and angles. */ quantize?: { position?: number; angle?: number; }; /** * Replicate each player's private per-user state (inventory) only to that player — other viewers * receive none of it. Off by default so existing games keep broadcasting every player's state. */ privatePerUser?: boolean; /** * Area-of-interest radius in world units: an entity replicates to a viewer only when within this * distance of the viewer's own entity (the entity whose `id` equals the viewer's `userId`). A viewer * always receives its own entity. Omit for no distance culling — every entity to every viewer. */ aoiRadius?: number; } /** True when at least one field of the policy would change the wire payload. A no-op policy needs no projection. * @internal host projection plumbing — games set ReplicationPolicy; the runtime applies it. */ export declare function policyProjectsViewers(policy: ReplicationPolicy | undefined): boolean; /** Quantize replicated entity poses according to a host projection policy. * @internal host projection plumbing */ export declare function quantizeWorldForReplication(world: WorldSnapshot, policy: ReplicationPolicy | undefined): WorldSnapshot; /** * Cull an entity list to a viewer's area of interest: keep the viewer's own entity plus every entity * within `radius` of it. When the viewer has no locatable entity the full list is returned (fail-open — * a spectator or not-yet-spawned player still sees the world rather than an empty one). * @internal host projection plumbing */ export declare function projectEntitiesForViewer(entities: readonly SceneEntity[], viewer: SnapshotViewer, radius: number): readonly SceneEntity[]; /** The set of entity ids a viewer can see under an area-of-interest radius — the visibility set entity-keyed modules cull against. * @internal host projection plumbing */ export declare function visibleEntityIds(entities: readonly SceneEntity[], viewer: SnapshotViewer, radius: number): Set; /** Keep only the entries of an entity-id-keyed record whose id is in `visible` — the projection for entity stats under area-of-interest. * @internal host projection plumbing */ export declare function projectByVisibleIds(byId: Record, visible: Set): Record; /** Where a viewer is standing, read off the replicated entity set; `undefined` when it has no entity yet. * @internal host projection plumbing */ export declare function viewerOrigin(world: WorldSnapshot, viewer: SnapshotViewer): EntityPosition | undefined; /** * Cull placed objects to a viewer's area of interest. Placed objects are the one large spatial set a * world grows without bound — a datacenter of racks, a city of props — so without this every viewer * downloads every placement. Fails open (full list) when the viewer has no locatable entity, matching * {@link projectEntitiesForViewer}. * @internal host projection plumbing */ export declare function projectObjectsForViewer(objects: readonly T[], origin: EntityPosition | undefined, radius: number): readonly T[]; /** * Narrow a `userId → state` record to only the viewer's own entry — the projection for private * per-user state (inventory, wallets) so one client never receives another player's private data. * @internal host projection plumbing */ export declare function projectPerUserForViewer(byUser: Record, viewer: SnapshotViewer): Record;