diff --git a/.project/objectives/p1-22a-huge-map-ai-quality.md b/.project/objectives/p1-22a-huge-map-ai-quality.md index aeedc3ca..1e79b0a5 100644 --- a/.project/objectives/p1-22a-huge-map-ai-quality.md +++ b/.project/objectives/p1-22a-huge-map-ai-quality.md @@ -119,7 +119,19 @@ improvement on top of that. - [ ] `ssh apricot '... bash tools/huge-map-5clan.sh'` with `TURN_LIMIT=500` produces `verdict.json` with `decisive_rate ≥ 5/10` and `pass: true`. - Batch `20260508_064601` in progress on apricot; check next wake. + **Batch `20260516_191254` (10 seeds, T=500, PARALLEL=10): 0/10 decisive — FAIL.** + Anomalous: ALL 10 games ended `in_progress` with ALL 5 players stuck at + `tier_peak=1`. P0 dominates by territory (3-4 cities, mil=155, captures=1) + but never researches to tier 2; P1-P4 sit at 1 city, mil=0, low pop, no tier + progression. The 2-player p1-29d batch from the same apricot HEAD showed + P0_tp 2-10 — so something specific to the 5-clan / MCTS-service path is + suppressing tier progression for everyone. Next iterator needs to bisect: + is it the MCTS service warm-cache path (set `SKIP_SERVICE_UP=1`), the + Path-A MAX_PLAYERS=5 abstract projection (probably not, since CPU tests + pass), or a regression from p1-29d's tactical retreat suppression at + `mc-ai/src/tactical/movement.rs:631-637` cascading into all-clan + defensive turtling? Evidence at + `.local/iter/20260516_191254/huge-map-5clan/`. - [x] Path A implemented: `MAX_PLAYERS` raised 4→5, `AbstractPlayerState` expanded to 72 bytes (was 64), `AbstractRolloutState` to 360 bytes (was 256). `force_rel[u16;5]`, `relations[i8;5]`, new padding fields `_pad_fr`/`_pad_rel`. diff --git a/src/simulator/crates/mc-ai/src/tactical/movement.rs b/src/simulator/crates/mc-ai/src/tactical/movement.rs index 4bd759fb..50423897 100644 --- a/src/simulator/crates/mc-ai/src/tactical/movement.rs +++ b/src/simulator/crates/mc-ai/src/tactical/movement.rs @@ -85,6 +85,14 @@ pub(crate) fn decide_movement( .filter(|u| is_military(u)) .count(); + // p1-29d / huge-map fix — the trailing AI gets sole-city-grace turtling, + // not anyone-at-1-city. Without this scope, every clan in the early game + // (when all start at 1 city) qualifies and the whole map turtles → no one + // researches → tier_peak=1 universal. Trailing := lowest total population + // among alive rivals AND at least one rival already has 2+ cities (so we + // are past the equal-start phase). + let is_trailing = compute_is_trailing(state, me); + let mut actions = Vec::with_capacity(me.units.len()); for unit in &me.units {