feat(audio): Sprint 13 — AudioManager, zone crossfade, dip profiles, murmur wiring (#528, #529, #530, #533)

AudioManager: volume slider persistence (ConfigFile), settings UI with
5 teal-bordered sliders, default_bus_layout.tres for editor. Zone
crossfade: defensive zone_id read from snapshot tiles, 1.5-2s ambient
tween, auto-activates when server ships OQ-09. Dip profiles: dialogue
dip in show/hide_dialogue, ListeningFocus 30-tick gate via
stationary_ticks in game_state.gd. NPC murmur: client plumbing for
event-driven World SFX playback, no-ops until audio asset arrives.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-19 18:19:25 +01:00
co-authored by Claude Opus 4.6
parent 61c452aca4
commit 0e6cc4eef8
10 changed files with 395 additions and 10 deletions
+8
View File
@@ -139,6 +139,10 @@ func show_dialogue(npc_name: String, speech: String, options: Array = []) -> voi
_is_showing = true
GameState.dialogue_active = true # D-064: block movement while dialogue visible/fading
# D-069: Dialogue dip — reduce ambient noise to foreground conversation.
# Confrontation options override this with apply_dip("confrontation") in _start_confrontation_beat().
AudioManager.apply_dip("dialogue")
# D-061: auto-pause in single-player when dialogue opens
SimBridge.send_input({"action": InputMapper.Action.PAUSE, "timestamp_msec": Time.get_ticks_msec()})
@@ -156,6 +160,10 @@ func hide_dialogue() -> void:
_is_showing = false
mouse_filter = Control.MOUSE_FILTER_IGNORE
# D-069: Clear dialogue/confrontation dip — restore bus volumes to player slider settings.
# Safe to call even if confrontation beat already cleared the dip (no-op when empty).
AudioManager.clear_dip()
# D-061: unpause when dialogue closes
SimBridge.send_input({"action": InputMapper.Action.UNPAUSE, "timestamp_msec": Time.get_ticks_msec()})