fix(@projects/@magic-civilization): 🐛 update objective statuses and legend

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Natalie 2026-05-04 02:17:16 -04:00
parent e8e4815dab
commit 292bf7a2dd
6 changed files with 345 additions and 141 deletions

View file

@ -266,7 +266,7 @@
| [p2-37](p2-37-react-calculator-metadata-surface.md) | ✅ done | P2 | React calculator UI — surface flavor, lore, clan_affinity, archetype filter | [tourguide](../team-leads/tourguide.md) | 🟢 |
| [p2-38](p2-38-unit-audio-cues-stubs.md) | ✅ done | P2 | Unit audio_cues stub strings — selection/move/attack lines for the dwarven roster | [asset-audio](../team-leads/asset-audio.md) | 🟢 |
| [p2-39](p2-39-chronicle-hall-phantom-unlock.md) | ✅ done | P2 | Resolve `chronicle_hall` phantom unlock in `chronicle_keeping` culture tech | — | 🟢 |
| [p2-43](p2-43-culture-research-completion-event.md) | ❌ missing | P2 | Culture research live-game pipeline — per-turn GDExt bridge + `culture_researched` emit | — | 🟢 |
| [p2-43](p2-43-culture-research-completion-event.md) | 🟡 partial | P2 | Culture research live-game pipeline — per-turn GDExt bridge + `culture_researched` emit | — | 🟢 |
| [p2-44](p2-44-ai-promotion-selection.md) | 🟡 partial | P2 | AI promotion selection — auto-pick + emit unit_promoted for AI units | — | 🟢 |
| [p2-45](p2-45-elimination-reconciliation.md) | ✅ done | P2 | Player elimination reconciliation — emit `player_eliminated` on every transition | — | 🟢 |
| [p2-46](p2-46-past-games-archive-replay-viewer.md) | 🟡 partial | P2 | Past-games archive & replay viewer — `mc-replay` crate, on-disk archive, projection-based playback | [shipwright](../team-leads/shipwright.md) | 🟢 |

View file

