diff --git a/.project/objectives/p1-29.md b/.project/objectives/p1-29.md index fc2e06e7..cf09329d 100644 --- a/.project/objectives/p1-29.md +++ b/.project/objectives/p1-29.md @@ -157,3 +157,32 @@ The winner_tier_peak median regression (4.0 → 3.0) suggests the catch-up multi **Real R3 lever:** the catch-up needs to compose with science-yield boost when behind (e.g. apply `ai_per_player_research_mult` from GameState dynamically when `is_behind`), or with a different intervention entirely (e.g. minimum tech-progress floor per turn for losing players, or merciful AI difficulty downgrade for trailing players). Both are larger surfaces than a tech-pick-multiplier and were not in scope for this cycle. `status: partial` — cycle 3 catch-up logic shipped to durable code but no objective bullet flips to ✓. + +## Cycle 4 — research-OUTPUT catch-up multiplier (LANDED, ineffective) + +Implemented per cycle 4 user request. Cycle 3's tech-PICK multiplier in `auto_play.gd::_pick_research` didn't move tier_peak_gap because the loser is research-OUTPUT starved (no cities → no science). Cycle 4 adds an OUTPUT-rate multiplier in `_process_research`: + +- New `_player_tier_peak`, `_max_opponent_tier_peak`, `_catchup_research_mult` static helpers in `src/game/engine/src/modules/management/turn_processor.gd` (mirroring auto_play.gd's helpers; duplicated rather than referenced via autoload because `_process_research` runs in code paths that don't always have AutoPlay loaded — live games, GUT tests, headless MCTS). +- `_process_research` line 156 changed: `var sci_modifier: float = GameState.get_effective_yield_mult(player, "research") * _catchup_research_mult(player)`. When `is_behind` (opp_tier_peak ≥ self_tier_peak + 2), science yield is multiplied by 1.5×; otherwise 1.0× (inert). +- 5 new GUT tests cover: tied tier_peak inert, 1-era gap inert, 2-era gap fires 1.5×, `_player_tier_peak` max-era logic, `_max_opponent_tier_peak` self-exclusion. **15/15 GUT tests pass on apricot** for `test_turn_processor.gd` (was 10, +5 new). 222/222 mc-ai cargo tests still pass. + +**Cycle 4 batch results (`~/Code/project-buildspace/magic-civilization/.local/batches/autoplay_batch_p1_29_cycle4/game_20260503_152522_*`, 10 seeds × T300 standard map):** + +| Metric | Cycle 2 (lever-3+4 only) | Cycle 3 (+ pick multiplier) | **Cycle 4** (+ output multiplier) | Gate | +|---|---|---|---|---| +| Victories | 10/10 | 10/10 | **10/10** | — | +| Median winner_tier_peak | 4.0 | 3.0 | **3.0** | ≥4 (still regressed) | +| tier_peak_gap (alive-aware) | N/A (all p1_tp=1) | N/A (all p1_tp=1) | **N/A** (all p1_tp=1) | ≤4 | +| peak_unit_tier ≥3 in N/10 | 10/10 | 10/10 | **10/10** | ≥7 PASS | +| Distinct winners | 3 | 3 | **3** | — | +| Median game length | n/a | 256 | **256** | — | + +**Verdict: cycle 4 OUTPUT multiplier ALSO didn't move the metric.** Every game still has `p1_tier_peak=1`. The science-output × 1.5 boost is too small to help when p1 has 1-2 cities producing minimal science to begin with. Diagnosis chain: + +- Cycle 3 (tech-pick mult): p1 picks the right techs but can't AFFORD to research era-2+ techs. Output starvation. +- Cycle 4 (output mult): p1's tiny base (~5-10 sci/turn from 1-2 cities) × 1.5 = still ~7-15 sci/turn. Era-2 techs cost 200-400 sci. p1 needs 30-60 turns to unlock one era-2 tech. By turn 100-150, p1 has already lost critical territory. +- The deeper pattern: **the gate fails because p1 loses cities faster than it can research new techs**. Research-side levers can't fix a territory problem. + +**Real R5 lever (cross-team to combat-dev):** the right intervention is on the COMBAT side, not the research side. When p1 has lost N-1 cities, defensive bonuses on the remaining city should scale up dramatically (e.g. 2× wall HP per lost city, +50% ranged damage from remaining city), buying p1 time to research catch-up techs that EXIST but they can't reach today. Or apply the catch-up science multiplier with a much larger constant (3× or 5×) — the test would be whether that creates new failure modes (e.g. p1 gets era-3 techs but loses the city anyway), but it's a one-line change worth trying before assuming research-side levers are dead. + +`status: partial` — cycle 4 logic shipped durably (helpers + tests) but no acceptance bullet flips to ✓. The R5 cross-team handoff to combat-dev is the new recommendation.