/** * Per-turn audibility dispatcher (ADR-172 Phase 6). * * Closes the loop between `emitSound` (authoring API; Step 6.1) and the * `audibility` channel (Phase 5). For each `ISound` buffered during a * turn, the dispatcher walks every entity carrying `ListenerTrait`, * calls `propagate(sound, listenerId, world, timestamp)`, and emits one * `sound.audibility.heard` `ISemanticEvent` per (sound × listener) pair * that produced a non-null `IAudibilityEvent`. * * The dispatcher is pure: same buffer + same world state + same * timestamp → same event array. Listeners are processed in entity-id * sort order for deterministic event ordering across turns and runs. * * Owner context: `@sharpee/engine` — runtime / sound subsystem. * * Public interface: * - `class SoundDispatcher` — the dispatcher itself. * - `SoundDispatcher.dispatch(buffer, world, timestamp)` — produces * the `sound.audibility.heard` events for the turn. * * @see ADR-172 — Spatial Sound Propagation * @see ADR-163 — Channel-Service Platform (audibility channel) */ import { type ISemanticEvent } from '@sharpee/core'; import type { IAudibilityEvent, ISound } from '@sharpee/if-domain'; import { type WorldModel } from '@sharpee/world-model'; /** * Semantic-event type fired by the dispatcher when a listener perceives * a propagated sound. Mirrors `SOUND_EVENT_TYPES.AUDIBILITY_HEARD` in * `@sharpee/stdlib/channels/sound-events`. The constant is duplicated * here as a string literal so the engine package does not depend on * stdlib at compile time (engine → stdlib is the existing dependency * direction; the inverse would be a cycle). The string value is the * contract — both sides must agree. */ export declare const AUDIBILITY_HEARD_EVENT_TYPE = "sound.audibility.heard"; /** * Per-turn audibility dispatcher. * * The class shape (rather than a free function) leaves room for a * future propagate-injection point in tests and for caching listener * lookups across multi-action turns. For Phase 6 the dispatcher is a * thin wrapper around `propagate()`; the class structure is the * extension seam for L2's "NPC voice profile" layer. */ export declare class SoundDispatcher { /** * The propagation function the dispatcher uses. Defaulted to the * production `propagate` from `./propagation`; tests may inject a * fake to isolate dispatcher behavior from edge-graph + Dijkstra * complexity. */ private readonly propagate; constructor(propagateFn?: (sound: ISound, listenerId: string, world: WorldModel, timestamp: number) => IAudibilityEvent | null); /** * Dispatch every buffered sound to every listener. * * @param buffer The per-turn sound buffer; iterated in insertion * order. May be empty (quiet turn). * @param world The world model the propagation function reads * from. Must be the same instance the actions * mutated during the turn. * @param timestamp The turn-sequence integer the engine assigns to * this turn. Used as the `IAudibilityEvent.timestamp` * for ordering across multi-emission turns. * @returns Array of `sound.audibility.heard` events, one per * (sound × listener) where `propagate()` returned * non-null. Order: outer iteration over the buffer in * emission order, inner iteration over listeners * sorted by entity id ascending. */ dispatch(buffer: readonly ISound[], world: WorldModel, timestamp: number): ISemanticEvent[]; } //# sourceMappingURL=dispatcher.d.ts.map