Files
settled-reach/docs/sprints/sprint-13/client.md
T
jpmschweitzerandClaude Opus 4.6 03f70ada97 docs(sprints): add Sprint 13 "Sound" briefings — 9 tickets across server, client, audio, visual
Full audio architecture sprint: AudioManager completion, zone crossfade,
dip profiles, recognition chime, murmur pipeline. Server gauntlet expansion
and OQ-09 resolution. Visual monologue display spec unblocks copy pipeline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 16:49:39 +01:00

5.5 KiB

Sprint 13: Sound — Client Tasks

Goal: Wire the full audio architecture end-to-end — AudioManager, zone crossfades, dip profiles, recognition chime, and conversation murmur — and complete v0.1 content authoring so opening hooks, tutorial monologue, and all content packs are done.

Branch: client Agents: Stig (client dev), Tyre (architect), Hoshe (QA)

Carry-over from Sprint 12

None. All Sprint 12 client tickets done.

New Tickets

# Title Blocked by
#528 AudioManager full implementation — 5-bus setup, directory registry, volume sliders
#529 Zone crossfade implementation — 1.5-2s tween on zone_id change #528
#530 Audio dip profiles — dialogue, confrontation, ListeningFocus boost #528
#531 Recognition chime — fires at cognitive delay onset (D-067) #528
#533 Wire NPC conversation murmur to World SFX bus — event-driven playback #528, #532 (audio)

Use db/connectors/ticket show <id> for full details.

Key Decisions

  • decisions/architecture.md — D-068 (5-bus audio architecture), D-073 (zone crossfade approach)
  • decisions/perception.md — D-067 (recognition chime timing), D-069 (audio dip profiles), D-070 (confrontation as cognitive vulnerability), D-071 (ListeningFocus boost), D-072 (NPC conversation murmur)

Notes

  • #528 — AudioManager full implementation: client/scripts/autoloads/audio_manager.gd already exists and is substantially built. The 5-bus setup, directory-scan registry, play(), play_at(), apply_dip(), clear_dip(), and set_volume() methods are all implemented. What remains: (1) set_zone() is a stub (pass) — this becomes the zone crossfade implementation for #529; (2) volume slider persistence (save/load player preferences); (3) settings UI bindings for the 5 sliders; (4) ensure the Godot project's AudioServer bus layout matches the 5 bus names in code. Before starting, verify bus names in Project > Audio match BUS_MUSIC, BUS_AMBIENT, BUS_WORLD_SFX, BUS_PLAYER_ACTIONS, BUS_UI_SOUNDS.

  • #529 — Zone crossfade: Implement set_zone(zone_id: String) in audio_manager.gd. SimBridge already receives tile data from ObserverSnapshot — determine the player's current tile zone and call AudioManager.set_zone() on zone change. Crossfade logic: kill any active ambient tweens, start a 1.5-2s create_tween() that fades out the current _ambient_players entry and fades in the new zone asset. Zone-to-asset mapping for v0.1: hub/workplace → amb_hub_layer, bar → amb_bar_layer, smuggling corridor → amb_corridor_layer (names must match filenames in res://audio/). Crossfade is interruptible — walking back across a boundary starts the reverse tween.

  • #530 — Audio dip profiles: DIP_SPECS and apply_dip() / clear_dip() are already implemented in audio_manager.gd. What remains: wire call sites. Dialogue open/close → apply_dip("dialogue") / clear_dip(). Confrontation start/end → apply_dip("confrontation") / clear_dip(). ListeningFocus: the tick gate (30+ stationary ticks) is the caller's responsibility (per existing comment in audio_manager.gd); sim_bridge.gd or game_state.gd must track stationary_ticks from the server's ListeningFocus field in the snapshot and call apply_dip("listening_focus") / clear_dip() accordingly. D-070: no UI indicator — the muffling is felt, not announced.

  • #531 — Recognition chime: CHIME_RECOGNITION = "sfx_monologue_chime" is already defined in audio_manager.gd. Wire it: when fog_entities.gd or entity_renderer.gd begins a recognition sequence (detecting RecognitionTrigger in the snapshot), call AudioManager.play(AudioManager.CHIME_RECOGNITION) at the ONSET of the cognitive delay — not at completion. The chime routes to the UISounds bus automatically (default bus in play()). Full sequence per D-067: entity detected → chime plays (300-400ms) → 0.6s cognitive delay begins concurrently → monologue text appears during delay → blob transitions to D-033 color + silhouette → recognition complete. The chime is the "unresolved" signal — it precedes recognition, does not confirm it.

  • #533 — NPC murmur wiring: Blocked by #532 (audio team produces the asset). Once the murmur asset exists in res://audio/, wire event-driven playback: when SimBridge receives conversation/voice events from ObserverSnapshot, call AudioManager.play_at(asset_key, world_pos, BUS_WORLD_SFX) for proximity or AudioManager.play(asset_key, BUS_WORLD_SFX) for ambient murmur. Single universal asset — zone ambient provides natural conspicuousness (bar's amb_bar_layer buries it, corridor's low ambient exposes it). No zone-specific murmur variants.

Dependency Chain

#528 (AudioManager — complete set_zone + settings UI + slider persistence)
  → #529 (zone crossfade — implement set_zone body)
  → #530 (dip profiles — wire call sites in sim_bridge / game_state)
  → #531 (recognition chime — wire ONSET trigger in fog_entities / entity_renderer)
  → #533 (murmur wiring) ← also blocked by #532 (audio team asset)

#528 can start immediately. #529, #530, #531 can proceed in parallel once #528 is done. #533 waits for both #528 and #532.

PR Workflow

When ready to submit, create a PR with tea CLI. All flags are required to avoid TTY prompts (see CLAUDE.md "Gitea access" section):

tea pr create --repo jpmschweitzer/settled-reach --login schweitz --title "feat(audio): description" --description "body" --base main --head client