docs(plan): Wave F — design-system fidelity gap (p2-73 pipeline + p2-74 de-hardcode)
Quantified gap: design-tokens.json drives the web guide but not Godot; ui_theme.tres never applied as root theme; 45 scene scripts hardcode 973 Color() + 307 theme overrides. Two objectives filed; foundation (p2-73) dispatched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0ed21945c1
commit
f05231b825
4 changed files with 188 additions and 6 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
61
.project/objectives/p2-73-ui-theme-token-pipeline.md
Normal file
61
.project/objectives/p2-73-ui-theme-token-pipeline.md
Normal file
|
|
@ -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`
|
||||
59
.project/objectives/p2-74-ui-dehardcode-to-tokens.md
Normal file
59
.project/objectives/p2-74-ui-dehardcode-to-tokens.md
Normal file
|
|
@ -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.
|
||||
Loading…
Add table
Reference in a new issue