Add tools/check-no-gdscript-sim-logic.py and wire it as verify step 18 (TOTAL
20→21). Fails if presentation GDScript (src/game/engine/src/**/*.gd) re-introduces
catalog yield aggregation (`yield_production += …`) or hand-built spec dicts
(`"yield_production": …`) — the exact drift class just moved to Rust. Verified to
flag the pre-7e2baa25d aggregation and pass clean on the current tree. Logic
belongs in the mc-* crates, reached via the GDExtension bridge (Rail 1).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- ranker: dedicated POI_GATES/POI_QUALITY for landmarks & lairs — they were
routed through BUILDING_GATES (roof_visible/single_building/no_front_facade),
so volcanoes, ley-confluence formations and lair camps failed every gate and
burned generations to the regen cap.
- grok_generator: _ensure_grok_sdk re-checks the import per candidate path and
raises a clear 'set GROK_BUILD_SDK_PATH' error instead of a cryptic ImportError.
- grok_generator: submit_batch generates a sprite's variants concurrently via
asyncio.gather so the client's max_concurrent semaphore is actually used.
- add test_grok_pipeline.py — 49 headless checks (factory, POI-gate routing
regression, prompt adaptation, PNG validation, starter manifest).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds a GUI preferences module and refines the worker engine, operations panel,
workers page, and coverage page.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds a worker abstraction (engine/worker.py) with registry wiring and a server
operations endpoint, surfaced in the GUI via new Workers and Operations pages
plus dashboard/coverage/theater/variant page updates. Refreshes the ranker.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds a Grok image backend (grok_generator.py) behind a generator factory, a
starter-set orchestrator (starter.py, orchestrate_starter.py, starter_manifest.json)
and a Grok PoC harness with proof renders. Updates the ranker/processor/composition
prompts and sprite-config; refreshes the sprite-gallery design preview.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Game opening becomes a moddable JSON script driven by mc_worldsim::StartScriptRunner
and exposed to Godot via GdStartScript. Start scripts + dwarf tribe/wanderer units
live in public/resources/start_scripts; START_SCRIPTS.md documents the contract.
Adds tools/validate-start-scripts.py + wires it into CI (stage 3b) and verify.sh
(step 0b). Marks p3-14 done and regenerates the objectives dashboard.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add tools/check-ui-color-sources.py: fails if a hardcoded numeric Color()/Color8()
is applied to a widget in a scene (add_theme_*_override / StyleBox *_color).
Allows computed Color(accent.r,…), transparent, named constants, and var-init
fallbacks; excludes scenes/tests + the 3 precursor deletion files. Passes clean
on live scenes (exit 0). Wired into ./run verify as step 17 so a hardcoded
colour can't creep back in.
Capstone for the override→inheritance / single-colour-system work: colours in
live scenes now provably come from the design-token source.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
world_map lair POI overlay, tile_info_panel tooltip wiring, lair standin
sprites + build_demo_lairs.py, tooltip unit test, lair proof scenes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Foundation for collapsing the ~188 add_theme_color_override calls onto Godot
Theme inheritance. Adds a `typeVariations` section to design-tokens.json and
emits each as a Godot type variation in ui_theme.tres.
9 Label variations covering the high-count font_color override patterns:
LabelTitle/Muted/Secondary/Disabled/Positive/Negative/Warning/Gold/Science
(→ text.title/muted/secondary/disabled, semantic.positive/negative/warning,
accent.gold/science). Widgets set `theme_type_variation = "LabelMuted"` to
inherit instead of `add_theme_color_override("font_color", ...)`.
Additive — nothing consumes them yet, zero visual change. Verified: variations
baked into ui_theme.tres, theme --check clean, headless load exit 0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The 12 player colours were authored TWICE (drift-prone): palettes.json
default.player_colors (runtime source + colourblind variants) AND a hand-copied
design-tokens.json `player.*` group used by UI chrome. Same values, two files.
- build-ui-theme.py: generate `player.<name>` tokens from palettes.json's default
variant (PLAYER_COLOR_NAMES ↔ array index) and merge into the baked meta blob.
- design-tokens.json: remove the hand-authored `player.*` group — now generated.
Player colours now have ONE source (palettes.json). Value-preserving: meta-blob
player.* == palettes default for all 12; build --check clean; headless load exit 0;
UI consumers (player.purple toasts, diplomacy/arena overlays) resolve unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make the design-token system genuinely layered instead of flat single-tier.
- build-ui-theme.py: add W3C-style alias resolution. A token $value may now be
a reference `{color.x.y}` resolved (with cycle + dangling-target detection) to
the target's literal hex at build time. Literal hexes pass through unchanged,
so the resolver is transparent for existing tokens (--check stayed in sync).
- design-tokens.json: introduce a primitive `palette.*` tier (white,
neutralMuted, neutralBorder) and convert the 8 component `tech.*` tokens from
bespoke hex into ALIASES: researched→semantic.positive, available→accent.gold,
available border→accent.goldBright, current→accent.science, locked→palette
neutrals, selected→palette.white. tech.* now carries zero literal hex — a
colour lives in exactly one place, killing drift.
Rationale: the prior `tech.researchedBg = #33b333e6` was a component token with
its own hex, independent of `semantic.positive` — the duplication the token
system exists to prevent. Now component → semantic → primitive.
Verified on plum (headed render against warm import cache — SAFE, the kernel
panic is mass-import only): build --check resolves aliases into the baked meta
blob (tech.researchedBg→66e666 etc.); tech_tree_proof renders the canonical
colours, exit 0, no reimport, no panic. Screenshot reviewed in conversation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Full integration of worktree-bridge-cse_01Nnt (54 commits) into main.
Conflicts (17) resolved: adopt branch's p2-65 GameState->mc-state crate move
across mc-ai/mc-core/mc-player-api/mc-turn; keep main's design-token theme
system (build-ui-theme.py, tile_info_panel.gd) and main's newer p0-26b evidence.
Workspace: 2624 tests pass; 5 pre-existing/environmental failures inherited from
main (constructor_smoke capping test, five_players_overflow, 3x gpu_rollout_parity)
— zero regressions introduced by the merge. api-gdext (GDExtension) compiles.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Close the gap where the design system (.project/designs/design-tokens.json)
drove the React guide but not the Godot game.
- tools/build-ui-theme.py: compiles the W3C/style-dictionary token SoT into a
complete Godot Theme (7 StyleBoxFlat sub-resources, Button/Label/Panel/
PanelContainer/ItemList/RichTextLabel colors + font sizes + corner radii/
border widths per UI_DESIGN_SYSTEM.md §3/§4/§6). ui_theme.tres is now a
GENERATED artifact; tokens are the single source of truth. Deterministic
output (sorted keys, fixed float fmt, preserved uid://ui_theme_fantasy) with
a --check drift gate. Idempotent; --import does not rewrite it.
- project.godot [gui] theme/custom: applies ui_theme.tres at viewport level so
every non-overriding default Control renders the copper fantasy styling.
- ThemeAssets.color(name) -> Color: resolves dotted token names (accent.gold,
semantic.positive, text.primary, …) against the metadata/tokens JSON blob
baked into the .tres by the generator. Fully data-driven from the SoT, no
hardcoded color map. (Godot rejects dots in Theme color item names, so the
token table ships as resource metadata.) Unknown names return an explicit
fallback. This is the API p2-74 will de-hardcode 45 scripts onto.
- ui_theme_proof.{tscn,gd}: bare-widget + color()-swatch proof scene.
test_theme_assets_color.gd: GUT accessor coverage (5/5 headless).
Proof captured on apricot under weston, reviewed in conversation:
.project/screenshots/p2-73-ui-theme-proof.png. Workspace green — full unit
(16==16) and integration (18==18) suites show identical HEAD-baseline-vs-patch
failure counts, zero regressions; patch adds +5 passing tests.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>