magicciv/.project/objectives/p2-16-audio-assets.md
Natalie 91ee619f25 feat(@projects/@magic-civilization): add hex terrain palette system
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-04-26 21:08:49 -07:00

6.1 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-04-27
public/games/age-of-dwarves/assets/audio/sources.csv — ledger skeleton with column docs (output_path / source_url / license / attribution / edits / added) and `#` comment lines for inline guidance. Header row in place; 0 data rows pending OSS sourcing.
tools/audio-licenses-render.py — renders LICENSES.md from sources.csv. Enforces: (a) -SA / -NC license modifiers rejected outright; (b) license string must match an allowlist (CC0-1.0, CC-BY-3.0, CC-BY-4.0, Pixabay, Sonniss-GDC-YYYY, Public-Domain); (c) CC-BY-* requires non-empty attribution; (d) source_url must be http(s); (e) duplicate output_path rejected. `--check` mode used by CI: re-renders to a buffer and diffs against committed LICENSES.md — hand-edits to LICENSES.md fail.
public/games/age-of-dwarves/assets/audio/LICENSES.md — regenerated from sources.csv (0 rows). The previous hand-curated `*(pending production)*` rows have been replaced by the auto-generated workflow doc + 'How to add a new asset' section.
scripts/run/test.sh — cmd_validate now runs audio-validate.py + audio-licenses-render.py --check after validate-game-data.py.
Policy spot-check (manual): seeded sources.csv with `CC-BY-SA-4.0` row → renderer correctly errored with `forbidden modifier '-SA' — ShareAlike and NonCommercial are blocked`. Restored.
audio.json shape already populated for the categorical keys (from p2-33). What this objective still owes: the actual ~57 .ogg files + their sources.csv rows. Asset curation requires manual OSS sourcing per .project/objectives/p2-16-audio-assets.md sources list.

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.