feat(@projects/@magic-civilization): update ai unit selection status to partial

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Natalie 2026-04-18 17:46:17 -07:00
parent ec6387c2c7
commit fd6d915236

View file

@ -2,7 +2,7 @@
id: p0-39
title: AI tier-progression unit selection — production.rs picks tier-2+ units once tech unlocks
priority: p0
status: stub
status: partial
scope: game1
owner: warcouncil
updated_at: 2026-04-18
@ -32,11 +32,12 @@ Shipwright audit 2026-04-18 of tech_web.json + research costs (requested by warc
## Acceptance
- ✗ **Unit-spec catalog accessible to production.rs.** Confirm `TacticalState` (at `src/simulator/crates/mc-ai/src/tactical/state.rs`) exposes `researched_techs` + either a unit-spec lookup or the tier/required_tech fields for each unit. If not, plumb via the existing JSON marshaler.
- ✗ **`production.rs::decide_production` selects tier-N+ units when their `required_tech` is researched.** Tier-N replaces tier-(N-1) for equivalent role (pikeman > warrior for melee line; cavalry > pikeman; ironwarden > cavalry). Preserves existing wealth / production / aggression / dominance axis biases.
- ✗ **Regression test lands.** `tactical::production::tests::tier_2_unit_selected_when_tech_researched` constructs a TacticalState with `bronze_working` in `researched_techs`, calls `decide_production()`, asserts `pikeman` in the candidate set (and the priority ladder picks it over `warrior` for the melee slot).
- ✗ **Apricot 10-seed T300 smoke shows median `peak_unit_tier ≥ 2`** across seeds. Stretch target `≥ 3` (would imply `steelworking` chains researched + cavalry units built; depends on tech ordering and gold budgets).
- ✗ **p0-01 peak-unit-tier bullet** — if the batch hits the p0-01 threshold ("≥1 player reached peak unit tier ≥ 6 in ≥7/10 games"), re-promote that bullet with citation. If not, update p0-01 prose with the lifted-ceiling evidence and note the remaining gap (likely needs p0-24 difficulty + better tech/production coordination).
- ✓ **Unit-spec catalog accessible to production.rs** (Approach 1 — data-driven, per Shipwright recommendation). `TacticalUnitSpec` struct (`src/simulator/crates/mc-ai/src/tactical/state.rs:126-141`) carries `id`, `tier`, `tech_required: Option<String>`, `unit_type`. `TacticalState::unit_catalog: Vec<TacticalUnitSpec>` added with `#[serde(default)]` for back-compat.
- ✓ **`production.rs::decide_production` selects tier-N+ units when `tech_required` is researched.** New helper `pick_best_melee(researched_techs, catalog)` filters by `unit_type == "military"`, excludes ranged specialists (`archer`/`ranger`/`flying`), keeps unlocked units, returns highest-tier. 4 melee-slot branches (`Posture::Threatened`, early-mil-floor, steady-mil, offensive push) now use the helper result instead of hardcoded `ids::WARRIOR`. Existing wealth/production/aggression/dominance axis biases preserved.
- ✓ **Regression test lands.** `tactical::production::tests::tier_2_unit_selected_when_tech_researched` (plus 5 `pick_best_melee_*` unit tests covering empty catalog, tier-1 fallback, tier climb, non-military exclusion, ranged exclusion). All 236/236 mc-ai tests green (was 230, +6 new).
- ✓ **Bridge emits catalog.** `ai_turn_bridge.gd::_build_unit_catalog()` reads `DataLoader.get_data("units")` and emits `{id, tier, tech_required, unit_type}` per unit on every `_build_mc_tree_state` call.
- ✗ **Apricot 10-seed T300 smoke shows median `peak_unit_tier ≥ 2`** across seeds. Smoke launched 2026-04-18; evidence pending.
- ✗ **p0-01 peak-unit-tier bullet** — pending batch results.
## Fix direction (non-prescriptive — warcouncil picks)