import { type PositionedPrompt, type PromptPoint } from "./proximityPrompt.js"; /** * A partial edit applied to an already-registered {@link PositionedPrompt} by * {@link PromptRegistry.update}. Any subset of the mutable fields — everything * but the stable `id` — may be supplied; omitted fields keep their prior value. */ export type PositionedPromptPatch = Partial>; /** * The serializable shape {@link PromptRegistry.snapshot} returns and * {@link PromptRegistry.restore} consumes: the full set of positioned prompts * (in registration order) plus the id of the prompt that was active when the * snapshot was taken. Prompt display/command payloads are free strings and ids — * keep them serializable and this round-trips through a save cleanly. */ export interface PromptRegistrySnapshot { /** Every registered prompt, in registration order (tie-break order for resolve). */ prompts: readonly PositionedPrompt[]; /** Id of the active prompt at snapshot time, or `null` if none was active. */ activeId: string | null; } /** * A live, observable set of interaction prompts that OWNS the registered * {@link PositionedPrompt}s and tracks which one is active for a player. It is a * thin stateful layer over {@link resolveActivePrompt}: registration/order lives * here, the nearest-within-radius / higher-priority selection stays in the pure * resolver. {@link resolve} is the per-frame hot path — call it as the player * moves; subscribers fire only when the active prompt actually CHANGES. */ export interface PromptRegistry { /** * Add (or replace, by id) a positioned prompt. Replacing an existing id keeps * its registration slot so tie-break order is stable. Changed active content * notifies immediately; selection is recalculated by the next {@link resolve}. */ register(prompt: PositionedPrompt): void; /** * Patch a registered prompt in place. No-op if `id` is unknown. Only the fields * present in `patch` change; the rest are preserved. Changed active content * notifies immediately without recalculating selection. */ update(id: string, patch: PositionedPromptPatch): void; /** Remove the prompt with this id, if present. Returns whether one was removed. */ unregister(id: string): boolean; /** Remove every prompt and clear the active selection. */ clear(): void; /** All registered prompts in registration order (do not mutate the returned array). */ all(): readonly PositionedPrompt[]; /** * Resolve the active prompt for a player at `playerPosition` by delegating to * {@link resolveActivePrompt}, cache its id, and notify subscribers only when * the active prompt changed since the last call — so a HUD bound to this * registry re-renders on transitions, not every frame. Returns the active * prompt or `null`. */ resolve(playerPosition: PromptPoint): PositionedPrompt | null; /** The prompt selected by the most recent {@link resolve}, or `null`. */ active(): PositionedPrompt | null; /** Observe active-prompt content changes, selection transitions, clear and restore. Returns an unsubscribe fn. */ subscribe(listener: () => void): () => void; /** Serializable state for a save. */ snapshot(): PromptRegistrySnapshot; /** Restore prompts + active id from a {@link PromptRegistrySnapshot}. */ restore(snapshot: PromptRegistrySnapshot): void; } /** * Create a live, observable interaction-prompt registry over the pure * {@link resolveActivePrompt} resolver. Register positioned "press E" prompts, * `resolve(playerPosition)` each frame as the hero moves, and read `active()` — * the nearest strictly-in-range prompt (higher `priority` beats closer). The set * is owned here (register/update/unregister/clear/all); selection stays pure. * Subscribers are notified only when the active prompt *changes*, so a HUD does * not thrash per frame, and `snapshot`/`restore` round-trip the prompts plus the * active id through a save (display payloads are free strings/ids the game owns — * the registry never branches on their meaning). Allocation-aware: `all()` and * `resolve()` reuse a cached array instead of rebuilding per call. * * @capability interaction-prompt observable nearest-interactable prompt registry over the proximity-prompt resolver — register/resolve/active with priority+range and change-notified snapshot/restore */ export declare function createPromptRegistry(): PromptRegistry;