From b38827d48eda2dca55623cb6db24cf0ae31ad5b3 Mon Sep 17 00:00:00 2001 From: Natalie Date: Thu, 7 May 2026 16:54:54 -0700 Subject: [PATCH] =?UTF-8?q?fix(@projects/@magic-civilization):=20?= =?UTF-8?q?=F0=9F=90=9B=20update=20p2-46=20status=20to=20done?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .project/objectives/DASHBOARD_CATEGORIES.md | 2 +- .project/objectives/DASHBOARD_COMPLETED.md | 1 + .project/objectives/README.md | 7 +++---- .project/objectives/objectives.json | 12 ++++++------ .project/objectives/p3-13b-geological-events.md | 6 ++++-- .project/objectives/p3-13c-biological-events.md | 2 ++ .project/objectives/p3-13d-anomalous-events.md | 4 +++- 7 files changed, 20 insertions(+), 14 deletions(-) diff --git a/.project/objectives/DASHBOARD_CATEGORIES.md b/.project/objectives/DASHBOARD_CATEGORIES.md index 0cc37608..1115e948 100644 --- a/.project/objectives/DASHBOARD_CATEGORIES.md +++ b/.project/objectives/DASHBOARD_CATEGORIES.md @@ -284,7 +284,7 @@ | [p2-44a](p2-44a-dataloader-promotion-trees-path.md) | ✅ done | P2 | DataLoader path mismatch — `get_promotion(\"trees\")` returns empty | [unassigned](../team-leads/unassigned.md) | 🟢 | | [p2-44b](p2-44b-promotion-dispatch-instrumentation.md) | ✅ done | P2 | AI promotion dispatch — instrumentation pass to identify the silent gate | [unassigned](../team-leads/unassigned.md) | 🟢 | | [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) | 🟢 | +| [p2-46](p2-46-past-games-archive-replay-viewer.md) | ✅ done | P2 | Past-games archive & replay viewer — `mc-replay` crate, on-disk archive, projection-based playback | [shipwright](../team-leads/shipwright.md) | 🟢 | | [p2-47](p2-47-in-game-statistics-screens.md) | 🟡 partial | P2 | In-game statistics screens — Civ-style 5-tab modal (Demographics / Graphs / Rankings / Replay / Histories) | [shipwright](../team-leads/shipwright.md) | 🟢 | | [p2-48](p2-48-end-of-game-summary-screen.md) | 🟡 partial | P2 | End-of-game summary screen — outcome banner, standings, score graph, awards, timeline, footer actions | [shipwright](../team-leads/shipwright.md) | 🟢 | | [p2-49](p2-49-climate-axes-latitude-continentality.md) | ✅ done | P2 | Climate axes refactor — latitude + continentality + zonal winds as first-class per-hex inputs | [terraformer](../team-leads/terraformer.md) | 🟢 | diff --git a/.project/objectives/DASHBOARD_COMPLETED.md b/.project/objectives/DASHBOARD_COMPLETED.md index e8b4e221..15cab4c0 100644 --- a/.project/objectives/DASHBOARD_COMPLETED.md +++ b/.project/objectives/DASHBOARD_COMPLETED.md @@ -154,6 +154,7 @@ | [p2-44a](p2-44a-dataloader-promotion-trees-path.md) | DataLoader path mismatch — `get_promotion(\"trees\")` returns empty | — | [unassigned](../team-leads/unassigned.md) | 2026-05-06 | | [p2-44b](p2-44b-promotion-dispatch-instrumentation.md) | AI promotion dispatch — instrumentation pass to identify the silent gate | — | [unassigned](../team-leads/unassigned.md) | 2026-05-06 | | [p2-45](p2-45-elimination-reconciliation.md) | Player elimination reconciliation — emit `player_eliminated` on every transition | — | — | 2026-04-30 | +| [p2-46](p2-46-past-games-archive-replay-viewer.md) | Past-games archive & replay viewer — `mc-replay` crate, on-disk archive, projection-based playback | — | [shipwright](../team-leads/shipwright.md) | 2026-05-07 | | [p2-49](p2-49-climate-axes-latitude-continentality.md) | 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) | 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) | Player-facing world-shape parameters on new-game screen | — | [terraformer](../team-leads/terraformer.md) | 2026-05-01 | diff --git a/.project/objectives/README.md b/.project/objectives/README.md index 967a9adf..7fff1233 100644 --- a/.project/objectives/README.md +++ b/.project/objectives/README.md @@ -16,9 +16,9 @@ |---|---|---|---|---|---|---|---| | **P0** | 0 | 0 | 0 | 0 | 0 | 44 | 44 | | **P1** | 1 | 13 | 1 | 5 | 1 | 55 | 76 | -| **P2** | 0 | 9 | 11 | 0 | 6 | 68 | 94 | +| **P2** | 0 | 8 | 11 | 0 | 6 | 69 | 94 | | **P3 (oos)** | 0 | 7 | 6 | 0 | 21 | 9 | 43 | -| **total** | **1** | **29** | **18** | **5** | **28** | **176** | **257** | +| **total** | **1** | **28** | **18** | **5** | **28** | **177** | **257** | @@ -29,7 +29,7 @@ | [unassigned](../team-leads/unassigned.md) | 19 | | [asset-sprite](../team-leads/asset-sprite.md) | 6 | | [combat-dev](../team-leads/combat-dev.md) | 6 | -| [shipwright](../team-leads/shipwright.md) | 5 | +| [shipwright](../team-leads/shipwright.md) | 4 | | [testwright](../team-leads/testwright.md) | 3 | | [warcouncil](../team-leads/warcouncil.md) | 2 | | [asset-audio](../team-leads/asset-audio.md) | 1 | @@ -79,7 +79,6 @@ | [p2-10k](p2-10k-gdlint-cleanup.md) | 🟡 partial | CI: fix 51 gdlint violations so Stage 3 is hard-green | — | [testwright](../team-leads/testwright.md) | 2026-05-07 | 🟢 unblocked | | [p2-10l](p2-10l-gut-regression-triage.md) | 🟡 partial | CI: fix 15 GUT regressions so Stage 5 is hard-green | — | [testwright](../team-leads/testwright.md) | 2026-05-07 | 🟢 unblocked | | [p2-18](p2-18-guide-public-deployment.md) | 🟡 partial | Guide web app — public hosting + deploy pipeline | — | — | 2026-04-17 | 🟢 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-07 | 🟢 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-07 (cycle-51) | 🟢 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 | — | [combat-dev](../team-leads/combat-dev.md) | 2026-05-07 | 🟢 unblocked | diff --git a/.project/objectives/objectives.json b/.project/objectives/objectives.json index 3833f6cd..08da3900 100644 --- a/.project/objectives/objectives.json +++ b/.project/objectives/objectives.json @@ -1,9 +1,9 @@ { - "generated_at": "2026-05-07T18:35:10Z", + "generated_at": "2026-05-07T23:50:58Z", "totals": { - "done": 176, + "done": 177, "in_progress": 1, - "partial": 29, + "partial": 28, "stub": 18, "missing": 5, "oos": 28, @@ -1841,7 +1841,7 @@ "id": "p2-46", "title": "Past-games archive & replay viewer — `mc-replay` crate, on-disk archive, projection-based playback", "priority": "p2", - "status": "partial", + "status": "done", "scope": "game1-stretch", "owner": "shipwright", "updated_at": "2026-05-07", @@ -2808,7 +2808,7 @@ "status": "partial", "scope": "game1", "owner": "unassigned", - "updated_at": "2026-05-05", + "updated_at": "2026-05-07", "blocked_by": [], "summary": "" }, @@ -2998,7 +2998,7 @@ }, { "owner": "shipwright", - "remaining": 5 + "remaining": 4 }, { "owner": "testwright", diff --git a/.project/objectives/p3-13b-geological-events.md b/.project/objectives/p3-13b-geological-events.md index dd2a32f5..3fb332dd 100644 --- a/.project/objectives/p3-13b-geological-events.md +++ b/.project/objectives/p3-13b-geological-events.md @@ -5,13 +5,15 @@ priority: p3 status: partial scope: game1 owner: unassigned -updated_at: 2026-05-05 +updated_at: 2026-05-07 evidence: - "src/simulator/crates/mc-mapgen/src/events.rs:142-256 — derive_events emits earthquake/volcanic_eruption/landslide gated by boundary_kind / plate_kind+mountain_proximity / mountain_proximity+moisture" - "src/simulator/crates/mc-mapgen/src/events.rs:25-39 — typed GeologicalEvent struct (kind-tagged like WeatherEvent in p3-13a)" - "src/simulator/crates/mc-mapgen/src/events.rs:262-372 — 6 tests passing (cargo test -p mc-mapgen events::): earthquake_only_at_plate_boundary, volcanic_eruption_only_on_volcanic_plate, landslide_requires_slope_and_saturation, determinism_same_seed_same_events, no_events_in_neutral_grid, thresholds_load_from_spec_json" - "public/resources/events/geological_thresholds.json — trigger thresholds tuned to EVENT_FREQUENCY_SPEC.md (seismic ~0.003/turn, volcanic ~0.002/turn)" - "src/simulator/crates/mc-mapgen/src/lib.rs:18-19 — re-exports derive_geological_events / GeologicalEvent / GeologicalThresholds" + - "src/simulator/crates/mc-sim/src/event_dispatch.rs — dispatch_world_events calls derive_geological_events; geo events routed through mc-ecology::tile::apply_damage (Land + Air channels) and ChronicleEntry::WorldEvent; dispatched in mc-sim (above the mc-turn cycle boundary)" + - "cargo test -p mc-sim p3_13_event_dispatch_geological_applies_land_damage: PASS" blocked_by: [] --- ## Context @@ -24,7 +26,7 @@ blocked_by: [] - ✓ Each event variant emitted as kind-tagged `GeologicalEvent` struct (mirrors `WeatherEvent` shape from p3-13a — no separate enum, kind in a String field for serde wire compat). (`src/simulator/crates/mc-mapgen/src/events.rs:25-39`) - ❌ Roll seeded via `seed::derive(SeedDomain::Geological, turn, tile)`. Used the same inline `det_roll(seed, turn, col, row, channel)` splitmix64 mixer as p3-13a's WeatherEvent. Byte-equivalent determinism contract; no `SeedDomain::Geological` variant added (would need a save-format bump). Tracked in follow-ups. - ❌ `is_active_volcano: bool` tile property — the field does not exist on `TileState`. Closest available proxy used: `plate_kind ∈ {VOLCANIC_ARC, HOTSPOT}` gates the eruption branch, with `mountain_proximity` standing in for `magma_pressure`. Documented inline (`events.rs:60-67`). Tracked in follow-ups. -- ❌ `mc-ecology::tile::apply_damage` wiring — out of scope per task brief ("Add 3 geological event types to the appropriate derive function"). The pure derivation pass returns `Vec`; an apply pass is a follow-up that needs a turn-pipeline integration point analogous to the existing weather → EventBus route. +- ✓ `mc-ecology::tile::apply_damage` wiring — `mc-sim::event_dispatch::dispatch_world_events` routes each `GeologicalEvent` through `apply_damage(TileEcoState, DamageChannel::Land, severity)` (and additionally Air for volcanic_eruption). Dispatch lives in mc-sim (not mc-turn) to avoid the mc-turn ← mc-mapgen ← mc-ecology cycle. `ChronicleEntry::WorldEvent` pushed per event. Covered by `p3_13_event_dispatch_geological_applies_land_damage` in mc-sim. (`src/simulator/crates/mc-sim/src/event_dispatch.rs:104-120`) - ✓ `cargo test -p mc-mapgen events::` green — 6 tests including `earthquake_only_at_plate_boundary`, `volcanic_eruption_only_on_volcanic_plate`, `landslide_requires_slope_and_saturation`, `determinism_same_seed_same_events`. (`src/simulator/crates/mc-mapgen/src/events.rs:262-372`) ## Source-of-truth rails diff --git a/.project/objectives/p3-13c-biological-events.md b/.project/objectives/p3-13c-biological-events.md index b42c626a..93b1ff88 100644 --- a/.project/objectives/p3-13c-biological-events.md +++ b/.project/objectives/p3-13c-biological-events.md @@ -16,6 +16,8 @@ evidence: - "src/simulator/crates/mc-ecology/src/biological.rs:327-357 (plague adjacency spread second pass, HashSet dedup, channel 14)" - "src/simulator/crates/mc-ecology/src/biological.rs:270-324 (migration chain walk, source_pop held constant, max_hops cap)" - "public/games/age-of-dwarves/data/balance/biological_events.json (plague.spread_factor, plague.spread_severity_scale, migration.max_hops added)" + - "src/simulator/crates/mc-sim/src/event_dispatch.rs — dispatch_world_events calls derive_biological_events; Plague events routed through apply_damage (Water channel) into eco_map; Bloom/MigrationPulse chronicle-only (positive/neutral events). Dispatched in mc-sim above the cycle boundary." + - "cargo test -p mc-sim p3_13_event_dispatch_biological_plague_applies_water_damage: PASS" blocked_by: [] --- ## Context diff --git a/.project/objectives/p3-13d-anomalous-events.md b/.project/objectives/p3-13d-anomalous-events.md index 19bad215..4a5a896c 100644 --- a/.project/objectives/p3-13d-anomalous-events.md +++ b/.project/objectives/p3-13d-anomalous-events.md @@ -14,6 +14,8 @@ evidence: - "cargo test -p mc-climate anomalous: 4/4 pass (test_aurora_high_latitude_low_humidity, test_fog_bank_humid_cool_with_cooldown, test_thermal_anomaly_z_threshold_and_volcanic_bonus, thresholds_load_from_spec_json)" - "src/simulator/crates/mc-observation/src/fog.rs (apply_fog, is_fogged, prune_expired, ActiveFog)" - "cargo test -p mc-observation -- fog: 4/4 pass (apply_fog_reduces_sight, fog_dissipates_over_turns, apply_fog_extends_existing_expiry, prune_expired_keeps_active_entries)" + - "src/simulator/crates/mc-sim/src/event_dispatch.rs:159-172 — FogBank → apply_fog(flat_idx, duration, current_turn, &mut state.fog_map) dispatch wired in mc-sim; GameState::fog_map added (HashMap, persisted in save)" + - "cargo test -p mc-sim p3_13_event_dispatch_anomalous_fog_populates_fog_map: PASS" blocked_by: [] --- ## Context @@ -24,7 +26,7 @@ The fourth event family in `public/games/age-of-dwarves/docs/terrain/CLIMATE.md` - ✓ `mc-climate::anomalous::derive_anomalous_events(grid, thresholds, turn, seed, temp_history) -> Vec` emits the three event types per documented rules. Source: `src/simulator/crates/mc-climate/src/anomalous.rs:165` (function declaration). - ✓ Typed enum `AnomalousEvent` with variants `Aurora { col, row }`, `FogBank { col, row, duration }`, `ThermalAnomaly { col, row, z_score }`. Source: `src/simulator/crates/mc-climate/src/anomalous.rs:33-66`. (Lives in `mc-climate` rather than `mc-core::events` — mirrors the sibling p3-13a `WeatherEvent` placement; `mc-core::events` module does not yet exist. See follow-up.) -- ✓ Fog bank applies a temporary visibility reduction via `mc-observation::apply_fog(tile_idx, duration, current_turn, fog)`; expires automatically via lazy expiry on `is_fogged` query. Source: `src/simulator/crates/mc-observation/src/fog.rs`. Verified by `cargo test -p mc-observation -- fog`: 4/4 pass (`apply_fog_reduces_sight`, `fog_dissipates_over_turns`, `apply_fog_extends_existing_expiry`, `prune_expired_keeps_active_entries`). Consumer dispatch (FogBank → apply_fog call site in mc-turn) filed as follow-up — no existing dispatch site in mc-turn yet. +- ✓ Fog bank applies a temporary visibility reduction via `mc-observation::apply_fog(tile_idx, duration, current_turn, fog)`; expires automatically via lazy expiry on `is_fogged` query. Source: `src/simulator/crates/mc-observation/src/fog.rs`. Verified by `cargo test -p mc-observation -- fog`: 4/4 pass. Consumer dispatch wired in `mc-sim::event_dispatch::dispatch_world_events` — FogBank → `apply_fog(flat_idx, duration, current_turn, &mut state.fog_map)`. `GameState::fog_map: HashMap` added to mc-turn (mc-observation has no mc-turn dep, so no cycle). Covered by `p3_13_event_dispatch_anomalous_fog_populates_fog_map`. (`src/simulator/crates/mc-sim/src/event_dispatch.rs:159-172`) - ✓ Thermal anomaly emits only when the tile's temperature z-score exceeds the configured threshold. z-score is computed from a `temp_history: Option<&[Vec]>` arg supplied by the caller (an explicit slice rather than the `&ObservationStore` plumb-through described in the original acceptance — see follow-up). Source: `src/simulator/crates/mc-climate/src/anomalous.rs:228-249`. Threshold gate verified by `test_thermal_anomaly_z_threshold_and_volcanic_bonus`. - ✓ Aurora rolls only on tiles above the latitudinal cutoff. Source: `src/simulator/crates/mc-climate/src/anomalous.rs:171-179`. Cutoff loaded from `climate_spec.json → anomalous.thresholds.aurora_latitude_min` (default 0.75 = polar). Verified by `test_aurora_high_latitude_low_humidity`. (Config currently lives in `climate_spec.json` rather than `climate/_config.json`; see follow-up.) - ✓ `cargo test -p mc-climate` green; 4 new tests under `anomalous::tests`: `test_aurora_high_latitude_low_humidity`, `test_fog_bank_humid_cool_with_cooldown`, `test_thermal_anomaly_z_threshold_and_volcanic_bonus`, `thresholds_load_from_spec_json`. The three name-mandated tests cover each variant + determinism + cooldown + volcanic bonus + spec loading.