feat(@projects/@magic-civilization): update last-stand defense objective status

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Natalie 2026-05-13 11:47:53 -07:00
parent 71430c47ab
commit e9df99befb
7 changed files with 107 additions and 6 deletions

View file

@ -6,10 +6,9 @@ status: partial
scope: game1
tags: [balance, combat, pacing]
owner: combat-dev
updated_at: 2026-05-07
updated_at: 2026-05-13
evidence:
- "cycle-45 batch autoplay_batch_p1_29a (2026-05-07): 10/10 seeds, 9/10 victories, median game 118 turns, p1_tp=1 ALL games, alive-aware gate FAIL, game-length gate PASS"
evidence:
- "src/simulator/crates/mc-combat/src/resolver.rs:588-592 (last_stand_defense_multiplier applied to defender_strength)"
- "src/simulator/crates/mc-turn/src/processor.rs:1711-1727 (resolve_single_pvp_attack wires at_last_city + cities_lost)"
- "src/simulator/crates/mc-turn/src/processor.rs:2151-2167 (bench process_pvp_combat wires fields)"
@ -20,6 +19,17 @@ evidence:
- "src/simulator/api-gdext/src/lib.rs:3784-3786 (bridge surface)"
- "src/game/engine/src/modules/combat/combat_resolver.gd:382-389 (live-engine wiring)"
---
## Blocker (2026-05-13)
Bullets 5 (alive-aware `tier_peak_gap ≤4`) and 7 (compose-isolation 3-batch) remain `❌` and are **structurally blocked**, not tuning-blocked. The combat-side mechanic (bullets 14) is durably landed and all Rust tests are green (`cargo test -p mc-combat -p mc-ai --tests`, 2026-05-13).
Dependency chain for the two open bullets:
1. **p1-29b-tier-gap-ai-quality** — closed cycle-50 (2026-05-07). 9/10 seeds now pass `tier_peak_gap ≤ 4`, but **p1 still stuck at `tier_peak = 1` in all 10 games**. The gap metric was tightened by clamping p0's runaway, not by lifting p1.
2. **p1-29c-sole-city-research-path** (recommended by p1-29b close-out, not yet filed) — required to actually lift the trailing AI to `tier_peak ≥ 2`. Until that lands, bullet 5's "p0_tp ≥ 2 AND p1_tp ≥ 2 in ≥7/10 seeds" cannot be reached, and bullet 7's compose-isolation has no signal to attribute.
Status stays `partial`: K=5, N=7 (per `.claude/instructions/objective-integrity.md` counting rule). Closing requires p1-29c to land first, then re-running `autoplay_batch_p1_29a` on apricot.
## Summary
Filed by p1-29 cycle 5 close-out as the combat-side intervention that should close p1-29's `tier_peak_gap ≤4` gate. Three consecutive cycles of research-side levers (catch-up tech-pick mult, catch-up tech-output mult, loss-tolerance lever) landed durably but failed to move the gate across three batches. The failure is structural: p1 (the losing AI) loses cities faster than research output can unlock era-2+ techs. Research-side levers multiply a tiny base into a tiny base. The gate is a **territory problem**, not a research problem.
@ -80,6 +90,8 @@ Remaining ❌ (cycle-44+, gameplay-outcome gates):
**Cycle-45 diagnosis**: The alive-aware gate failure is structural, not a tuning issue. Both the last-stand multiplier (combat side) and the catch-up science multiplier (research side) are now in place; the 10-seed batch with both enabled still shows p1_tp=1. The fix requires either: (a) seeding p1 with era-2 buildings/units earlier, or (b) adjusting the AI difficulty to reduce p0's overwhelming early advantage. Filed as follow-up needed: `p1-29b-tier-gap-ai-quality` (similar to `p1-22a-huge-map-ai-quality`).
**Cycle-50 update (2026-05-07)**: `p1-29b-tier-gap-ai-quality` closed `done` — 9/10 seeds now satisfy raw `tier_peak_gap ≤ 4`, but **p1 still stuck at `tier_peak = 1` in all 10 seeds**. The gap metric was clamped by capping p0's runaway, not by lifting p1. p1-29a's bullet 5 (alive-aware filter requires `p0_tp ≥ 2 AND p1_tp ≥ 2`) therefore still fails. Filed `p1-29c-sole-city-research-path` (2026-05-13) as the structural dependency for bullet 5 + 7. p1-29a remains `partial` until p1-29c lands and `autoplay_batch_p1_29a` is re-run.
(Original cycle-5 remaining-work analysis preserved below for context.)
### Bullet: Combat-strength multiplier on last-stand defense

View file

