magicciv/.project/objectives/p2-16-audio-assets.md
Natalie 215b022dc0 feat(@projects/@magic-civilization): add gpu rollout performance tracking objectives
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-05-03 23:03:07 -04:00

10 KiB
Raw Blame History

id title priority status scope owner updated_at evidence
p2-16 Audio assets — in-theme OSS launch pack + source ledger p1 in_progress game1 asset-audio 2026-05-03
public/games/age-of-dwarves/assets/audio/sources.csv — 11 rows now (10 lighter UI/civic cues + city_grew). All CC0-1.0 from Kenney via Calinou's GitHub repackage.
public/games/age-of-dwarves/assets/audio/sfx/*.ogg — 11 actual .ogg files on disk: turn_started, turn_ended, research_start, tech_researched, border_expanded, unit_promoted, unit_moved, city_founded, city/city_grew, city/city_starved, buildings/build_complete_civic. All Ogg Vorbis 44.1 kHz / 128 kbps, loudnorm I=-16/TP=-3 normalised.
tools/audio-fetch-batch.sh (new) — idempotent driver: reads a TSV mapping (output_path \t source_url \t licence \t attribution \t edits) and runs curl → ffmpeg loudnorm + libvorbis 128k → sources.csv append → LICENSES.md re-render → audio-validate.py. Skips rows already shipped (file present + sources.csv row).
tools/audio-batch-01-kenney-interface.tsv (new) — first batch mapping. Source pages on github.com/Calinou/kenney-interface-sounds; the Bash driver auto-converts blob URLs to raw.githubusercontent.com.
tools/audio-licenses-render.py output: LICENSES.md regenerated, 11 rows, no policy violations. Allowlist gates working (CC0-1.0 accepted, would reject any -SA / -NC / off-list licences).
tools/audio-validate.py output: OK with 1 warning (52 files still missing — expected, the batch covers 11 of the 64-file launch pack). No orphans. Fallback chain valid. _silent sentinel intact.
Idempotency verified: re-running audio-fetch-batch.sh with the same TSV yields ok=0 / skip=10 / fail=0.
.project/audio-sourcing-checklist.md — 11 of 64 rows now closed; 53 remain. Next batches: kenney.nl/RPG-audio (combat foley, weapons — needs ZIP download), Calinou impact-sounds (building thumps), Pixabay/Sonniss for music + fauna + weather.

Summary

The audio capability shipped as p0-21AudioManager, manifest, signal wiring, volume sliders all work. The schema + categorical routing extension lands as p2-33 (this objective is blockedBy that). What's missing is the actual .ogg files plus the source ledger that proves their licenses are clean.

Per user directive 2026-04-17 the asset work was pulled out of the original p1-04 so capability and assets are tracked independently. A silent ship is shippable; a broken or licence-tainted audio system is not.

This objective ships the launch sound pack assembled from free / OSS sources (CC0, CC-BY 3.0/4.0, royalty-free commercial; no ShareAlike, no NonCommercial). Pack covers ~57 files spanning UI, turn cycle, units (categorical melee / ranged / siege / civilian), buildings (categorical civic / production / military / wonder), fauna (categorical predator / herbivore / apex), city events, research, weather, victory. ~50 SFX + 7 music tracks.

Acceptance

  • sources.csv ledger at public/games/age-of-dwarves/assets/audio/sources.csv listing every file's source URL, license string, attribution name, edits applied, and date added. Schema: output_path,source_url,license,attribution,edits,added.
  • License rule enforcedtools/audio-licenses-render.py generates LICENSES.md from sources.csv and rejects any license value containing -SA or -NC. The script is wired into ./run validate. Hand-edits to LICENSES.md fail CI (rendered diff non-zero).
  • ~50 SFX files shipped under public/games/age-of-dwarves/assets/audio/sfx/{ui,turn,units, buildings,combat,city,research,fauna,weather,victory}/. Coverage matches the categorical keys in audio.json (unit.melee.attack, building.production.complete, fauna.apex.roar, etc.). Multiple variants (*_01.ogg, *_02.ogg, *_03.ogg) for combat foley to drive streams[] randomisation.
  • 7 music tracks shipped under public/games/age-of-dwarves/assets/audio/music/: 5 era-linked ambient (T1-2 awakening, T3-4 craft, T5-6 kingdoms, T7-8 industry, T9-10 ascension) + golden-age track + victory theme.
  • Encoding spec — Ogg Vorbis 44.1 kHz / 128 kbps stereo (SFX may be mono). SFX peak ~3 dBFS; per-event volume_db scales from there. Music files are seamless loops (except victory).
  • Theme fit — every file curated against the dwarven / forge / dark stone hall aesthetic in .project/designs/UI_DESIGN_SYSTEM.md. Search keywords used: hammer, anvil, forge, mine, cavern, stone, torch, armor, gauntlet, drum, horn, chant.
  • audio.json populated — manifest carries the 50+ categorical entries (using the schema p2-33 lands), each pointing at the new files with sane volume_db and (where multiple takes exist) streams[] arrays + pitch_jitter.
  • tools/audio-validate.py clean — every manifest stream resolves to a real file ≥1 channel and ≥0.1 s duration; no orphan files under assets/audio/**.
  • Live audible smoke — manual capture: launch on plum, click through main_menu (UI clicks), found a city, end turn, fight a wild creature, research a tech. Every event audibly triggers and routes via the correct mixer bus. Smoke checklist saved at .project/screenshots/audio-smoke-2026-XX-XX.md with timestamps.

Sources to draw from (in priority order)

  1. Sonniss GameAudio GDC bundles — royalty-free commercial, no attribution. Multi-year archive.
  2. Pixabay Audio — Pixabay Content License, commercial OK, no attribution.
  3. Freesound.org — filter to CC0 + CC-BY 3.0/4.0 (skip CC-BY-SA, CC-BY-NC).
  4. OpenGameArt.org — filter to CC0 + CC-BY (skip CC-BY-SA, CC-BY-NC, GPL-audio).

Depends on / blocked by

  • p0-21 (Audio system capability) — done.
  • p2-33 (Sound system extension)blockedBy. The categorical manifest keys this pack uses don't validate until p2-33's schema ships. The dashboard ordering mechanism reflects this dependency.

Non-goals

  • Custom music composition (licensed ambient is fine).
  • Voice-over narration (post-EA).
  • 3D / positional audio (Game 2).
  • Per-instance personality variants ("this specific dwarf has a deeper voice") — categorical is enough for EA.
  • User mod-pack user://overrides/audio.json — hook reserved in p2-33 notes; code path deferred.

2026-05-03 verification

Audio asset tree relocated from public/games/age-of-dwarves/assets/audio/ (per evidence frontmatter) to public/resources/audio/ per the post-p1-40 data architecture (single source of truth at public/resources/<category>/). Ground truth as of today:

  • public/resources/audio/sources.csv — 137 lines (was 11 on 2026-04-27).
  • public/resources/audio/{sfx,music}/**/*.ogg106 real .ogg files on disk (was 11). Per .project/audio-status.md "Tally" the curated launch-pack target of 65 / 65 is met; remaining files are variant takes
    • music tracks above the minimum.
  • public/resources/audio/LICENSES.md regenerated; allowlist gate intact (no -SA / -NC).
  • public/games/age-of-dwarves/data/audio/ — manifest dir present; audio-status.md reports 49 SFX + 8 music entries wired through audio.schema.json (streams[], pitch_jitter, fallback, _silent).
  • tools/audio-fetch-batch.sh, tools/audio-licenses-render.py, tools/audio-validate.py — all shipped per status doc.
  • GUT test_audio_manager.gd — 13/13 pass headless on apricot.

