# Audio Authoring

Blacksite provides a complete scene-to-runtime audio loop for Bevy-supported Ogg/Vorbis and Speex,
WAV, MP3, and FLAC clips. Audio assets live under `assets/audio/`; the Asset Browser assigns a
stable registry ID plus the runtime project path used by standalone games and packages.

## Authoring Workflow

- Drag an audio clip into empty viewport space to create an `AudioSource` actor at the snapped drop
  position. With an audio source selected, dropping another clip assigns it through one undoable
  command.
- The Audio Source Inspector controls clip, gain, pitch, loop, autoplay, 2D/spatial blend,
  attenuation distances/curve, and stable bus routing. **Audition** uses the editor camera as the
  spatial listener; **Stop** ends it immediately.
- Add an Audio Listener component from the Audio category when a scene needs an explicit listener.
  The highest-priority enabled listener wins; stable actor ID order is the deterministic fallback.
- Source/listener root icons and selected-only attenuation/listener gizmos can be hidden with the
  Audio option in Viewport options.

Audition entities are `EditorOnly`. They are stopped on PIE entry, scene replacement, source
deletion, natural clip completion, or explicit Stop. Audition does not mutate the source descriptor,
push history, or mark the active scene dirty. The preview owns a transient listener that follows the
editor camera without replacing camera components, and a failed clip load stops with an editor
status message instead of leaving a silent preview active.

## Buses

**Edit -> Project Settings -> Audio Buses** edits the project bus graph. `master`, `music`, and `sfx`
are required stable IDs; labels, gain, and mute state are editable. Custom buses receive stable IDs,
route through a parent, and may be removed while unused. Apply/Save is disabled while the graph has
duplicate IDs, missing parents, cycles, invalid gain, or missing required buses.

Runtime code can change user/session mixer state through `game::audio::AudioBusRuntime` without
rewriting project settings. Effective gain includes the complete parent route. A muted parent mutes
all descendants.

## Runtime And PIE

`game::audio::GameAudioPlugin` derives Bevy `AudioPlayer`, sink, and `SpatialListener` state from the
authored descriptors. A continuous spatial blend uses equal-power 2D and spatial voices between the
endpoints; selected attenuation is applied from the effective listener position. Spatial backend
coordinates are normalized inside the authored audible radius, so left/right panning does not add a
second distance falloff on top of the Inspector curve. F6 pauses/resumes existing PIE voices, while
stopping PIE clears derived voices so the next session starts from the authored autoplay state.

The runtime exposes `play_authored_audio_source`, `stop_authored_audio_source`, and
`reset_authored_audio_runtime` for gameplay/session control. `AudioRuntimeDiagnostics` reports the
active CPAL backend, default output device, and compiled codec set without making headless content
validation depend on an audio device.

## Validation And Sample

Interactive validation, `cargo validate-levels`, and packaging share checks for:

- missing, unsafe, excluded, unreadable, or Git LFS pointer clips;
- unresolved clip identities and unsupported codec extensions;
- invalid gain, pitch, spatial blend, attenuation, listener ear gap, or bus references;
- invalid project bus graphs and tied highest-priority enabled listeners.

`assets/levels/audio_authoring_showcase.scn.ron` and
`assets/audio/editor_audition_tone.ogg` provide a small deterministic source/listener fixture for
save/load, audition, PIE, headless validation, and package smoke tests.
