import type { SoundEntry, SoundPackManifest, SoundQuery } from './types.js'; /** A structured, actionable warning surfaced by {@link SoundRegistry.load}. */ export type LoadWarning = { /** The offending location (e.g. an id or `entries[2].domain`). */ field: string; /** What is wrong and, where applicable, what to do about it. */ message: string; }; /** Options for {@link SoundRegistry.load}. */ export type LoadOptions = { /** * Run {@link validateManifest} and fold any schema errors into the returned * warnings. Off by default so the hot path stays cheap; turn it on when * loading untrusted/third-party packs. */ validate?: boolean; }; /** Result of {@link SoundRegistry.load}. */ export type LoadResult = { /** Number of entries written into the registry by this call. */ loaded: number; /** * Structured, actionable warnings (duplicate ids, optional schema errors). * Empty when the manifest loaded cleanly. Mirrors the * validateManifest/validateAbilityPack warning convention so consumers can * surface them in dev tooling instead of hitting silent overwrites. */ warnings: LoadWarning[]; }; /** Registry of sound entries from loaded packs. */ export declare class SoundRegistry { private entries; /** * Load a sound pack manifest into the registry. * * Returns a {@link LoadResult}. Per the engine's warn-and-degrade contract, * `load` does not throw on consumer mistakes: a duplicate id (within the * manifest or colliding with an already-loaded entry) is applied last-write * and reported as a warning naming the collision and the winning pack, and — * when `opts.validate` is set — schema errors from {@link validateManifest} * are folded in as warnings too. A malformed manifest (non-object, or * `entries` not an array) is the one case that throws, since there is nothing * to load and proceeding would crash on the `for…of` anyway. * * @param manifest The sound pack to load. * @param opts `{ validate }` to additionally run schema validation. */ load(manifest: SoundPackManifest, opts?: LoadOptions): LoadResult; /** Query entries by tags, domain, mood, or intensity. */ query(q: SoundQuery): SoundEntry[]; /** Get a specific entry by ID. Returned object is a clone (F-74ba230b). */ get(id: string): SoundEntry | undefined; /** * Pick a variant filename for an entry from a caller-supplied roll. * * Determinism: the engine bills itself reproducible, so variant selection must * not draw from a hidden RNG. The caller passes `roll` — a value in [0, 1] * (typically from the project's seeded dice/RNG) — and the variant index is * `floor(roll * length)`, clamped so `roll === 1` maps to the last variant * rather than overflowing. Same roll ⇒ same variant, every run. * * @param id The entry id. * @param roll Deterministic selector in [0, 1]. Out-of-range values are clamped. */ pickVariant(id: string, roll: number): string | undefined; /** * Pick an ambient bed from a query using a deterministic roll (F-57203b5e). * Forces `domain: 'ambient'` and keeps loop duration classes, then indexes * the id-sorted matches the same way {@link pickVariant} indexes variants. */ pickAmbientBed(query: SoundQuery, roll: number): SoundEntry | undefined; /** * Pick a music stem from a query using a deterministic roll (F-768980bb). * Forces `domain: 'music'` and keeps loop duration classes, then indexes * the id-sorted matches the same way {@link pickAmbientBed} indexes beds. */ pickMusicStem(query: SoundQuery, roll: number): SoundEntry | undefined; /** * Pick a music sting — a one-shot overlay (victory fanfare, defeat * stinger) meant to play OVER the current stem, never replace it * (F-fa44e956). Forces `domain: 'music'` and keeps only * `durationClass: 'oneshot'` entries — the inverse of * {@link pickMusicStem}'s loop-only filter — then indexes the id-sorted * matches the same way {@link pickMusicStem} indexes stems. Play the * result via `AudioDirector.scheduleSting`, not `scheduleMusic`/`musicCue`. */ pickMusicSting(query: SoundQuery, roll: number): SoundEntry | undefined; /** Get all loaded entry IDs. */ getIds(): string[]; /** Get total number of entries. */ get size(): number; } /** A start/stop pair for bringing active ambient layers in line with a desired set. */ export type AmbientLayerDiff = { start: string[]; stop: string[]; }; type AmbientLayerRef = { domain?: string; resourceId: string; }; /** * Diff desired ambient ids against currently active layers (F-57203b5e). * Accepts `AudioDirector.getActiveLayers()` (a Map), an iterable of ids, or * `{resourceId, domain}` records. Non-ambient map entries are ignored. */ export declare function diffAmbientLayers(desiredIds: readonly string[], activeLayers: Iterable | Map | readonly AmbientLayerRef[]): AmbientLayerDiff; /** * Deterministic roll in [0, 1) from a string id — FNV-1a 32-bit then / 2^32 * (F-cf6a6952). Copied locally so soundpack-core stays dependency-free * (do not import encounter-spawn). Behavior-neutral on a 1-match * {@link SoundRegistry.pickMusicStem} / {@link SoundRegistry.pickAmbientBed} * list; a richer pack with two stems in one mood family can pass * `hashRoll(zoneId)` as the roll so each zone stays stable but distinct. */ export declare function hashRoll(id: string): number; export {}; //# sourceMappingURL=registry.d.ts.map