Sound Effects — Audit & Phased Build-Out Plan
Sound Effects — Audit & Phased Build-Out Plan
Section titled “Sound Effects — Audit & Phased Build-Out Plan”Date: 2026-07-01 Status: Design — awaiting review Goal: Take audio from “one placeholder sound bolted onto every event” to a full, distinct, mixed soundscape (SFX + music) across weapons, enemies, bosses, player events, and UI — with a living document that always shows what’s implemented vs. still silent.
1. Context & current state
Section titled “1. Context & current state”Audio was added in a single commit (30e5ca7) that reused chess-defense’s SFX files as placeholders. A full codebase audit (2026-07-01) found:
- 11 of 17 shipped
.wavfiles are actually loaded; 6 are dead weight (attack,enemy_hit,special_aegis,special_freeze,special_rally,wave_clear— never referenced). - Every weapon fire event is silent. All 6 weapons (base + 7 evolutions) emit an
fx_eventskind (bolt/beam/slash/nova) or nothing at all (Orbit/Turret/Scatter emit no fx kind whatsoever, visual or audio), and none is mapped to a sound. - Every boss telegraph/attack that has any sound at all shares the exact same one (
special_barrage.wav) — Warden’s barrage/spiral, Boss2’s cutter/artillery/rings/charge/summon, FunZo’s dash/enrage, Graviton’s singularity, The Eye’s blink — all sonically identical, and identical to a routine mid-combat elemental reaction proc. - Two events double-sound (two unrelated sounds fire together in the same tick): weapon pickup (
pickup+ namedreaction) and the NUKE powerup (special_stomp+ trailing genericpickup). special_freeze.wavsits unused while the FREEZE powerup plays the genericui_tap.wavpickup sound instead.ui_nav()/ui_buy()are fully implemented but have zero call sites anywhere — no menu, panel, or shop in the game makes UI sound.- No audio bus layout — everything hardcoded to the Master bus, no SFX/Music/UI separation, no volume controls, no ducking.
- No music anywhere in the shipped game (a marketing trailer theme exists in
marketing/audio/but is not wired into the runtime). - No platform gating —
AudioManagerruns unconditionally on all platforms, relying on Godot’s dummy audio driver being a safe no-op headless/in CI. This has been fine because every sound to date is a short one-shot; untested for looping/long-duration audio (relevant once Phase 5 adds music).
Full call-site-by-call-site detail lives in audio/SOUND_MAP.md (§2 below) — this spec captures decisions and phasing, the map is the living inventory.
2. The living audit document — audio/SOUND_MAP.md
Section titled “2. The living audit document — audio/SOUND_MAP.md”A permanent, git-tracked markdown file, organized into sections that mirror the phase plan below (Weapons / Enemies / Bosses / Player / UI / Music / Mixing-Infra). Updated in place every time a sound is added or changed — this repo’s equivalent of the Design Bible being the source of truth for content, but for audio state.
Row schema per event:
| Column | Meaning |
|---|---|
| Event | The gameplay thing that should make sound (e.g. “Pulse fire”, “Charger dash release”) |
| Trigger | fx_events kind, or the discrete method/call site, with file:line |
| Sound file | Which .wav plays today, or — |
| Status | See vocabulary below |
| Sound type needed | Closed taxonomy, see below |
| Notes | Anything that affects sourcing/wiring (e.g. “evolution should layer, not replace”) |
Status vocabulary:
SILENT— no sound at allGENERIC— plays, but shares a sound with unrelated events (e.g. every boss telegraph today)MISWIRED— plays the wrong/mismatched sound while a better-fitting unused asset exists (e.g. FREEZE powerup)DOUBLE— two sounds fire for one eventDONE— distinct, correct sound
Sound type taxonomy (closed vocabulary, used consistently when sourcing from sample packs): impact · zap-cast · whoosh-cast · explosion · drone-ambient · telegraph-cue · ui-feedback · music-stinger · music-loop.
This document is populated now (as part of this spec’s delivery) from the full codebase audit, and gets a status update at the end of every phase below.
3. Phase plan
Section titled “3. Phase plan”Each phase is scoped as one self-contained bh-dev-chunk cycle (TDD → boot-check → determinism-reverify → commit → tvOS-sync), matching how every other content cycle in this project has shipped. Audio is render-side only (AudioManager extends Node, no /sim involvement), so determinism re-verification in every phase is expected to be a no-op confirmation, not a real risk.
-
Foundation & fixes — no new content, fixes what’s broken:
- Audio bus layout:
Master → {SFX, Music, UI}. - Fix the weapon-pickup and NUKE double-sounds (skip the generic
pickupemit when a named special-case already covers the same event). - Wire
special_freeze.wavto the FREEZE powerup. - Decide fate of the 6 dead
.wavfiles (repurpose or delete). - Add explicit platform-gate parity check (confirm the “dummy driver is safe” assumption still holds; no code change expected unless it doesn’t).
- Audio bus layout:
-
Weapon fire sounds — the single biggest silent gap. 6 base weapons get a distinct fire sound; 7 evolutions layer/intensify rather than replace (matching the existing “power grows, doesn’t replace” balance philosophy). Orbit/Turret/Scatter need a new
fx_eventskind added first (they currently emit none, audio or visual) — same shape as the cycle-10 “invisible entity” fix. -
Enemy & boss distinct sounds — universal enemy telegraph cues (dash charge/release, ranged-attack fire) currently 100% silent; each boss’s 3-5 attacks gets its own sound instead of sharing one. FunZo zone-creation/jester-spawn/confetti need a new
fx_eventskind first (same gap as Orbit/Turret/Scatter). -
UI sound — wire the already-built
ui_nav()/ui_buy()intostart_menu.gd/level_up_panel.gd/meta_shop_panel.gd/pause_menu.gd; add new hooks for any remaining gaps (panel open/close). -
Music — menu theme, survival loop, 4 story-region themes, boss stinger, victory/defeat. Largest asset-sourcing lift; done last since it’s independent of the SFX work. First place to explicitly verify looping-audio behavior on tvOS (see platform note above) rather than assume it.
Phase 1 gets its own implementation plan doc (docs/superpowers/plans/) next, per this project’s brainstorming → writing-plans flow. Phases 2-5 each get their own plan doc when their turn comes, scoped against whatever SOUND_MAP.md still shows as SILENT/GENERIC at that time.
4. Asset sourcing & platform notes
Section titled “4. Asset sourcing & platform notes”- Sourcing: licensed sample packs (Chris’s choice over AI-generation or keeping placeholders). Each
SOUND_MAP.mdrow’s “sound type needed” column makes picking from a pack a lookup, not a re-analysis. Specific pack/license selection happens per-phase, not in this spec. - Format: stay on
.wav(matches all 17 existing files, simplest for the currentAudioStreamPlayerpool). No format standardization forced if a pack only ships.ogg/.mp3— Godot imports either. - Platform: no new gating needed for SFX (existing no-gate approach holds). Music (Phase 5) is the one place to explicitly verify tvOS looping/long-duration behavior, since it’s the first time this class of audio exists in the game.
- Testing: extend
tests/test_audio_manager.gdper phase (e.g. “every weapon fire kind has aSOUND_FOR_FXentry”, “no fx kind double-fires two sounds”) — no new test framework needed.
5. Out of scope (for this spec)
Section titled “5. Out of scope (for this spec)”- Picking specific sample packs or license terms — a sourcing task inside each content phase, not a design decision.
- Spatial/3D audio (panning by world position) — not requested, current game has no stereo-relevant camera behavior that would benefit.
- A player-facing volume settings screen — mixing infra (Phase 1) adds the buses; exposing a UI slider is a separate, smaller follow-up if Chris wants one after playing with the bus levels.