@genex-ai/cli-demo 0.78.1-dev.203 → 0.80.0-dev.211

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
@@ -287,7 +287,7 @@ async function hasGenexSkills(skillsDir) {
287
287
  return false;
288
288
  }
289
289
  }
290
- var REMOVED_SKILLS = ["genex-explore"];
290
+ var REMOVED_SKILLS = ["genex-explore", "genex-threejs-skill-router"];
291
291
  async function pruneRemovedSkills(skillsDir, log) {
292
292
  const removed = [];
293
293
  for (const name of REMOVED_SKILLS) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genex-ai/cli-demo",
3
- "version": "0.78.1-dev.203",
3
+ "version": "0.80.0-dev.211",
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": {
@@ -17,5 +17,5 @@ command keeps them in sync with the installed CLI version automatically
17
17
  - `agents/` - example subagent definitions.
18
18
  - `commands/` - example slash commands.
19
19
 
20
- Start with `skills/genex-threejs-skill-router/SKILL.md` when asking your agent
20
+ Start with `skills/genex-game-director/SKILL.md` when asking your agent
21
21
  to build or improve a 3D browser game.
@@ -43,10 +43,8 @@ Meshy Image-to-3D first produces an unremeshed high-detail model. Show its
43
43
  front, back, left, and right views and report its measured face count. Preserve
44
44
  that model in R2. Before rigging, ask the user to approve a separate
45
45
  10,000-face triangle remesh. The 10k remesh—not the high-detail source—is
46
- rigged and animated. (For these approvals, use your environment's structured
47
- question tool when it has one Claude Code: `AskUserQuestion`; Codex:
48
- `request_user_input`; if it has none, e.g. Cursor, a short numbered list in
49
- chat.)
46
+ rigged and animated. (For these approvals, use your question tool when you
47
+ have one; if you have none, a short numbered list in chat.)
50
48
 
51
49
  The high-detail pre-rig generation stays in the selected neutral A-pose. There
52
50
  is no dynamic-pose concept and no silent T-pose fallback. After the user has
@@ -48,14 +48,12 @@ ring) that no hand-written CSS can fake.
48
48
  semi-transparency physically cannot survive sprite extraction: a composited
49
49
  panel's pixels are a blend of panel and background, and no cutout can
50
50
  un-blend them. Plates are NEVER baked into sprites. Give the plate its
51
- corners with `border-radius` or a clean `clip-path`/`mask` shape — a CSS
52
- chamfer/notch is allowed, as long as the cut never clips the plate's
53
- content (text, padding, a glow), leaves no jagged-edge artifacts, and
54
- nothing ends up crooked and a plain `border`/`box-shadow` won't follow a
55
- `clip-path` cut, so use `$genex-threejs-game-ui`'s two-layer chamfer-border
56
- recipe when a chamfer needs a frame; a genuinely ornamented angular frame is still
57
- best as chrome, generated. The load-bearing `mask`/`clip-path` in this
58
- skill is the masked-fill reveal below.
51
+ corners with `border-radius` **never a raw `clip-path`/`mask` chamfer**
52
+ (it shears off borders, shadows, and content near the cut and re-breaks on
53
+ every padding/value change: the recurring "cut corners" defect). A genuinely
54
+ ornamented or angular frame belongs in chrome, generated. The one
55
+ load-bearing `mask`/`clip-path` in this skill is the masked-fill reveal
56
+ below never corner shaping.
59
57
  - **Chrome (sprites — what THIS pipeline generates).** Opaque frames, corner
60
58
  brackets, ornaments, emblems, icons, medallions — hard-alpha art laid over
61
59
  the glass. The Stage-2 sheet contains ONLY chrome; never a panel with its
@@ -82,7 +80,7 @@ ring) that no hand-written CSS can fake.
82
80
  the container is the sprite and the content is DOM — the default split.
83
81
  - **Rule B — image vs code (the 5-minute test).** If CSS can build the
84
82
  element in under ~5 minutes without losing fidelity — flat plates, simple
85
- dots/pips, plain strokes, a chamfered corner — it is CSS. If it needs
83
+ dots/pips, plain strokes, a rounded corner — it is CSS. If it needs
86
84
  craft (material, ornament, painterly texture), it is a sprite. One
87
85
  exception cuts the other way: a static label engraved/embossed into a
88
86
  frame's craft stays BAKED in the sprite (`baked_static` below) even
@@ -90,9 +88,10 @@ ring) that no hand-written CSS can fake.
90
88
  - **CSS-chrome recipes — the middle ground.** Between bare CSS and the full
91
89
  sprite pipeline sits brief-styled CSS chrome, right for utilitarian panels