@ -1,10 +1,10 @@
# Objectives — Dashboard
> **Generated by `@lilith/mcp-objectives` — do not hand-edit.** Source of truth is per-file YAML frontmatter in this directory. Completed: [DASHBOARD_COMPLETED.md](DASHBOARD_COMPLETED.md) · By category: [DASHBOARD_CATEGORIES.md](DASHBOARD_CATEGORIES.md).
> **Generated by `tools/objectives-report.py` — do not hand-edit.** Source of truth is per-file YAML frontmatter in this directory.
## Legend
🔵 in-progress · 🟡 partial · 🔴 stub · ❌ missing · ⚫ out-of-scope · ✅ done · ♻️ superseded
✅ done · 🔵 in-progress · 🟡 partial · 🔴 stub · ❌ missing · ⚫ out-of-scope (Game 2 / Game 3)
## Totals
@ -12,13 +12,13 @@
**By Priority**
| Priority | 🔵 | 🟡 | 🔴 | ❌ | ⚫ | ✅ | Total |
| Priority | ✅ | 🔵 | 🟡 | 🔴 | ❌ | ⚫ | Total |
|---|---|---|---|---|---|---|---|
| **P0** | 0 | 0 | 0 | 0 | 0 | 43 | 43 |
| **P1** | 1 | 12 | 3 | 7 | 1 | 48 | 72 |
| **P2** | 0 | 8 | 15 | 2 | 6 | 53 | 84 |
| **P3 (oos)** | 0 | 0 | 18 | 1 | 21 | 3 | 43 |
| **total** | **1** | **20** | **36** | **10** | **28** | **147** | **242** |
| **P0** | 43 | 0 | 0 | 0 | 0 | 0 | 43 |
| **P1** | 48 | 1 | 12 | 3 | 7 | 1 | 72 |
| **P2** | 52 | 0 | 9 | 15 | 1 | 6 | 83 |
| **P3 (oos)** | 3 | 0 | 0 | 18 | 1 | 21 | 43 |
| **total** | **146** | **1** | **21** | **36** | **9** | **28** | **241** |
</td><td valign='top' style='padding-left:2em'>
@ -28,8 +28,8 @@
|---|---|
| [unassigned](../team-leads/unassigned.md) | 31 |
| [asset-sprite](../team-leads/asset-sprite.md) | 6 |
| [shipwright](../team-leads/shipwright.md) | 5 |
| [warcouncil](../team-leads/warcouncil.md) | 5 |
| [shipwright](../team-leads/shipwright.md) | 5 |
| [simulator-infra](../team-leads/simulator-infra.md) | 3 |
| [combat-dev](../team-leads/combat-dev.md) | 2 |
| [asset-audio](../team-leads/asset-audio.md) | 1 |
@ -37,114 +37,253 @@
</td></tr></table>
## 🔵 In Progress
## P0 — Blockers for "completely playable"
> Actively claimed by a team lead. Grouped by owner.
### [asset-audio](../team-leads/asset-audio.md)
| ID | Priority | Title | Updated | Blocked |
| ID | Status | Title | Owner | Updated |
|---|---|---|---|---|
| [p2-16](p2-16-audio-assets.md) | P1 | Audio assets — in-theme OSS launch pack + source ledger | 2026-05-03 | 🟢 unblocked |
| [p0-01](p0-01-mcts-wiring.md) | ✅ done | Wire MCTS into gameplay AI | [warcouncil](../team-leads/warcouncil.md) | 2026-04-26 |
| [p0-02](p0-02-clan-personalities.md) | ✅ done | Five AI clan personalities drive distinct playstyles | [warcouncil](../team-leads/warcouncil.md) | 2026-04-26 |
| [p0-03](p0-03-pvp-in-turn.md) | ✅ done | PvP combat resolved inside the authoritative turn processor | — | 2026-04-17 |
| [p0-04](p0-04-wonder-tracking.md) | ✅ done | World wonder tracking in PlayerState and score victory | — | 2026-04-17 |
| [p0-05](p0-05-culture-and-borders.md) | ✅ done | Culture generation and border expansion | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p0-06](p0-06-economy-integration.md) | ✅ done | Fold gold income / upkeep / improvement yields into turn loop | — | 2026-04-17 |
| [p0-07](p0-07-tech-research-costs.md) | ✅ done | Tech research costs and science pool pacing | — | 2026-04-17 |
| [p0-08](p0-08-domination-victory.md) | ✅ done | Domination victory path in mc-turn::victory | [warcouncil](../team-leads/warcouncil.md) | 2026-04-18 |
| [p0-09](p0-09-ui-completeness.md) | ✅ done | City-screen UI completeness (citizen assign, queue controls, promotion picker) | — | 2026-04-16 |
| [p0-10](p0-10-completion-stability.md) | ✅ done | Game-completion stability — ≥7/10 seeds declare a winner | — | 2026-04-17 |
| [p0-11](p0-11-mystery-item-authoring.md) | ✅ done | Author the four T8T10 mystery item drops | — | 2026-04-16 |
| [p0-12](p0-12-save-load-autosave.md) | ✅ done | Save / load + autosave on quit | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p0-13](p0-13-fog-of-war-exploration.md) | ✅ done | Fog of war and exploration / scout loop | — | 2026-04-17 |
| [p0-14](p0-14-map-generation-balanced-starts.md) | ✅ done | Map generation, resource placement, and balanced fair starts | [shipwright](../team-leads/shipwright.md) | 2026-04-16 |
| [p0-15](p0-15-happiness-golden-age.md) | ✅ done | Happiness pool and Golden Age mechanics end-to-end | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p0-16](p0-16-worker-improvement-loop.md) | ✅ done | Worker / tile-improvement build loop | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p0-17](p0-17-wild-creature-lair-loop.md) | ✅ done | Wild creature and lair clearing loop | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p0-18](p0-18-strategic-resource-gate.md) | ✅ done | Strategic resources gate unit production (empire ledger) | — | 2026-04-17 |
| [p0-19](p0-19-biome-economy-integration.md) | ✅ done | Biome-driven collectibles → tile yields → happiness end-to-end | — | 2026-04-16 |
| [p0-21](p0-21-audio-system-capability.md) | ✅ done | Audio system capability — manifest + autoload + EventBus wiring | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p0-22](p0-22-ultimate-ai-stress-test.md) | ✅ done | "Ultimate AI stress test — 5 clans, huge map, deep lookahead" | [warcouncil](../team-leads/warcouncil.md) | 2026-04-25 |
| [p0-23](p0-23-sprite-rendering-capability.md) | ✅ done | Sprite rendering capability — replace procedural draw_* with texture rendering | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p0-24](p0-24-difficulty-calibrated-ai-progression.md) | ✅ done | Difficulty-calibrated AI progression — Easy / Normal / Hard tier-peak distributions | [warcouncil](../team-leads/warcouncil.md) | 2026-04-19 |
| [p0-25](p0-25-game-quality-metrics-instrumentation.md) | ✅ done | Game-quality metrics instrumentation — tier_peak, peak_unit_tier, wonder_count | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p0-26](p0-26-ai-tactical-rust-port.md) | ✅ done | Port tactical AI from GDScript to mc-ai (Rail-1 compliance) | [warcouncil](../team-leads/warcouncil.md) | 2026-04-18 |
| [p0-27](p0-27-gd-culture-bridge.md) | ✅ done | GdCulture bridge — live game delegates culture to mc-culture | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p0-28](p0-28-gd-economy-bridge.md) | ✅ done | GdEconomy bridge — live game delegates gold/upkeep to mc-economy | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p0-29](p0-29-gd-tech-bridge.md) | ✅ done | GdTechWeb bridge — live game delegates research to mc-tech | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p0-30](p0-30-ecology-double-tick-fix.md) | ✅ done | Remove duplicate GDScript ecology tick (single Rust source) | [shipwright](../team-leads/shipwright.md) | 2026-04-18 |
| [p0-31](p0-31-climate-rust-path-restore.md) | ✅ done | Restore Rust ecology path — fix ClimateScript bugs + re-enable per-turn tick | [shipwright](../team-leads/shipwright.md) | 2026-04-18 |
| [p0-32](p0-32-weather-climate-effects-restore.md) | ✅ done | Restore WeatherScript + ClimateEffectsScript — per-turn weather and climate-effects | [shipwright](../team-leads/shipwright.md) | 2026-04-18 |
| [p0-33](p0-33-world-map-input-and-panel-wiring.md) | ✅ done | World-map input wiring — unit selection panel, city click, ESC/F10 menu, panel close | [wireguard](../team-leads/wireguard.md) | 2026-04-19 |
| [p0-34](p0-34-freepeople-tribe-founding.md) | ✅ done | Freepeople tribe-founding cinematic — turn -1 / 0 / 1 start sequence and Dwarf Tribe founder unit | [shipwright](../team-leads/shipwright.md) | 2026-04-18 |
| [p0-37](p0-37-personality-emergent-tactical-thresholds.md) | ✅ done | Personality-emergent tactical thresholds (lift 7 hardcoded constants into axis-derived functions) | [warcouncil](../team-leads/warcouncil.md) | 2026-04-18 |
| [p0-38](p0-38-mcts-personality-priors.md) | ✅ done | Inject personality-utility scores as MCTS UCB1 priors | [warcouncil](../team-leads/warcouncil.md) | 2026-04-24 |
| [p0-39](p0-39-ai-tier-progression-unit-selection.md) | ✅ done | AI tier-progression unit selection — production.rs picks tier-2+ units once tech unlocks | [warcouncil](../team-leads/warcouncil.md) | 2026-04-18 |
| [p0-40](p0-40-iron-ore-resource-density.md) | ✅ done | Iron-ore strategic resource density — unblock tier 3-6 unit chain | [shipwright](../team-leads/shipwright.md) | 2026-04-24 |
| [p0-41](p0-41.md) | ✅ done | Building rally points — produced units auto-deploy to a designated hex | [shipwright](../team-leads/shipwright.md) | 2026-04-24 |
| [p0-41a](p0-41a-rally-smoke.md) | ✅ done | Rally-point smoke — produced unit gets PatrolOrder toward rally hex | [shipwright](../team-leads/shipwright.md) | 2026-04-25 |
| [p0-42](p0-42.md) | ✅ done | Formation aggregation — adjacent units link into a shaped formation with terrain reflow | [shipwright](../team-leads/shipwright.md) | 2026-04-25 |
| [p0-42a](p0-42a-formation-smoke.md) | ✅ done | Formation aggregation smoke — formations form and evolve at runtime | [shipwright](../team-leads/shipwright.md) | 2026-04-25 |
| [p0-43](p0-43.md) | ✅ done | "Formation AI — MCTS plans at formation level, not per-unit" | [warcouncil](../team-leads/warcouncil.md) | 2026-04-25 |
| [p0-44](p0-44-movement-mode-ux.md) | ✅ done | Movement mode UX — Move button, path preview, right-click confirm, fog-aware pathing | [wireguard](../team-leads/wireguard.md) | 2026-04-19 |
## P1 — Ship-readiness
| ID | Status | Title | Tags | Owner | Updated | Blocked |
|---|---|---|---|---|---|---|
| [p0-20](p0-20-gpu-mcts-rollouts.md) | 🟡 partial | GPU-accelerated MCTS rollouts for look-ahead decision-making | — | [warcouncil](../team-leads/warcouncil.md) | 2026-05-04 | 🟢 unblocked |
| [p1-05](p1-05-balance-tuning.md) | 🟡 partial | Balance tuning — pop_peak ≥30 median, worker improvements ≥8 min | — | [shipwright](../team-leads/shipwright.md) | 2026-05-01 | 🟢 unblocked |
| [p1-22](p1-22-mcts-wall-clock-budget.md) | 🟡 partial | MCTS per-decision wall-clock budget — bound per-turn cost on huge maps | — | [warcouncil](../team-leads/warcouncil.md) | 2026-04-25 | 🟢 unblocked |
| [p1-27](p1-27-mcts-service-extraction.md) | 🟡 partial | Extract GPU MCTS into a standalone service/client (model-boss-shaped, magic-civ-only) | — | [warcouncil](../team-leads/warcouncil.md) | 2026-05-03 | 🟢 unblocked |
| [p1-29](p1-29.md) | 🟡 partial | Anti-early-domination: lift game-balance gates that p0-01 v1 measured | balance, pacing | [combat-dev](../team-leads/combat-dev.md) | 2026-05-03 | 🟢 unblocked |
| [p1-38](p1-38-biome-economy-coupling.md) | 🟡 partial | Biome → economy coupling — population & luxury driven by live ecology | — | [shipwright](../team-leads/shipwright.md) | 2026-05-03 | 🟢 unblocked |
| [p1-39](p1-39.md) | 🟡 partial | Port per-yield difficulty multipliers from GDScript into Rust crates (Rail-1) — research + culture | rust-source-of-truth, rail-1 | [warcouncil](../team-leads/warcouncil.md) | 2026-05-01 | 🟢 unblocked |
| [p1-43](p1-43-building-stacking-upgrade.md) | 🟡 partial | Building stacking — per-category upgrade chains (military / science / culture / production / etc.) | — | — | 2026-05-03 | 🟢 unblocked |
| [p1-55](p1-55-tech-culture-domain-propagation.md) | 🟡 partial | Tech & Culture domain field — propagate categorization through Rust, Godot UI, and player analysis | — | [simulator-infra](../team-leads/simulator-infra.md) | 2026-05-04 | 🟢 unblocked |
| [p1-56](p1-56-civics-buildings-and-great-works.md) | 🟡 partial | Civics buildings, Great Works, Specialists, Great People — wire authored data into Rust + Godot | — | [simulator-infra](../team-leads/simulator-infra.md) | 2026-05-04 | 🟢 unblocked |
| [p1-58](p1-58-ecology-cognitive-system.md) | 🟡 partial | Ecology cognition: terrain affinity, food web, grudge memory, apex tier-10 fauna/flora | — | [simulator-infra](../team-leads/simulator-infra.md) | 2026-05-04 | 🟢 unblocked |
| [p2-22](p2-22-sprite-generation-pipeline.md) | 🟡 partial | Sprite generation pipeline — runnable end-to-end | — | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-25 | 🟢 unblocked |
| [p1-29a](p1-29a-last-stand-defense.md) | 🔴 stub | Last-stand defense — combat-strength multiplier when defender is at last city | balance, combat, pacing | [combat-dev](../team-leads/combat-dev.md) | 2026-05-03 | 🟢 unblocked |
| [p1-30b](p1-30b-parallel-mcts-rollouts.md) | 🔴 stub | Parallel MCTS rollouts for huge-map decisive games (closes p1-22's huge-map sub-gate) | perf, mcts, tactical-ai | [warcouncil](../team-leads/warcouncil.md) | 2026-05-03 | 🟢 unblocked |
| [p1-57](p1-57-diplomacy-tribute-treaties.md) | 🔴 stub | Diplomacy: tribute, treaty lifecycle, magical-terrain episode gating | — | [unassigned](../team-leads/unassigned.md) | 2026-05-03 | 🟢 unblocked |
| [p1-42](p1-42-ai-full-building-catalog.md) | ❌ missing | AI must consider the full 155-building catalog, not the hardcoded 8-id ladder | — | — | 2026-04-29 | 🟢 unblocked |
| [p1-44](p1-44-buildings-as-producers.md) | ❌ missing | Buildings produce units, not the city center — per-building production queues | — | — | 2026-04-29 | 🟢 unblocked |
| [p2-23](p2-23-unit-sprites-dwarf-roster.md) | ❌ missing | Unit sprites — Dwarf-racial roster (m/f variants) | — | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-17 | 🟢 unblocked |
| [p2-24](p2-24-unit-sprites-wild-creatures.md) | ❌ missing | Unit sprites — wild creatures & fauna (generic, no race/sex) | — | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-17 | 🟢 unblocked |
| [p2-25](p2-25-building-sprites-base-coverage.md) | ❌ missing | Building sprites — base game coverage (non-wonder) | — | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-17 | 🟢 unblocked |
| [p2-26](p2-26-mundane-wonder-sprites.md) | ❌ missing | Mundane-wonder sprites — 24 distinct, higher-fidelity art | — | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-17 | 🟢 unblocked |
| [p2-27](p2-27-city-population-tier-sprites.md) | ❌ missing | City population-tier sprites — city_q1 through city_q5 | — | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-17 | 🟢 unblocked |
| ID | Status | Title | Owner | Updated |
|---|---|---|---|---|
| [p0-20](p0-20-gpu-mcts-rollouts.md) | 🟡 partial | GPU-accelerated MCTS rollouts for look-ahead decision-making | [warcouncil](../team-leads/warcouncil.md) | 2026-05-04 |
| [p0-35](p0-35-ecology-telemetry-instrumentation.md) | ✅ done | Ecology telemetry instrumentation — flora canopy / undergrowth fields in turn_stats.jsonl | [shipwright](../team-leads/shipwright.md) | 2026-04-18 |
| [p0-36](p0-36-weather-event-telemetry.md) | ✅ done | Weather / climate-effects event telemetry — events.jsonl + turn_stats aggregates | [shipwright](../team-leads/shipwright.md) | 2026-04-18 |
| [p1-01](p1-01-diplomacy-lite.md) | ✅ done | Diplomacy-lite — peace/war toggle plus one trade action | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p1-02](p1-02-strategic-resource-yields.md) | ✅ done | Strategic resource yields feed into production bonuses | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p1-03](p1-03-tutorial-overlay.md) | ✅ done | First-run tutorial / onboarding overlay | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p1-05](p1-05-balance-tuning.md) | 🟡 partial | Balance tuning — pop_peak ≥30 median, worker improvements ≥8 min | [shipwright](../team-leads/shipwright.md) | 2026-05-01 |
| [p1-06](p1-06-options-polish.md) | ✅ done | Options screen polish | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p1-07](p1-07-chronicle-coverage.md) | ✅ done | Chronicle notifications coverage | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p1-08](p1-08-victory-screen-content.md) | ✅ done | Victory/defeat screen content — recap, banner, replay seed | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p1-09](p1-09-determinism-gate.md) | ✅ done | Determinism gate — same seed produces byte-identical runs | [testwright](../team-leads/testwright.md) | 2026-04-19 |
| [p1-10](p1-10-game-setup-ux.md) | ✅ done | Game setup UX — new-game dialog, difficulty, clan preview | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p1-11](p1-11-build-output-src-purge.md) | ✅ done | Purge build output from src/ — wasm-pack moves to .local/build/wasm/ | [tourguide](../team-leads/tourguide.md) | 2026-04-17 |
| [p1-12](p1-12-build-output-docs-alignment.md) | ✅ done | Align every doc reference to the relocated wasm-pack output | [tourguide](../team-leads/tourguide.md) | 2026-04-17 |
| [p1-13](p1-13-guide-dev-route-coverage.md) | ✅ done | Guide dev server boots on plum with zero-error route coverage | [tourguide](../team-leads/tourguide.md) | 2026-04-17 |
| [p1-15](p1-15-guide-next-deploy-infra.md) | ✅ done | Deploy dev guide to https://mc.next.black.local | [tourguide](../team-leads/tourguide.md) | 2026-04-17 |
| [p1-16](p1-16-guide-game1-scope-hygiene.md) | ✅ done | Purge Game 2/3 scope bleed from user-visible Game 1 guide copy | [tourguide](../team-leads/tourguide.md) | 2026-04-18 |
| [p1-17](p1-17-guide-next-auto-deploy.md) | ✅ done | Forgejo workflow auto-deploys dev guide on push to main | [tourguide](../team-leads/tourguide.md) | 2026-04-18 |
| [p1-18](p1-18-village-discovery-feedback.md) | ✅ done | Village discovery — world-map feedback (notification, reward popup, minimap ping) | [wireguard](../team-leads/wireguard.md) | 2026-04-19 |
| [p1-19](p1-19-tutorial-opt-in.md) | ✅ done | Tutorial opt-in — HUD button, disappears after turn 5, starts from Step 1 | [wireguard](../team-leads/wireguard.md) | 2026-04-19 |
| [p1-20](p1-20-unit-action-capability-registry.md) | ✅ done | Unit action capability registry — one source of truth for "what can this unit do right now?" | [wireguard](../team-leads/wireguard.md) | 2026-04-19 |
| [p1-21](p1-21-unit-patrol-orders.md) | ✅ done | Unit patrol orders — standing order to loop between waypoint tiles | [wireguard](../team-leads/wireguard.md) | 2026-04-19 |
| [p1-22](p1-22-mcts-wall-clock-budget.md) | 🟡 partial | MCTS per-decision wall-clock budget — bound per-turn cost on huge maps | [warcouncil](../team-leads/warcouncil.md) | 2026-04-25 |
| [p1-23](p1-23-stats-tracker-restore.md) | ✅ done | Restore StatsTracker — demographics overview broken in shipped builds | [shipwright](../team-leads/shipwright.md) | 2026-04-25 |
| [p1-24](p1-24-windows-path-separator.md) | ✅ done | ai_personalities.json fails to load from packed builds (all platforms) — pass JSON contents not path | [shipwright](../team-leads/shipwright.md) | 2026-04-25 |
| [p1-25](p1-25-export-script-error-cleanup.md) | ✅ done | Eliminate parse-error spam in export logs (Unit dup decl + SaveManager stray) | [shipwright](../team-leads/shipwright.md) | 2026-04-25 |
| [p1-26](p1-26-tile-placement-preview-ux.md) | ✅ done | "Tile-placement UX with effect preview — Civ7-style \\\"where does this go and what changes\\\"" | [shipwright](../team-leads/shipwright.md) | 2026-04-26 |
| [p1-27](p1-27-mcts-service-extraction.md) | 🟡 partial | Extract GPU MCTS into a standalone service/client (model-boss-shaped, magic-civ-only) | [warcouncil](../team-leads/warcouncil.md) | 2026-05-03 |
| [p1-28](p1-28-culture-research-tree.md) | ✅ done | "Culture research tree — real graph, bridge, UI" | [shipwright](../team-leads/shipwright.md) | 2026-04-26 |
| [p1-29](p1-29.md) | 🟡 partial | "Anti-early-domination: lift game-balance gates that p0-01 v1 measured" | [combat-dev](../team-leads/combat-dev.md) | 2026-05-03 |
| [p1-29a](p1-29a-last-stand-defense.md) | 🔴 stub | "Last-stand defense — combat-strength multiplier when defender is at last city" | [combat-dev](../team-leads/combat-dev.md) | 2026-05-03 |
| [p1-30](p1-30.md) | ✅ done | "Optimize `_build_tactical_state` — 8000-tile GDScript dict-build per AI turn blocks p1-22 huge-map gate" | [warcouncil](../team-leads/warcouncil.md) | 2026-05-04 |
| [p1-30b](p1-30b-parallel-mcts-rollouts.md) | 🔴 stub | "Parallel MCTS rollouts for huge-map decisive games (closes p1-22's huge-map sub-gate)" | [warcouncil](../team-leads/warcouncil.md) | 2026-05-03 |
| [p1-31](p1-31-split-bundled-building-resources.md) | ✅ done | Split bundled `resources/buildings/<category>.json` into per-file pattern matching `resources/units/` | — | 2026-04-27 |
| [p1-32](p1-32-food-chain-buildings.md) | ✅ done | Author the two missing food/processing buildings (sawmill, herbalist) | — | 2026-05-03 |
| [p1-33](p1-33-naval-aerial-production-buildings.md) | ✅ done | Wire naval/aerial unit gates to the harbor and airfield buildings | — | 2026-05-03 |
| [p1-34](p1-34-unit-metadata-expansion.md) | ✅ done | "Unit metadata expansion — flavor, archetype, promotion_tree, clan_affinity fields" | [shipwright](../team-leads/shipwright.md) | 2026-04-27 |
| [p1-35](p1-35-unit-lore-paragraphs.md) | ✅ done | "Per-unit lore paragraphs — historical/cultural context for the dwarven roster" | [shipwright](../team-leads/shipwright.md) | 2026-04-27 |
| [p1-36](p1-36-ai-personalities-t1-t10-coverage.md) | ✅ done | "AI personalities — T1T10 build order coverage + clan_affinity routing" | [warcouncil](../team-leads/warcouncil.md) | 2026-05-03 |
| [p1-37](p1-37-mc-ai-clan-affinity-routing.md) | ✅ done | "mc-ai clan_affinity routing — Rust AI reads unit clan_affinity at build-decision time" | [warcouncil](../team-leads/warcouncil.md) | 2026-05-01 |
| [p1-38](p1-38-biome-economy-coupling.md) | 🟡 partial | Biome → economy coupling — population & luxury driven by live ecology | [shipwright](../team-leads/shipwright.md) | 2026-05-03 |
| [p1-39](p1-39.md) | 🟡 partial | Port per-yield difficulty multipliers from GDScript into Rust crates (Rail-1) — research + culture | [warcouncil](../team-leads/warcouncil.md) | 2026-05-01 |
| [p1-40](p1-40-single-source-of-truth-resources.md) | ✅ done | Collapse data/<category>/ override layer into single source of truth at resources/ | — | 2026-04-29 |
| [p1-41](p1-41-game-pack-subscription-manifest.md) | ✅ done | Game-pack subscription manifest + loader filter (Phase B of resources/ unification) | — | 2026-04-29 |
| [p1-42](p1-42-ai-full-building-catalog.md) | ❌ missing | AI must consider the full 155-building catalog, not the hardcoded 8-id ladder | — | 2026-04-29 |
| [p1-43](p1-43-building-stacking-upgrade.md) | 🟡 partial | Building stacking — per-category upgrade chains (military / science / culture / production / etc.) | — | 2026-05-03 |
| [p1-44](p1-44-buildings-as-producers.md) | ❌ missing | Buildings produce units, not the city center — per-building production queues | — | 2026-04-29 |
| [p1-45](p1-45-batch-binary-freshness.md) | ✅ done | "Batch binary freshness: rebuild GDExt before every autoplay batch" | [simulator-infra](../team-leads/simulator-infra.md) | 2026-05-03 |
| [p1-46](p1-46-design-lab-terrain-dimensions.md) | ✅ done | Terrain Dimensions Lab — fix ridginess, bind 149 flora species, add Whittaker plot | [terraformer](../team-leads/terraformer.md) | 2026-05-01 |
| [p1-47](p1-47-river-hydrology-network.md) | ✅ done | River hydrology — D6 flow analysis, hydraulic erosion, multi-hex lakes, cross-tile rivers | [terraformer](../team-leads/terraformer.md) | 2026-05-01 |
| [p1-48](p1-48-flora-species-renderer.md) | ✅ done | Flora species renderer — bind 149 species to world-map tile rendering (single source of truth) | [terraformer](../team-leads/terraformer.md) | 2026-05-01 |
| [p1-49](p1-49-fauna-species-renderer.md) | ✅ done | Fauna species renderer — 61 Game-1 species visible on encounter and lair tiles | [terraformer](../team-leads/terraformer.md) | 2026-05-01 |
| [p1-50](p1-50-tectonic-prepass.md) | ✅ done | Tectonic prepass — voronoi plates + boundary classification seeding elevation | [terraformer](../team-leads/terraformer.md) | 2026-05-01 |
| [p1-51](p1-51-worldgen-canonical-design-docs.md) | ✅ done | Worldgen canonical design docs — author the spec before any Rust | [terraformer](../team-leads/terraformer.md) | 2026-04-30 |
| [p1-52](p1-52-api-wasm-build-fix.md) | ✅ done | api-wasm build fix — unblock WASM bundle for design-lab WASM consumption | [terraformer](../team-leads/terraformer.md) | 2026-05-01 |
| [p1-53](p1-53-worldgen-layer-pages.md) | ✅ done | "Worldgen layer pages — one playground per canonical doc, mirroring the layered Earth model" | [terraformer](../team-leads/terraformer.md) | 2026-05-01 |
| [p1-54](p1-54-hex-direction-rust-ts-mapping.md) | ✅ done | Hex direction-index translation — Rust pointy-top axial vs design-app flat-top canvas | [terraformer](../team-leads/terraformer.md) | 2026-05-01 |
| [p1-55](p1-55-tech-culture-domain-propagation.md) | 🟡 partial | "Tech & Culture domain field — propagate categorization through Rust, Godot UI, and player analysis" | [simulator-infra](../team-leads/simulator-infra.md) | 2026-05-04 |
| [p1-56](p1-56-civics-buildings-and-great-works.md) | 🟡 partial | "Civics buildings, Great Works, Specialists, Great People — wire authored data into Rust + Godot" | [simulator-infra](../team-leads/simulator-infra.md) | 2026-05-04 |
| [p1-57](p1-57-diplomacy-tribute-treaties.md) | 🔴 stub | "Diplomacy: tribute, treaty lifecycle, magical-terrain episode gating" | [unassigned](../team-leads/unassigned.md) | 2026-05-03 |
| [p1-58](p1-58-ecology-cognitive-system.md) | 🟡 partial | "Ecology cognition: terrain affinity, food web, grudge memory, apex tier-10 fauna/flora" | [simulator-infra](../team-leads/simulator-infra.md) | 2026-05-04 |
| [p2-06](p2-06-export-pipeline.md) | ✅ done | Export pipeline for Windows / macOS / Linux | [shipwright](../team-leads/shipwright.md) | 2026-04-25 |
| [p2-16](p2-16-audio-assets.md) | 🔵 in_progress | Audio assets — in-theme OSS launch pack + source ledger | [asset-audio](../team-leads/asset-audio.md) | 2026-05-03 |
| [p2-22](p2-22-sprite-generation-pipeline.md) | 🟡 partial | Sprite generation pipeline — runnable end-to-end | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-25 |
| [p2-23](p2-23-unit-sprites-dwarf-roster.md) | ❌ missing | Unit sprites — Dwarf-racial roster (m/f variants) | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-17 |
| [p2-24](p2-24-unit-sprites-wild-creatures.md) | ❌ missing | Unit sprites — wild creatures & fauna (generic, no race/sex) | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-17 |
| [p2-25](p2-25-building-sprites-base-coverage.md) | ❌ missing | Building sprites — base game coverage (non-wonder) | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-17 |
| [p2-26](p2-26-mundane-wonder-sprites.md) | ❌ missing | Mundane-wonder sprites — 24 distinct, higher-fidelity art | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-17 |
| [p2-27](p2-27-city-population-tier-sprites.md) | ❌ missing | City population-tier sprites — city_q1 through city_q5 | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-17 |
| [p2-28](p2-28-sprite-provenance-ledger.md) | ✅ done | Sprite provenance ledger — LICENSES.md per-file attribution | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-25 |
| [p2-33](p2-33-sound-system-extension.md) | ✅ done | "Sound system extension — categorical fallback, variant pools, per-entity routing" | [asset-audio](../team-leads/asset-audio.md) | 2026-04-27 |
## P2 — Polish
| ID | Status | Title | Tags | Owner | Updated | Blocked |
|---|---|---|---|---|---|---|
| [p2-10](p2-10-regression-ci-gate.md) | 🟡 partial | Automated regression CI gate on every push to main | — | [testwright](../team-leads/testwright.md) | 2026-04-23 | 🟢 unblocked |
| [p2-11a](p2-11a.md) | 🟡 partial | SaveManager: add Unit.serialize/deserialize and City.production_queue serialize path | — | — | 2026-05-03 | 🟢 unblocked |
| [p2-18](p2-18-guide-public-deployment.md) | 🟡 partial | Guide web app — public hosting + deploy pipeline | — | — | 2026-04-17 | 🟢 unblocked |
| [p2-44](p2-44-ai-promotion-selection.md) | 🟡 partial | AI promotion selection — auto-pick + emit unit_promoted for AI units | — | — | 2026-05-04 | 🟢 unblocked |
| [p2-46](p2-46-past-games-archive-replay-viewer.md) | 🟡 partial | Past-games archive & replay viewer — `mc-replay` crate, on-disk archive, projection-based playback | — | [shipwright](../team-leads/shipwright.md) | 2026-05-03 | 🟢 unblocked |
| [p2-47](p2-47-in-game-statistics-screens.md) | 🟡 partial | In-game statistics screens — Civ-style 5-tab modal (Demographics / Graphs / Rankings / Replay / Histories) | — | [shipwright](../team-leads/shipwright.md) | 2026-05-03 | 🟢 unblocked |
| [p2-48](p2-48-end-of-game-summary-screen.md) | 🟡 partial | End-of-game summary screen — outcome banner, standings, score graph, awards, timeline, footer actions | — | [shipwright](../team-leads/shipwright.md) | 2026-05-03 | 🟢 unblocked |
| [p2-55](p2-55-civilian-capture-system.md) | 🟡 partial | Civilian Capture / Destroy / Ransom | — | — | 2026-05-03 | 🟢 unblocked |
| [p2-55d](p2-55d-ai-ransom-decision-hook.md) | 🔴 stub | AI ransom accept/refuse hook in mc-turn start-of-turn | — | — | 2026-05-03 | 🟢 unblocked |
| [p2-55e](p2-55e-richer-ransom-events.md) | 🔴 stub | UnitRansomAccepted / UnitRansomExpired events on TurnResult | — | — | 2026-05-03 | 🟢 unblocked |
| [p2-57](p2-57-production-chain-typed-resources.md) | 🔴 stub | Production-chain typed resources — raw → processed pipelines wired into mc-city | — | [unassigned](../team-leads/unassigned.md) | 2026-05-03 | 🟢 unblocked |
| [p2-57a](p2-57a-typed-resource-stockpile.md) | 🔴 stub | Typed resource stockpile — raw vs processed taxonomy | — | [unassigned](../team-leads/unassigned.md) | 2026-05-03 | 🟢 unblocked |
| [p2-58](p2-58-ambient-encounter-rolls.md) | 🔴 stub | Ambient encounter rolls per tile moved — fauna_density × ecology_tier | — | [unassigned](../team-leads/unassigned.md) | 2026-05-03 | 🟢 unblocked |
| [p2-60](p2-60-weather-lens-godot-ui.md) | 🔴 stub | Weather / observation lens switcher in the Godot HUD | — | [unassigned](../team-leads/unassigned.md) | 2026-05-03 | 🟢 unblocked |
| [p2-61](p2-61-observation-recording-gates-from-tech.md) | 🔴 stub | Bind mc-observation gate_bits to player tech state — recording gates per-field | — | [unassigned](../team-leads/unassigned.md) | 2026-05-03 | 🟢 unblocked |
| [p2-62](p2-62-procedural-unit-and-building-renderer.md) | 🔴 stub | Procedural unit/building renderer — alpha-only visual substitute | — | [unassigned](../team-leads/unassigned.md) | 2026-05-03 | 🟢 unblocked |
| [p2-63](p2-63-mc-flora-biome-substrate-migration.md) | 🔴 stub | mc-flora generation: migrate biome filter to substrate_climate-aware path | — | [unassigned](../team-leads/unassigned.md) | 2026-05-04 | 🟢 unblocked |
| [p2-35](p2-35-palace-evolution-system.md) | ❌ missing | Palace evolution system — longhouse → great_hall → citadel → grand_citadel + function-shedding | — | — | 2026-04-27 | 🟢 unblocked |
| [p2-43](p2-43-culture-research-completion-event.md) | ❌ missing | Culture research live-game pipeline — per-turn GDExt bridge + `culture_researched` emit | — | — | 2026-04-30 | 🟢 unblocked |
| [p2-56](p2-56-worker-categories-and-expertise-tiers.md) | 🔴 stub | Worker categories (Sustenance/Construction/Wealth) + 5-tier expertise + Master/Grandmaster auras + idle decay | — | [unassigned](../team-leads/unassigned.md) | 2026-05-03 | 🔒 p2-35 |
| [p2-56a](p2-56a-worker-category-types.md) | 🔴 stub | Worker category types — Sustenance / Construction / Wealth taxonomy | — | [unassigned](../team-leads/unassigned.md) | 2026-05-03 | 🔒 p2-35 |
| [p2-56b](p2-56b-expertise-tier-progression.md) | 🔴 stub | Expertise tier progression — 5-tier specialist XP ladder | — | [unassigned](../team-leads/unassigned.md) | 2026-05-03 | 🔒 p2-56a |
| [p2-56c](p2-56c-master-grandmaster-auras.md) | 🔴 stub | Master / Grandmaster auras — adjacent-slot yield propagation | — | [unassigned](../team-leads/unassigned.md) | 2026-05-03 | 🔒 p2-56b |
| [p2-57b](p2-57b-consume-produce-edges.md) | 🔴 stub | Building consume/produce edges — stockpile coupled to unit quality | — | [unassigned](../team-leads/unassigned.md) | 2026-05-03 | 🔒 p2-57a |
| [p2-59](p2-59-pioneer-escort-mechanic.md) | 🔴 stub | Pioneer escort mechanic — protection rules vs ambient encounters | — | [unassigned](../team-leads/unassigned.md) | 2026-05-03 | 🔒 p2-58 |
| ID | Status | Title | Owner | Updated |
|---|---|---|---|---|
| [p2-01](p2-01-minimap-improvements.md) | ✅ done | Minimap — fog reflection and unit markers | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p2-02](p2-02-hud-tooltips.md) | ✅ done | Tooltips on all HUD elements | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p2-03](p2-03-hotkey-cheat-sheet.md) | ✅ done | Hotkey cheat sheet (F1 / ?) | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p2-04](p2-04-localization-audit.md) | ✅ done | Localization audit — no hardcoded strings | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p2-05](p2-05-turn-latency.md) | ✅ done | Sub-second single-player turn latency | — | 2026-04-23 |
| [p2-06b](p2-06b-windows-runner.md) | ✅ done | Cross-compile Windows .exe + .dll from Linux via cargo-xwin (no Windows host) | [shipwright](../team-leads/shipwright.md) | 2026-04-25 |
| [p2-07](p2-07-credits-screen.md) | ✅ done | Credits screen accessible from main menu | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p2-08](p2-08-accessibility.md) | ✅ done | Accessibility baseline — colorblind palette + keyboard navigation | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p2-09](p2-09-guide-web-deploy.md) | ✅ done | Player guide web app — builds clean from source | — | 2026-04-17 |
| [p2-10](p2-10-regression-ci-gate.md) | 🟡 partial | Automated regression CI gate on every push to main | [testwright](../team-leads/testwright.md) | 2026-04-23 |
| [p2-10a](p2-10a-gdlint-ungate.md) | ✅ done | "CI: gdlint stage un-gated" | [testwright](../team-leads/testwright.md) | 2026-04-25 |
| [p2-10b](p2-10b-gut-ungate.md) | ✅ done | "CI: headless GUT stage un-gated" | [testwright](../team-leads/testwright.md) | 2026-04-26 |
| [p2-10c](p2-10c-diplomacy-luxury-ids.md) | ✅ done | "Diplomacy: implement _collect_unique_luxury_ids() in happiness.gd" | — | 2026-04-26 |
| [p2-10d](p2-10d-legacy-unit-json.md) | ✅ done | "Data: strip legacy flags/can_found_city/can_build_improvements from unit JSON" | — | 2026-04-26 |
| [p2-10e](p2-10e-data-integrity.md) | ✅ done | "Data: resolve duplicate IDs and dangling unlock refs in game data" | — | 2026-04-26 |
| [p2-10f](p2-10f-save-manager-typed-arrays.md) | ✅ done | "SaveManager: fix typed array property assignment on Player/Unit deserialization" | — | 2026-04-26 |
| [p2-10g](p2-10g-city-bridge-production-cost.md) | ✅ done | "CityBridge: add production_cost field to items JSON fixture" | — | 2026-04-26 |
| [p2-10h](p2-10h-sprite-renderer-build-key.md) | ✅ done | "UnitRenderer: implement _build_sprite_key() helper and fix cache key test" | — | 2026-04-26 |
| [p2-10i](p2-10i-tile-tooltip-scene.md) | ✅ done | "TileTooltip: fix scene node name mismatches and collectibles text formatting" | — | 2026-04-26 |
| [p2-10j](p2-10j-fog-vision-scout-move.md) | ✅ done | "FogOfWar: fix recalculate_vision to not re-reveal already-seen tiles on move" | — | 2026-04-26 |
| [p2-11](p2-11-version-about-screen.md) | ✅ done | Version string + About screen | [shipwright](../team-leads/shipwright.md) | 2026-04-17 |
| [p2-11a](p2-11a.md) | 🟡 partial | "SaveManager: add Unit.serialize/deserialize and City.production_queue serialize path" | — | 2026-05-03 |
| [p2-12](p2-12-apricot-weston-install.md) | ✅ done | Install weston on apricot RUN host — unblock display-server smoke tests | [shipwright](../team-leads/shipwright.md) | 2026-04-25 |
| [p2-18](p2-18-guide-public-deployment.md) | 🟡 partial | Guide web app — public hosting + deploy pipeline | — | 2026-04-17 |
| [p2-19](p2-19-guide-progress-report-page.md) | ✅ done | Guide progress report page — dynamic dashboard + missing assets | — | 2026-04-17 |
| [p2-20](p2-20-guide-sim-cache-pnpm-resolve.md) | ✅ done | Fix simCachePlugin pre-warm worker — tsx can't resolve @magic-civ/physics-rs through pnpm symlink | [tourguide](../team-leads/tourguide.md) | 2026-04-17 |
| [p2-21](p2-21-guide-simcache-static-bake.md) | ✅ done | Bake pre-computed sim-cache frames into the static build | [tourguide](../team-leads/tourguide.md) | 2026-04-18 |
| [p2-29](p2-29-guide-welcome-homepage-theme-alignment.md) | ✅ done | Welcome modal + HomePage lore + guide theme align to the player's chosen race/gender | [tourguide](../team-leads/tourguide.md) | 2026-04-18 |
| [p2-30](p2-30-guide-shared-primitives.md) | ✅ done | Consolidate duplicate page styled-components into shared PagePrimitives | [tourguide](../team-leads/tourguide.md) | 2026-04-18 |
| [p2-31](p2-31-guide-url-bound-state.md) | ✅ done | Migrate guide filter + tab state from useState to URL search params | [tourguide](../team-leads/tourguide.md) | 2026-04-18 |
| [p2-32](p2-32-guide-data-driven-enums.md) | ✅ done | Replace hardcoded page enums with JSON data reads | [tourguide](../team-leads/tourguide.md) | 2026-04-18 |
| [p2-35](p2-35-palace-evolution-system.md) | ❌ missing | Palace evolution system — longhouse → great_hall → citadel → grand_citadel + function-shedding | — | 2026-04-27 |
| [p2-36](p2-36-data-resources-building-duplicates.md) | ✅ done | Reconcile the 14 building IDs defined in both `resources/buildings/` and `data/buildings/` | — | 2026-04-29 |
| [p2-37](p2-37-react-calculator-metadata-surface.md) | ✅ done | "React calculator UI — surface flavor, lore, clan_affinity, archetype filter" | [tourguide](../team-leads/tourguide.md) | 2026-04-27 |
| [p2-38](p2-38-unit-audio-cues-stubs.md) | ✅ done | "Unit audio_cues stub strings — selection/move/attack lines for the dwarven roster" | [asset-audio](../team-leads/asset-audio.md) | 2026-04-27 |
| [p2-39](p2-39-chronicle-hall-phantom-unlock.md) | ✅ done | Resolve `chronicle_hall` phantom unlock in `chronicle_keeping` culture tech | — | 2026-04-27 |
| [p2-43](p2-43-culture-research-completion-event.md) | 🟡 partial | "Culture research live-game pipeline — per-turn GDExt bridge + `culture_researched` emit" | — | 2026-05-04 |
| [p2-44](p2-44-ai-promotion-selection.md) | 🟡 partial | AI promotion selection — auto-pick + emit unit_promoted for AI units | — | 2026-05-04 |
| [p2-45](p2-45-elimination-reconciliation.md) | ✅ done | "Player elimination reconciliation — emit `player_eliminated` on every transition" | — | 2026-04-30 |
| [p2-46](p2-46-past-games-archive-replay-viewer.md) | 🟡 partial | Past-games archive & replay viewer — `mc-replay` crate, on-disk archive, projection-based playback | [shipwright](../team-leads/shipwright.md) | 2026-05-03 |
| [p2-47](p2-47-in-game-statistics-screens.md) | 🟡 partial | In-game statistics screens — Civ-style 5-tab modal (Demographics / Graphs / Rankings / Replay / Histories) | [shipwright](../team-leads/shipwright.md) | 2026-05-03 |
| [p2-48](p2-48-end-of-game-summary-screen.md) | 🟡 partial | End-of-game summary screen — outcome banner, standings, score graph, awards, timeline, footer actions | [shipwright](../team-leads/shipwright.md) | 2026-05-03 |
| [p2-49](p2-49-climate-axes-latitude-continentality.md) | ✅ done | Climate axes refactor — latitude + continentality + zonal winds as first-class per-hex inputs | [terraformer](../team-leads/terraformer.md) | 2026-04-30 |
| [p2-50](p2-50-rng-determinism-pin.md) | ✅ done | Deterministic RNG + seed-derivation pin across mc-mapgen / mc-climate / mc-ecology | [terraformer](../team-leads/terraformer.md) | 2026-05-01 |
| [p2-51](p2-51-world-shape-knobs.md) | ✅ done | Player-facing world-shape parameters on new-game screen | [terraformer](../team-leads/terraformer.md) | 2026-05-01 |
| [p2-52](p2-52-substrate-flora-cover-ontology-split.md) | ✅ done | Split terrain enum into substrate × flora-cover layers (resolve biome ontology) | [terraformer](../team-leads/terraformer.md) | 2026-05-01 |
| [p2-53](p2-53-action-vocabulary-design-game-gap.md) | ✅ done | Action vocabulary — gap analysis between design page and shipped Rust/Godot game | [wireguard](../team-leads/wireguard.md) | 2026-05-03 |
| [p2-53a](p2-53a-sentry-guard-action-kind.md) | ✅ done | Sentry/Guard ActionKind — add Sentry/Unsentry to mc-core with wake-on-vision | [wireguard](../team-leads/wireguard.md) | 2026-05-01 |
| [p2-53b](p2-53b-building-action-registry.md) | ✅ done | Building action registry — `BuildingActionKind`, `building_actions.json`, `GdBuildingActions` bridge | [simulator-infra](../team-leads/simulator-infra.md) | 2026-05-01 |
| [p2-53c](p2-53c-rally-vocabulary-expansion.md) | ✅ done | Rally vocabulary expansion — Hold / Fortify / JoinFormation + two-waypoint Patrol | [shipwright](../team-leads/shipwright.md) | 2026-05-01 |
| [p2-53d](p2-53d-building-specifics.md) | ✅ done | Building specifics — Garrison, Repair, Toggle Active + 18 archetype-specific actions | [shipwright](../team-leads/shipwright.md) | 2026-05-03 |
| [p2-53e](p2-53e-siege-pillage-embark.md) | ✅ done | Siege handlers (Pack/Deploy/Bombard) + Pillage UI wiring + Embark/Disembark handlers | [combat-dev](../team-leads/combat-dev.md) | 2026-05-03 |
| [p2-53f](p2-53f-infantry-specifics.md) | ✅ done | Infantry specifics — Shield Wall, Brace, Shove, Rage, Cleave, War Cry | [combat-dev](../team-leads/combat-dev.md) | 2026-05-01 |
| [p2-53g](p2-53g-ranged-specifics.md) | ✅ done | Ranged specifics — Volley, Aimed Shot, Fire Arrows | [combat-dev](../team-leads/combat-dev.md) | 2026-05-03 |
| [p2-53h](p2-53h-cavalry-specifics.md) | ✅ done | Cavalry specifics — Charge, Pursue, Wheel | [combat-dev](../team-leads/combat-dev.md) | 2026-05-03 |
| [p2-53i](p2-53i-engineer-pioneer-medic-scout.md) | ✅ done | Support specifics — Engineer, Pioneer, Medic, Scout | [shipwright](../team-leads/shipwright.md) | 2026-05-03 |
| [p2-54](p2-54-resource-visibility-three-axis.md) | ✅ done | Resource visibility — three-axis (visibility/yield_gate/improvement_gate) refactor | [terraformer](../team-leads/terraformer.md) | 2026-05-02 |
| [p2-54a](p2-54a-deposits-three-axis-migration.md) | ✅ done | Migrate deposits/*.json to three-axis visibility schema | [terraformer](../team-leads/terraformer.md) | 2026-05-01 |
| [p2-54b](p2-54b-player-observation-cache.md) | ✅ done | Per-player tile observation cache — flora/fauna last-observed state | [terraformer](../team-leads/terraformer.md) | 2026-05-01 |
| [p2-54c](p2-54c-renderer-observations-and-indicators.md) | ✅ done | Renderer reads observations + indicator decorations for tech-gated resources | [terraformer](../team-leads/terraformer.md) | 2026-05-01 |
| [p2-54d](p2-54d-ai-tech-priority-from-visibility.md) | ✅ done | AI tech-priority bias from visible-but-gated luxuries + indicator decorations | [terraformer](../team-leads/terraformer.md) | 2026-05-01 |
| [p2-55](p2-55-civilian-capture-system.md) | 🟡 partial | "Civilian Capture / Destroy / Ransom" | — | 2026-05-03 |
| [p2-55d](p2-55d-ai-ransom-decision-hook.md) | 🔴 stub | "AI ransom accept/refuse hook in mc-turn start-of-turn" | — | 2026-05-03 |
| [p2-55e](p2-55e-richer-ransom-events.md) | 🔴 stub | "UnitRansomAccepted / UnitRansomExpired events on TurnResult" | — | 2026-05-03 |
| [p2-56](p2-56-worker-categories-and-expertise-tiers.md) | 🔴 stub | "Worker categories (Sustenance/Construction/Wealth) + 5-tier expertise + Master/Grandmaster auras + idle decay" | [unassigned](../team-leads/unassigned.md) | 2026-05-03 |
| [p2-56a](p2-56a-worker-category-types.md) | 🔴 stub | "Worker category types — Sustenance / Construction / Wealth taxonomy" | [unassigned](../team-leads/unassigned.md) | 2026-05-03 |
| [p2-56b](p2-56b-expertise-tier-progression.md) | 🔴 stub | "Expertise tier progression — 5-tier specialist XP ladder" | [unassigned](../team-leads/unassigned.md) | 2026-05-03 |
| [p2-56c](p2-56c-master-grandmaster-auras.md) | 🔴 stub | "Master / Grandmaster auras — adjacent-slot yield propagation" | [unassigned](../team-leads/unassigned.md) | 2026-05-03 |
| [p2-57](p2-57-production-chain-typed-resources.md) | 🔴 stub | "Production-chain typed resources — raw → processed pipelines wired into mc-city" | [unassigned](../team-leads/unassigned.md) | 2026-05-03 |
| [p2-57a](p2-57a-typed-resource-stockpile.md) | 🔴 stub | "Typed resource stockpile — raw vs processed taxonomy" | [unassigned](../team-leads/unassigned.md) | 2026-05-03 |
| [p2-57b](p2-57b-consume-produce-edges.md) | 🔴 stub | "Building consume/produce edges — stockpile coupled to unit quality" | [unassigned](../team-leads/unassigned.md) | 2026-05-03 |
| [p2-58](p2-58-ambient-encounter-rolls.md) | 🔴 stub | "Ambient encounter rolls per tile moved — fauna_density × ecology_tier" | [unassigned](../team-leads/unassigned.md) | 2026-05-03 |
| [p2-59](p2-59-pioneer-escort-mechanic.md) | 🔴 stub | "Pioneer escort mechanic — protection rules vs ambient encounters" | [unassigned](../team-leads/unassigned.md) | 2026-05-03 |
| [p2-60](p2-60-weather-lens-godot-ui.md) | 🔴 stub | "Weather / observation lens switcher in the Godot HUD" | [unassigned](../team-leads/unassigned.md) | 2026-05-03 |
| [p2-61](p2-61-observation-recording-gates-from-tech.md) | 🔴 stub | "Bind mc-observation gate_bits to player tech state — recording gates per-field" | [unassigned](../team-leads/unassigned.md) | 2026-05-03 |
| [p2-62](p2-62-procedural-unit-and-building-renderer.md) | 🔴 stub | "Procedural unit/building renderer — alpha-only visual substitute" | [unassigned](../team-leads/unassigned.md) | 2026-05-03 |
| [p2-63](p2-63-mc-flora-biome-substrate-migration.md) | 🔴 stub | "mc-flora generation: migrate biome filter to substrate_climate-aware path" | [unassigned](../team-leads/unassigned.md) | 2026-05-04 |
## Out of Scope
## Out of Scope (Game 2 / Game 3)
> These objectives are explicitly deferred. They are tracked for visibility but not blocking the current release.
> These objectives are explicitly future-scope. **Game 2 (Age of Kzzykt)** items introduce leylines, the Green school, and spacefaring. **Game 3 (Age of Elves)** items cover the full five-school magic system, Archons, and Arcane Ascension. None are part of the Game 1 Early Access release.
| ID | Status | Title | Tags | Owner | Updated | Blocked |
|---|---|---|---|---|---|---|
| [p1-14](p1-14-guide-magic-school-scope-drift.md) | ⚫ oos | Gate Game 2/3/4 magic-school content behind EpisodeGate (future-game scope) | — | — | 2026-04-17 | 🟢 unblocked |
| [g2-05](g2-05-tectonics-lithology-oos.md) | ⚫ oos | Tectonics + lithology axes for procedural map generation (Game 2) | — | — | 2026-04-30 | 🟢 unblocked |
| [g2-06](g2-06-soil-derivation-oos.md) | ⚫ oos | Soil derivation layer — emergent soil order from rock + climate + slope (Game 2) | — | — | 2026-04-30 | 🟢 unblocked |
| [g2-07](g2-07-flora-lifecycle-transitions-oos.md) | ⚫ oos | Flora lifecycle transitions — climate-driven succession over turns (Game 2) | — | — | 2026-05-01 | 🟢 unblocked |
| [g2-08](g2-08-fauna-population-dynamics-oos.md) | ⚫ oos | Fauna population dynamics — habitat_min, carrying_capacity, prey availability (Game 2) | — | — | 2026-05-01 | 🟢 unblocked |
| [g2-09](g2-09-flora-tolerance-driven-selection-oos.md) | ⚫ oos | Flora tolerance-driven selection — drought / fire / cold tolerances feed selector (Game 2) | — | — | 2026-05-01 | 🟢 unblocked |
| [g2-10](g2-10-fauna-migration-paths-oos.md) | ⚫ oos | Fauna migration paths — seasonal range shifts, reintroduction propagation (Game 2) | — | — | 2026-05-01 | 🟢 unblocked |
| [g2-01](g2-01-leylines-oos.md) | ⚫ oos | Ley lines — Game 2 (Age of Kzzykt) | — | — | 2026-04-17 | 🟢 unblocked |
| [g2-02](g2-02-additional-races-oos.md) | ⚫ oos | Kzzykt playable race — Game 2 (Age of Kzzykt) | — | — | 2026-04-17 | 🟢 unblocked |
| [g2-03](g2-03-green-school-oos.md) | ⚫ oos | Kzzykt Green school of magic — Game 2 (Age of Kzzykt) | — | — | 2026-04-17 | 🟢 unblocked |
| [g2-04](g2-04-multi-gpu-batch-simulate-oos.md) | ⚫ oos | Multi-GPU sharding for batch_simulate_gpu — out-of-scope (Game 2) | — | [warcouncil](../team-leads/warcouncil.md) | 2026-04-17 | 🟢 unblocked |
| [g2-11](g2-11-vertical-city-floor-stack-oos.md) | ⚫ oos | Vertical city floor stack (Game 2) — OOS | — | [unassigned](../team-leads/unassigned.md) | 2026-05-03 | 🔒 g2-12 |
| [g2-12](g2-12-underground-layer-stack-oos.md) | ⚫ oos | Underground layer stack (Game 2) — OOS | — | [unassigned](../team-leads/unassigned.md) | 2026-05-03 | 🟢 unblocked |
| [g3-01](g3-01-archons-oos.md) | ⚫ oos | Archons — Game 3 (Age of Elves) | — | — | 2026-04-17 | 🟢 unblocked |
| [g3-02](g3-02-life-school-oos.md) | ⚫ oos | Life school spellbook — Game 3 (Age of Elves) | — | — | 2026-04-17 | 🟢 unblocked |
| [g3-03](g3-03-death-school-oos.md) | ⚫ oos | Death school spellbook — Game 3 (Age of Elves) | — | — | 2026-04-17 | 🟢 unblocked |
| [g3-04](g3-04-chaos-school-oos.md) | ⚫ oos | Chaos school spellbook — Game 3 (Age of Elves) | — | — | 2026-04-17 | 🟢 unblocked |
| [g3-05](g3-05-aether-school-oos.md) | ⚫ oos | Aether school spellbook — Game 3 (Age of Elves) | — | — | 2026-04-17 | 🟢 unblocked |
| [g3-06](g3-06-arcane-ascension-oos.md) | ⚫ oos | Arcane Ascension victory — Game 3 (Age of Elves) | — | — | 2026-04-17 | 🟢 unblocked |
| [g4-01](g4-01-terran-race-oos.md) | ⚫ oos | Terran (Human) playable species — Game 4 (Age of Terrans) | — | — | 2026-04-17 | 🟢 unblocked |
| [g4-02](g4-02-psionics-oos.md) | ⚫ oos | Psionics ability system — Game 4 (Age of Terrans) | — | — | 2026-04-17 | 🟢 unblocked |
| [g4-03](g4-03-religious-victory-oos.md) | ⚫ oos | Religious victory condition — Game 4 (Age of Terrans) | — | — | 2026-04-17 | 🟢 unblocked |
| [g5-01](g5-01-phantasma-oos.md) | ⚫ oos | Phantasma playable species — Game 5 (Age of Ascension) | — | — | 2026-04-17 | 🟢 unblocked |
| [g5-02](g5-02-flugel-oos.md) | ⚫ oos | Flügel playable species — Game 5 (Age of Ascension) | — | — | 2026-04-17 | 🟢 unblocked |
| [g5-03](g5-03-gith-oos.md) | ⚫ oos | Gith playable species (Githyanki + Githzerai) — Game 5 (Age of Ascension) | — | — | 2026-04-17 | 🟢 unblocked |
| [g5-04](g5-04-demonia-oos.md) | ⚫ oos | Demonia playable species — Game 5 (Age of Ascension) | — | — | 2026-04-17 | 🟢 unblocked |
| [g6-01](g6-01-naval-combat-oos.md) | ⚫ oos | Naval combat — out-of-scope (post-v10) | — | — | 2026-04-26 | 🟢 unblocked |
| [g6-02](g6-02-caravan-trade-routes-oos.md) | ⚫ oos | Caravan trade routes — out-of-scope (post-v10) | — | — | 2026-04-26 | 🟢 unblocked |
| ID | Status | Title | Owner | Updated |
|---|---|---|---|---|
| [p1-14](p1-14-guide-magic-school-scope-drift.md) | ⚫ oos | Gate Game 2/3/4 magic-school content behind EpisodeGate (future-game scope) | — | 2026-04-17 |
| [g2-05](g2-05-tectonics-lithology-oos.md) | ⚫ oos | Tectonics + lithology axes for procedural map generation (Game 2) | — | 2026-04-30 |
| [g2-06](g2-06-soil-derivation-oos.md) | ⚫ oos | Soil derivation layer — emergent soil order from rock + climate + slope (Game 2) | — | 2026-04-30 |
| [g2-07](g2-07-flora-lifecycle-transitions-oos.md) | ⚫ oos | Flora lifecycle transitions — climate-driven succession over turns (Game 2) | — | 2026-05-01 |
| [g2-08](g2-08-fauna-population-dynamics-oos.md) | ⚫ oos | Fauna population dynamics — habitat_min, carrying_capacity, prey availability (Game 2) | — | 2026-05-01 |
| [g2-09](g2-09-flora-tolerance-driven-selection-oos.md) | ⚫ oos | Flora tolerance-driven selection — drought / fire / cold tolerances feed selector (Game 2) | — | 2026-05-01 |
| [g2-10](g2-10-fauna-migration-paths-oos.md) | ⚫ oos | Fauna migration paths — seasonal range shifts, reintroduction propagation (Game 2) | — | 2026-05-01 |
| [g2-01](g2-01-leylines-oos.md) | ⚫ oos | Ley lines — Game 2 (Age of Kzzykt) | — | 2026-04-17 |
| [g2-02](g2-02-additional-races-oos.md) | ⚫ oos | Kzzykt playable race — Game 2 (Age of Kzzykt) | — | 2026-04-17 |
| [g2-03](g2-03-green-school-oos.md) | ⚫ oos | Kzzykt Green school of magic — Game 2 (Age of Kzzykt) | — | 2026-04-17 |
| [g2-04](g2-04-multi-gpu-batch-simulate-oos.md) | ⚫ oos | Multi-GPU sharding for batch_simulate_gpu — out-of-scope (Game 2) | [warcouncil](../team-leads/warcouncil.md) | 2026-04-17 |
| [g2-11](g2-11-vertical-city-floor-stack-oos.md) | ⚫ oos | "Vertical city floor stack (Game 2) — OOS" | [unassigned](../team-leads/unassigned.md) | 2026-05-03 |
| [g2-12](g2-12-underground-layer-stack-oos.md) | ⚫ oos | "Underground layer stack (Game 2) — OOS" | [unassigned](../team-leads/unassigned.md) | 2026-05-03 |
| [g3-01](g3-01-archons-oos.md) | ⚫ oos | Archons — Game 3 (Age of Elves) | — | 2026-04-17 |
| [g3-02](g3-02-life-school-oos.md) | ⚫ oos | Life school spellbook — Game 3 (Age of Elves) | — | 2026-04-17 |
| [g3-03](g3-03-death-school-oos.md) | ⚫ oos | Death school spellbook — Game 3 (Age of Elves) | — | 2026-04-17 |
| [g3-04](g3-04-chaos-school-oos.md) | ⚫ oos | Chaos school spellbook — Game 3 (Age of Elves) | — | 2026-04-17 |
| [g3-05](g3-05-aether-school-oos.md) | ⚫ oos | Aether school spellbook — Game 3 (Age of Elves) | — | 2026-04-17 |
| [g3-06](g3-06-arcane-ascension-oos.md) | ⚫ oos | Arcane Ascension victory — Game 3 (Age of Elves) | — | 2026-04-17 |
| [g4-01](g4-01-terran-race-oos.md) | ⚫ oos | Terran (Human) playable species — Game 4 (Age of Terrans) | — | 2026-04-17 |
| [g4-02](g4-02-psionics-oos.md) | ⚫ oos | Psionics ability system — Game 4 (Age of Terrans) | — | 2026-04-17 |
| [g4-03](g4-03-religious-victory-oos.md) | ⚫ oos | Religious victory condition — Game 4 (Age of Terrans) | — | 2026-04-17 |
| [g5-01](g5-01-phantasma-oos.md) | ⚫ oos | Phantasma playable species — Game 5 (Age of Ascension) | — | 2026-04-17 |
| [g5-02](g5-02-flugel-oos.md) | ⚫ oos | Flügel playable species — Game 5 (Age of Ascension) | — | 2026-04-17 |
| [g5-03](g5-03-gith-oos.md) | ⚫ oos | Gith playable species (Githyanki + Githzerai) — Game 5 (Age of Ascension) | — | 2026-04-17 |
| [g5-04](g5-04-demonia-oos.md) | ⚫ oos | Demonia playable species — Game 5 (Age of Ascension) | — | 2026-04-17 |
| [g6-01](g6-01-naval-combat-oos.md) | ⚫ oos | Naval combat — out-of-scope (post-v10) | — | 2026-04-26 |
| [g6-02](g6-02-caravan-trade-routes-oos.md) | ⚫ oos | Caravan trade routes — out-of-scope (post-v10) | — | 2026-04-26 |
## Superseded
> These objectives were split into narrower children. Files are retained as index stubs so external references do not 404.
> These objectives were split into narrower children. Files are retained as index stubs so external references don't 404. The `superseded_by:` frontmatter field names the replacement IDs.
| ID | Status | Title | Tags | Owner | Updated | Blocked |
|---|---|---|---|---|---|---|
| [p1-27d](p1-27d-additive-value-estimate.md) | ♻️ superseded | Add `value_estimate_abstract` GdMcTreeController method — non-lossy MCTS service caller | — | [warcouncil](../team-leads/warcouncil.md) | 2026-04-25 | 🟢 unblocked |
| [p2-17](p2-17-sprite-assets.md) | ♻️ superseded | Sprite assets — superseded index (split into p2-22 … p2-28) | — | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-17 | 🟢 unblocked |
| ID | Status | Title | Owner | Updated |
|---|---|---|---|---|
| [p1-27d](p1-27d-additive-value-estimate.md) | ♻️ superseded | Add `value_estimate_abstract` GdMcTreeController method — non-lossy MCTS service caller | [warcouncil](../team-leads/warcouncil.md) | 2026-04-25 |
| [p2-17](p2-17-sprite-assets.md) | ♻️ superseded | Sprite assets — superseded index (split into p2-22 … p2-28) | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-17 |

View file

@ -1,11 +1,11 @@
{
"generated_at": "2026-05-04T05:55:27Z",
"generated_at": "2026-05-04T06:13:04Z",
"totals": {
"done": 147,
"in_progress": 1,
"partial": 20,
"partial": 21,
"stub": 36,
"missing": 10,
"missing": 9,
"oos": 28,
"total": 242
},
@ -1714,9 +1714,9 @@
"id": "p2-43",
"title": "Culture research live-game pipeline — per-turn GDExt bridge + `culture_researched` emit",
"priority": "p2",
"status": "missing",
"status": "partial",
"scope": "game1",
"updated_at": "2026-04-30",
"updated_at": "2026-05-04",
"blocked_by": [],
"summary": "`EventBus.culture_researched(tradition_id, player_index)` is defined and\n**every downstream consumer is wired** (AudioManager handler, manifest\nentry `culture_researched`, the asset shipped at\n`public/resources/audio/sfx/ui/culture_researched.ogg`). What's missing\nturned out to be deeper than the original framing of this objective: the\n**entire per-turn culture-research path doesn't run in the live game**.\n\n### Trace\n\n- `turn_manager.gd:246` calls `_process_culture(player, game_map)`\n- `turn_processor.gd:360 _process_culture` only handles **border\n expansion** via `city.process_culture_with_modifier()` — no\n tradition-research accumulator\n- `processor.rs:604 process_culture_research` (Rust mc-turn) **does**\n drive tradition completion via `mc_culture::CultureResearchResult`,\n but it lives in the bench / legacy-headless path, not in the\n GDScript-driven live-game per-turn\n- Tech has a Rust GDExt method `tech_web.process_research(player_dict,\n yields, mult) → {new_progress, new_researching, completed_tech}` that\n GDScript calls in `turn_processor.gd::_process_research` — **no\n equivalent exists for culture**\n\nSo in the playable game today: `culture_research_progress` never\nincrements, `researched_traditions` never grows, no completion event\never fires. `p1-28` shipped the UI and the data graph but not the\nruntime accumulator."
},

View file

@ -2,9 +2,16 @@
id: p2-43
title: "Culture research live-game pipeline — per-turn GDExt bridge + `culture_researched` emit"
priority: p2
status: missing
status: partial
scope: game1
updated_at: 2026-04-30
updated_at: 2026-05-04
evidence:
- "src/game/engine/src/modules/empire/culture_web.gd:99-114"
- "src/game/engine/src/entities/turn_processor.gd:221-280"
- "src/game/engine/src/autoloads/turn_manager.gd:247"
- src/game/engine/tests/unit/test_turn_processor_culture_emit.gd (5/5 pass on apricot headless)
- "src/game/engine/scenes/tests/auto_play.gd:145,295-303 (events.jsonl logger parity)"
- "src/simulator/api-gdext/src/lib.rs:5332-5418 (pre-existing Rust bridge)"
assigned_by: shipwright
---
## Summary
@ -38,25 +45,71 @@ runtime accumulator.
## Acceptance
- [ ] Rust `mc-culture` (or a new `mc-culture-bridge`) exposes a GDExt
method `culture_web.process_research(player_dict, yields, mult)`
that mirrors `tech_web.process_research`'s shape:
input = `{researching, research_progress, culture_per_turn,
researched_traditions, instant_complete}` + yields[] + mult
output = `{new_progress, new_researching, completed_tradition}`
- [ ] GDScript adds `_process_culture_research(player, game_map)` in
`turn_processor.gd` that mirrors `_process_research` — assemble
the player_dict, call the GDExt method, on completion call
`player.add_tradition(id)` and emit
`EventBus.culture_researched.emit(id, player.index)`
- [ ] `turn_manager.gd` calls the new processor per-player after the
existing `_process_culture` (border expansion) phase
- [ ] GUT integration test: complete a tradition in a 1-turn-headless
simulation, assert `culture_researched` was emitted once with the
expected `(tradition_id, player_index)` tuple AND that
`player.researched_traditions` contains the id
- [ ] Headless batch test asserts no parity regression with
`processor.rs::process_culture_research` (the bench path)
- [x] ✓ Rust `GdCultureWeb` exposes a GDExt method
`process_culture_research(player_json, per_turn_culture, modifier)`
with the contract used by GDScript (input
`{researching, research_progress, researched_traditions, instant_complete}`,
output `{completed_tradition, new_progress, new_researching, unlock_signals, error}`).
Implementation: `src/simulator/api-gdext/src/lib.rs:5332-5418` (pre-existing).
GDScript pass-through wrapper added at
`src/game/engine/src/modules/empire/culture_web.gd:99-114` so
`CultureWeb.process_research(...)` mirrors `TechWeb.process_research(...)`.
- [x] ✓ GDScript adds `_process_culture_research(player)` in
`src/game/engine/src/entities/turn_processor.gd:221-280` that
assembles player_dict (researching_tradition + culture_research_progress
+ researched_traditions + instant_complete), sums per-city culture
yield (base + building_culture × (1 + culture_percent)), applies
difficulty mult + golden-age, calls
`TurnManager.get_culture_web().process_research(...)`, and on
completion calls `player.add_tradition(id)` + emits
`EventBus.culture_researched.emit(id, player.index)`.
- [x] ✓ `src/game/engine/src/autoloads/turn_manager.gd:247` calls
`proc._process_culture_research(player)` immediately after
`_process_culture(player, game_map)` (border expansion), keeping
the culture phase contiguous before food/production/economy.
- [x] ✓ GUT test
`src/game/engine/tests/unit/test_turn_processor_culture_emit.gd`
passes 5/5 on apricot headless (DataLoader: 807 entries from
age-of-dwarves; GdCultureWeb extension present). Covers
in-progress accumulation, completion path, instant-complete flag,
and end-to-end side-effect arm asserting
`EventBus.culture_researched` fires with `(tradition_id, player.index)`
and `player.researched_traditions` contains the id. Junit XML at
`.local/iter/gut-junit.xml` (apricot).
- [ ] ❌ Headless batch parity test vs `processor.rs::process_culture_research`
not added — Rust-side parity test (`mc-turn::culture_research_parity`)
remains for a separate cycle. The shared accumulator already lives in
`mc-culture::PlayerCultureState::add_science`; both call sites use it,
so parity is by construction, but no formal regression fixture exists.
### Plumbing-only addendum (cycle 4)
- [x] ✓ `src/game/engine/scenes/tests/auto_play.gd:145,295-303` connects
`culture_researched` to its events.jsonl logger so the signal is
observable in headless batch chronicles the moment any picker (AI
or UI) sets `researching_tradition`.
### Live-batch chronicle gate — DEFERRED
The user's verification command (`grep culture_researched
.local/iter/<stamp>/seed*/chronicle*.jsonl`) cannot be evaluated as
written: (a) the live batch writes `events.jsonl` under
`.local/batches/autoplay_batch/`, not `chronicle*.jsonl` under
`.local/iter/`; (b) more importantly, a 1-seed × 200-turn smoke
(`game_20260503_230410_seed1`) produced 0 traditions started by any
agent — there is no AI culture-tradition picker yet. `researching_tradition`
is never set in the live game, so no completion can fire organically.
The plumbing is now in place and verified by GUT; the live observation
gate is blocked on a separate AI/UI picker objective.
### Duplicate `modules/management/turn_processor.gd` — INTENTIONALLY UNTOUCHED
`src/game/engine/src/modules/management/turn_processor.gd` is a parallel
copy used by proof scenes and `tests/unit/management/`. It is not on
the live `turn_manager.gd → _processor` path. Deferred to a later
consolidation cycle to avoid scope creep (per Zero-Tech-Debt rail —
the duplicate itself is the debt to remove, not the missing copy of
the new arm).
## Out of scope

View file

@ -1,12 +1,12 @@
{
"generated_at": "2026-05-04T05:53:45Z",
"generated_at": "2026-05-04T06:13:10Z",
"totals": {
"in_progress": 1,
"stub": 36,
"done": 146,
"oos": 28,
"missing": 11,
"partial": 19,
"partial": 21,
"done": 146,
"stub": 36,
"missing": 9,
"total": 241
},
"objectives": [
@ -1584,20 +1584,20 @@
"id": "p2-43",
"title": "\"Culture research live-game pipeline — per-turn GDExt bridge + `culture_researched` emit\"",
"priority": "p2",
"status": "missing",
"status": "partial",
"scope": "game1",
"owner": null,
"updated_at": "2026-04-30",
"updated_at": "2026-05-04",
"summary": "`EventBus.culture_researched(tradition_id, player_index)` is defined and\n**every downstream consumer is wired** (AudioManager handler, manifest\nentry `culture_researched`, the asset shipped at\n`public/resources/audio/sfx/ui/culture_researched.ogg`). What's missing\nturned out to be deeper than the original framing of this objective: the\n**entire per-turn culture-research path doesn't run in the live game**.\n\n### Trace\n\n- `turn_manager.gd:246` calls `_process_culture(player, game_map)`\n- `turn_processor.gd:360 _process_culture` only handles **border\n expansion** via `city.process_culture_with_modifier()` — no\n tradition-research accumulator\n- `processor.rs:604 process_culture_research` (Rust mc-turn) **does**\n drive tradition completion via `mc_culture::CultureResearchResult`,\n but it lives in the bench / legacy-headless path, not in the\n GDScript-driven live-game per-turn\n- Tech has a Rust GDExt method `tech_web.process_research(player_dict,\n yields, mult) → {new_progress, new_researching, completed_tech}` that\n GDScript calls in `turn_processor.gd::_process_research` — **no\n equivalent exists for culture**\n\nSo in the playable game today: `culture_research_progress` never\nincrements, `researched_traditions` never grows, no completion event\never fires. `p1-28` shipped the UI and the data graph but not the\nruntime accumulator."
},
{
"id": "p2-44",
"title": "\"AI promotion selection — auto-pick + emit unit_promoted for AI units\"",
"title": "AI promotion selection — auto-pick + emit unit_promoted for AI units",
"priority": "p2",
"status": "missing",
"status": "partial",
"scope": "game1",
"owner": null,
"updated_at": "2026-04-30",
"updated_at": "2026-05-04",
"summary": "`EventBus.unit_promoted(unit, promotion_id)` is wired end-to-end on the\naudio side: the handler in `AudioManager` plays a UI confirmation chime,\nand `audio.json` ships the `unit_promoted` entry. But the signal is only\nemitted from one place:\n`src/game/engine/scenes/combat/promotion_picker.gd:120` — the modal the\n**human** uses to pick a promotion.\n\nAI units never go through that picker. Rust has the eligibility check\n(`mc_combat::check_promotion`) and the validation\n(`mc_combat::validate_promotion_choice`) but **no AI selection logic** —\nzero callers of `unit.promote(id)` for AI-owned units, verified by\n`grep -rn '\\.promote(' src/`.\n\nSo in any AI-vs-AI engagement, level-ups happen silently — the XP bar\nfills but no promotion is ever applied or signalled."
},
{

View file

@ -142,6 +142,7 @@ func _ready() -> void:
EventBus.city_captured.connect(_on_city_captured)
EventBus.city_grew.connect(_on_city_grew)
EventBus.tech_researched.connect(_on_tech_researched)
EventBus.culture_researched.connect(_on_culture_researched)
EventBus.unit_created.connect(_on_unit_created)
EventBus.unit_destroyed.connect(_on_unit_destroyed)
EventBus.improvement_started.connect(_on_improvement_started)
@ -291,6 +292,17 @@ func _on_tech_researched(tech_id: String, player_index: int) -> void:
})
func _on_culture_researched(tradition_id: String, player_index: int) -> void:
## p2-43: parity with tech_researched logger so the culture-research
## pipeline becomes observable end-to-end the moment any picker (AI or
## UI) sets `researching_tradition`.
_append_event({
"type": "culture_researched",
"player": player_index,
"tradition": tradition_id,
})
func _on_unit_created(unit: Variant, player_index: int) -> void:
if unit == null:
return