3.5 KiB
| id | title | priority | status | scope | owner | updated_at | assigned_by |
|---|---|---|---|---|---|---|---|
| p1-34 | Unit metadata expansion — flavor, archetype, promotion_tree, clan_affinity fields | p1 | missing | game1 | shipwright | 2026-04-27 | shipwright |
Summary
The newly authored 50-unit dwarven military roster (p1-34 follow-on from the
T1–T10 design pass) currently mashes mechanical role text and lore one-liner
into a single description field. The schema is missing four high-value
metadata fields the rest of the system needs:
flavor— the lore one-liner, separate from the mechanical description. Already the convention in tech files (combined_arms,runelore, etc.); units inherit zero of that pattern.archetype— the explicit role categorization (light_melee / heavy_melee / anti_cavalry / ranged / siege / cavalry_walker / wild). Currently the React calculator and AI builders infer this fromunit_type+keywordsheuristics, which is fragile and breaks the moment a new keyword combination lands.promotion_tree— the link from unit to whichpromotions.jsontree applies (melee/ranged/siege/ null for wild). Without this, units can't actually use the promotion system that's already authored.clan_affinity— list of 1–3 AI clan IDs that favor building this unit (ironhold/goldvein/blackhammer/deepforge/runesmith). Drives clan personality differentiation; currently all five clans pick units off the same flat priority list.
This is a schema-and-data objective. Touches all 75 existing unit JSONs
(50 newly-authored dwarven + 25 original including wild creatures). React
calculator data loader (allUnits.ts) gets cleanup — drop the inference
logic, read fields directly.
Acceptance criteria
- All 75 unit JSON files in
public/games/age-of-dwarves/data/units/containflavor(string),archetype(enum),promotion_tree(enum or null),clan_affinity(string array) flavorfor each dwarven military unit pulled out ofdescription; remainingdescriptiontext is purely mechanical rolearchetypevalues are one of:light_melee,heavy_melee,anti_cavalry,ranged,siege,cavalry_walker,wildpromotion_treevalues are one of:melee,ranged,siege, ornull(wild creatures, support units)clan_affinityarrays reference only valid clan IDs fromdata/ai_personalities.jsonallUnits.tsVite glob loader normalises new fields intoUnittype; no inference fallback remainspnpm --prefix .project/designs/app run buildexits 0- No regression: existing units (warrior, berserker, etc.) keep their
current
descriptionsemantics; new fields are additive
Notes for the implementing agent
The expanded Unit type in .project/designs/app/src/data/units.ts
already declares domain as a union — extend the same way for archetype
and promotionTree. The wild creature units have no clan_affinity (use
empty array []).
Suggested clan_affinity defaults (drives AI distinctness):
- ironhold (industrial/defensive): heavy melee line, iron walls, defender, ironwarden, mountain_king
- blackhammer (warmonger): light melee line, berserker, hearth_raider, goretooth, doomsoul, war_ram
- goldvein (mercantile): cheap units, archer, quarrelman, light_field_gun, scouts
- deepforge (isolationist): siege + heavy mech, forge_titan, rail_cannon, adamantine_tank, ancestral_walker
- runesmith (balanced/scholarly): runic units, runesmith, rune_spear, marksman, soulbolt