feat(@projects/@magic-civilization): 🔌 p3-23 revival step 2 — enable Diplomacy.process_turn in the turn loop (loop-survival proven)

Step 1 made diplomacy.gd's contract correct + isolation-proven. Step 2 wires it into
the turn loop, carefully.

- turn_manager.gd now calls (diplomacy as DiplomacyScript).process_turn(GameState.players,
  GameState.turn_number, GameState.get_game_map()) once per full round, where the old
  empty-stub call sat disabled. The original abort risk was a MISSING method (the stub
  had none, so the call killed next_player + the arena loop). process_turn now exists and
  is internally defensive (null game_map, missing GdTrade extension, unknown resources all
  handled) so it cannot abort the round loop.

Verified (carefully, per owner): 25-turn headless AUTO_PLAY arena (seed 7) →
  exit 0, 0 SCRIPT ERRORs, 0 process_trades errors, 26 turn_stats rows, clean score victory.
The trade-eval runs every round against real players/cities/map without crashing.
NOT yet shown: in-game trade FORMATION evidence (auto_play has no trade logging; 25 turns
is sparse for complementary surpluses). Mechanism itself is GUT round-trip-proven (step 1).

Next (step 3): in-game trade visibility — GdTradeLedger agreements-enumeration #[func] +
wire EventBus.trade_agreed (dangling, no listener) into the chronicle, then a longer arena
to confirm deals form in play. p3-23 stays partial.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Natalie 2026-06-25 22:08:37 -04:00
parent e926345ad2
commit 32dd6d2723
3 changed files with 31 additions and 9 deletions

View file

@ -83,6 +83,22 @@ step). **Next:** step 2 — enable `Diplomacy.process_turn` in turn_manager.gd (
it doesn't abort the arena loop, headless + GUT); step 3 — unit-gating reads
`traded_strategics`; then relation advancement + deal UI.
**Revival step 2 — turn-loop call ENABLED + loop-survival proven (2026-06-25).**
`turn_manager.gd` now calls `(diplomacy as DiplomacyScript).process_turn(GameState.players,
GameState.turn_number, GameState.get_game_map())` once per full round (after
`_process_wild_creatures`, where the old empty-stub call was disabled). The old abort
risk was a *missing method*; `process_turn` now exists and is internally defensive
(guards null game_map, missing GdTrade extension, unknown resources) so it cannot kill
the round loop. **Verified:** 25-turn headless arena (`AUTO_PLAY` seed 7) → **exit 0, 0
script errors / 0 process_trades errors, 26 turn_stats rows, clean score victory**. The
trade-eval runs every round harmlessly against real players/cities/map. NOT yet shown:
in-game trade *formation* evidence (auto_play has no trade logging; 25 turns is sparse
for complementary surpluses) — the mechanism itself is GUT round-trip-proven.
**Next (step 3):** in-game trade visibility + formation evidence — add a GdTradeLedger
agreements-enumeration `#[func]` + wire `EventBus.trade_agreed` (currently a dangling
signal with no listener) into the chronicle, then re-run a longer arena to confirm
deals actually form in play.
**In-game application part A — gold flow LIVE (2026-06-25).** `GdTradeLedger`
gains `gold_flow_for` + `incoming_strategics` #[func]s; `GdEconomy` gains a
`trade_gold` param added to net gold after the yield/golden-age multipliers (a

View file

@ -1,12 +1,12 @@
{
"generated_at": "2026-06-26T01:53:35Z",
"generated_at": "2026-06-26T02:08:37Z",
"totals": {
"stub": 0,
"missing": 0,
"in_progress": 0,
"done": 295,
"oos": 31,
"missing": 0,
"done": 295,
"partial": 2,
"stub": 0,
"in_progress": 0,
"total": 328
},
"objectives": [

View file

@ -281,10 +281,16 @@ func next_player() -> void:
# RUST_FAUNA_ENCOUNTERS env flag is set (off by default).
proc._process_rust_fauna_encounters()
proc._process_wild_creatures()
# DISABLED: Diplomacy.process_turn() — empty stub module.
# See turn_processor.gd top-of-file out-of-scope list. Revive once
# the diplomacy module is rebuilt.
# (diplomacy as DiplomacyScript).process_turn()
# p3-23 revival step 2: evaluate inter-player trades once per full round,
# after all players have moved. Sends PlayerTradeInput records (per-player
# controlled luxuries + strategics + trade_willingness), applies the
# resulting ledger — traded luxuries feed happiness, strategics gate unit
# builds. process_turn is internally defensive (guards null game_map,
# missing GdTrade extension, unknown resources) so it cannot abort the
# round loop the way the old empty-stub call did.
(diplomacy as DiplomacyScript).process_turn(
GameState.players, GameState.turn_number, GameState.get_game_map()
)
# DISABLED: EconomyScript.apply_protection_effects — empty stub
# module has no such method; the call aborts next_player and kills
# the arena turn loop. See turn_processor.gd top-of-file out-of-scope