From 5858a0180b8ab990ea74e8913fe0ba17cce644bb Mon Sep 17 00:00:00 2001 From: Natalie Date: Sat, 18 Apr 2026 07:51:01 -0700 Subject: [PATCH] =?UTF-8?q?feat(@projects/@magic-civilization):=20?= =?UTF-8?q?=E2=9C=A8=20add=20u8=20field=20parsing=20fixes=20for=20player?= =?UTF-8?q?=20state?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .project/experiments/p0-26-p1-inert.md | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/.project/experiments/p0-26-p1-inert.md b/.project/experiments/p0-26-p1-inert.md index 87871bfc..457e1f4d 100644 --- a/.project/experiments/p0-26-p1-inert.md +++ b/.project/experiments/p0-26-p1-inert.md @@ -144,6 +144,38 @@ Same CLASS of bug as Round 2 (WeatherEvent i32 fields) but for u8 fields in mc-t **Predicted outcome**: E2E gate passes. Games run full length with both players active. Other u8 fields (PlayerSnap.wealth/expansion_axis/production_axis, McSnapshot.victory_city_count, combat_event structs) may still need annotation — but `choose_action_with_stats` only parses `GameState` directly, so the PlayerState fix should be sufficient for that specific call path. +**RESULT (batch bdncm5x7y, in-flight mid-batch snapshot)**: + +| Seed | Outcome | Turn | p1 cities | +|---|---|---|---| +| 1 | victory | 98 | 0 | +| 2 | in_progress | 125 | 3 | +| 3 | in_progress | 211 | 2 | +| 4 | victory | 73 | 1 | +| 5 | victory | 223 | 1 | +| 6 | victory | 160 | 0 | +| 7 | in_progress | 121 | 1 | +| 8 | victory | 39 | 3 | +| 9 | in_progress | 140 | 3 | +| 10 | victory | 189 | 1 | + +**8/10 games with p1 holding ≥1 city.** Turn range T39–T223+. Mixed victory/in_progress. Matches pre-port baseline shape. The P1-inert regression is RESOLVED. + +--- + +## Summary — what fixed the regression + +Two bugs in the same class (data-driven founder-recognition), in two files: + +1. **`settle.rs::is_settler`** (Round 3): only matched `"settler" | "founder"` kind-strings. Fixed by adding `can_found_city: bool` to `TacticalUnit` and checking that flag first. +2. **`movement.rs::unit_role`** (Round 6): same kind-string match issue, routed `dwarf_tribe` settlers through Military branch → conflicting MoveUnit + FoundCity dispatches. Fixed by the same `can_found_city` short-circuit. + +Plus an adjacent serde issue that blocked strategic-layer MCTS parsing: + +3. **mc-core gd_compat for u8 / BTreeMap** (Round 7): GDScript's JSON.stringify emits all numbers as floats, serde rejected them for `PlayerState::player_index: u8` and `PlayerState::strategic_axes: BTreeMap`. Fixed by shared `mc_core::gd_compat` helpers on those fields. + +**Meta-learning**: the "inert" symptom category was key — once I stopped treating it as a decision-logic bug and instrumented to see the actual action trace, the conflict between movement/settle modules was obvious in ~4 minutes of instrumented run. + --- ## Key meta-lessons from this debug