@genex-ai/cli-demo 0.86.0-dev.217 → 0.87.0-dev.218

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -254,10 +254,10 @@ var GENEX_CONTRACT_BLOCK = `${CONTRACT_BEGIN}
254
254
 
255
255
  Your capabilities (all via \`npx genex \u2026\`): generate \`model\` \xB7 \`skybox\` \xB7 \`sfx\` \xB7 \`music\` \xB7 \`voice\` \xB7 \`texture\` \xB7 \`image\` (\`--edit\` \xB7 \`--inpaint\` \xB7 \`--glass\` \xB7 \`--clean\` \xB7 \`--upscale\`) \xB7 \`video\` \xB7 rigged \`character\` / \`creature\` \xB7 the pixel toolbox \`ui extract|masks|plate|text-color|trim|audit\` \xB7 vendored \`controller character|car|drone|touch|quality\` \xB7 \`animations search\` \xB7 \`wait <id>\` / \`wait --all\` \xB7 \`preview\` / \`publish\`. Full options: \`npx genex --help\`. Task\u2192lane routing lives in the \`genex-game-director\` skill's routing map \u2014 re-load it whenever you're unsure which lane owns a task.
256
256
 
257
- 1. Load the \`genex-game-director\` skill and follow it end to end before any game code. After ANY context compaction or session resume, re-read this file, \`DESIGN.md\`, and the skill for the stage you are executing.
257
+ 1. Load the \`genex-game-director\` skill and follow it end to end before any game code. After ANY context compaction or session resume, re-read this file and \`DESIGN.md\`, re-load the skill for the stage you are executing, and continue from the Build plan's \`Now:\` line \u2014 never from memory alone.
258
258
  2. The design interview always happens: 2\u20134 build-forking questions, ONE round, before DESIGN.md is written \u2014 even when the request already names the game (then it confirms the pitch). Ask with your built-in question tool with clickable answer options when you have one; a short numbered list in plain chat otherwise. Only after asking may you proceed on stated assumptions if the player stays silent; record each as "assumed \u2014 player didn't answer" in DESIGN.md \u2192 Decisions.
259
- 3. \`DESIGN.md\` at the project root is the design contract. Keep it current; record every decision, assumption, and generation id there.
260
- 4. ALL generated art, audio, video, characters, and UI come from \`genex\` commands \u2014 never from any other generation tool your platform bundles, unless the player explicitly asks for that tool by name. A local reference image is not a reason to switch tools: pass its file path to genex (\`--edit\` and \`--inpaint\` accept local paths).
259
+ 3. \`DESIGN.md\` at the project root is the design contract AND the build plan. It must carry a \`## Build plan & status\` section: numbered milestones with status marks and a \`Now:\` line naming the current one \u2014 a milestone is done only when its work reached a preview. Keep it current; record every decision, assumption, and generation id there. When the plan first lands, tell the player in one plain line that the plan is locked in and lives in \`DESIGN.md\`.
260
+ 4. ALL generated art, audio, video, characters, and UI come from \`genex\` commands \u2014 never from any other generation tool your platform bundles, unless the player explicitly asks for that tool by name. A local reference image is not a reason to switch tools: pass its file path to genex (\`--edit\` and \`--inpaint\` accept local paths). The same exclusivity covers shipping: building, previewing, and publishing go only through \`genex preview\` / \`genex publish\` \u2014 never load your platform's own site-building, hosting, or deploy skills for this game.
261
261
  5. The Stage-1 HUD mockup IS the game concept \u2014 it is your FIRST art action at the UI plan gate. ONE concept image, no candidate variants (generate variants only when the player asks for them), anchored to any reference image the player gave.
262
262
  6. The moment the mockup lands: you are the art director \u2014 immediately enqueue the Stage-2 HUD sheet, the menu still, and the logotype (\`--no-wait\`). THEN show the player the frame and ask keep/change as information, never as a gate. Silence = the concept stands; a later "change" loops it with the player's notes.
263
263
  7. The menu video fires at the FIRST of: the player's yes \xB7 the next \`genex preview\` after the menu still landed \xB7 style art being the only work left. It never fires while a player objection is open. Two failed videos \u2192 ship the still (menu skill rule).
@@ -267,8 +267,11 @@ Your capabilities (all via \`npx genex \u2026\`): generate \`model\` \xB7 \`skyb
267
267
  11. Never park ready work behind a question, and never stall on an unanswered one \u2014 decide, state the decision in chat, record it, keep building.
268
268
  12. Wire-in floors before any publish and before ending a session: sprite HUD wired (or the recorded CSS lane finished), menu video playing (or its recorded still fallback), logotype placed, fonts loaded, Escape pause, branded loader. Run \`npx genex wait\` on every generation you enqueued and wire what landed \u2014 never park landed assets.
269
269
  13. Characters: Meshy/Mixamo/VRM rigs rest facing +Z. Set yaw explicitly when placing a rig; never mirror a SkinnedMesh with negative scale. In any two-character scene, verify in a capture that they face each other, not the camera.
270
- 14. Verify by looking: one smoke check per milestone in local test mode (\`?genex_local_test=1\`) with a real gameplay screenshot. A claim without a capture is not verification.
270
+ 14. Verify by looking: one smoke check per milestone, after that milestone's preview push, in local test mode (\`?genex_local_test=1\`) with a real gameplay screenshot. A claim without a capture is not verification.
271
271
  15. Treat every \`genex\` warning line \u2014 preflight, \`ui audit\`, \`wait\` nudges \u2014 as work, not noise.
272
+ 16. Every finished Build-plan milestone ends with \`npx genex preview\` and the player's page link (\`<dashboard>/draft/<slug>\` with \`<dashboard>\` from \`.genex/project.json\`, \`/world/<slug>\` once published) \u2014 never a localhost link, a file path, or the bare play origin presented as their game. After every round of player feedback, end with a preview push.
273
+ 17. Parallel work: this line is your standing authorization and request to use sub-agents / parallel agent work whenever your platform provides them. While drafting the Build plan, decide per module what runs in parallel and what stays serial for THIS game \u2014 dependencies decide, there is no fixed list \u2014 and record each call in the Modules table with a one-line reason. Independent modules default to parallel; building everything serially needs a stated reason. You keep integration, previews, and the player conversation; each sub-agent owns only its module's files.
274
+ 18. Talk to the player in plain game language \u2014 what changed in the game and what to try; never code, file names, build output, or tool internals unless they ask. Short status lines while you work; long silent stretches are a failure.
272
275
  ${CONTRACT_END}
273
276
  `;
