Skip to content

Commit 326d658

Browse files
georgiclaude
andauthored
feat(setup): Game guided flow to a Godot project (E6) (#5665)
* docs(setup): design the Game guided flow to a Godot project (E6) A sixth entry card on the New Project surface that walks from a sentence to an exported Godot 4.3 project on the existing SetupFlow shell. The build is a slot-filling workflow graph built without a model call, ending in an export node that wraps the existing Godot join, so the graph re-runs and the agent takes over for the playtest loop. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TDqhsPX3jAxwKFUvvK9qkf * feat(setup): game style tiles, template cards and harness docs (G3) Nine deterministic PNGs drawn by scripts/make-game-style-tiles.mjs from each preset's palette and each template's own placeholder art, with a --check that fails on a changed byte or a missing tile. The harness docs, the AGENTS.md table row and the godot-game skill point at the flow's graph. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TDqhsPX3jAxwKFUvvK9qkf * feat(protocol): game flow contracts — settings.game, designer, slot prompt, graph builder (G1a) The designer writes cast, level and one prompt per slot against a schema that pins the manifest's slot ids; the slot prompt sizes each generation to the slot's exact pixels; gameGraphPlacement is a pure function of manifest, design and choices, so no model decides which chain a slot gets. Six game style presets join the storyboard ones. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TDqhsPX3jAxwKFUvvK9qkf * test(audio-nodes): read the pacer test's clock before constructing the pacer RealtimePacer's origin is its construction time. The test captured its own start afterwards, so on a loaded CI runner the gap shortened the measured wait (52 ms against a 70 ms floor) and failed a diff that never touched audio-nodes. Reading the clock first makes the measured wait a lower bound. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TDqhsPX3jAxwKFUvvK9qkf * feat(web): Game guided flow — steps, hooks, landing checklist, ui_game_* tools (G2) The sixth entry card on the New Project surface. Idea, Template with the designer, Design review, Look with game style presets and one model per slot kind, then Build places the slot-filling graph through the node tools and runs it once. The landing checklist folds the run's per-node results into assets, export and verification rows and reports Verified only on a true export output. Four ui_game_* tools give the flow headless parity. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TDqhsPX3jAxwKFUvvK9qkf * feat(game-nodes): ExportGodotProject node, game seeds and capabilities, game-flow harness (G1b) packages/game-nodes holds nodetool.game.ExportGodotProject and the export join extracted from the export_godot_project capability, which now calls it. The node takes one dynamic input per slot, exports the template with its placeholders for slots left unfilled, writes the zip beside the directory, and reports verified only when Godot ran. The checker fills carry the asset id the node needs; nodetool.image.ResizeImage joins the registry it was missing from. games.templates and games.stylePresets serve the flow, the four game setup capabilities mirror the ui_game_* tools, and the game-flow harness entry runs every suite the flow depends on. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TDqhsPX3jAxwKFUvvK9qkf * feat(web): mount the game landing checklist in the canvas chat dock The panel renders above the conversation only for a workflow whose settings.game reads stage done with a recorded build, and the build record is written onto settings.game so a reload still shows it. Build opens the dock; the next steps open the folder, download the zip, stage the play-test turn for the project agent, or run the graph again. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TDqhsPX3jAxwKFUvvK9qkf * feat(game-nodes): one export node for the flow and the capability After merging main, the flow builds on main's game-nodes package. The ExportGodotProject node gains the flow's behaviours: empty fills export the template's placeholders, unfilled slots keep theirs, the zip lands beside the directory, and verified stays false unless Godot ran clean. The graph builder feeds every checker's output into the node's fills list, the flow's prompt builder rides on slotPrompt, and the capability imports the shared join. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TDqhsPX3jAxwKFUvvK9qkf * fix(game): address review — templates array, named run outputs, resume on reopen, placeholder sentinels F1: games.templates returns the array, so the hook reads it as one and the router's slot type is the protocol's, which drops the client cast. F2: the landing summary reads the focused job's completed generation outputs, which keep handle names and are never edge-suppressed; the old source lost the export node's named handles and every checker's asset row. F3: the workflow editor surface renders the game setup host while settings.game.stage is not done, so a reload during Design or Look resumes the flow. F4: one protocol helper normalizes the keep-placeholder sentinel for both the browser flow and the build_game capability. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TDqhsPX3jAxwKFUvvK9qkf * fix(game): restore the finished export after a reload, count checkers only The landing panel read the export outcome from the focused job's live generations, so a reload lost it. Persist the outcome once on settings.game.build.export keyed by job id and read it back only when no job is focused. The checked count now counts a slot only when its checker node produced outputs without an error, with the checker node types exported from the graph builder so both sides agree. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TDqhsPX3jAxwKFUvvK9qkf * fix(game): recover exports from completed jobs --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 2ab48ed commit 326d658

107 files changed

Lines changed: 13873 additions & 472 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/skills/godot-game/SKILL.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ sheet generated with a different model than the tileset reads as two games.
2020

2121
Each phase ends with a report and a wait. The user approves before the next spends.
2222

23+
Look at the project's workflows first. The Game entry card builds a slot-filling
24+
workflow that ends in `nodetool.game.ExportGodotProject`, so when the project
25+
already holds one, a first build is a re-run rather than P0-P2 by hand: run the
26+
whole workflow to refill every slot, or re-run one slot's chain to replace a
27+
single asset, then pick up at P3. Do the phases below by hand when there is no
28+
such workflow.
29+
2330
### P0 — Brief to design
2431

2532
1. `list_game_templates`. Pick the template whose loop matches the brief; say why.

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ reference is [docs/harnesses.md](docs/harnesses.md) plus [docs/cli.md](docs/cli.
502502
| Re-run an approved storyboard, script, timeline or entity from a graph | `npm run fixtures:graph-resources` — seeds a scratch install and runs the four shipped examples on the fake provider | `create_storyboard`, `get_storyboard`, `list_entities`, `get_script`, `validate_timeline` on what the graph wrote | minutes |
503503
| Build or fix a 3D scene with no editor open | no command of its own — the `capability-suites` selfcheck the `model3d` harness entry names | `list_model3ds`, `create_model3d`, `get_model3d`, `edit_model3d`, `validate_model3d` | sub-second |
504504
| Fill a Godot template with generated sprites, tiles and audio, export the project, and run it headless | no command of its own — the `capability-suites` selfcheck the `godot` harness entry names; real Godot runs when `GODOT_BIN` is set | `list_game_templates`, `export_godot_project`, `verify_godot_project`; the `nodetool.game.*` nodes fill slots | seconds; Godot import and smoke tens of seconds |
505+
| Take one sentence to a running Godot project — design, slot-filling graph, export | no command of its own — the suites the `game-flow` harness entry names, run by `harness gate` on diffs touching the flow | `ui_game_set_setup`, `ui_game_design`, `ui_game_update_design`, `ui_game_build`; the graph ends in `nodetool.game.ExportGodotProject` | seconds to build, the run as long as its models take |
505506
| Season a prompt with the entity library | no command of its own — the `capability-suites` selfcheck the `entities` harness entry names | `list_entities`, `get_entity`, `apply_entities` | sub-second |
506507
| Measure a clip instead of watching it — duration, loudness, frequency content, motion, cuts | no command of its own — the `capability-suites` selfcheck the `agent-capabilities` harness entry names | `analyze_audio`, `analyze_audio_spectrum`, `detect_audio_events`, `analyze_video`, `detect_video_scenes` | seconds, no ffmpeg |
507508
| See what a timeline looks like at a timecode — tracks layered, animations mid-flight, transitions part way, text drawn | no command of its own — the `capability-suites` selfcheck the `agent-capabilities` harness entry names | `preview_timeline_frame` (composited frames + per-layer opacity/z-order/wipe), then `view_image` | seconds, no GPU or browser |

docs/creation-flows/game-prd.md

Lines changed: 517 additions & 0 deletions
Large diffs are not rendered by default.

docs/creation-flows/prd.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
**Shipped plan this builds on:** [plans/project-view/PLAN.md](../plans/project-view/PLAN.md) (Phases 0 and 4)
77
**Tasks:** [tasks.md](tasks.md)
88
**Related:** [creative-agent.md](../creative-agent.md), [agentic-video-product.md](../agentic-video-product.md), [script-storyboard-link/prd.md](../script-storyboard-link/prd.md), [timeline-editor-prd.md](../timeline-editor-prd.md), [image-editor-prd.md](../image-editor-prd.md), [triggers-prd.md](../triggers-prd.md)
9+
**Sixth flow:** [game-prd.md](game-prd.md) — E6 Game, the guided flow to a Godot project, built on this shell
910

1011
---
1112

docs/creation-flows/tasks.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,89 @@ of each other. Inside a phase, tasks are listed in dependency order.
411411
- [ ] **Entry.** Enable the Workflow card on the New Project surface (not
412412
Studio); resume by stage in the workflow editor surface.
413413

414+
## P10 — Game flow
415+
416+
> Spec: [game-prd.md](game-prd.md). Depends on P2 (the shell) and P9 (the
417+
> build-from-placement path it mirrors). Sub-phases G1a → (G1b ∥ G2 ∥ G3).
418+
419+
### G1a — Contracts (protocol only, first)
420+
421+
- [x] **Settings shape.** `settings.game` per game-prd § 5.1: `gameSetup`,
422+
`readGameSetup`, `writeGameSetup` beside the workflow setup helpers in
423+
`packages/protocol/src/api-schemas/workflows.ts`. Tests: a workflow
424+
without `game` reads null; every stage round-trips; a patch keeps the
425+
other settings keys.
426+
- [x] **Designer contract.** `packages/protocol/src/game-design.ts`:
427+
system prompt, `buildGameDesignSchema(manifest)` with slot ids pinned
428+
as enums, `parseGameDesign` filling skipped slots from the manifest
429+
and reporting them, `GAME_INSPIRATION_CHIPS` with a pinned design per
430+
shipped template. Tests: a design missing a slot prompt is filled and
431+
reported; a chip's design has one cast entry per spritesheet slot.
432+
- [x] **Slot prompt.** `packages/protocol/src/game-flow-prompt.ts`, on top of
433+
`slotPrompt`, per § 5.3. Test table: sizes per kind for every slot in the three shipped
434+
manifests, style descriptor present verbatim, cast descriptor present
435+
only on the slot that names it, closest aspect ratio.
436+
- [x] **Graph builder.** `packages/protocol/src/game-graph.ts`
437+
`gameGraphPlacement` per § 5.3, returning a `WorkflowPlacement`.
438+
Tests: one chain per slot kind, audio chains omitted when unchosen,
439+
every checker's stamped output feeds the one export node's `fills` list
440+
and nothing else does, an unknown node type is an issue and no node.
441+
- [x] **Style presets.** `GAME_STYLE_PRESETS` in `style-presets.ts` per
442+
§ 5.6, thumbnails as `package://nodetool-base/styles/game-<id>.png`.
443+
444+
### G1b — Node, seeds, harness (backend)
445+
446+
- [x] **`packages/game-nodes`.** `nodetool.game.ExportGodotProject` per
447+
§ 5.5, the export join (`joinGodotProject` in `src/project.ts`) that the
448+
node and `packages/agents/src/capabilities/godot.ts` both call, the zip
449+
beside the directory. Registered in `@nodetool-ai/base-nodes`,
450+
the root workspaces, the backend bundle. Tests: the filled fixture
451+
exports and reports `verified: false` with a reason without Godot; no
452+
fills exports the placeholders; an unfilled slot keeps its own; a fill
453+
for a slot the template lacks is an error naming it.
454+
- [x] **Templates query and seeds.** `games.templates` trpc query;
455+
`seedStylePresets` takes a preset list; `games.stylePresets` seeds the
456+
six game presets idempotently.
457+
- [x] **Headless setup capabilities.** `ui_game_*`'s server mirrors in
458+
`packages/agents/src/capabilities/workflows.ts`, capability table rows,
459+
`npm run capabilities:check` green.
460+
- [x] **Harness.** `game-flow` entry in `packages/cli/src/harness/registry.ts`
461+
whose selfcheck runs the protocol suites, a `packages/base-nodes` suite
462+
that builds every chip's placement against the real registry and
463+
passes it through the validator (criterion 5), the game-nodes suite,
464+
and the web suites. `harness gate` maps the new paths to it. Docs:
465+
`docs/harnesses.md` entry, AGENTS.md harness table row.
466+
467+
### G2 — Web flow
468+
469+
- [x] **Hooks.** `web/src/hooks/game/useGameSetup.ts` (reader, stage, writer
470+
over `settings.game`), `useDesignGame.ts` (one `generate_text` call),
471+
`useBuildGame.ts` (place, validate, run per § 5.4), `useGameTemplates.ts`
472+
(the trpc query), `useGameStylePresets.ts`.
473+
- [x] **Steps.** `web/src/components/setup/game/`: `IdeaStep`, `TemplateStep`,
474+
`ReviewStep`, `LookStep`, `useGameSetupFlow.ts`, `GameSetupHost.tsx`,
475+
`templates.ts` (card copy), `GameLandingChecklist.tsx`. Copy from
476+
game-prd Appendix A. Blocked reasons per § 4.2 and § 4.3.
477+
- [x] **Entry.** `game` in `EntryFlowId` and `ENTRY_CARDS` (not Studio),
478+
`startGameFlow` and the `game` setup target in `NewProjectSurface`,
479+
landing through `handleSetupFinished` with the checklist in the agent
480+
panel. Update the "five flows" tests to six.
481+
- [x] **Tools.** `ui_game_set_setup`, `ui_game_design`,
482+
`ui_game_update_design`, `ui_game_build` in
483+
`web/src/lib/tools/builtin/gameSetup.ts`, registered in the index,
484+
tests in `__tests__/gameSetupTools.test.ts`.
485+
- [x] **Tests.** Each step, the flow config at every stage, the checklist's
486+
verified-only-when-true rule (criterion 7), the entry card.
487+
488+
### G3 — Assets and docs
489+
490+
- [x] **Tiles.** `scripts/make-game-style-tiles.mjs` and its nine PNGs under
491+
`packages/base-nodes/nodetool/assets/nodetool-base/` per § 6.2 and
492+
§ 6.3, each under the asset budget.
493+
- [x] **Docs.** `docs/harnesses.md` game-flow entry, `docs/creation-flows/prd.md`
494+
link, `.claude/skills/godot-game/SKILL.md` gains a line pointing the
495+
agent at the flow's graph for a first build.
496+
414497
## Cross-cutting, every phase
415498

416499
- [ ] UI primitives only, design tokens only, media through `ResponsiveImage`

docs/harnesses.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,6 +1151,47 @@ through `GODOT_BIN` or `godot`/`godot4`/`Godot` on `PATH`; the suites that
11511151
need it skip with a named reason when it is absent. Implementations:
11521152
`packages/agents/src/capabilities/godot.ts`.
11531153

1154+
### Game flow (guided build: design, graph, export)
1155+
1156+
The Game entry card turns one sentence into a graph that fills every slot the
1157+
pipeline above declares and ends in `nodetool.game.ExportGodotProject`. Three
1158+
pure pieces carry it, each with its own suite: `packages/protocol/src/game-design.ts`
1159+
holds the designer contract that writes the cast, the level and one prompt per
1160+
slot; `game-flow-prompt.ts` wraps `slotPrompt` so the reviewed subject, the
1161+
style preset and the slot's cast member become a sized prompt with the aspect
1162+
ratio the generator takes; and `game-graph.ts`'s `gameGraphPlacement` is a pure
1163+
function of manifest, design and choices, so nothing a model decides changes
1164+
the chain a slot gets. The flow's state is `settings.game` on the workflow, so
1165+
a half-built game resumes at the step it stopped on.
1166+
1167+
`game-flow` is the harness over that path. Its selfcheck runs the `game`
1168+
suites in `packages/protocol`; the `game-graph-chips` suite in
1169+
`packages/base-nodes`, which builds each shipped inspiration chip's pinned
1170+
design against the real node registry and passes the result through
1171+
`validateGraph`, so a slot chain naming a node type nobody registered fails
1172+
here instead of on a creator's canvas; the `packages/game-nodes` suite over the
1173+
export node; the `capabilities-game-setup` and `capabilities-godot` suites in
1174+
`packages/agents`, which drive the four `ui_game_*` mirrors and the export join
1175+
both the node and the capability call; the `trpc-games` suite in
1176+
`packages/websocket` over the templates query and the preset seed; and the web
1177+
suites under `web/src/components/setup/game`, `web/src/hooks/game` and
1178+
`web/src/lib/tools/builtin/__tests__/gameSetupTools.test.ts`. `harness gate`
1179+
fires it on any diff touching those paths.
1180+
1181+
It simulates everything up to the art. A design is parsed and the slots the
1182+
model skipped are filled from the manifest and reported, prompts are sized from
1183+
the slot spec, the placement is built and validated against the registry, the
1184+
export node writes the project directory and the zip from the filled fixture in
1185+
`packages/protocol/fixtures/game-assets/`, and the `ui_game_*` tools drive
1186+
every step with no browser open.
1187+
1188+
It does not generate art, call a provider, or assume Godot. No image, sound or
1189+
music model runs, so whether a sheet still reads at the slot's exact cell size
1190+
is not answered here (game-prd R8) — `nodetool debug` on the built graph is
1191+
where that shows up. Godot runs only where `GODOT_BIN` or a binary on `PATH` is
1192+
found; without one the export node reports `verified: false` with a reason, and
1193+
the suite asserts the reason rather than skipping the case.
1194+
11541195
### Entity library tools (no browser)
11551196

11561197
The reusable production entities — characters, locations, styles, props — are

package-lock.json

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@
161161
"gen:example-thumbnails": "node scripts/generate-example-thumbnails.mjs",
162162
"gen:icons": "node scripts/generate-brand-icons.mjs",
163163
"gen:icons:check": "node scripts/generate-brand-icons.mjs --check",
164+
"gen:game-tiles": "node scripts/make-game-style-tiles.mjs",
165+
"gen:game-tiles:check": "node scripts/make-game-style-tiles.mjs --check",
164166
"build:example-storyboards": "node scripts/build-example-storyboards.mjs",
165167
"build:example-storyboards:check": "node scripts/build-example-storyboards.mjs --check",
166168
"examples:smoke": "node scripts/smoke-examples.mjs",

packages/agents/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"@nodetool-ai/browser": "*",
2828
"@nodetool-ai/config": "*",
2929
"@nodetool-ai/execution": "*",
30+
"@nodetool-ai/game-nodes": "*",
3031
"@nodetool-ai/godot": "*",
3132
"@nodetool-ai/godot-templates": "*",
3233
"@nodetool-ai/image-editor": "*",

0 commit comments

Comments
 (0)