@ -0,0 +1,58 @@
---
id: p1-29c
title: "Sole-city research path — lift trailing AI from tier_peak=1 to ≥2"
priority: p1
status: stub
scope: game1
owner: game-ai
tags: [ai, balance, tech]
updated_at: 2026-05-13
evidence: []
---
## Summary
Filed by p1-29b cycle-50 close-out (2026-05-07) and re-confirmed by p1-29a cycle-45 diagnosis (2026-05-07). p1-29b clamped p0's runaway (9/10 seeds now satisfy `tier_peak_gap ≤ 4`) but **p1 remains stuck at `tier_peak = 1` in every game**. The gap metric was tightened by capping the leader, not by lifting the trailing sole-city AI.
This objective is the missing structural fix for p1-29a's bullet 5 (alive-aware `tier_peak_gap ≤ 4`, requiring `p0_tp ≥ 2 AND p1_tp ≥ 2`) and bullet 7 (compose-isolation 3-batch, which has no signal to attribute while p1_tp=1 in 100% of seeds).
## Root Cause (carried forward from p1-29b diagnosis)
Cycle-48's three fix sites (evaluator `tech_weight_mult=2.5`, rollout `tech_coeff=0.25`, tactical production `sole_city_threatened` flag) shifted the MCTS/rollout signal toward research for sole-city players, but did not produce a *concrete actionable research path*:
- The sole-city AI never founds a second city (no second-city action priority).
- The sole-city AI's gold/production base is too narrow to actually queue era-2 buildings before being overrun by the last-stand-extended combat window.
- The personality priors (`policy.rs`) still sample `Research` at the base personality rate — no situational uplift for "tech is the only escape hatch".
## Acceptance criteria
- [ ] **Sole-city tier-2 reach in 10-seed batch**: ≥ 7/10 alive-aware seeds (both `p0_tp ≥ 2 AND p1_tp ≥ 2`) in `autoplay_batch_p1_29c`. This is the same gate p1-29a's bullet 5 requires — closing this objective closes that gate.
- [ ] **Tactical action priority — "found second city when sole-city and threatened"**: when `city_count == 1 && threat_level > 0.4 && available_founder_action`, raise founder-action prior. Requires verifying `mc-ai::policy` and tactical action enumeration.
- [ ] **Research priority bonus when below median tier**: when `state.tech_index < median(opponents.tech_index)`, multiply `Research` action prior by ≥ 1.5×. Implement in `mc-ai::policy::PersonalityPriors::action_prior`.
- [ ] **Mc-ai unit tests** cover: sole-city threatened → founder prior raised; below-median tier → research prior raised; neither condition → no change.
- [ ] **Compose with p1-29 catch-up science + p1-29a last-stand**: existing multipliers stay in place; this is an action-priority fix, not a yield-multiplier fix. Multiplicative composition unchanged.
## Verification
```
ssh apricot 'cd ~/Code/project-buildspace/magic-civilization && \
AUTOPLAY_HOST=apricot SEEDS=10 TURN_LIMIT=300 \
bash tools/autoplay-batch.sh 10 300 .local/batches/autoplay_batch_p1_29c'
```
Analyzer: alive-aware `tier_peak_gap ≤ 4` (≥ 7/10) AND median game length ≤ 384.
## Non-goals
- Changing combat multipliers — owned by p1-29a.
- Changing the tier_peak metric — owned by p1-29b.
- Adding new personality axes — this is calibration of existing action priors.
## Notes
- Filed 2026-05-13 to unblock p1-29a's remaining acceptance bullets.
- Owner default `game-ai`; reassign if a team-lead claims it.

View file

@ -509,3 +509,34 @@ is fixed — that belongs to a separate harness/turn_processor objective
not to `p1-38`. The Phase A coupling code itself is unchanged and ready;
it's only the regression batch that this attempt could not produce.
### 2026-05-13 game-systems audit — blocker cleared, no Rust work remains
A close-out pass by `game-systems` confirmed:
1. **Harness regression resolved.** Commit `40f937394`
("fix: resolve turn-processor culture research regression",
2026-05-04) consolidated the duplicate `turn_processor.gd` files
(entities/ → modules/management/) and reinstates
`_process_culture_research` at
`src/game/engine/src/modules/management/turn_processor.gd:371`. The
`SCRIPT ERROR: Nonexistent function '_process_culture_research'`
cited in the 2026-05-04 closure attempt no longer reproduces on
`origin/main`; the coupled-batch evidence path is unblocked.
2. **No Rust implementation work outstanding.** `mc-city::biome_yield`
exports the full Phase A + Phase D surface
(`ecology_food_modifier`, `carrying_capacity_modifier`,
`effective_food_modifier`, `EcologyYieldsConfig`,
`BiomeCapacity`, `BiomeCapacityConfig`); composition logic + 13 unit
tests are green. Tunables already live in
`data/balance/ecology_yields.json` + `data/balance/biome_capacity.json`.
Adding any further Rust surface would be scope creep.
3. **Owner-locked to Shipwright.** The remaining bullet is the
coupled-mode 10-seed regression batch + sign-off to flip
`fallback_when_dormant`. Per the frontmatter `owner: shipwright`
and the Coordination notes, `game-systems` cannot self-sign-off;
the bullet stays open until Shipwright re-runs the recipe in the
2026-05-03 closure-attempt section against a worktree that now
includes commit `40f937394`.
Status remains `partial`; one bullet open; ready for Shipwright re-pick.

View file

@ -2,7 +2,7 @@
id: p2-67-followup-mcts-tactical-state-impl
title: "TreeState impl for TacticalState — wire real MCTS into the AI decision path"
priority: p2
status: open
status: stub
scope: game1
category: simulation
owner: simulator-infra

View file

@ -2,7 +2,7 @@
id: p2-72
title: "GdPlayerApi → render bridge (visualise the API-held game world)"
priority: p2
status: blocked
status: stub
scope: game1
category: tooling
owner: simulator-infra

View file

@ -2,7 +2,7 @@
id: p2-72a
title: "Make `GdGameState` the canonical render source"
priority: p2
status: open
status: stub
scope: game1
category: architecture
owner: simulator-infra

View file

@ -2,7 +2,7 @@
id: p2-72b-promote-playerstate-cities-to-city
title: "Parallel-field cities synthesis at Godot bridge (Option C)"
priority: p2
status: blocked
status: stub
scope: game1
category: architecture
owner: simulator-infra