chore(audio): add download script, audio credits, and sprint 21/22 docs
- docs/download_audio.py: freesound batch downloader with all 22 confirmed IDs (API key removed — fill in locally from freesound.org) - docs/credits-audio.md: generated CC-BY attribution table - docs/superpowers/plans+specs: sprint 15, 21, 22 implementation plan/spec docs - .claude/settings.json: enable experimental agent teams env var Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
# Sprint 21 — Interactive Object SFX Design Spec
|
||||
|
||||
## Goal
|
||||
|
||||
Add SFX to all 6 tappable interactive objects. Each object makes a sound when its animation starts — XRay scan, TeaPot pour, Cradle rock, GiftBox open, Ambulance drive-in, DeliveryBed mama arrival. UltrasoundMachine is excluded (continuous auto-loop, not tap-triggered).
|
||||
|
||||
## New SFX Events
|
||||
|
||||
7 new events added to `AudioManager._SFX_MAP`:
|
||||
|
||||
| Event key | Object | Trigger |
|
||||
|---|---|---|
|
||||
| `xray_scan` | XRayMachine | `_start_scan()` |
|
||||
| `tea_pour` | TeaPot | `_start_pouring()` |
|
||||
| `cradle_rock` | Cradle | `_start_rocking()` |
|
||||
| `gift_open` | GiftBox | `_start_opening()` |
|
||||
| `ambulance_siren` | Ambulance | `_drive_in()` |
|
||||
| `delivery_cheer` | DeliveryBed | mama arrives (`_start_mama_arriving()`) |
|
||||
| `object_tap` | Generic fallback | any tap on InteractiveObject base |
|
||||
|
||||
## Asset Specification
|
||||
|
||||
New files:
|
||||
|
||||
```
|
||||
assets/audio/sfx/xray_scan.ogg — electrical hum / machine beep
|
||||
assets/audio/sfx/tea_pour.ogg — liquid pouring
|
||||
assets/audio/sfx/cradle_rock.ogg — gentle creak / lullaby chime
|
||||
assets/audio/sfx/gift_open.ogg — unwrapping / pop
|
||||
assets/audio/sfx/ambulance_siren.ogg — short siren sting (<1.5s, child-friendly)
|
||||
assets/audio/sfx/delivery_cheer.ogg — happy chime / fanfare
|
||||
assets/audio/sfx/object_tap.ogg — soft tap / click
|
||||
```
|
||||
|
||||
All CC0 or CC-BY from freesound.org. Placeholder 0-byte files committed; real downloads documented in `docs/audio-assets-sprint19.md` (extend existing file).
|
||||
|
||||
## Integration Points
|
||||
|
||||
Each is a single `AudioManager.play_sfx("key")` call at the start of the action:
|
||||
|
||||
- `xray_machine.gd` → in `_start_scan()`, before tween
|
||||
- `tea_pot.gd` → in `_start_pouring()`, before tween
|
||||
- `cradle.gd` → in `_start_rocking()`, before tween
|
||||
- `gift_box.gd` → in `_start_opening()` (the method that starts the animation)
|
||||
- `ambulance.gd` → in the drive-in animation method, before tween
|
||||
- `delivery_bed.gd` → when mama starts arriving, before tween
|
||||
- `interactive_object.gd` → in the base tap handler if one exists (object_tap)
|
||||
|
||||
## Testing
|
||||
|
||||
Append to `test/unit/test_audio_manager.gd`:
|
||||
|
||||
- `test_sfx_map_has_all_interactive_object_keys` — verifies all 7 new keys exist in `_SFX_MAP`
|
||||
|
||||
No per-object unit tests for SFX wiring — the calls are single-line, and the AudioManager Dummy-driver guard makes headless tests safe.
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- UltrasoundMachine heartbeat sound (continuous loop, separate sprint)
|
||||
- Character reaction sounds (Häschen/Kätzchen — separate sprint)
|
||||
- Per-state-transition sounds (e.g., XRay completion sound)
|
||||
@@ -0,0 +1,70 @@
|
||||
# Sprint 22 — Character & Ambient SFX Design Spec
|
||||
|
||||
## Goal
|
||||
|
||||
Two deferred SFX items from Sprint 21:
|
||||
|
||||
1. **UltrasoundMachine ambient heartbeat** — continuous looping audio that starts when the player enters the ultrasound room and stops when they leave.
|
||||
2. **Character SFX** — pickup, place, and tap sounds wired into `character.gd`.
|
||||
|
||||
## New SFX Events
|
||||
|
||||
### AudioManager._SFX_MAP additions (3 new keys)
|
||||
|
||||
| Event key | Trigger |
|
||||
|---|---|
|
||||
| `character_pickup` | `Character._on_drag_picked_up()` |
|
||||
| `character_place` | `Character._on_drag_released()` — drag distance ≥ tap threshold |
|
||||
| `character_tap` | `Character._on_drag_released()` — drag distance < tap threshold |
|
||||
|
||||
### UltrasoundMachine (self-managed, not via _SFX_MAP)
|
||||
|
||||
The heartbeat is a looping ambient sound owned by the `UltrasoundMachine` node itself. It does not go through `AudioManager.play_sfx()` — that path is for one-shot SFX. Instead, `UltrasoundMachine` creates its own `AudioStreamPlayer` child, sets `stream.loop = true` at runtime, and starts/stops it in response to `RoomNavigator.room_changed`.
|
||||
|
||||
## Asset Specification
|
||||
|
||||
New files:
|
||||
|
||||
```
|
||||
assets/audio/sfx/ultrasound_heartbeat.ogg — soft beep/blip, ~1s, loops seamlessly
|
||||
assets/audio/sfx/character_pickup.ogg — happy soft squeak / whoosh
|
||||
assets/audio/sfx/character_place.ogg — gentle thud / landing
|
||||
assets/audio/sfx/character_tap.ogg — short happy chime / pop
|
||||
```
|
||||
|
||||
All CC0 or CC-BY from freesound.org. Placeholder 0-byte files committed; real downloads documented in `docs/audio-assets-sprint19.md` (extend existing file).
|
||||
|
||||
## Integration Points
|
||||
|
||||
### UltrasoundMachine (`scripts/objects/ultrasound_machine.gd`)
|
||||
|
||||
Full replacement. New behaviour:
|
||||
|
||||
- `@export var trigger_floor: int = 2` and `@export var trigger_room: int = 0` (matches ultrasound room position in `_ROOM_NAMES`)
|
||||
- In `_ready()`: create `AudioStreamPlayer` child, load stream with `loop = true`, connect to `RoomNavigator.room_changed`
|
||||
- In `_on_room_changed(floor_index, room_index)`: if matches trigger position → `_audio.play()`, else → `_audio.stop()`
|
||||
- `AudioServer.get_driver_name() == "Dummy"` guard wraps all audio operations
|
||||
- `_exit_tree()`: disconnect signal (mirrors Ambulance pattern)
|
||||
- Volume is inherited from the bus (no explicit volume set — ambient heartbeat is soft by design)
|
||||
|
||||
### Character (`scripts/characters/character.gd`)
|
||||
|
||||
Three one-liner additions:
|
||||
|
||||
- `_on_drag_picked_up()` → `AudioManager.play_sfx("character_pickup")` as first line
|
||||
- `_on_drag_released()` tap branch → `AudioManager.play_sfx("character_tap")` before `_handle_outfit_tap()`
|
||||
- `_on_drag_released()` place branch → `AudioManager.play_sfx("character_place")` before `character_placed.emit()`
|
||||
|
||||
## Testing
|
||||
|
||||
Append to `test/unit/test_audio_manager.gd`:
|
||||
|
||||
- `test_sfx_map_has_all_character_keys` — verifies `character_pickup`, `character_place`, `character_tap` exist in `_SFX_MAP`
|
||||
|
||||
No unit test for UltrasoundMachine audio start/stop — the trigger is room-navigation-driven and mirrors the Ambulance pattern (which also has no per-SFX unit test).
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- Per-state-transition character sounds (e.g., happy sound when healed — separate sprint)
|
||||
- Room-specific ambient audio for other rooms
|
||||
- UltrasoundMachine volume linked to `GameState.sfx_volume` (ambient bus handles this via AudioServer)
|
||||
Reference in New Issue
Block a user