From e747d9c7cb0043f825a69124d05048193046eb60 Mon Sep 17 00:00:00 2001 From: Natalie Date: Fri, 8 May 2026 21:28:34 -0700 Subject: [PATCH] =?UTF-8?q?docs(@projects/@magic-civilization):=20?= =?UTF-8?q?=E2=9C=85=20verify=20victory=20json=20parser=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- .project/objectives/p2-48-end-of-game-summary-screen.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.project/objectives/p2-48-end-of-game-summary-screen.md b/.project/objectives/p2-48-end-of-game-summary-screen.md index 8df041df..db2bcf0f 100644 --- a/.project/objectives/p2-48-end-of-game-summary-screen.md +++ b/.project/objectives/p2-48-end-of-game-summary-screen.md @@ -39,7 +39,7 @@ The `GameOver { reason, winner }` event is fired by `mc-turn::end_conditions` (R ## Acceptance - [x] **`mc-turn::end_conditions::GameOver` event** authored with `GameOverReason` enum (`LastSurvivor`, `ConditionMet { condition: VictoryType }`, `TurnLimit`, `Resigned { clan }`) and `winner: Option`. Fired from the turn-end pipeline via `TurnEvent::GameOver` in `events_emitted`. Unit tests: `LastSurvivor` fires when N-1 clans eliminated; `TurnLimit` fires when `turn >= turn_limit` and picks highest-score winner; `Resigned` fires on the player action. ✓ `cargo test -p mc-turn --test game_over_event` — 3/3 pass (`last_survivor_fires_when_one_alive`, `turn_limit_fires_at_max_turns`, `resigned_fires_on_player_action`). `VictoryConfig::turn_limit: Option` added (`#[serde(default)]`). `GameState::pending_resignations: BTreeSet` added. `TurnEvent::GameOver` variant added to `mc-replay::event` with string payload to avoid dep-inversion. -- [-] ◐ **`victory.json` + parser** — `victory.json` authored at `public/games/age-of-dwarves/data/victory.json` with all 6 Game-1 conditions (domination/economic/culture/science/city_count/score) and threshold values mirroring `mc-turn::victory::VictoryConfig` defaults (city_count=28, gold=60k, culture=600k, science_chain=6 techs ascending cost^1.4, turn_limit=500). Parser side: `VictoryConfig::default()` carries identical values; explicit JSON-load helper not yet wired (would supersede `Default` impl). Per-turn `check_victory_at_turn` already evaluates all 6 paths (`mc-turn/src/victory.rs:230-292`). Remaining: `evaluate_conditions(state) -> Option` typed wrapper + per-condition fires-under-crafted-inputs tests. +- [x] **`victory.json` + parser** — `victory.json` authored at `public/games/age-of-dwarves/data/victory.json` with all 6 Game-1 conditions (domination/economic/culture/science/city_count/score) and threshold values mirroring `mc-turn::victory::VictoryConfig` defaults (city_count=28, gold=60k, culture=600k, science_chain=6 techs ascending cost^1.4, turn_limit=500). `mc-turn::end_conditions::load_conditions(json) -> Result` deserialises with `serde_json` and silently ignores `_doc`/`_conditions` advisory fields. ✓ `cargo test -p mc-turn --test victory_json` — 7/7 pass on apricot: `test_victory_json_loads_with_all_six_conditions` (verifies all field values from JSON match doc), plus 6 fires-under-crafted-inputs (`domination`, `economic`, `culture`, `science`, `city_count`, `score`). - [x] **`awards.json` + `compute_awards`** — file authored with the eight awards from the design doc; `mc-replay::compute_awards(history, defs)` returns `Vec`. Tests: each award resolves correctly on a 50-turn fixture; ties broken deterministically (lowest `clan_id`). ✓ `cargo test -p mc-replay --test award_computation` — 2/2 pass (`compute_awards_returns_8`, `compute_awards_handles_ties`). `TurnSnapshot` widened: `buildings_built_total: u32`, `culture_total: f32`. - [x] **`end_game_summary.gd` scene** — single scene skeleton at `src/game/engine/scenes/menus/end_game_summary.gd` with hero strip + four sections (standings, graph, awards, timeline) + five-button footer. Hero strip resolves via `ThemeVocabulary` (`endgame_banner_victory`, `endgame_banner_defeat`, `endgame_banner_gameover` + per-reason flavour keys). Awards section renders one card per `AwardWinner` from `_awards: Array[Dictionary]` passed via `setup()` — no award logic in GDScript (Rail-1). All five footer actions wired. `.tscn` not yet authored (requires godot-engine or godot-renderer); `_awards` population via GdReplayPlayer bridge pending GDExtension wiring. ✓ All strings via ThemeVocabulary. ✓ Rail-1 compliant. - [ ] **All five footer actions wired**: