Phase 18 — Audio (music director + SFX catalog + bus wiring)
Adds an AudioManager autoload with three buses (Master, Music routed to Master, SFX routed to Master), a small catalog of looping music + one-shot SFX, and a single persistent AudioStreamPlayer for the music director. Music * Day and night loops swap on Clock.phase_changed (night during the night phase, day everywhere else). Tracks pulled from Retro Farming Music 1 (day) and Cozy Melodies Pack 1 (night), both loopable OGG. SFX * Tree.fell, Rock.mined, BigRock.mined → tree_fell / mine_tick. * EventBus.pawn_took_damage → combat_hit (Sword Pack 1). * EventBus.storyteller_event_fired → ui_confirm sting. * EventBus.alert_added → ui_click. * play_sfx is rate-limited per key (80ms cooldown) so fast-sim doesn't saturate the mixer. Settings + suspend * SettingsMenu master/music/sfx sliders now live-bind to the bus dB via Audio.set_*_linear (linear → dB internally, 0 → -80dB silence). The ambient slider is intentionally unwired; no ambient bus this pass. * NOTIFICATION_APPLICATION_PAUSED + FOCUS_OUT mute the Master bus to match the existing "no background sim" rule. Resume + focus restore it. Bundle housekeeping * Two zipped packs in the ElvGames bundle (Cozy Melodies Pack 1, Retro Farming Music 1) extracted in place to keep pack identity intact for the license/credits string. 8 OGG files curated into audio/ at ~5.3MB. Verified end-to-end via MCP runtime: buses online, day_loop plays at boot, manual phase swap day→night→day round-trips, slider linear→dB mapping correct (0.5 → -6.02dB, 0.0 → -80dB), tree_fell SFX triggers. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fb07a3fa15
commit
d819c13a9d
25 changed files with 437 additions and 8 deletions
|
|
@ -147,6 +147,8 @@ func mined() -> void:
|
|||
get_parent().add_child(item)
|
||||
item.setup(Item.TYPE_STONE, 1, ft)
|
||||
Audit.log("big_rock", "mined 2×2 at %s; %d stone drops" % [origin_tile, STONE_DROPS_ON_MINE])
|
||||
if Audio != null:
|
||||
Audio.play_sfx(&"mine_tick")
|
||||
queue_free()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -122,6 +122,8 @@ func mined() -> void:
|
|||
get_parent().add_child(item)
|
||||
item.setup(Item.TYPE_STONE, 1, tile)
|
||||
Audit.log("rock", "mined at %s; %d stone drop" % [tile, STONE_DROPS_ON_MINE])
|
||||
if Audio != null:
|
||||
Audio.play_sfx(&"mine_tick")
|
||||
queue_free()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -117,6 +117,8 @@ func fell() -> void:
|
|||
item.setup(Item.TYPE_WOOD, STACK_SIZE_PER_DROP, drop_tile)
|
||||
drops_count += 1
|
||||
Audit.log("tree", "felled at %s; %d wood drops" % [tile, drops_count])
|
||||
if Audio != null:
|
||||
Audio.play_sfx(&"tree_fell")
|
||||
queue_free()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -206,6 +206,20 @@ func _load_from_game_state() -> void:
|
|||
_sl_sfx.value = float(s.get("audio_sfx", 1.0))
|
||||
_sl_ambient.value = float(s.get("audio_ambient", 1.0))
|
||||
|
||||
# Push initial slider values into the live audio buses + bind live updates.
|
||||
# Done here rather than _ready because _load_from_game_state fires after
|
||||
# GameState has restored settings from disk.
|
||||
if Audio != null:
|
||||
Audio.set_master_linear(_sl_master.value)
|
||||
Audio.set_music_linear(_sl_music.value)
|
||||
Audio.set_sfx_linear(_sl_sfx.value)
|
||||
if not _sl_master.value_changed.is_connected(Audio.set_master_linear):
|
||||
_sl_master.value_changed.connect(Audio.set_master_linear)
|
||||
_sl_music.value_changed.connect(Audio.set_music_linear)
|
||||
_sl_sfx.value_changed.connect(Audio.set_sfx_linear)
|
||||
# Ambient slider isn't wired to a bus yet (no ambient bus in Phase 18).
|
||||
# Phase 19 onboarding pass may add a third bus for nature SFX.
|
||||
|
||||
_cb_large_text.button_pressed = bool(s.get("accessibility_large_text", false))
|
||||
_cb_reduce_motion.button_pressed = bool(s.get("accessibility_reduce_motion", false))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue