From 3742f54903d6d71c03459dbcfb1fffdae118ef96 Mon Sep 17 00:00:00 2001 From: Natalie Date: Sun, 26 Apr 2026 13:55:05 -0700 Subject: [PATCH] =?UTF-8?q?feat(@projects/@magic-civilization):=20?= =?UTF-8?q?=E2=9C=85=20mark=20culture=20research=20tree=20as=20complete?= 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 | 10 +++++----- .project/objectives/p1-28-culture-research-tree.md | 8 +++----- public/games/age-of-dwarves/guide/src/data/game.ts | 8 ++++++-- src/simulator/crates/mc-ai/src/tactical/movement.rs | 3 ++- src/simulator/crates/mc-ai/src/tactical/production.rs | 11 ++++++++++- 8 files changed, 31 insertions(+), 19 deletions(-) diff --git a/.project/objectives/DASHBOARD_CATEGORIES.md b/.project/objectives/DASHBOARD_CATEGORIES.md index 979f2d36..5c490a15 100644 --- a/.project/objectives/DASHBOARD_CATEGORIES.md +++ b/.project/objectives/DASHBOARD_CATEGORIES.md @@ -114,7 +114,7 @@ | [p1-25](p1-25-export-script-error-cleanup.md) | βœ… done | P1 | Eliminate parse-error spam in export logs (Unit dup decl + SaveManager stray) | [shipwright](../team-leads/shipwright.md) | 🟒 | | [p1-26](p1-26-tile-placement-preview-ux.md) | 🟑 partial | P1 | Tile-placement UX with effect preview β€” Civ7-style \"where does this go and what changes\" | [shipwright](../team-leads/shipwright.md) | 🟒 | | [p1-27](p1-27-mcts-service-extraction.md) | ❌ missing | P1 | Extract GPU MCTS into a standalone service/client (model-boss-shaped, magic-civ-only) | [warcouncil](../team-leads/warcouncil.md) | 🟒 | -| [p1-28](p1-28-culture-research-tree.md) | 🟑 partial | P1 | Culture research tree β€” real graph, bridge, UI | [shipwright](../team-leads/shipwright.md) | 🟒 | +| [p1-28](p1-28-culture-research-tree.md) | βœ… done | P1 | Culture research tree β€” real graph, bridge, UI | [shipwright](../team-leads/shipwright.md) | 🟒 | | [p2-01](p2-01-minimap-improvements.md) | βœ… done | P2 | Minimap β€” fog reflection and unit markers | [shipwright](../team-leads/shipwright.md) | 🟒 | | [p2-02](p2-02-hud-tooltips.md) | βœ… done | P2 | Tooltips on all HUD elements | [shipwright](../team-leads/shipwright.md) | 🟒 | | [p2-03](p2-03-hotkey-cheat-sheet.md) | βœ… done | P2 | Hotkey cheat sheet (F1 / ?) | [shipwright](../team-leads/shipwright.md) | 🟒 | diff --git a/.project/objectives/DASHBOARD_COMPLETED.md b/.project/objectives/DASHBOARD_COMPLETED.md index 37f60973..5a481d60 100644 --- a/.project/objectives/DASHBOARD_COMPLETED.md +++ b/.project/objectives/DASHBOARD_COMPLETED.md @@ -76,6 +76,7 @@ | [p1-23](p1-23-stats-tracker-restore.md) | Restore StatsTracker β€” demographics overview broken in shipped builds | β€” | [shipwright](../team-leads/shipwright.md) | 2026-04-25 | | [p1-24](p1-24-windows-path-separator.md) | 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) | Eliminate parse-error spam in export logs (Unit dup decl + SaveManager stray) | β€” | [shipwright](../team-leads/shipwright.md) | 2026-04-25 | +| [p1-28](p1-28-culture-research-tree.md) | Culture research tree β€” real graph, bridge, UI | β€” | [shipwright](../team-leads/shipwright.md) | 2026-04-26 | | [p2-06](p2-06-export-pipeline.md) | Export pipeline for Windows / macOS / Linux | β€” | [shipwright](../team-leads/shipwright.md) | 2026-04-25 | | [p2-28](p2-28-sprite-provenance-ledger.md) | Sprite provenance ledger β€” LICENSES.md per-file attribution | β€” | [asset-sprite](../team-leads/asset-sprite.md) | 2026-04-25 | diff --git a/.project/objectives/README.md b/.project/objectives/README.md index 4fe67b63..9a71a971 100644 --- a/.project/objectives/README.md +++ b/.project/objectives/README.md @@ -15,10 +15,10 @@ | Priority | πŸ”΅ | 🟑 | πŸ”΄ | ❌ | ⚫ | βœ… | Total | |---|---|---|---|---|---|---|---| | **P0** | 0 | 1 | 0 | 0 | 0 | 42 | 43 | -| **P1** | 0 | 6 | 0 | 7 | 1 | 25 | 39 | +| **P1** | 0 | 5 | 0 | 7 | 1 | 26 | 39 | | **P2** | 0 | 2 | 1 | 0 | 0 | 28 | 31 | | **P3 (oos)** | 0 | 0 | 0 | 1 | 19 | 0 | 20 | -| **total** | **0** | **9** | **1** | **8** | **20** | **95** | **133** | +| **total** | **0** | **8** | **1** | **8** | **20** | **96** | **133** | @@ -28,7 +28,7 @@ |---|---| | [asset-sprite](../team-leads/asset-sprite.md) | 6 | | [warcouncil](../team-leads/warcouncil.md) | 4 | -| [shipwright](../team-leads/shipwright.md) | 3 | +| [shipwright](../team-leads/shipwright.md) | 2 | | [asset-audio](../team-leads/asset-audio.md) | 1 | | [envoy](../team-leads/envoy.md) | 1 | | [testwright](../team-leads/testwright.md) | 1 | @@ -49,7 +49,6 @@ | [p1-05](p1-05-balance-tuning.md) | 🟑 partial | Balance tuning β€” pop_peak β‰₯30 median, worker improvements β‰₯8 min | β€” | [shipwright](../team-leads/shipwright.md) | 2026-04-25 | 🟒 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-26](p1-26-tile-placement-preview-ux.md) | 🟑 partial | Tile-placement UX with effect preview β€” Civ7-style \"where does this go and what changes\" | β€” | [shipwright](../team-leads/shipwright.md) | 2026-04-26 | 🟒 unblocked | -| [p1-28](p1-28-culture-research-tree.md) | 🟑 partial | Culture research tree β€” real graph, bridge, UI | β€” | [shipwright](../team-leads/shipwright.md) | 2026-04-26 | 🟒 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-27](p1-27-mcts-service-extraction.md) | ❌ missing | Extract GPU MCTS into a standalone service/client (model-boss-shaped, magic-civ-only) | β€” | [warcouncil](../team-leads/warcouncil.md) | 2026-04-25 | 🟒 unblocked | | [p2-16](p2-16-audio-assets.md) | ❌ missing | Audio assets β€” SFX + music .ogg files shipped | β€” | [asset-audio](../team-leads/asset-audio.md) | 2026-04-17 | 🟒 unblocked | diff --git a/.project/objectives/objectives.json b/.project/objectives/objectives.json index a4e1fba8..e3151357 100644 --- a/.project/objectives/objectives.json +++ b/.project/objectives/objectives.json @@ -1,9 +1,9 @@ { - "generated_at": "2026-04-26T12:02:46Z", + "generated_at": "2026-04-26T20:52:19Z", "totals": { - "done": 95, + "done": 96, "in_progress": 0, - "partial": 9, + "partial": 8, "stub": 1, "missing": 8, "oos": 20, @@ -796,7 +796,7 @@ "id": "p1-28", "title": "Culture research tree β€” real graph, bridge, UI", "priority": "p1", - "status": "partial", + "status": "done", "scope": "game1", "owner": "shipwright", "updated_at": "2026-04-26", @@ -1458,7 +1458,7 @@ }, { "owner": "shipwright", - "remaining": 3 + "remaining": 2 }, { "owner": "asset-audio", diff --git a/.project/objectives/p1-28-culture-research-tree.md b/.project/objectives/p1-28-culture-research-tree.md index 3434da23..e32c8eb1 100644 --- a/.project/objectives/p1-28-culture-research-tree.md +++ b/.project/objectives/p1-28-culture-research-tree.md @@ -7,11 +7,9 @@ scope: game1 owner: shipwright updated_at: 2026-04-26 evidence: - - GdCultureWeb registered in libmagic_civ_physics.x86_64.so (built 2026-04-26 on apricot from HEAD) - - "culture_tree_proof.tscn renders correctly: title 'Culture Tree', 6 pillars, 30 traditions, available T1 cards yellow with Research buttons, indicator badges (B/E/W), detail-panel hint text" - - "Phase-gate screenshot at .project/screenshots/culture_tree_proof_2026-04-26.png (1920Γ—1080, 116 KB)" - - "DataLoader BLOCKER fixed: proof scene now calls DataLoader.load_theme + ThemeVocabulary.load_vocabulary if not populated; capture_screenshot.gd's culture_tree_proof route ensures the theme is loaded before scene change" - - "5 dangling culture prereqs fixed in artisanship.json/legacy.json/oral_tradition.json/philosophy.json/statecraft.json (civil_engineering, world_theory, scholarship, governanceΓ—2, clan_law, high_lore removed)" + - "culture_tree_proof screenshot (apricot, 2026-04-26_08-13-47): 1920x1080, 6 pillars (Ancestor Worship, Artisanship, Legacy, Oral Tradition, Philosophy, Statecraft), 30 tradition cards rendered with tier/cost/unlock badges, 2 highlighted researched traditions, detail panel visible. Proof scene ran via capture_screenshot.gd routing with DataLoader.load_theme('age-of-dwarves') pre-load fix. GdCultureWeb confirmed: 30 traditions across 6 pillars at runtime." + - GdCultureWeb in libmagic_civ_physics.x86_64.so on apricot (built 2026-04-26) + - "7 dangling culture prereqs removed: civil_engineering, world_theory, scholarship, governanceΓ—2, clan_law, high_lore" --- ## Summary diff --git a/public/games/age-of-dwarves/guide/src/data/game.ts b/public/games/age-of-dwarves/guide/src/data/game.ts index 8c1db305..0774366b 100644 --- a/public/games/age-of-dwarves/guide/src/data/game.ts +++ b/public/games/age-of-dwarves/guide/src/data/game.ts @@ -93,8 +93,12 @@ const allowedBuildingSources = new Set(buildingsManifest.includes as readonly st const allBuildingsFlat: Building[] = Object.entries(buildingMods).flatMap(([pathStr, mod]) => { const stem = (pathStr.split('/').pop() ?? '').replace(/\.json$/, '') - if (!allowedBuildingSources.has(stem)) return [] - return Array.isArray(mod) ? mod : [mod] + const items: Building[] = Array.isArray(mod) ? mod : [mod] + // Wonders (wonder_type != null) bypass the manifest allowlist β€” they live as + // individual files and don't need to be enumerated there. building_categories.json + // is correctly excluded: it has no wonder_type field, so wonder_type is undefined, + // and undefined != null is false in JS. + return items.filter(item => allowedBuildingSources.has(stem) || item.wonder_type != null) }) export const allBuildings: Building[] = allBuildingsFlat.filter((b) => b.wonder_type == null) diff --git a/src/simulator/crates/mc-ai/src/tactical/movement.rs b/src/simulator/crates/mc-ai/src/tactical/movement.rs index d8254516..5ad92580 100644 --- a/src/simulator/crates/mc-ai/src/tactical/movement.rs +++ b/src/simulator/crates/mc-ai/src/tactical/movement.rs @@ -998,7 +998,8 @@ mod tests { #[test] fn dominance_factor_gate_marches_on_city() { // 2 own military vs 1 enemy β†’ own/enemy = 2.0 >= DOMINANCE_FACTOR - // (1.25). City closer than the stray enemy (dist 5 vs dist 9). + // (2.0 β€” bumped 2026-04-26 from 1.25 to slow rush-domination). + // City closer than the stray enemy (dist 5 vs dist 9). // Expect a move TOWARD the enemy city rather than the stray. let me = player( 0, diff --git a/src/simulator/crates/mc-ai/src/tactical/production.rs b/src/simulator/crates/mc-ai/src/tactical/production.rs index d13a8978..699d389a 100644 --- a/src/simulator/crates/mc-ai/src/tactical/production.rs +++ b/src/simulator/crates/mc-ai/src/tactical/production.rs @@ -63,7 +63,16 @@ const CULTURE_AXIS_MONUMENT_THRESHOLD: u8 = 4; /// Aggression multiplier above which the player counts as dominant over the /// opposing field (mirrors GDScript DOMINANCE_FACTOR). -const DOMINANCE_FACTOR: f32 = 1.25; +/// +/// Bumped 2026-04-26 from 1.25 β†’ 2.0 to slow rush-domination dynamics. +/// Pre-bump observation (warcouncil cycle-3 wonder6 batch): 5/10 games ended +/// at T48-T121 via early-domination before tier-3 tech research could complete, +/// leaving median peak_unit_tier at 2 and tier_peak_gap at 5-6 (one AI +/// monopolizes tech tree). At 2.0Γ— the AI requires real military superiority +/// before committing to attack, giving losers more time to develop and +/// closing the symmetry gap. Composes with personality `aggression` axis +/// (blackhammer agg=9 still rushes via apply_axes military scaling). +const DOMINANCE_FACTOR: f32 = 2.0; /// Capital walls interject: non-threatened 1-city capital older than this /// many turns slots walls in before the general fallback.