/** * When an sfx fires relative to the narration text. Structural mirror of * `SfxTiming` in @ai-rpg-engine/presentation — duplicated (three literals) * rather than imported so soundpack-core keeps zero dependencies. A drift * would be caught at the terminal-ui composition site by the type checker. */ export type SfxCueTiming = 'immediate' | 'with-text' | 'after-text'; /** Which tier of the map resolved a cue. */ export type CueMatchTier = 'exact' | 'namespace' | 'fallback'; /** * A gameplay cue resolved into the canonical soundpack vocabulary. * `{ effectId, timing, intensity }` is structurally assignable to * presentation's `SfxCue`, so a resolved cue can be placed directly into a * NarrationPlan's `sfx` array. */ export type ResolvedSfxCue = { /** Canonical soundpack entry id (a CORE_SOUND_PACK id by default). */ effectId: string; timing: SfxCueTiming; /** 0..1 — matches SfxCue.intensity bounds enforced by validateNarrationPlan. */ intensity: number; /** Which map tier matched — `fallback` means "unknown cue, degraded". */ via: CueMatchTier; }; type CueTarget = Omit; /** Exact-match tier: the cues modules and starters emit by literal id. */ export declare const EXACT_CUE_MAP: Readonly>; /** * Namespace tier: matched on the segment before the first `.` when no exact * entry exists. Covers open-ended families — every `ability.` cue a * content pack invents, every unlisted `scene.` stinger a starter * emits, and any future `gate.*` refusal besides `gate.refused`. */ export declare const NAMESPACE_CUE_MAP: Readonly>; /** Final tier: any cue from an unknown namespace degrades to a neutral chime. */ export declare const FALLBACK_CUE: Readonly; type BedTarget = { layerId: string; }; /** * Optional ambient-bed hints for scene.* gameplay cues (F-57203b5e). * Independent of {@link EXACT_CUE_MAP} / {@link NAMESPACE_CUE_MAP} so existing * SFX exact/namespace rows (e.g. scene.enter → ui_whoosh) stay unchanged. */ export declare const SCENE_BED_MAP: Readonly>; export declare const NAMESPACE_BED_MAP: Readonly>; /** * Optional ambient bed for a gameplay cue. Undefined when the cue has no bed * hint (combat.* / ability.* / unknown namespaces) — hosts then keep the * current mix. Does not emit an SFX cue. */ export declare function resolveAmbientBed(cue: string): { layerId: string; via: CueMatchTier; } | undefined; export declare function sceneBedTargetIds(): string[]; type MusicTarget = { trackId: string; }; /** * Optional music-stem hints for scene.* gameplay cues (F-768980bb). * Independent of SFX exact/namespace rows and of {@link SCENE_BED_MAP} so * hosts can pick a stem without changing ambient beds or one-shot cues. */ export declare const SCENE_MUSIC_MAP: Readonly>; export declare const NAMESPACE_MUSIC_MAP: Readonly>; /** * Optional music stem for a gameplay cue. Undefined when the cue has no music * hint (combat.* / ability.* / unknown namespaces). Does not emit an SFX cue * and does not change ambient beds. */ export declare function resolveMusicStem(cue: string): { trackId: string; via: CueMatchTier; } | undefined; export declare function sceneMusicTargetIds(): string[]; type StingTarget = { trackId: string; }; /** * Optional music-sting hints for combat.* gameplay cues (F-fa44e956). * Independent of {@link SCENE_MUSIC_MAP} / {@link resolveMusicStem}: a sting * is a one-shot overlay layered over whatever stem is already playing (play * it via `AudioDirector.scheduleSting`), never a stem replacement — so it * gets its own resolver rather than folding into resolveMusicStem's * loop-only vocabulary. Exact tier only; no namespace fallback (there is no * generic "combat.*" sting to fall back to). */ export declare const COMBAT_STING_MAP: Readonly>; /** * Optional music sting for a gameplay cue. Undefined when the cue has no * sting hint (everything except combat.victory/combat.defeat/combat.retreat * today). Does not emit an SFX cue and does not change ambient beds or the * active stem — unlike {@link resolveMusicStem}, a resolved sting is never * meant to replace what schedule() already has playing. */ export declare function resolveMusicSting(cue: string): { trackId: string; via: CueMatchTier; } | undefined; export declare function combatStingTargetIds(): string[]; /** * The exact-tier cue ids, for docs and totality tests. Namespace families are * open-ended by design and therefore not enumerable here. */ export declare const KNOWN_EVENT_SOUND_CUES: readonly string[]; /** * Resolve a gameplay cue to its canonical soundpack target. * * Total: every string input resolves (exact → namespace → fallback), so a * cue can never crash or silently vanish from the audio path. Pure and * deterministic: same input, same output, no state. * * @param cue A gameplay cue id (e.g. `combat.hit`, `ability.holy-smite`). */ export declare function resolveSoundCue(cue: string): ResolvedSfxCue; /** * Build a resolver with per-cue overrides layered over the built-in map — * how a game with a richer soundpack redirects cues to its own entry ids * without editing the canonical table. Overrides win on exact cue id only * (they are reported as `via: 'exact'`); unmatched cues fall through to * {@link resolveSoundCue}. * * @param overrides Exact cue id → replacement target. */ export declare function extendCueMap(overrides: Record): (cue: string) => ResolvedSfxCue; /** * Build a district-tone resolver with per-tone overrides layered over the * built-in {@link districtToneToSoundMood} table — how a richer pack * extends the 6-value DistrictMood vocabulary (e.g. volatile→chaos, * prosperous→festive) without editing the canonical map (F-798fc019). * `Object.hasOwn(overrides, tone)` wins and returns a fresh copy; * unmatched tones fall through to {@link districtToneToSoundMood}. * Pack-override coverage is the author's problem, same as * {@link extendCueMap} extraTargets via {@link cueMapCoverage}. * * @param overrides Exact tone → replacement mood array. */ export declare function extendDistrictToneMap(overrides: Record): (tone: string) => string[] | undefined; /** * Every soundpack id the built-in map can emit. Exposed so tests (and pack * authors swapping in their own manifest) can assert the map only points at * entries that exist — the property that makes the vocabulary actually * unified rather than a third disjoint space. */ export declare function cueMapTargetIds(): string[]; /** True when every id the cue map can emit exists in the given entry-id set. */ export declare function cueMapIsCoveredBy(entryIds: readonly string[]): boolean; /** Coverage report of cue-map targets (plus optional extendCueMap effectIds) vs a pack. */ export type CueMapCoverage = { covered: string[]; missing: string[]; extra: string[]; }; /** * Which cue-map targets a pack implements. `extraTargets` are additional * required ids (typically `extendCueMap` override `effectId`s) so an author * can see that `holy_smite_01` is referenced but absent from entries. */ export declare function cueMapCoverage(entryIds: readonly string[], extraTargets?: readonly string[]): CueMapCoverage; /** * Translate a district's computed `tone` into the sound-mood vocabulary for * `SoundQuery.mood` — pass the result to `SoundRegistry.pickMusicStem` / * `pickAmbientBed` (F-f8412999). Returns `undefined` for an unrecognized * tone: an explicit non-match, not a guess, so a caller knows to fall * through to today's fixed `resolveMusicStem('scene.enter')` / * `resolveAmbientBed('scene.enter')` result rather than querying with an * empty or wrong mood array. Returns a fresh copy each call — like * {@link resolveSoundCue}, mutating a result cannot poison the bridge table. * * `tone: string`, not a `DistrictMood['tone']` import from * @ai-rpg-engine/modules — soundpack-core stays dependency-free, the same * posture @ai-rpg-engine/presentation's builder.ts documents for itself. A * drift between the two vocabularies surfaces as a type error at the * composition site instead. * * Composing this with a registry query and an actual fallback is the * composition layer's job (not soundpack-core) — this pure helper only * answers "what mood does this tone mean", nothing about what to do when it * doesn't match. */ export declare function districtToneToSoundMood(tone: string): string[] | undefined; /** * Every sound-mood string {@link districtToneToSoundMood} can emit, deduped * and sorted — for the boot-time coverage invariant below and for coverage * tests. Mirrors {@link sceneBedTargetIds} / {@link sceneMusicTargetIds} / * {@link combatStingTargetIds}'s "everything this table can point at" shape, * except these values are `SoundEntry.mood` strings, not soundpack entry ids. */ export declare function districtToneMoodValues(): string[]; export {}; //# sourceMappingURL=cue-map.d.ts.map