Remaining gap to close p2-16: the live in-game audible smoke test on plum/apricot (.project/screenshots/audio-smoke-2026-XX-XX.md). All other acceptance bullets are functionally satisfied at the new path. Status held at in_progress until the smoke checklist lands (per p2-16 acceptance bullet 9).

Remaining work (2026-05-03)

One acceptance bullet remains substantively un-met. The other ✗ bullets in the original Acceptance list are functionally satisfied per the 2026-05-03 verification block (asset tree relocated to public/resources/audio/, 106 .ogg files, manifest wired, validator/license tools clean) — they should flip to ✓ as part of the audit pass that closes this objective.

1. Live audible smoke checklist

  • Bullet: Live audible smoke — manual capture: launch on plum, click through main_menu (UI clicks), found a city, end turn, fight a wild creature, research a tech. Every event audibly triggers and routes via the correct mixer bus. Smoke checklist saved at .project/screenshots/audio-smoke-2026-XX-XX.md with timestamps.
  • Files to touch:
    • new: .project/screenshots/audio-smoke-2026-05-03.md (or whatever date the smoke is captured) — checklist with one row per event (UI click, found city, end turn, combat, tech researched), columns: timestamp · expected stream key · heard? · mixer bus · notes
    • capture host: plum (per acceptance bullet wording — needs an actual audio device, not a headless host)
    • reference: src/game/engine/src/audio/audio_manager.gd for stream-key → bus mapping
  • Dependencies: p2-33 (categorical schema) per blockedBy frontmatter — must be live in audio.json for the categorical events (unit.melee.attack, building.production.complete, fauna.apex.roar) to fire. Verify p2-33 status before scheduling smoke.
  • Acceptance gate: checklist file present, every row marked heard, mixer bus correct. Optional but encouraged: short screen-recording capture under .project/screenshots/audio-smoke-2026-05-03.mp4 linked from the checklist (audio in the recording is the durable proof; markdown alone is unverifiable).
  • SOLID/DRY/SSoT: smoke checklist references stream keys from the live audio.json manifest (single source of truth at public/games/age-of-dwarves/data/audio/audio.json); do NOT inline the expected stream paths in the checklist. If a stream key is missing from the manifest, that is a manifest bug — fix the manifest, do not work around it in the checklist. Sources ledger and license render remain the single source of truth (public/resources/audio/sources.csvLICENSES.md); never hand-edit the rendered file.

2. Acceptance-list audit (housekeeping)

  • All ✗ bullets except "Live audible smoke" are functionally satisfied per the verification block. Re-audit each against the relocated public/resources/audio/ tree and flip to ✓ in a single pass when the smoke lands. Do NOT flip any ✗ to ✓ ahead of the smoke — Rail-objective-integrity requires cited evidence per bullet.