92
90
  and secondary screens: a two-hue gradient frame (border + inset
93
- box-shadow in brief hues), a clip-path chamfer (execution bar per
94
- `$genex-threejs-game-ui`'s corner rules), a 9-slice-ish panel from nested
95
- divs (outer div = border hue, inset div = plate hue, 2–3px reveal). What
91
+ box-shadow in brief hues), rounded with `border-radius` (never a raw
92
+ `clip-path` chamfer — see `$genex-threejs-game-ui`'s corner rules), a
93
+ 9-slice-ish panel from nested divs (outer div = border hue, inset div =
94
+ plate hue, 2–3px reveal). What
96
95
  makes these legitimate: **CSS elements are styled FROM THE BRIEF — hue,
97
96
  weight, texture. Default-gray CSS anywhere on screen is a defect** (the
98
97
  classic failure: score pips shipped as unstyled "○ ●" system glyphs).
@@ -219,8 +218,16 @@ serves as the user's style checkpoint, and anchors all later art
219
218
  is frame-anchored, so it waits for the user's keep/change YES on that
220
219
  checkpoint — kick it off the instant they approve, not before.** The scene half
221
220
  of the prompt is written in TEXT from the game plan — `[GAME_SCENE]` in the
222
- Stage-1 template: setting, the moment, what the player is doing, lighting
223
- never `--edit`-anchored to a prior image (there is none). Then write the
221
+ Stage-1 template: setting, the moment, what the player is doing, lighting.
222
+ **If a concept/reference image already exists the user's own concept art, or
223
+ a look frame you generated and they approved — anchor Stage 1 to it with
224
+ `--edit <that-url>` so the HUD inherits its exact palette, materials, and
225
+ lighting; that anchoring is what makes the final HUD actually match the
226
+ concept, and skipping it is why a text-only mockup drifts.** A text-only
227
+ Stage 1 is the fallback for when no reference exists. (To `--edit` a
228
+ user-supplied image it must be reachable as an R2 URL — a bare chat attachment
229
+ is not; reproduce it as a generation first, or say plainly you can't anchor to
230
+ it rather than silently guessing.) Then write the
224
231
  widget layout and wiring code (placement, masked-fill scaffolding,
225
232
  plain-CSS placeholder bars) while it renders — the CSS HUD keeps
226
233
  the game playable until the sprites land. When a sprite lands it REPLACES
@@ -238,8 +245,9 @@ re-run from Stage 1 with their notes — cheaper than it sounds (one image
238
245
  is the whole concept now), so say so in one line and do it.
239
246
 
240
247
  ```bash
241
- # Stage 1 — the game CONCEPT: full HUD composited over the game's own scene,
242
- # described in TEXT (one generation covers concept + layout reference).
248
+ # Stage 1 — the game CONCEPT: full HUD composited over the game's own scene.
249
+ # TEXT-described; add `--edit <concept-url>` to anchor it to an existing
250
+ # concept/reference image so the HUD inherits its exact style.
243
251
  # Two candidates in one call; pick the better, save its URL:
244
252
  npx genex image "<filled stage-1 prompt>" --size 2560x1440 --quality high --candidates 2
245
253
 
@@ -492,6 +500,13 @@ Two hard rules:
492
500
 
493
501
  ## Verify before calling it done
494
502
 
503
+ **This is a gate, not a suggestion — the HUD is not "done", does not ship, and
504
+ is not called a milestone until you have looked at it running.** The field
505
+ failure is an agent that wires the sprites, takes one glance, notices a possible
506
+ clip or cutoff, and ships anyway with "I'll refine if the user reports issues."
507
+ That punt IS the defect. You are the one who verifies, not the user. If you are
508
+ out of budget to check, say the HUD is unverified — never call it done.
509
+
495
510
  - **Open every extracted PNG and eyeball it** — right subject, right name.
496
511
  The reading-order sort can mismap when rows are uneven; re-run `extract`
497
512
  with corrected name order rather than regenerating anything.
@@ -502,9 +517,11 @@ Two hard rules:
502
517
  Display fonts run 25–50% wider than a naive estimate; widen the box or drop
503
518
  the weight, don't shrink the font.
504
519
  - **No widget overlaps** at the reference viewport, and none off-screen.
505
- - **Screenshot-check over real gameplay** — bright AND dark scenes — with
506
- `$genex-threejs-visual-validation`'s capture discipline. Judge the pixels,
507
- not your intent.
520
+ - **Screenshot the running HUD and inspect it** — bright AND dark scenes —
521
+ with `$genex-threejs-visual-validation`'s capture discipline. **Zoom every
522
+ corner:** no sheared frames, no clipped/cut corners, no text truncated or
523
+ colliding with an edge. Judge the pixels, not your intent — skipping this is
524
+ exactly how the "cut corners" defect ships.
508
525
 
509
526
  ## The closing wiring audit — the pipeline's final stage, not optional
510
527
 
@@ -536,6 +553,16 @@ does not count. fillBox numbers, `segments`, and real sprite dims do not
536
553
  survive paraphrase; the canonical version of this failure is a subagent
537
554
  reporting "masks validated" while the parent ships width% fills.
538
555
 
556
+ **Do not fire-and-forget the whole HUD/menu/logo into one background subagent.**
557
+ The field failure: the entire production art pipeline was handed to a single
558
+ background agent that then stalled overnight, so every preview the user played
559
+ showed the CSS placeholder and the real HUD only landed hours later, unseen. If
560
+ art runs in a subagent it is a BOUNDED task you wait on, then wire and verify in
561
+ THIS session — not an overnight handoff. While the art is pending the HUD is
562
+ unverified: do not call the game done or push it as a finished milestone. If a
563
+ subagent stalls or misses its window, wire what landed and say plainly what is
564
+ still placeholder — never present a placeholder HUD as the finished look.
565
+
539
566
  ## Cost & latency honesty
540
567
 
541
568
  A full HUD is **~9 image generations** (mockup + deconstruct + clean + a few
@@ -370,13 +370,14 @@ not):
370
370
  re-anchored the look) re-opens this rule once — re-edit the still
371
371
  (`--edit` against the new concept mockup) and re-run the video from the
372
372
  new still. Agent-initiated polish never does.
373
- - **1080p is the defaultleave it.** The menu clip is full-screen key art,
374
- the first moving thing the player sees, and 720p visibly softens it on any
375
- modern display. `genex video` renders 1080p by default; pass
376
- `--resolution 720p` only as an explicit cost fallback (about half the
377
- credits) when the user asks to economize. The flip side of 1080p: getting
378
- the phone rule above wrong now costs twice as much bandwidth poster on
379
- phone tiers, always.
373
+ - **The menu (`--frame`) path renders 720p don't force 1080p.** The
374
+ frame-conditioned first-last-frame route was rejected by the provider at
375
+ 1080p (repeated 422 failures that shipped a dead static menu), so the menu
376
+ video path defaults to the proven-good, seamless-looping 720p no flag
377
+ needed. The DOM crossfade + full-screen scale read fine at 720p; do NOT pass
378
+ `--resolution 1080p` on a `--frame` menu clip just to sharpen it, or you risk
379
+ re-triggering the 422 and losing the video entirely. (Plain text-to-video,
380
+ without `--frame`, still defaults to 1080p.)
380
381
  - **Pause/victory/defeat variants reuse the same video — as GRADES.** Same
381
382
  `<video>` element or URL, different emotion via CSS `filter` on the
382
383
  background: pause = a plain dark overlay (`rgba(0,0,0,0.55)`); defeat =
@@ -406,9 +407,11 @@ not):
406
407
  genuine state change; expect a loop seam.
407
408
  - `--duration <sec>` (video) — 4, 6, or 8 for frame-conditioned clips;
408
409
  default 8.
409
- - `--resolution <720p|1080p>` (video) — default 1080p; `720p` is the
410
- explicit cost fallback (~half the credits). Loop clips (`--loop`) ignore
411
- it (that model has no resolution parameter).
410
+ - `--resolution <720p|1080p>` (video) — plain text-to-video defaults to 1080p;
411
+ the frame-conditioned (`--frame`) menu path defaults to **720p** for
412
+ reliability (1080p was rejected there). `720p` is also the cost fallback
413
+ (~half the credits). Loop clips (`--loop`) ignore it (that model has no
414
+ resolution parameter).
412
415
  - `--aspect 16:9 --quality high` (image) — the right settings for a menu frame.
413
416
  - `--no-wait` — enqueue and return immediately with the generation id; pick
414
417
  the result up later with `npx genex wait <id>` (safe to re-run — it attaches
@@ -87,16 +87,22 @@ const gltf = await loadModelWithFallback(
87
87
  MODEL_URL, tier, (u) => gltfLoader.loader.loadAsync(u), { ktx2: gltfLoader.ktx2 },
88
88
  );
89
89
  const model = gltf.scene;
90
- // Clamp the provider's mirror-metal PBR (metalness~1 reflects the whole sky
91
- // env and swims with every camera move):
90
+ // Tame ONLY the provider's mirror-metal artifact (metalness1 + near-zero
91
+ // roughness mirrors the whole sky env and swims with every camera move). Do
92
+ // NOT flatten every material to 0.6 — that was dulling legitimately metallic
93
+ // props (gunmetal, chrome, gold, polished stone). Clamp the extreme case only;
94
+ // leave everything else as authored.
92
95
  model.traverse((o) => {
93
96
  const m = (o as THREE.Mesh).material as THREE.MeshStandardMaterial;
94
- if (m?.isMeshStandardMaterial) {
95
- m.metalness = Math.min(m.metalness, 0.6);
96
- m.roughness = Math.max(m.roughness, 0.35);
97
- m.envMapIntensity = 0.6;
97
+ if (!m?.isMeshStandardMaterial) return;
98
+ if (m.metalness > 0.85 && m.roughness < 0.2) {
99
+ m.metalness = 0.7; // still reads metallic, no longer a full mirror
100
+ m.roughness = Math.max(m.roughness, 0.3);
98
101
  }
102
+ m.envMapIntensity = Math.min(m.envMapIntensity, 0.8);
99
103
  });
104
+ // If a model that SHOULD read metallic still looks dull, this clamp is not the
105
+ // cause — check the model against the concept and lift per-material as needed.
100
106
  model.scale.setScalar(1); // tune to taste
101
107
  model.position.set(0, 0, 0);
102
108
  scene.add(model);
@@ -0,0 +1,265 @@
1
+ ---
2
+ name: genex-game-director
3
+ description: The Genex game director — the entry point for every Genex build. Checks what your environment can do, writes the DESIGN.md design contract, routes any new-game, feature, or component request to the right Genex skills in the right order, and fans independent modules out to your sub-agents when you have them. Load first for any game work, or when unsure which skill applies.
4
+ ---
5
+
6
+ # Genex Game Director
7
+
8
+ Own the end-to-end outcome: a finished, playable, good-looking game — not a
9
+ tech demo that boots. You are the director; the other Genex skills are your
10
+ specialists. Load only the skills that change the result; never the whole
11
+ pack by default.
12
+
13
+ ## 1. Check what you can do (once, before planning)
14
+
15
+ Look at your own tool list and note the answers — the rest of this workflow
16
+ uses them:
17
+
18
+ - **A question tool?** Something that asks the player a structured question
19
+ with clickable options. If you have one, use it wherever this workflow says
20
+ "ask"; if not, a short numbered list in plain chat.
21
+ - **Sub-agents?** A way to hand a scoped task to a background worker. If you
22
+ have them, delegation (§6) is your default for independent modules; if not,
23
+ do the same work yourself, in the same order — nothing else changes.
24
+ - **A browser?** If you can open pages and take screenshots, verify visuals
25
+ yourself; if not, ask the player to look and tell you what they see.
26
+
27
+ Never claim a capability you didn't find, and never stall because one is
28
+ missing.
29
+
30
+ ## 2. Scope check — what is this?
31
+
32
+ - **A new game** → the full flow: contract (§3), teams menu (§4), build order
33
+ (§5), delegation (§6).
34
+ - **A feature or fix for an existing game** → read the game's `DESIGN.md` if
35
+ present (keep it current as you work; create a stub if it's missing and the
36
+ change is big), then load just the skills the
37
+ [routing map](references/routing-map.md) names for the touched systems.
38
+ Read before writing: learn the current renderer choice, physics setup, and
39
+ file conventions first, then extend them — don't rebuild working systems or
40
+ switch renderers mid-project.
41
+ - **A component or tool** — a custom controller, a shader, an asset-pipeline
42
+ piece → skip the contract; route straight to the matching skills via the
43
+ routing map. Mostly we build games, but nothing here breaks for
44
+ game-adjacent work.
45
+
46
+ ## 3. The design contract — DESIGN.md
47
+
48
+ Before rendering code, write `DESIGN.md` at the project root from
49
+ [references/design-contract.md](references/design-contract.md). Post a short
50
+ summary in chat (the plan-message duties from `$genex-threejs-game-ui` fold
51
+ into this file plus that summary). The file is the single source of truth:
52
+ sub-agents build against it, and after any long break it is how work resumes.
53
+ Keep it current — decisions land in its log the moment they're made.
54
+
55
+ ## 4. Know your teams — what we can generate
56
+
57
+ Plan the DESIGN.md Assets table from this menu. Details, flags, and approval
58
+ steps live in each owning skill — load it when its lane fires:
59
+
60
+ - `npx genex model "<prompt>"` — a real 3D thing (GLB): what you chase,
61
+ drive, fight → `$genex-ai-model`
62
+ - `npx genex texture "<prompt>"` — any surface bigger than a prop
63
+ (`--terrain` for ground) → `$genex-ai-texture`
64
+ - `npx genex skybox "<prompt>"` — a described 360° sky when the game is
65
+ outdoors → `$genex-ai-skybox`
66
+ - `npx genex sfx "<prompt>"` — the core verb and every impact →
67
+ `$genex-ai-sfx`
68
+ - `npx genex image "<prompt>"` — posters, signs, sprites, decals, HUD art
69
+ (`--transparent` for anything laid on a surface) → `$genex-ai-image`,
70
+ `$genex-ai-hud`
71
+ - `npx genex video "<prompt>"` — in-world screens, billboards, an animated
72
+ menu backdrop (`--loop` for seamless) → `$genex-ai-video`, `$genex-ai-menu`
73
+ - `npx genex character "<prompt>"` — a custom playable humanoid (REQUIRED
74
+ player approvals — §7) → `$genex-ai-character`
75
+ - `npx genex controller character|car|drone|touch|quality` and
76
+ `npx genex animations search "<intent>"` — ready-made, tuned movement and
77
+ motion; never write movement physics from scratch →
78
+ `$genex-threejs-character-controller`,
79
+ `$genex-threejs-vehicle-controllers`, `$genex-threejs-touch-controls`,
80
+ `$genex-threejs-adaptive-quality`
81
+
82
+ Run the commands inside the project (the `@genex-ai/cli-demo` dev dependency
83
+ makes `npx genex` resolve to the right CLI). Each prints a permanent
84
+ `assets.genex.technology` URL you load straight from at runtime — the asset
85
+ lives in Genex storage, not your repo, so there's nothing to commit; each
86
+ owning `genex-ai-…` skill has the exact loader code. Prefer the procedural skills in
87
+ the routing map for abstract/parametric/animated systems (no files, infinite
88
+ variation); prefer these generators for concrete, describable, photoreal
89
+ assets — they complement each other. Assets you didn't plan don't exist: if
90
+ the menu has a lane this game needs, put a row in the Assets table.
91
+
92
+ **Generate a core asset set by default — don't wait to be asked.** For any
93
+ game that needs concrete objects or surfaces, decide a small core set from the
94
+ game IDEA — and from the Content lines when there are any (locations and the
95
+ enemy roster name the set) — and put it in the Assets table up front. This set
96
+ is concept-INDEPENDENT (prompted from the idea, not the concept image, and it
97
+ mostly survives a style change), so it does NOT wait on the concept yes. Each
98
+ `npx genex` job is an independent ~1-minute render: launch them concurrently
99
+ in the background (`--no-wait`), scaffold the scene while they run, and wire
100
+ each in as it lands, with a procedural placeholder until then:
101
+
102
+ - the **hero model** the player controls or chases (`npx genex model`),
103
+ - one key **texture** for the ground/main surface (`--terrain` for ground),
104
+ - a **skybox** when the scene is outdoors,
105
+ - a **sfx** or two for the core action and its feedback.
106
+
107
+ Skip generation only for purely abstract/geometric games. For three.js
108
+ questions no skill covers, use the official three.js documentation
109
+ (https://threejs.org/docs/) — the skills cover the Genex-specific parts, not
110
+ the whole engine.
111
+
112
+ ## 5. Build order — the same hard floors, one owner
113
+
114
+ The mandatory rows, in order, each with its one "done when" line:
115
+
116
+ 1. **Identity first** — load `$genex-threejs-embed-auth` unconditionally,
117
+ every game (multiplayer or not), before any boot code. Done when:
118
+ `initEmbed(...)` runs at the very top of boot and the right gate
119
+ (`waitForPlayer()` vs `waitForAuth()`) is wired.
120
+ 2. **Adaptive quality at boot** — `$genex-threejs-adaptive-quality`. Done
121
+ when: the device tier is wired at boot (tier-capped pixel ratio), the
122
+ governor runs in the loop, and generated skyboxes/textures load through
123
+ their rungs. Phones enforce a hard GPU-memory kill desktop testing never
124
+ shows; the tier is what keeps a phone boot alive.
125
+ 3. **UI plan gate** — `$genex-threejs-game-ui`, every game: the screen
126
+ inventory, one shared style brief, 2–3 AAA references, the menu archetype,
127
+ then the concept image with its full HUD already on it. Show the player
128
+ the picture the moment it lands and ask the keep-or-change question with
129
+ your question tool. Done when: the player said yes to a frame. The yes
130
+ gates ONLY style-dependent art — everything else keeps moving while you
131
+ wait.
132
+ 4. **Content contract when the request names plural content** — quests,
133
+ enemies, bosses, locations, spells, items, or a content genre (an RPG, an
134
+ adventure, an open world, a story game) — `$genex-threejs-game-content`.
135
+ Its countable lines live in DESIGN.md's Content section, written before
136
+ the asset batch (the asset set derives from it). Done when: every plural
137
+ noun of the request has a countable line. Shrinking one is a question to
138
+ the player, never a silent cut.
139
+ 5. **Route the rest** via [references/routing-map.md](references/routing-map.md):
140
+ the smallest useful skill set, the execution order, the visual-direction
141
+ gate (renderer baseline + named post stack), and the world-dressing
142
+ decision. Done when: DESIGN.md names the chosen skills and gates.
143
+ 6. **Multiplayer when 2+ players share a world** — `$genex-threejs-multiplayer`
144
+ before any networking code. Choose the net model from the experience
145
+ (`connect()` for one ongoing drop-in world, `matchmake()` for fresh capped
146
+ matches) — never ask the player to pick an SDK API. When a Play/Online
147
+ button exists, nothing connects before the click. A `matchmake()` game
148
+ declares its `genex.matchmaking` block before preview. Done when: the
149
+ model, start rule, and late-join behavior are stated in DESIGN.md and the
150
+ netcode feel gate ran before handoff.
151
+ 7. **Ship the first playable v0 fast and preview it.** The scaffold prompt
152
+ owns the player-facing milestones and links — don't restate them; obey
153
+ them. Done when: the player has a draft link within about ten minutes of
154
+ the build starting.
155
+
156
+ Two rules for every game that moves (decide both before building, state them
157
+ in DESIGN.md):
158
+
159
+ - **Pointer bucket** — the bundled `FollowCamera` locks the pointer by
160
+ default on desktop, so this is mostly a decision to opt OUT. **Mandatory
161
+ pointer lock**: first-person of any kind, and any mouse-aimed action
162
+ (third-person shooter, FPS, sniper, turret, crosshair/reticle) — leave it
163
+ on. **Lock by default**: third-person free-camera action/adventure —
164
+ drag-orbit (`pointerLockAim: false`) only with a stated reason (e.g. a
165
+ cursor-heavy UI core). **Never**: cursor-core games (click-to-move, tower
166
+ defense, builder, card/puzzle), orbit showcases, touch-only — these MUST
167
+ pass `pointerLockAim: false`. Keyboard-only games (racer, platformer) lock
168
+ too: the cursor is either a gameplay tool or locked away during play. The
169
+ mechanism and the full aim contract live in
170
+ `$genex-threejs-camera-direction`.
171
+ - **Input direction** — D/ArrowRight must move or turn the player
172
+ screen-RIGHT, mouse-right must turn the view right, drag-pan axes share one
173
+ convention. The screen-direction contract and verified copy-paste bases
174
+ live in `$genex-threejs-camera-direction` — hand-rolled steering/pan/look
175
+ math copies one instead of deriving signs, and the smoke check's
176
+ input-direction pass verifies it.
177
+
178
+ ## 6. Delegate — sub-agents own Modules rows
179
+
180
+ If your environment has sub-agents, delegation is the DEFAULT for every
181
+ independent DESIGN.md Modules row — not a big-game special case. If it
182
+ doesn't, run the same rows yourself in order; the `--no-wait` generation
183
+ pattern still hides most latency. Either way this skill is worn by the main
184
+ agent: you stay the director.
185
+
186
+ - One row = one worker = one disjoint file set. One writer per file — that
187
+ rule is anti-collision, never a reason to serialize work.
188
+ - You stay the integrator and the only writer of shared files (boot, main
189
+ loop, netcode). Workers never spawn workers — one level deep, always.
190
+ - Concept-DEPENDENT rows (the HUD chain, style-matched art) wait for the
191
+ player's yes on the concept; concept-INDEPENDENT rows (world/terrain,
192
+ content data, enemies, asset wiring) launch immediately. Typing a big game
193
+ alone, line by line, is how sessions run out before the world exists.
194
+ - Give each worker everything by path: the `DESIGN.md` path, its Modules row,
195
+ and the skill files it needs (skills live in this project —
196
+ `.claude/skills/<name>/SKILL.md`, `.codex/skills/…`, or `.cursor/skills/…`,
197
+ whichever this project has). A worker prompt shape that works: "You own the
198
+ `<row>` module of `<project>/DESIGN.md` — read it first, then read the
199
+ named skill files. Build ONLY the files your row owns. Generate ONLY your
200
+ row's assets already marked `planned` in the Assets table; anything new you
201
+ need, add it as a `proposed` row and say so. Report what landed and what's
202
+ left."
203
+ - **The Assets table is the budget.** A worker runs generation commands only
204
+ for its own rows already marked `planned`; anything new it wants goes in as
205
+ a `proposed` row for you to approve first. An asset-shepherd lane polls
206
+ `npx genex wait --all` and wires + flips landed rows to `wired` — it never
207
+ enqueues. (Whoever wires the HUD after a worker finishes follows
208
+ `$genex-ai-hud`'s handoff rule: read the produced mask/bbox JSON from disk,
209
+ never wire from a prose summary.)
210
+ - Do NOT spawn workers to write extra test suites or audits — one
211
+ verification worker at most, running the smoke checks the scaffold prompt
212
+ already requires.
213
+
214
+ ## 7. A custom playable character (Meshy) — approvals are the product
215
+
216
+ Use the existing VRM + UAL character controller by default
217
+ (`npx genex controller character`). Use `npx genex character` when the game
218
+ needs a custom generated humanoid or an action unavailable in UAL. Before
219
+ generating a Meshy character, discuss two or three visual directions. When the
220
+ user names a visual reference, inspect references before writing the concept
221
+ prompt. Recommend a neutral A-pose for characters that will be rigged.
222
+
223
+ Generate concept images first and show the actual images to the user. Do not
224
+ start Image-to-3D until the user explicitly selects a candidate. Generate
225
+ exactly three concepts, all neutral A-pose; never use a dynamic concept pose
226
+ or silently fall back to T-pose. Warn that held, slung, or overlapping props
227
+ and straps can fuse into the body or obscure limbs, and recommend separate
228
+ gameplay props. Only after the explicit choice, run
229
+ `npx genex character preview <concept-id> --candidate <1|2|3> --user-approved`.
230
+
231
+ Meshy Image-to-3D first produces an unremeshed high-detail model. Show its
232
+ front, back, left, and right views and report its measured face count. Preserve
233
+ that model in R2. Before rigging, ask the user to approve a separate
234
+ 10,000-face triangle remesh. The 10k remesh—not the high-detail source—is
235
+ rigged and animated. Keep every pre-animation generation in the selected
236
+ neutral A-pose. Wait for that explicit approval before
237
+ `npx genex character finalize <preview-id> --user-approved --approve-remesh 10000 [--animation <action-id>…]`.
238
+ (`npx genex character "<prompt>" --direct-text` is the explicit legacy
239
+ one-shot path, not a substitute for these approvals.)
240
+
241
+ Load `$genex-ai-character`, search Meshy actions first with
242
+ `npx genex animations search "<intent>" --json`, and use returned action IDs;
243
+ never invent IDs. Meshy limb rotations play unchanged. Never freeze hand tracks
244
+ or apply post-mixer arm, hand, leg, or foot corrections. Only horizontal root
245
+ or hip translation may be normalized for Rapier. In both lanes, the
246
+ ECCTRL-derived character controller owns collision and world translation.
247
+ Before handoff, visibly check idle, walk, run, crouch-idle, crouch-move, and
248
+ jump — shoulders, elbows, wrists, hands, both leg cycles, and feet — and press
249
+ every control the HUD advertises.
250
+
251
+ ## 8. Fresh-eyes review — before publish
252
+
253
+ Take the game's current screenshots (desktop and phone sizes) and hand them,
254
+ with DESIGN.md only, to a fresh reviewer — a sub-agent if you have one,
255
+ otherwise re-read them yourself adversarially, looking to refute "it's done":
256
+ untextured surfaces, a bare HUD, missing screens, Content lines not in the
257
+ game, Assets rows never flipped to `wired`. Fix or honestly report what it
258
+ finds; never publish over an unacknowledged gap.
259
+
260
+ ## 9. Say it straight
261
+
262
+ "Loaded" means you read a file. "Built" means the thing runs. "Done" means its
263
+ "done when" line is true. Never report a skill as applied because you read it,
264
+ an asset as wired because it generated, or a gate as passed because you meant
265
+ to.
@@ -0,0 +1,148 @@
1
+ # The design contract — DESIGN.md
2
+
3
+ Write `DESIGN.md` at the game project root before any rendering code, from the
4
+ template below. Plain game language, readable by the player, committed to the
5
+ game's repo (it travels into remixes). It is a working document, not paperwork:
6
+ it replaces the plan you would otherwise post only in chat, and it is the
7
+ recovery point after any long break — sub-agents read it by path, and so do
8
+ you when a session resumes.
9
+
10
+ Rules the director enforces about this file:
11
+
12
+ - Create it right after the scope check, before the concept generation; fill
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.
17
+ - **The Assets table is the budget**: the asset list falls out of Content
18
+ (enemies → models, an arena → a ground texture, outdoors → a skybox).
19
+ Status flow per row: `proposed → planned → generating (id) → landed (URL) →
20
+ wired`. Workers generate only their own rows already marked `planned`; new
21
+ wants enter as `proposed` for the main agent to approve; the asset shepherd
22
+ flips statuses and never enqueues. Re-rolls follow the player's notes only.
23
+ The `Wired?` column exists because "generated but never wired in" is the
24
+ most common way finished art gets lost — a row isn't done at `landed`.
25
+ - Shrinking any Content line is a question to the player first, never a
26
+ silent cut.
27
+
28
+ ## Template
29
+
30
+ ```markdown
31
+ # <Game name> — Design
32
+
33
+ _Living document — the agent keeps this current; changes land in the log at
34
+ the bottom._
35
+
36
+ ## Concept
37
+ One paragraph: what the game is, what playing it feels like.
38
+ Concept image: <asset URL> (candidate <n> — my pick, approved by the player
39
+ on <date>)
40
+
41
+ ## Core loop
42
+ - **You do:** <primary verb — drive, shoot, build…>
43
+ - **To:** <objective>
44
+ - **Under pressure from:** <what pushes back>
45
+ - **You earn:** <reward / progression>
46
+ - **You lose when:** <fail state> → **and retry by:** <restart shape>
47
+
48
+ ## Content (only when the request names plural content or a content genre)
49
+ Every plural noun from the request becomes a countable line:
50
+ - Quests: <N>, chained by <how>
51
+ - Locations: <named list>
52
+ - Enemies: <N kinds, which are bosses>
53
+ - Grows: <levels/gear/abilities> · Earn/spend: <economy>
54
+ - Ten minutes in, I am: <one honest sentence>
55
+
56
+ ## Screens & UI
57
+ Screens: <loader, menu, HUD, pause, win/lose…> · Style brief: <one line>
58
+ References: <2–3 named games> · Menu archetype: <name>
59
+
60
+ ## Assets — the generation plan AND the budget
61
+ | Asset | Kind | Status | Wired? |
62
+ |------------------|-------------|---------------------------------|--------|
63
+ | Concept + HUD | image | landed → <URL> (candidate <n>) | n/a |
64
+ | <main surface> | texture | generating (<id>) | — |
65
+ | <hero model> | model | planned | — |
66
+ | Menu still+video | image+video | blocked on concept yes → queued | — |
67
+ Status flow: proposed → planned → generating (id) → landed (URL) → wired.
68
+ (Optionally note the prompt gist per row — it makes style-change re-rolls one
69
+ command.)
70
+
71
+ ## World & scale
72
+ <Size in numbers if open world; arena bounds otherwise. Streamed terrain? y/n>
73
+
74
+ ## Multiplayer
75
+ <single-player | ongoing world (connect) | fresh matches (matchmake: quorum,
76
+ teams, backfill…)> — and why. Play-button rule: nothing connects before the
77
+ click (when a Play screen exists).
78
+
79
+ ## Modules — the build split
80
+ | Module | Owns files | Built by | Done when |
81
+ |---|---|---|---|
82
+ | Boot & identity | src/main.ts, src/genex-boot.ts | main agent (only writer) | boots, tier wired, initEmbed runs |
83
+ | World/terrain | src/world/** | sub-agent when available | walkable, matches World & scale |
84
+ | Quests & dialogue data | src/content/** | sub-agent when available | counts match Content lines |
85
+ | Enemies/AI | src/enemies/** | sub-agent when available | roster matches Content |
86
+ | HUD chain (style-dependent) | src/ui/** | sub-agent AFTER concept yes | all screens from Screens & UI |
87
+ | Verification | (no source files) | one sub-agent max | smoke check notes per milestone |
88
+
89
+ ## Decisions & changes
90
+ - <date> — <one-liner per decision, including anything the player said no or
91
+ yes to>
92
+ ```
93
+
94
+ ## Filled example (a small arena shooter)
95
+
96
+ ```markdown
97
+ # Rustyard — Design
98
+
99
+ ## Concept
100
+ A scrap-robot arena shooter: you skate a magnetized junkyard bot around a
101
+ crusher pit, blasting rival bots into spare parts before the magnet cycle
102
+ pulls everything in. Fast, crunchy, thirty-second lives.
103
+ Concept image: https://assets.genex.technology/g/rustyard/concept.png
104
+ (candidate 2 — approved 2026-07-20)
105
+
106
+ ## Core loop
107
+ - **You do:** skate + shoot
108
+ - **To:** outscore three rival bots before the magnet cycle ends
109
+ - **Under pressure from:** rivals hunting you; the pit's edges electrify as
110
+ the cycle counts down
111
+ - **You earn:** scrap for hits → speed/armor pickups mid-round
112
+ - **You lose when:** your bot breaks → **and retry by:** one key, instant
113
+ respawn, same round
114
+
115
+ ## Screens & UI
116
+ Screens: loader, title menu, HUD (health, scrap, cycle timer), pause,
117
+ win/lose. Style brief: oily metal, warning-stripe accents, stencil type.
118
+ References: <three named AAA games>. Menu archetype: hangar pan.
119
+
120
+ ## Assets
121
+ | Asset | Kind | Status | Wired? |
122
+ |------------------|---------|----------------------------|--------|
123
+ | Concept + HUD | image | landed → <URL> (cand. 2) | n/a |
124
+ | Junkyard ground | texture | landed → <URL> | yes |
125
+ | Player bot | model | generating (gen_8f2k) | — |
126
+ | Rival bot | model | planned | — |
127
+ | Overcast sky | skybox | landed → <URL> | yes |
128
+ | Blaster zap | sfx | landed → <URL> | yes |
129
+ | Menu still+video | image+video | blocked on concept yes | — |
130
+
131
+ ## World & scale
132
+ One 60×60 m arena, walled; no streaming.
133
+
134
+ ## Multiplayer
135
+ Single-player v1 (rivals are host-free local AI). Revisit after publish.
136
+
137
+ ## Modules
138
+ | Module | Owns files | Built by | Done when |
139
+ |---|---|---|---|
140
+ | Boot & identity | src/main.ts | main agent | boots, tier wired, initEmbed runs |
141
+ | Arena & pickups | src/world/** | sub-agent | walkable, magnet cycle fires |
142
+ | Rival AI | src/enemies/** | sub-agent | 3 rivals hunt + shoot |
143
+ | HUD chain | src/ui/** | sub-agent after yes | all 5 screens live |
144
+
145
+ ## Decisions & changes
146
+ - 2026-07-20 — player picked concept candidate 2; asked for "more sparks".
147
+ - 2026-07-20 — sparks added as the ambient-motion loop, not particles-everywhere.
148
+ ```