diff --git a/.project/FINISH_GAME1_PLAN.md b/.project/FINISH_GAME1_PLAN.md index f4d76a3e..12543d0e 100644 --- a/.project/FINISH_GAME1_PLAN.md +++ b/.project/FINISH_GAME1_PLAN.md @@ -73,3 +73,16 @@ Rail-1 hygiene: make the existing UI read game state from Rust. **Game renders f ## Integration / commits All work lands as atomic commits on the `worktree-bridge-cse_*` submodule branch; the live `commits.service` + `claire-agent` daemons propagate to `main` automatically (do NOT manually merge — it races the daemons). Proof screenshots capture on apricot (plum down). + +--- + +## Wave F — Design-system fidelity (NEW 2026-06-04 · L · the "Godot UI ≠ design guides" gap) + +**Gap (quantified):** the design system (`design-tokens.json` + `UI_DESIGN_SYSTEM.md` + HTML sketches + React gallery) drives the **web guide** (`fantasy-theme.ts`) but **not the Godot game**. `ui_theme.tres` exists yet is never applied as the root theme, and **45 scene scripts hardcode 973 raw `Color()` + 307 `add_theme_*_override` calls**, hand-rolling visuals that diverge from the spec. The scenes are GUT-green but visually plain — a real "missing UI side" beyond wiring. + +| Task | Objective | Detail | +|---|---|---| +| Token→theme pipeline + global apply + `ThemeAssets.color()` accessor | **p2-73** | Generate `ui_theme.tres` from `design-tokens.json` (tokens = SoT); apply it as the root Control theme; add a semantic token-color accessor. Foundation — **in progress.** | +| De-hardcode 45 scene scripts | **p2-74** (blocked_by p2-73) | Route 973 inline `Color()` + 307 overrides onto the theme / `ThemeAssets.color()` tokens, per-screen-cluster, always-green. The bulk of the visual-fidelity work — **L, multi-session.** | + +**Why it matters / honest framing:** the web feels "easier" because tokens flow straight to CSS; Godot's Control/Theme/StyleBox + programmatic tree-building threw that away. The fix is the missing `tokens → .tres` plumbing + a de-hardcode pass — *not* shipping HTML (Godot is the Steam target). **Polish-tier, not demo-blocking**, but required if "Game 1 complete" means fidelity to the design guides. diff --git a/.project/objectives/objectives.json b/.project/objectives/objectives.json index e487145b..965010f6 100644 --- a/.project/objectives/objectives.json +++ b/.project/objectives/objectives.json @@ -1,14 +1,14 @@ { - "generated_at": "2026-06-05T01:20:08Z", + "generated_at": "2026-06-05T02:16:20Z", "totals": { "done": 242, "in_progress": 1, "missing": 1, "oos": 29, "partial": 20, - "stub": 7, + "stub": 10, "superseded": 4, - "total": 304 + "total": 307 }, "objectives": [ { @@ -1324,6 +1324,17 @@ "blocked_by": [], "summary": "p1-29h Phase 2 isolated the elimination wall: on the fair gridded two-`scripted:default` duel (`mc-player-api/tests/p1_29h_gridded_elimination.rs`) the army-lock engages and captures land (20 captures / 160 turns) but **0 eliminations** — the loser refounds before the attacker can take the last city. p1-29h flagged refound-suppression / capture-stickiness as the candidate lever and asked for a new objective if scope warranted. It does — this is it." }, + { + "id": "p1-29j-autoplay-rust-action-application", + "title": "Route autoplay action-application (city-founding / capture) through Rust mc_turn::processor", + "priority": "p1", + "status": "stub", + "scope": "game1", + "owner": "warcouncil", + "updated_at": "2026-06-04", + "blocked_by": [], + "summary": "p1-29i ran the deferred full-game validation of the refound-suppression lever and resolved a deeper architectural root cause that gates **all** of Wave-C AI-convergence work, not just that one lever:" + }, { "id": "p1-30", "title": "Optimize `_build_tactical_state` — 8000-tile GDScript dict-build per AI turn blocks p1-22 huge-map gate", @@ -3144,6 +3155,30 @@ "blocked_by": [], "summary": "**Status flipped `open` → `blocked` before any code changes.** Option C as specified cannot land as written because the per-instance `GdCity` architecture invalidates the implicit \"small presentation field set\" premise the spec relies on. User decision required between three resolution paths (below) before this objective can proceed." }, + { + "id": "p2-73-ui-theme-token-pipeline", + "title": "UI theme pipeline — generate ui_theme.tres from design-tokens.json + apply globally", + "priority": "p2", + "status": "stub", + "scope": "game1", + "owner": "godot-engine", + "updated_at": "2026-06-04", + "blocked_by": [], + "summary": "The project has a real design system (`.project/designs/design-tokens.json` + `UI_DESIGN_SYSTEM.md` + 8 HTML sketches + a React design-gallery app), and the **React guide consumes it cleanly** (`guide/src/theme/fantasy-theme.ts`). The **Godot game does not**:" + }, + { + "id": "p2-74-ui-dehardcode-to-tokens", + "title": "De-hardcode the Godot UI — route 45 scene scripts off raw Color() onto theme/tokens", + "priority": "p2", + "status": "stub", + "scope": "game1", + "owner": "godot-ui", + "updated_at": "2026-06-04", + "blocked_by": [ + "p2-73-ui-theme-token-pipeline" + ], + "summary": "The Godot scenes hand-roll their visuals instead of inheriting the design system. Measured across `src/game/engine/scenes/**` (excluding tests):" + }, { "id": "p3-01", "title": "Courier-gated diplomacy — open borders + shared maps via tech-tiered courier units", @@ -3458,6 +3493,12 @@ "p2-72a-gdgamestate-canonical-render-source" ] }, + { + "id": "p2-74-ui-dehardcode-to-tokens", + "blockedBy": [ + "p2-73-ui-theme-token-pipeline" + ] + }, { "id": "p3-05a-gdext-bridge", "blockedBy": [ @@ -3526,11 +3567,11 @@ "remaining": 7 }, { - "owner": "asset-sprite", - "remaining": 6 + "owner": "warcouncil", + "remaining": 7 }, { - "owner": "warcouncil", + "owner": "asset-sprite", "remaining": 6 }, { @@ -3545,6 +3586,14 @@ "owner": "asset-audio", "remaining": 1 }, + { + "owner": "godot-engine", + "remaining": 1 + }, + { + "owner": "godot-ui", + "remaining": 1 + }, { "owner": "testwright", "remaining": 1 diff --git a/.project/objectives/p2-73-ui-theme-token-pipeline.md b/.project/objectives/p2-73-ui-theme-token-pipeline.md new file mode 100644 index 00000000..57e3bbcf --- /dev/null +++ b/.project/objectives/p2-73-ui-theme-token-pipeline.md @@ -0,0 +1,61 @@ +--- +id: p2-73-ui-theme-token-pipeline +title: "UI theme pipeline — generate ui_theme.tres from design-tokens.json + apply globally" +priority: p2 +status: stub +scope: game1 +category: ui +owner: godot-engine +created: 2026-06-04 +updated_at: 2026-06-04 +blocked_by: [] +relates_to: [p2-74-ui-dehardcode-to-tokens] +--- + +## Why this exists (gap found 2026-06-04) + +The project has a real design system (`.project/designs/design-tokens.json` + +`UI_DESIGN_SYSTEM.md` + 8 HTML sketches + a React design-gallery app), and the +**React guide consumes it cleanly** (`guide/src/theme/fantasy-theme.ts`). The +**Godot game does not**: + +- `grep design-tokens src/game/` → empty. Godot never reads the canonical tokens. +- `public/games/age-of-dwarves/ui_theme.tres` exists and is well-formed (StyleBoxFlat + sub-resources, copper borders, corner radii) **but is never applied as the root + Control theme** — `ThemeAssets.set_theme()` only loads palettes/textures. +- `design-tokens.json` lists `ui_theme.tres` as a *source* — backwards. The `.tres` + should be a **build artifact generated from the tokens** (single source of truth). + +Net: the design system drives the web but not the game, so scenes hand-roll their +visuals (see `p2-74` — 45 scripts, 973 raw `Color()`). + +## Acceptance + +- ☐ **Generator** `tools/build-ui-theme.py` (or style-dictionary config): reads + `.project/designs/design-tokens.json` → emits `public/games/age-of-dwarves/ui_theme.tres` + (the full Godot `Theme` — StyleBoxes, colors, font sizes, constants per + `UI_DESIGN_SYSTEM.md` §3/§4/§6). The `.tres` becomes a generated artifact; tokens + are the SoT. Re-runnable + a `--check` drift gate. +- ☐ **Global apply**: `ui_theme.tres` is set as the root Control theme — via + `project.godot` `gui/theme/custom`, or `ThemeAssets` at boot setting + `get_tree().root.theme`. A non-overriding Control (default Button/Panel/Label) + now renders themed (proof: a bare-widget proof scene on apricot shows the copper + fantasy styling, not Godot defaults). +- ☐ **Semantic token accessor**: `ThemeAssets.color(name)` (e.g. `"accent.copper"`, + `"semantic.success"`, `"text.primary"`) resolves a token → `Color` so GDScript can + reference NAMED tokens instead of raw literals (the API `p2-74` de-hardcodes onto). + Data-driven from tokens/palettes, no hardcoded map. +- ☐ Proof scene on apricot + GUT for the accessor; workspace green. + +## Source-of-truth rails +- **Token SoT**: `.project/designs/design-tokens.json`. `ui_theme.tres` and + `fantasy-theme.ts` are both GENERATED/derived, never hand-edited as SoT. +- **No hardcoded color map** in `ThemeAssets` — read tokens. + +## Out of scope +- The actual de-hardcoding of the 45 scene scripts — that's `p2-74` (this objective + provides the theme + accessor it consumes). + +## References +- `.project/designs/UI_DESIGN_SYSTEM.md`, `design-tokens.json` +- `public/games/age-of-dwarves/ui_theme.tres`, `src/game/engine/src/autoloads/theme_assets.gd` diff --git a/.project/objectives/p2-74-ui-dehardcode-to-tokens.md b/.project/objectives/p2-74-ui-dehardcode-to-tokens.md new file mode 100644 index 00000000..ae302b4c --- /dev/null +++ b/.project/objectives/p2-74-ui-dehardcode-to-tokens.md @@ -0,0 +1,59 @@ +--- +id: p2-74-ui-dehardcode-to-tokens +title: "De-hardcode the Godot UI — route 45 scene scripts off raw Color() onto theme/tokens" +priority: p2 +status: stub +scope: game1 +category: ui +owner: godot-ui +created: 2026-06-04 +updated_at: 2026-06-04 +blocked_by: [p2-73-ui-theme-token-pipeline] +relates_to: [p2-73-ui-theme-token-pipeline] +--- + +## Why this exists (gap quantified 2026-06-04) + +The Godot scenes hand-roll their visuals instead of inheriting the design system. +Measured across `src/game/engine/scenes/**` (excluding tests): + +- **45 scene scripts** hardcode raw `Color(...)` — **973 occurrences**. +- **17 scripts** build `StyleBoxFlat.new()` inline. +- **307 `add_theme_*_override` calls** (185 color / 92 constant / 30 stylebox) — each + bypasses the inherited theme. + +Example (`statistics.gd`): `style.bg_color = Color(0.09,0.08,0.07,0.97)`, +`style.border_color = Color(0.55,0.48,0.32,0.9)` — hand-built panels duplicating the +palette the design tokens already define. Result: scenes are GUT-green but visually +diverge from `UI_DESIGN_SYSTEM.md` and the HTML sketches (functional, plain). + +This is the bulk of the design-system-fidelity gap. It is LARGE and incremental. + +## Acceptance + +- ☐ With `p2-73`'s global theme applied + `ThemeAssets.color()` accessor available, + refactor scene scripts so visual constants reference NAMED tokens, not inline + literals: replace `Color(r,g,b)` with `ThemeAssets.color("...")`, and prefer + inherited theme over `add_theme_*_override` / `StyleBoxFlat.new()` where the global + theme already provides the style. +- ☐ Legitimate data-driven colors (player colors, climate/fog/biome, rank + success/warning/danger) route through their token/palette source, not inline RGB. +- ☐ Raw `Color()` count in `scenes/**` (excl tests) drops toward ~0 (target: only + genuinely dynamic/computed colors remain, all others tokenized). +- ☐ Per-screen proof screenshots on apricot compared against the `.project/designs/` + HTML sketches; visual fidelity verified for the core screens (HUD, city, tech, + culture, combat, stats, end-game, menus). +- ☐ Workspace green; GUT unaffected (visual-only refactor, no logic change). + +## Execution note +Incremental, per-screen-cluster (it's 45 scripts) — land one cluster per commit, +always-green. Order by player visibility: HUD/world-map → city → combat → tech/culture +→ modals (stats/summary/encyclopedia) → menus. Multi-session. + +## Source-of-truth rails +- Colors reference tokens via `ThemeAssets.color()` / inherited theme (from `p2-73`). +- No new inline literals; no logic change (Rail 3 — presentation only). + +## References +- `p2-73-ui-theme-token-pipeline` (provides the theme + accessor — HARD dependency). +- `.project/designs/UI_DESIGN_SYSTEM.md`, the 8 `.project/designs/*.html` sketches.