feat(tools): Add validation rules for game data and introduce defeat audio assets in batch 12

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
autocommit 2026-04-29 13:13:23 -07:00
parent f08d12c9d7
commit 0cdb3d36ec
2 changed files with 38 additions and 6 deletions

View file

@ -0,0 +1,18 @@
# Batch 12 — Per-victory-condition defeat music pool.
#
# Mirror of victory_pool: when an AI wins by a particular victory type,
# the human player hears a defeat track keyed to *how* they lost. Falls
# back to the generic `defeat` track for unmapped types or eliminations
# that don't carry a victory_type (last-unit-destroyed without a winner).
#
# Track choices (Junkala, all CC0):
# defeated by domination → Action1 (ominous, witches encounter)
# defeated by culture → Calm3 (peaceful but lost — others outshone you)
# defeated by science → Exploration5 (sneaking — left behind)
# defeated by economic → Calm4 (sand castles — transient ambition)
# defeated by score → reuse existing `defeat` track (Calm6 - Innocence)
audio/music/defeat_domination.ogg https://opengameart.org/sites/default/files/JRPG%20Music%20Pack%20%235%20%5BAction%5D%20by%20Juhani%20Junkala.zip#Action1 - Encounter With The Witches.ogg CC0-1.0 Juhani Junkala (SubspaceAudio, OpenGameArt) loudnorm I=-16/TP=-3+ogg 128kbps
audio/music/defeat_culture.ogg https://opengameart.org/sites/default/files/JRPG%20Music%20Pack%20%234%20%5BCalm%5D%20by%20Juhani%20Junkala_0.zip#Calm3 - Peaceful Days.ogg CC0-1.0 Juhani Junkala (SubspaceAudio, OpenGameArt) loudnorm I=-16/TP=-3+ogg 128kbps
audio/music/defeat_science.ogg https://opengameart.org/sites/default/files/JRPG%20Music%20Pack%20%231%20%5BExploration%5D%20by%20Juhani%20Junkala.zip#Exploration5 - Sneaking Around.ogg CC0-1.0 Juhani Junkala (SubspaceAudio, OpenGameArt) loudnorm I=-16/TP=-3+ogg 128kbps
audio/music/defeat_economic.ogg https://opengameart.org/sites/default/files/JRPG%20Music%20Pack%20%234%20%5BCalm%5D%20by%20Juhani%20Junkala_0.zip#Calm4 - Sand Castles.ogg CC0-1.0 Juhani Junkala (SubspaceAudio, OpenGameArt) loudnorm I=-16/TP=-3+ogg 128kbps
Can't render this file because it has a wrong number of fields in line 15.

View file

@ -118,7 +118,8 @@ class GameDataValidator:
if schema is None:
return
files = sorted(f for f in dir_path.glob("*.json")
if not f.name.endswith(".schema.json") and f.name != "manifest.json")
if not f.name.endswith(".schema.json")
and f.name not in ("manifest.json", "building_categories.json"))
if not files:
print(f" (no files in {dir_path.relative_to(self.root)})")
return
@ -191,7 +192,7 @@ class GameDataValidator:
"""Collect all 'id' values from every JSON entry in a split directory."""
ids: set[str] = set()
for f in dir_path.glob("*.json"):
if f.name in ("manifest.json",) or f.name.endswith(".schema.json"):
if f.name in ("manifest.json", "building_categories.json") or f.name.endswith(".schema.json"):
continue
for _label, entry in self._collect_entries_from_file(f):
if "id" in entry:
@ -348,8 +349,14 @@ class GameDataValidator:
if resources is None:
return
unit_ids = self._load_id_set_from_split_dir(self.game_data / "units")
building_ids = self._load_id_set_from_split_dir(self.game_data / "buildings")
unit_ids = (
self._load_id_set_from_split_dir(self.resources / "units")
| self._load_id_set_from_split_dir(self.game_data / "units")
)
building_ids = (
self._load_id_set_from_split_dir(self.resources / "buildings")
| self._load_id_set_from_split_dir(self.game_data / "buildings")
)
print("\n cross-reference checks")
@ -391,8 +398,15 @@ class GameDataValidator:
print("── Age of Dwarves game data validation ──")
self.validate_split_dir("units", self.game_data / "units", "unit")
self.validate_split_dir("buildings", self.game_data / "buildings", "building")
# Single source of truth at resources/<category>/ post-p1-40 migration; the
# game_data fallback paths remain for the transitional period and as a hook
# for genuinely game-specific entities a game pack might author later.
self.validate_split_dir("units", self.resources / "units", "unit")
self.validate_split_dir("buildings", self.resources / "buildings", "building")
if (self.game_data / "units").exists():
self.validate_split_dir("units (game-specific)", self.game_data / "units", "unit")
if (self.game_data / "buildings").exists():
self.validate_split_dir("buildings (game-specific)", self.game_data / "buildings", "building")
self.validate_split_dir("techs", self.game_data / "techs", "tech")
self.validate_split_dir("terrain", self.game_data / "terrain", "terrain")
self.validate_single_file(