Owner flagged the duplication: live game runs GDScript turn orchestration (turn_processor.gd _process_* + EcologyState.tick) while headless runs mc-turn::step — two turn orchestrations. This session built mc-turn::step into the complete single source of truth; p3-29 is the capstone: switch turn_manager to GdTurnProcessor.step (bridge already exists at lib.rs:6354), render the TurnResult for UI, delete the GDScript orchestration. HIGH-STAKES live-game rewrite — needs a render proof before merge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2.7 KiB
| id | title | priority | scope | owner | status | updated_at |
|---|---|---|---|---|---|---|
| p3-29 | Rail-1 turn unification — live game calls the Rust turn, delete GDScript orchestration | p3 | game1 | warcouncil | open | 2026-06-27 |
Summary
The DRY / Rail-1 violation (verified 2026-06-27). There are TWO turn orchestrations:
- LIVE:
turn_manager.gd→turn_processor.gd::_process_*(GDScript) +EcologyState.tick+WorldsimState— GDScript orchestrating the turn. - HEADLESS:
GdPlayerApi→mc_turn::TurnProcessor::step(Rust).
The system math lives once in the Rust crates (DRY). The turn orchestration is duplicated —
and the p3-26/p3-27 work this session added happiness/healing/improvements/recipes/equipment/
ecology to mc-turn while the live game still runs its GDScript copies (e.g. EcologyState.tick
duplicates the new Rust ecology_phase). This session BUILT mc-turn::step into the complete
single source of truth; this objective is the capstone that makes it actually single.
The bridge already exists: GdTurnProcessor::step(GdGameState) (api-gdext/src/lib.rs:6354) runs
mc_turn::TurnProcessor::step on the LIVE game's state. The live turn just doesn't call it.
Acceptance
turn_manager.gdruns the turn viaGdTurnProcessor.step(GameState)instead of the per-playerproc._process_*loop.- The returned
TurnResultis rendered to UI (EventBus signals: chronicle, combat log, flora succession, notifications) — GDScript translates the result, emits no sim logic. turn_processor.gd::_process_*orchestration + the duplicateEcologyState.tickdeleted (or reduced to UI-only translation).- WorldsimState/terraform: either ported into
mc-turn(preferred, completes Rail-1) or kept as the one remaining GDScript-driven pass with a tracked carve-out. - Render proof: a
scenes/tests/proof scene + screenshot showing the live game plays a turn correctly through the Rust step (UI parity with the old GDScript turn). - GUT green; headless
mc-turnalready proven (it IS the step being adopted).
Notes
Created 2026-06-27 after the owner flagged that "headless runs every system the live game does"
is duplication, not DRY. HIGH-STAKES: rewrites the playable game's turn loop — must not merge
without the render proof (Rail UI rule + phase-gate). Sequence: (1) audit what the GDScript loop
emits vs TurnResult; (2) wire turn_manager → GdTurnProcessor.step behind the result-render;
(3) delete the GDScript orchestration; (4) render-proof on apricot/plum. This is the true
Rail-1 finish line — bigger than B7 (per-building queues), which becomes moot once the live
game runs the Rust turn (which has the model the unified turn will use).