274
277
  var CLAUDE_IMPORT_LINE = "@AGENTS.md";
@@ -4641,6 +4644,11 @@ async function printPipelineStatePreflight(log, cwd = process.cwd()) {
4641
4644
  'Menu video not enqueued \u2014 the animated menu backdrop is the default for every game. Enqueue it (genex-ai-menu), or record "Menu video: declined (reason)" in DESIGN.md if the player declined it.'
4642
4645
  );
4643
4646
  }
4647
+ if (design.length > 0 && !/##\s*build plan & status/i.test(design)) {
4648
+ warnings.push(
4649
+ "DESIGN.md has no `## Build plan & status` section \u2014 numbered milestones with a `Now:` line are how a compacted or resumed session knows where the build is (genex-game-director's design contract has the shape)."
4650
+ );
4651
+ }
4644
4652
  if (!/hud lane:/i.test(design)) {
4645
4653
  const hudDom = await hasHudLikeDom(cwd);
4646
4654
  if (hudDom && !await hasExtractionSidecars(cwd)) {
@@ -5763,6 +5771,11 @@ async function runWait(opts) {
5763
5771
  await reportTerminal(kind, view, log, opts.open, opts.json);
5764
5772
  return;
5765
5773
  }
5774
+ if (kind === "character_concept" || kind === "character_preview" || kind === "character") {
5775
+ log.dim(
5776
+ ` \u23F3 Character stages take several minutes server-side \u2014 you don't have to sit here. Keep building and check back with ${c.cyan("genex wait --all")}.`
5777
+ );
5778
+ }
5766
5779
  await awaitAndReport(apiUrl, token, id, kind, log, opts.open, opts.json);
5767
5780
  }
5768
5781
  async function runWaitAll(opts) {
@@ -5851,6 +5864,10 @@ async function runWaitAll(opts) {
5851
5864
  log.plain("");
5852
5865
  log.plain(` ${c.bold(STAGE1_LANDING_NUDGE)}`);
5853
5866
  }
5867
+ log.plain("");
5868
+ log.dim(
5869
+ " \u{1F4DC} Resumed or compacted? Re-read AGENTS.md + DESIGN.md (continue from its Now: line) before building on."
5870
+ );
5854
5871
  }
5855
5872
  async function toRow(e, v, cwd) {
5856
5873
  const base = { id: e.id, kind: e.kind, prompt: e.prompt, queuedAt: e.queuedAt };
@@ -15787,6 +15804,22 @@ async function context(opts) {
15787
15804
  const project = await readProject();
15788
15805
  return { token, apiUrl: getApiUrl(opts.apiUrl ?? project?.apiUrl) };
15789
15806
  }
15807
+ var CHARACTER_BRIEF_MAX_CHARS = 600;
15808
+ function apiErrorMessage(data, fallback) {
15809
+ if (typeof data !== "object" || data === null) return fallback;
15810
+ const body = data;
15811
+ if (typeof body.message === "string" && body.message) return body.message;
15812
+ if (typeof body.error === "string" && body.error) return body.error;
15813
+ const err = body.error;
15814
+ if (err && Array.isArray(err.issues) && err.issues.length > 0) {
15815
+ const lines = err.issues.map((i) => {
15816
+ const where = Array.isArray(i.path) && i.path.length > 0 ? `${i.path.join(".")}: ` : "";
15817
+ return typeof i.message === "string" ? `${where}${i.message}` : "";
15818
+ }).filter(Boolean);
15819
+ if (lines.length > 0) return `${fallback} ${lines.join("; ")}`;
15820
+ }
15821
+ return fallback;
15822
+ }
15790
15823
  async function quote(url, token, body) {
15791
15824
  const response = await apiFetch(url, {
15792
15825
  method: "POST",
@@ -15796,7 +15829,7 @@ async function quote(url, token, body) {
15796
15829
  if (printedStructuredError(response)) return null;
15797
15830
  if (!response.ok) {
15798
15831
  const data = await response.json().catch(() => ({}));
15799
- throw new Error(data.message ?? data.error ?? `Quote failed (HTTP ${response.status}).`);
15832
+ throw new Error(apiErrorMessage(data, `Quote failed (HTTP ${response.status}).`));
15800
15833
  }
15801
15834
  return (await response.json()).quote;
15802
15835
  }
@@ -15848,7 +15881,7 @@ async function postWorkflow(url, token, body) {
15848
15881
  if (printedStructuredError(response)) return null;
15849
15882
  if (!response.ok) {
15850
15883
  const data2 = await response.json().catch(() => ({}));
15851
- throw new Error(data2.message ?? data2.error ?? `Character workflow request failed (HTTP ${response.status}).`);
15884
+ throw new Error(apiErrorMessage(data2, `Character workflow request failed (HTTP ${response.status}).`));
15852
15885
  }
15853
15886
  const data = await response.json();
15854
15887
  if (typeof data.id !== "string" || data.id.length === 0) {
@@ -15909,6 +15942,14 @@ async function runCharacterConcept(opts) {
15909
15942
  fail2(opts, 'Missing brief. Usage: genex character "<brief>".', "character_concept");
15910
15943
  return;
15911
15944
  }
15945
+ if (prompt.length > CHARACTER_BRIEF_MAX_CHARS) {
15946
+ fail2(
15947
+ opts,
15948
+ `The brief is ${prompt.length} characters \u2014 the character concept endpoint caps it at ${CHARACTER_BRIEF_MAX_CHARS}. Tighten it to the look that matters (silhouette, materials, palette, mood); gameplay details don't belong in the brief.`,
15949
+ "character_concept"
15950
+ );
15951
+ return;
15952
+ }
15912
15953
  if (opts.polycount !== void 0) {
15913
15954
  fail2(opts, "--polycount is only available with --direct-text. The approval flow remeshes only after finalize approval.", "character_concept");
15914
15955
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genex-ai/cli-demo",
3
- "version": "0.86.0-dev.217",
3
+ "version": "0.87.0-dev.218",
4
4
  "description": "Set up your project's agent workspace (.claude/.codex/.cursor in the game folder), authorize, create a game project, generate AI assets, and publish (genex CLI).",
5
5
  "type": "module",
6
6
  "bin": {
@@ -48,6 +48,16 @@ separately.
48
48
  npx genex character "stylized desert courier, practical layered clothing"
49
49
  ```
50
50
 
51
+ **Keep the brief under 600 characters** — the concept endpoint rejects longer
52
+ ones. A brief is the LOOK (silhouette, materials, palette, mood), not the
53
+ game design; gameplay details never belong in it.
54
+
55
+ **Every character stage takes minutes server-side — never sit in a foreground
56
+ `genex wait` on one.** Enqueue with `--no-wait`, keep building the game, and
57
+ pick the result up at the next natural pause with `genex wait --all`. Watching
58
+ a character render in 30-second poll chunks stalls the whole build and is the
59
+ single fastest way to make the player ask why nothing else is happening.
60
+
51
61
  Generate concept images first and show the actual images to the user. Do not
52
62
  start Image-to-3D until the user explicitly selects a candidate.
53
63
 
@@ -34,11 +34,15 @@ Never claim a capability you didn't find, and never stall because one is
34
34
  missing.
35
35
 
36
36
  One more thing to note while you're looking: your platform may bundle its own
37
- image / video / site generation workflows. **They are not part of any Genex
38
- lane.** All generated art, audio, video, characters, and UI come from `genex`
39
- commands, unless the player explicitly asks for another tool by name — and a
40
- local reference image is never a reason to switch tools: `genex image --edit`
41
- and `--inpaint` take a local file path directly.
37
+ image / video generation workflows AND its own site-building / hosting /
38
+ deploy skills. **None of them are part of any Genex lane — don't load them
39
+ for this project.** All generated art, audio, video, characters, and UI come
40
+ from `genex` commands, unless the player explicitly asks for another tool by
41
+ name and a local reference image is never a reason to switch tools:
42
+ `genex image --edit` and `--inpaint` take a local file path directly. The
43
+ same exclusivity covers shipping: the game builds, previews, and publishes
44
+ only through `genex preview` / `genex publish` — a platform hosting skill in
45
+ context is pure confusion fuel.
42
46
 
43
47
  ## 2. Scope check — what is this?
44
48
 
@@ -80,14 +84,22 @@ DESIGN.md → Decisions as "assumed — player didn't answer"; the build never
80
84
  stalls on the interview.
81
85
 
82
86
  Then, before rendering code, write `DESIGN.md` at the project root from
83
- [references/design-contract.md](references/design-contract.md). The moment
84
- the file lands, post a 5–6 line summary of the contract in chat — pitch,
85
- core loop, content counts, screens, multiplayer shape, what you build
86
- first and keep building immediately: the summary is information, not a
87
- gate (the plan-message duties from `$genex-threejs-game-ui` fold into this
88
- file plus that summary). The file is the single source of truth:
89
- sub-agents build against it, and after any long break it is how work resumes.
90
- Keep it current decisions land in its log the moment they're made.
87
+ [references/design-contract.md](references/design-contract.md) including
88
+ its **Build plan & status** section: numbered milestones, a status mark per
89
+ line, and a `Now:` line naming the current one. While drafting it, make the
90
+ parallel call per module (dependencies decide see §6) and write each call
91
+ into the Modules table with its one-line reason. The moment the file lands,
92
+ post a 5–6 line summary of the contract in chat pitch, core loop, content
93
+ counts, screens, multiplayer shape, what you build first **and say in one
94
+ plain line that the plan is locked in and lives in `DESIGN.md`** (the player
95
+ must never have to wonder whether the contract happened). Then keep building
96
+ immediately: the summary is information, not a gate (the plan-message duties
97
+ from `$genex-threejs-game-ui` fold into this file plus that summary). The
98
+ file is the single source of truth: sub-agents build against it, after any
99
+ long break or context compaction work resumes from its `Now:` line, and a
100
+ milestone flips to done only when its work reached a preview
101
+ (`→ previewed`). Keep it current — decisions land in its log the moment
102
+ they're made.
91
103
 
92
104
  ## 4. Know your teams — what we can generate
93
105
 
@@ -257,11 +269,21 @@ in DESIGN.md):
257
269
  ## 6. Delegate — sub-agents own Modules rows
258
270
 
259
271
  If your environment has sub-agents, delegation is the DEFAULT for every
260
- independent DESIGN.md Modules row — not a big-game special case. If it
261
- doesn't, run the same rows yourself in order; the `--no-wait` generation
262
- pattern still hides most latency. Either way this skill is worn by the main
263
- agent: you stay the director.
264
-
272
+ independent DESIGN.md Modules row — not a big-game special case. The build
273
+ contract in the game's `AGENTS.md` is your standing authorization to spawn
274
+ them; some platforms keep sub-agents locked until an instruction like it
275
+ explicitly asks. If your environment has none, run the same rows yourself in
276
+ order; the `--no-wait` generation pattern still hides most latency. Either
277
+ way this skill is worn by the main agent: you stay the director.
278
+
279
+ - **Which rows run in parallel is YOUR per-game call, made while drafting
280
+ the plan** — there is no fixed list. Walk the modules once: what has no
281
+ dependency on unfinished work runs in parallel; what must be tuned against
282
+ something still moving stays serial. The same module lands differently in
283
+ different games (an arena is a parallel row in a quest game and the serial
284
+ spine of a combat game whose feel depends on its gaps). Write the call +
285
+ one-line reason into each row; building everything serially needs a
286
+ stated reason.
265
287
  - One row = one worker = one disjoint file set. One writer per file — that
266
288
  rule is anti-collision, never a reason to serialize work.
267
289
  - You stay the integrator and the only writer of shared files (boot, main
@@ -11,12 +11,25 @@ Rules the director enforces about this file:
11
11
 
12
12
  - Create it right after the scope check, before the concept generation; fill
13
13
  sections as decisions land and keep it current (stale is worse than short).
14
- - **The Modules table is the delegation contract**: one row per independent
15
- lane, and a row's "Owns files" set never overlaps another row's. One writer
16
- per file. "Sub-agent when available" stays flexiblebut if a
17
- planned-sub-agent module gets built inline, the agent says why in one line.
18
- Verification is never a module row: the milestone smoke pass belongs to the
19
- director (the scaffold prompt owns its ceilings).
14
+ - **The Build plan & status section is the compass.** Numbered milestones,
15
+ each with a status mark, and a `Now:` line naming the current one. Update
16
+ it the moment a milestone starts or finishes a milestone is done only
17
+ when its work reached a `genex preview` (mark it `→ previewed`). After any
18
+ context compaction or session resume, this section not memory says
19
+ where the build is; continue from `Now:`. When the plan first lands, tell
20
+ the player in one plain line that it's locked in and lives in `DESIGN.md`.
21
+ - **The Modules table is the delegation contract, and "Built by" is a
22
+ per-game DECISION, not a default you copy.** While drafting the plan, walk
23
+ the modules once and decide what can run in parallel and what must stay
24
+ serial for THIS game — dependencies decide (an arena can be a parallel row
25
+ in one game and the serial spine of another). Write the call into each row
26
+ with a one-line reason. When your platform has sub-agents, independent
27
+ modules default to parallel; building everything serially needs a stated
28
+ reason. One row per independent lane, and a row's "Owns files" set never
29
+ overlaps another row's — one writer per file. If a planned-parallel module
30
+ gets built inline, say why in one line. Verification is never a module
31
+ row: the milestone smoke pass belongs to the director (the scaffold prompt
32
+ owns its ceilings).
20
33
  - **The Assets table is the budget**: the asset list falls out of Content
21
34
  (enemies → models, an arena → a ground texture, outdoors → a skybox).
22
35
  Status flow per row: `proposed → planned → generating (id) → landed (URL) →
@@ -50,6 +63,14 @@ Concept image: <asset URL> (standing — shown <date>; player said
50
63
  - **You earn:** <reward / progression>
51
64
  - **You lose when:** <fail state> → **and retry by:** <restart shape>
52
65
 
66
+ ## Build plan & status
67
+ Now: ▶ <number + name of the milestone in progress>
68
+ 1. <milestone> — ✅ → previewed
69
+ 2. <milestone> — ▶ in progress (<who: main agent | sub-agent>)
70
+ 3. <milestone> — ⬜ (<parallel: sub-agent | serial: main agent — one-line why>)
71
+ (One line per milestone; update on every start/finish; done requires its
72
+ preview. This section is the post-compaction compass — resume from `Now:`.)
73
+
53
74
  ## Content (only when the request names plural content or a content genre)
54
75
  Every plural noun from the request becomes a countable line:
55
76
  - Quests: <N>, chained by <how>
@@ -99,13 +120,15 @@ teams, backfill…)> — and why. Play-button rule: nothing connects before the
99
120
  click (when a Play screen exists).
100
121
 
101
122
  ## Modules — the build split
123
+ ("Built by" is decided per game while drafting the plan — dependencies
124
+ decide, with a one-line reason per row; the rows below are only a SHAPE.)
102
125
  | Module | Owns files | Built by | Done when |
103
126
  |---|---|---|---|
104
- | Boot & identity | src/main.ts, src/genex-boot.ts | main agent (only writer) | boots, tier wired, initEmbed runs |
105
- | World/terrain | src/world/** | sub-agent when available | walkable, matches World & scale |
106
- | Quests & dialogue data | src/content/** | sub-agent when available | counts match Content lines |
107
- | Enemies/AI | src/enemies/** | sub-agent when available | roster matches Content |
108
- | HUD chain (style-dependent) | src/ui/** | sub-agent on concept landing | all screens from Screens & UI |
127
+ | Boot & identity | src/main.ts, src/genex-boot.ts | main agent (only writer of shared boot) | boots, tier wired, initEmbed runs |
128
+ | World/terrain | src/world/** | parallel: sub-agent (no dependency on combat) | walkable, matches World & scale |
129
+ | Quests & dialogue data | src/content/** | parallel: sub-agent (pure data) | counts match Content lines |
130
+ | Enemies/AI | src/enemies/** | serial: main agent (tuned against movement feel) | roster matches Content |
131
+ | HUD chain (style-dependent) | src/ui/** | parallel: sub-agent on concept landing | all screens from Screens & UI |
109
132
 
110
133
  ## Decisions & changes
111
134
  - <date> — <one-liner per decision, including anything the player said no or
@@ -133,6 +156,15 @@ Concept image: https://assets.genex.technology/g/rustyard/concept.png
133
156
  - **You lose when:** your bot breaks → **and retry by:** one key, instant
134
157
  respawn, same round
135
158
 
159
+ ## Build plan & status
160
+ Now: ▶ 3. Rival AI feels dangerous
161
+ 1. Arena skeleton + movement — ✅ → previewed
162
+ 2. Shooting + scrap scoring — ✅ → previewed
163
+ 3. Rival AI feels dangerous — ▶ main agent
164
+ 4. HUD sprite swap — ⬜ parallel: sub-agent (concept landed, chain enqueued)
165
+ 5. Magnet cycle + pickups — ⬜ parallel: sub-agent (own files, no AI dependency)
166
+ 6. Menus, music, publish floors — ⬜
167
+
136
168
  ## Screens & UI
137
169
  Screens: loader, title menu, HUD (health, scrap, cycle timer), pause,
138
170
  win/lose. Style brief: oily metal, warning-stripe accents, stencil type.
@@ -167,10 +199,10 @@ Single-player v1 (rivals are host-free local AI). Revisit after publish.
167
199
  ## Modules
168
200
  | Module | Owns files | Built by | Done when |
169
201
  |---|---|---|---|
170
- | Boot & identity | src/main.ts | main agent | boots, tier wired, initEmbed runs |
171
- | Arena & pickups | src/world/** | sub-agent | walkable, magnet cycle fires |
172
- | Rival AI | src/enemies/** | sub-agent | 3 rivals hunt + shoot |
173
- | HUD chain | src/ui/** | sub-agent after yes | all 5 screens live |
202
+ | Boot & identity | src/main.ts | main agent (shared boot) | boots, tier wired, initEmbed runs |
203
+ | Arena & pickups | src/world/** | parallel: sub-agent (independent of AI) | walkable, magnet cycle fires |
204
+ | Rival AI | src/enemies/** | serial: main agent (tuned vs player feel) | 3 rivals hunt + shoot |
205
+ | HUD chain | src/ui/** | parallel: sub-agent on concept landing | all 5 screens live |
174
206
 
175
207
  ## Decisions & changes
176
208
  - 2026-07-20 — player picked concept candidate 2; asked for "more sparks".