@genex-ai/cli-demo 0.81.0-dev.214 → 0.85.0-dev.216

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.
Files changed (27) hide show
  1. package/README.md +9 -7
  2. package/dist/index.js +2623 -1684
  3. package/package.json +1 -1
  4. package/templates/controllers/character/first-person.ts +54 -0
  5. package/templates/controllers/character/follow-camera.ts +35 -1
  6. package/templates/skills/genex-ai-character/SKILL.md +25 -5
  7. package/templates/skills/genex-ai-hud/SKILL.md +175 -63
  8. package/templates/skills/genex-ai-hud/references/masked-fill.md +19 -13
  9. package/templates/skills/genex-ai-hud/references/stage1-prompt-template.md +42 -5
  10. package/templates/skills/genex-ai-hud/references/stage2-prompt-template.md +7 -3
  11. package/templates/skills/genex-ai-image/SKILL.md +40 -2
  12. package/templates/skills/genex-ai-menu/SKILL.md +47 -22
  13. package/templates/skills/genex-ai-model/SKILL.md +8 -0
  14. package/templates/skills/genex-ai-music/SKILL.md +142 -0
  15. package/templates/skills/genex-ai-skybox/SKILL.md +21 -5
  16. package/templates/skills/genex-ai-video/SKILL.md +13 -7
  17. package/templates/skills/genex-ai-voice/SKILL.md +151 -0
  18. package/templates/skills/genex-game-director/SKILL.md +183 -58
  19. package/templates/skills/genex-game-director/references/design-contract.md +40 -10
  20. package/templates/skills/genex-game-director/references/routing-map.md +44 -29
  21. package/templates/skills/genex-threejs-camera-direction/SKILL.md +4 -1
  22. package/templates/skills/genex-threejs-character-controller/SKILL.md +25 -1
  23. package/templates/skills/genex-threejs-character-controller/references/wiring.md +13 -2
  24. package/templates/skills/genex-threejs-creatures/SKILL.md +201 -0
  25. package/templates/skills/genex-threejs-game-ui/SKILL.md +79 -71
  26. package/templates/skills/genex-threejs-multiplayer/SKILL.md +6 -1
  27. package/templates/skills/genex-threejs-visual-validation/SKILL.md +9 -4
@@ -21,7 +21,9 @@ Three.js release or branch, and do not blindly copy demo architecture.
21
21
  | --- | --- |
22
22
  | shot composition, chase/side/orbit rigs, camera handoffs, projection ownership, pointer look, mouse-aimed action (shooter, FPS/first-person, sniper, turret, crosshair/reticle), mouse-look, hand-rolled steering/pan/look input signs (screen-direction contract), floating origins | `$genex-threejs-camera-direction` |
23
23
  | on-foot player movement: walk/run/jump/crouch, third-person character, slopes, stairs, moving platforms, personal VRM animation, directional locomotion, transitions, action motion | `$genex-threejs-character-controller` |
24
- | a custom generated playable humanoid or Meshy animation coverage beyond UAL: reference-informed A-pose concepts, explicit candidate + 10k-remesh approvals, exact action IDs, same-rig adapter | `$genex-ai-character` + `$genex-threejs-character-controller` |
24
+ | the game's themed character the DEFAULT whenever the protagonist is visible (third-person, or first-person with co-op/remote players); one user stop riding the concept review, owner-ratified auto-pick on silence (director §7) — or Meshy animation coverage beyond UAL: reference-informed A-pose concepts, exact action IDs, same-rig adapter | `$genex-ai-character` + `$genex-threejs-character-controller` |
25
+ | remote player bodies in multiplayer — NEVER hand-built primitives: the themed character model in themed games, the player's `p.avatarUrl` VRM otherwise | `$genex-threejs-multiplayer` + `$genex-threejs-character-controller` |
26
+ | the game has enemies, NPCs, or creatures — **load whenever an enemy roster exists**: rigged bipeds via `npx genex creature`, static + procedural motion for other body shapes, plus the mechanical floor every enemy owes (collider, verified facing, hit reaction, death moment) | `$genex-threejs-creatures` |
25
27
  | the player drives or flies something: cars, drones, vehicle physics, gearbox, enter/exit between character and vehicle | `$genex-threejs-vehicle-controllers` |
26
28
  | playable on phones: touch/mobile input for any game — joystick, virtual buttons, drag zones, per-genre touch recipes, rotate-device overlay — wired by default for every NEW game when a recipe fits (skip with a one-line reason) | `$genex-threejs-touch-controls` |
27
29
  | phone-survivable rendering — device tiers, DPR/shadow/post budgets, the runtime quality governor, per-tier asset rungs for generated skyboxes/textures, the Quality picker, dispose-on-swap discipline — **mandatory for every game at boot wiring** | `$genex-threejs-adaptive-quality` |
@@ -53,6 +55,7 @@ Three.js release or branch, and do not blindly copy demo architecture.
53
55
  | the 2D interface — HUD, menus, pause/win/lose screens, loaders, lobby, on-screen text and buttons, UI state flow — **mandatory for every game**, and its "Plan the UI first" gate runs right after the concept is locked | `$genex-threejs-game-ui` |
54
56
  | a cinematic menu — main menu/title/pause/victory/defeat/lobby/credits with a looping generated video backdrop behind DOM buttons | `$genex-ai-menu` |
55
57
  | a cohesive art-directed HUD — generated sprite set (matched frames, masks, icons in one style) wired with masked fills | `$genex-ai-hud` |
58
+ | background music — the looping instrumental track under gameplay and menu (default ONE ~90 s track; Music + SFX sliders in settings) | `$genex-ai-music` |
56
59
  | the game works but feels flat, floaty, or unresponsive: input response, acceleration curves, camera shake, hit feedback, hitstop, cooldowns, difficulty ramp, fail/retry loop | `$genex-threejs-game-feel` |
57
60
  | realtime multiplayer: movement sync, a shared ball/NPC, host-run scores/enemies, shots/emotes, persistence | `$genex-threejs-multiplayer` |
58
61
  | player identity, sign-in, guests, saves/progress, per-player state, a shared persistent world, leaderboards — **mandatory for every game** | `$genex-threejs-embed-auth` |
@@ -85,24 +88,28 @@ Three.js release or branch, and do not blindly copy demo architecture.
85
88
  decided silently. FIRST of all art, generate the gate's **concept mockup** —
86
89
  a playable-moment shot (verb + threat + objective in frame, per the
87
90
  game-ui gate) WITH the full HUD composited over it: the `$genex-ai-hud`
88
- Stage-1 image, one generation serving as concept, style checkpoint, and
89
- HUD blueprint (never a separate UI-free concept first). Show it to the user
90
- the moment it lands and get a keep-or-change answer through your question
91
- tool (a short numbered list in chat when you have none). This answer
92
- GATES but only the style-dependent pipeline: until the user approves a
93
- frame, do NOT enqueue the Tier-2 art that builds on the look (the
94
- `$genex-ai-hud` Stage-2 chain, and the `$genex-ai-menu` still + video
95
- whenever the menu decision is yes the default for every game, "it's only
96
- a draft" is not a reason to decide no plus the logotype). The instant
97
- they say yes, fire those with `--no-wait` (pick them up with
98
- `npx genex wait <id>`); the game-ui skill owns the re-anchor loop when notes
99
- arrive, and later `--edit`-able generations anchor to the approved frame for
100
- STYLE while the game contract owns content. Everything that does NOT depend
101
- on the look scaffold, boot wiring, the core loop, and the
102
- concept-independent worker lanes (the director's Delegate section)
103
- keeps building in parallel while the answer is pending, so the wait is
104
- never idle. Skipping this enqueue is the #1 way a finished game ships an
105
- ugly HUD by step 12 there is nothing to swap in.
91
+ Stage-1 image, ONE generation serving as concept, style checkpoint, and
92
+ HUD blueprint (never a separate UI-free concept first, and no candidate
93
+ variants unless the player asks for them). **The moment it lands, the
94
+ cheap style chain fires nothing waits for the player here**: decide the
95
+ HUD lane as art director and record the `HUD lane:` line in DESIGN.md
96
+ (director §5), then enqueue with `--no-wait` the `$genex-ai-hud` Stage-2
97
+ sheet, the `$genex-ai-menu` still (the menu is the default for every
98
+ game "it's only a draft" is not a reason to decide no), and the
99
+ logotype. THEN show the player the frame and ask keep-or-change through
100
+ your question tool (a short numbered list in chat when you have none) —
101
+ the answer is INFORMATION, never a gate: silence means the concept
102
+ stands; "change" loops the concept with their notes and the chain re-runs
103
+ from the new frame (image-priced cheap by design; the game-ui skill
104
+ owns the re-anchor loop). Only the menu VIDEO waits, for the FIRST of:
105
+ the player's yes · the next `genex preview` after the menu still landed ·
106
+ style work being the only work left and never while a player objection
107
+ is open (two failed videos ship the still). Later `--edit`-able
108
+ generations anchor to the standing frame for STYLE while the game
109
+ contract owns content. Everything concept-independent — scaffold, boot
110
+ wiring, the core loop, the worker lanes — keeps building in parallel.
111
+ Skipping this enqueue is the #1 way a finished game ships an ugly HUD —
112
+ by step 12 there is nothing to swap in.
106
113
  4. Lock the visual direction — the same plan-first logic as the UI gate, in
107
114
  the same plan block, before any rendering code:
108
115
  - **camera**: the rig type and the pointer bucket
@@ -247,12 +254,15 @@ Three.js release or branch, and do not blindly copy demo architecture.
247
254
  `$genex-threejs-game-ui` (HUD, pause on Escape, fail/retry, win, and the
248
255
  full loading state grown from the step-6 loader), then `npx genex wait`
249
256
  the step-3 UI generations and wire them in — the sprite HUD replaces the
250
- placeholder CSS, the menu video replaces the still frame (wired with the
251
- menu skill's loop crossfade), and the scene's planned generated models
252
- replace their placeholder primitives a shipped wave of enemies may not
253
- be untextured boxes. This swap is a
254
- completion gate, not an option: a game still on the placeholder CSS HUD,
255
- or without a working Escape pause, is not done. Then run a feel pass via
257
+ placeholder CSS (or the recorded `HUD lane: CSS` build lands finished to
258
+ its brief), the menu video replaces the still frame (wired with the menu
259
+ skill's loop crossfade), the logotype lands on the menu and loader, and
260
+ the scene's planned generated models replace their placeholder
261
+ primitives a shipped wave of enemies may not be untextured boxes. This
262
+ swap is a completion gate, not an option: a game still on the
263
+ placeholder CSS HUD (with no recorded CSS lane), without the menu video
264
+ playing (or its recorded still fallback), or without a working Escape
265
+ pause, is not done. Then run a feel pass via
256
266
  `$genex-threejs-game-feel` (input response, camera, impact feedback,
257
267
  retry speed).
258
268
  13. Validate in a real browser with fixed seeds, captures, interaction checks,
@@ -261,8 +271,9 @@ Three.js release or branch, and do not blindly copy demo architecture.
261
271
  ## Delegation
262
272
 
263
273
  Fan-out is owned by the director: sub-agents own DESIGN.md Modules rows,
264
- concept-DEPENDENT lanes wait for the player's yes on the concept, one writer
265
- per file, workers never spawn workers, and the Assets table is the budget
274
+ concept-DEPENDENT lanes launch the moment the concept lands (only the menu
275
+ video waits for its event triple step 3), one writer per file, workers
276
+ never spawn workers, and the Assets table is the budget —
266
277
  the full rules and the worker prompt shape live in the Delegate section of
267
278
  `$genex-game-director`. This map adds no separate delegation rules; it is the
268
279
  routing source the director and its workers read.
@@ -282,7 +293,9 @@ routing source the director and its workers read.
282
293
  done = a screenshot plus an interaction smoke check (load the page, press each
283
294
  control, assert a visible response in its labeled direction — `$genex-threejs-visual-validation` has the
284
295
  procedure), **plus the UI floor from `$genex-threejs-game-ui` (the generated
285
- sprite HUD wired in — not the CSS placeholder — pause on Escape, the branded
296
+ sprite HUD wired in — not the CSS placeholder — or the DESIGN.md-recorded
297
+ `HUD lane: CSS` build finished to its brief; the menu video playing, or its
298
+ recorded still fallback; the logotype placed; pause on Escape, the branded
286
299
  loader with its key-art background, the brief's font pair actually loaded)
287
300
  and the look floor (the step-4 renderer baseline + named post stack actually
288
301
  built; every placed 2D/media piece — decals, posters, in-world screens —
@@ -320,7 +333,9 @@ A routed Genex scene is incomplete until it exposes:
320
333
  ## Publish and multiplayer awareness
321
334
 
322
335
  **Publishing IS calling it done.** Before `npx genex publish`, every completion
323
- gate above must pass — sprite HUD wired, Escape pause working, branded loader
336
+ gate above must pass — sprite HUD wired (or the recorded CSS lane finished),
337
+ the menu video playing (or its recorded still fallback), the logotype placed,
338
+ Escape pause working, branded loader
324
339
  with its key art, fonts loaded, renderer baseline + one built post effect
325
340
  (tier-aware), the adaptive-quality tier wired at boot, world dressing placed
326
341
  or validly waived, and the content contract's countables present or
@@ -45,7 +45,10 @@ the build plan:
45
45
  - **MANDATORY** — first-person of any kind (FPS, walking sim, horror) and any
46
46
  mouse-aimed action (third-person shooter, turret/range). Lock is on by default;
47
47
  leave it on. Shipping this unlocked is a defect, not a style choice — validation
48
- fails it.
48
+ fails it. For first-person on the bundled controller, use the REAL mode —
49
+ `firstPerson: true` on `FollowCamera` (eye-height target, no zoom, no
50
+ collision pullback) + `setFirstPersonBody()` to hide the local body while
51
+ keeping its shadow — never a pinned tiny follow distance.
49
52
  - **HIGHLY RECOMMENDED** — third-person free-camera action/adventure (the default
50
53
  `genex controller character` game). On by default; leave it on. Opt out with
51
54
  `pointerLockAim: false` only for a stated reason (a cursor-heavy UI at the core
@@ -316,7 +316,12 @@ they leave) — move it with the interpolator from `$genex-threejs-multiplayer`,
316
316
  and **never** create a rigid body, a `CharacterController`, or any physics for
317
317
  it. Simulating remote players' physics locally guarantees divergence — every
318
318
  client would compute a different world. Never render every remote with your
319
- own avatar file: players picked their looks, show them.
319
+ own avatar file: players picked their looks, show them. And a remote player's
320
+ body is **never hand-built primitives** (no capsule-plus-cone "person"): in a
321
+ themed game remotes wear the SAME themed character model the local player
322
+ uses; otherwise they wear their `p.avatarUrl` VRM. First-person games are not
323
+ exempt — the local player may be invisible to themselves
324
+ (`setFirstPersonBody`), but every remote is a full character on screen.
320
325
 
321
326
  - **Publish `character.netState()`** on the fixed 10–20 Hz tick (never per frame):
322
327
  `room.me.set(character.netState())`. It bundles the network-safe position, a four-number
@@ -334,6 +339,25 @@ own avatar file: players picked their looks, show them.
334
339
  - Load `$genex-threejs-multiplayer` before writing any networking code; it is
335
340
  mandatory for any 2+ player game.
336
341
 
342
+ ## Placing rigs outside the controller — facing is explicit
343
+
344
+ The vendored controller owns the local player's facing. Any rig you place
345
+ YOURSELF — a duel opponent, an NPC, a fighter in a side-view game — obeys
346
+ three hard rules:
347
+
348
+ - **Meshy / Mixamo / VRM rigs rest facing +Z** — from a side camera that
349
+ means straight at the lens. Set the yaw explicitly from the character's
350
+ ROLE the moment you place it (`model.rotation.y = …`); never leave the
351
+ rest pose and assume it reads right.
352
+ - **Never mirror a SkinnedMesh with negative scale.** `scale.x = -1` is a
353
+ 2D-sprite trick: on a 3D rig it flips triangle winding and normals
354
+ (broken lighting and culling) and does NOT turn the character. Turning is
355
+ always a yaw rotation.
356
+ - **Duel / side-view / two-character scenes: the combatants face EACH
357
+ OTHER along the duel axis.** Two fighters staring into the camera is a
358
+ bug, not a pose — verify it in the milestone smoke capture (an enemy in
359
+ frame facing the player's CHARACTER, never the lens).
360
+
337
361
  ## If the user asks for ecctrl
338
362
 
339
363
  ecctrl is a React / React Three Fiber component; a Genex game is plain
@@ -118,8 +118,19 @@ Rules that matter:
118
118
  non-recursive) and must never include the character or vehicle meshes — the
119
119
  rays start at the character's head and would hit them every frame. The array
120
120
  is public — mutate it after level loads.
121
- - `minDistance` defaults to 0.02, so zooming all the way in is effectively
122
- first-person; clamp with `minDistance`/`maxDistance` for your scale.
121
+ - **First-person is a real mode, not a zoom trick**: pass
122
+ `firstPerson: true` (or flip the public `followCam.firstPerson` field at
123
+ runtime) — the camera sits AT the follow target and looks out along the
124
+ aim direction, wheel zoom is ignored, and collision pullback is skipped.
125
+ Feed the follow target the character's EYE height (~1.6–1.7 m up the
126
+ capsule, not the head-top orbit anchor), hide the local body with
127
+ `setFirstPersonBody(model, true)` (`first-person.ts` — keeps the shadow,
128
+ clones materials so shared remote-player materials are untouched), and
129
+ parent the viewmodel (held weapon/hands) to the CAMERA so it moves with
130
+ the view. Pointer lock stays mandatory (`$genex-threejs-camera-direction`).
131
+ Do NOT fake first-person by pinning a tiny follow distance — the old
132
+ 0.02-min-distance trick leaves collision pullback and zoom live, and both
133
+ fight the player.
123
134
  - Feel: `smoothTime` (0.05 snappy → 0.25 cinematic, default 0.1),
124
135
  `initialDistance` (default 4), `initialAzimuthAngle` (default `Math.PI` —
125
136
  camera starts behind a +Z-facing character).
@@ -0,0 +1,201 @@
1
+ ---
2
+ name: genex-threejs-creatures
3
+ description: Build enemies and creatures that hold up in play — rigged Meshy bipeds via `npx genex creature` or static models with procedural motion, plus the mechanical floor every enemy owes the player regardless of rigging - a physics collider (no walking through bodies), verified facing, hit reactions, and a death moment. Load whenever the game has enemies, NPCs, or creatures.
4
+ ---
5
+
6
+ # Genex Three.js · Creatures & Enemies
7
+
8
+ An enemy the player can walk through, that faces sideways, and that dies by
9
+ vanishing is the fastest way for a finished-looking game to feel broken. This
10
+ skill owns the enemy-quality floor: which generation lane each creature takes,
11
+ and the four mechanical rules that apply to ALL of them.
12
+
13
+ ## Choose the lane per creature — by body shape
14
+
15
+ **Meshy rigs biped-shaped bodies only.** This is a measured platform limit
16
+ (live-tested 2026-07-23), and it starts at the MODEL stage: a prompt for a
17
+ four-legged stance comes back standing upright, and wings get no bones (they
18
+ skin to the spine/arms and move rigidly — a wing flap is impossible through
19
+ the rig). Route by silhouette:
20
+
21
+ - **Biped-shaped** (werewolf, orc, skeleton, gargoyle, zombie, knight — two
22
+ legs, two arms, upright): the **rigged lane** below. Real skeleton, real
23
+ library animations. This is the DEFAULT for every enemy that fits it.
24
+ - **Everything else** (true quadrupeds, serpents, swarms, fliers mid-flight,
25
+ blobs): the **static + procedural lane** — `npx genex model` for the body,
26
+ motion authored in code. Say it honestly in the Assets table:
27
+ `hound: static + procedural — Meshy rigs bipeds only`. Never pretend a
28
+ procedural creature is rigged.
29
+
30
+ ## The rigged lane — `npx genex creature`
31
+
32
+ One shot, no approval ceremony (an enemy is production scenery, not the
33
+ player's identity piece — the themed PLAYER character keeps its review beat,
34
+ `$genex-ai-character`):
35
+
36
+ ```bash
37
+ # 1. Find real clip ids first — never invent them:
38
+ npx genex animations search "zombie walk" --json
39
+ npx genex animations search "melee attack" --json
40
+ npx genex animations search "death backward" --json
41
+
42
+ # 2. One command: model → rig → bind those clips (enqueue and keep building):
43
+ npx genex creature "hulking bone seraph, tattered wing membranes, upright stance" \
44
+ --animation <walk-id> --animation <attack-id> --animation <death-id> --no-wait
45
+ ```
46
+
47
+ Each creature is one Assets-table row (visible spend — the usual budget
48
+ rules). The result is a rigged GLB whose clips play on a standard
49
+ `THREE.AnimationMixer`; Meshy limb rotations play unchanged — never apply
50
+ post-mixer limb corrections. Prompt the body UPRIGHT and unpropped (held
51
+ props fuse into bodies); prompt "facing the viewer" but never trust it —
52
+ facing is verified below.
53
+
54
+ ### State → clip wiring (one mixer per creature)
55
+
56
+ ```ts
57
+ import * as THREE from "three";
58
+
59
+ interface CreatureRig {
60
+ root: THREE.Object3D;
61
+ mixer: THREE.AnimationMixer;
62
+ actions: Record<"walk" | "attack" | "hit" | "death", THREE.AnimationAction>;
63
+ current?: THREE.AnimationAction;
64
+ }
65
+
66
+ function play(rig: CreatureRig, name: keyof CreatureRig["actions"], fade = 0.18): void {
67
+ const next = rig.actions[name];
68
+ if (rig.current === next) return;
69
+ next.reset();
70
+ if (name === "attack" || name === "hit" || name === "death") {
71
+ next.setLoop(THREE.LoopOnce, 1);
72
+ next.clampWhenFinished = true; // death holds its last frame
73
+ }
74
+ if (rig.current) next.crossFadeFrom(rig.current, fade, false);
75
+ next.play();
76
+ rig.current = next;
77
+ }
78
+ // drive from the enemy state machine: chase → play(rig, "walk");
79
+ // windup+strike → play(rig, "attack"); damaged → play(rig, "hit");
80
+ // hp <= 0 → play(rig, "death") and only AFTER the clip finishes, run the
81
+ // death VFX moment (embers/dissolve) — animation first, particles second.
82
+ // mixer.update(dt) every frame; one mixer per creature, clips cloned per
83
+ // instance (THREE.AnimationUtils / SkeletonUtils.clone for shared GLBs).
84
+ ```
85
+
86
+ ## The mechanical floor — ALL enemies, rigged or not
87
+
88
+ ### 1. A collider — the player never walks through a body
89
+
90
+ An enemy that is only a `THREE.Group` is a ghost. Give every enemy a physics
91
+ presence. The recipe (Rapier, matching `$genex-threejs-physics-rapier` and
92
+ the bundled character controller):
93
+
94
+ ```ts
95
+ import RAPIER from "@dimforge/rapier3d-compat";
96
+
97
+ /** One kinematic capsule per enemy: the CONTROLLER collides with it (no
98
+ * walk-through) but the enemy's own movement stays script-driven — AI code
99
+ * keeps teleport-free authority via setNextKinematicTranslation. */
100
+ function addEnemyCollider(world: RAPIER.World, e: { root: THREE.Object3D; halfHeight: number; radius: number }) {
101
+ const body = world.createRigidBody(
102
+ RAPIER.RigidBodyDesc.kinematicPositionBased().setTranslation(
103
+ e.root.position.x, e.root.position.y + e.halfHeight + e.radius, e.root.position.z,
104
+ ),
105
+ );
106
+ world.createCollider(RAPIER.ColliderDesc.capsule(e.halfHeight, e.radius), body);
107
+ return body;
108
+ }
109
+ // every frame AFTER the AI moves the root:
110
+ // body.setNextKinematicTranslation({ x, y: y + halfHeight + radius, z });
111
+ // Size from the model's real bounding box (new THREE.Box3().setFromObject),
112
+ // not guessed numbers. Gameplay range tests (aggro, melee reach) keep using
113
+ // your own distance math — the collider exists so BODIES are solid.
114
+ ```
115
+
116
+ If the game has no physics world at all, the minimal honest fallback is a
117
+ controller-side overlap resolve: each frame, push the player out of each
118
+ enemy's XZ radius (`if (dist < r) player.position.addScaledVector(away, r - dist)`).
119
+ Solid beats elegant.
120
+
121
+ ### 2. Verified facing — walk in front of each enemy type once
122
+
123
+ Generated models are NOT reliably authored front-toward-+Z, and a
124
+ `lookAt`-driven enemy with a sideways-authored model walks sideways forever —
125
+ invisible from behind-the-player camera angles, glaring head-on. Two steps:
126
+
127
+ ```ts
128
+ /** Wrap the GLB so +Z is the FORWARD your code can trust: rotate the child
129
+ * inside the wrapper until its face agrees, then aim only the wrapper. */
130
+ function wrapForward(model: THREE.Object3D, yawCorrection: number): THREE.Group {
131
+ const wrapper = new THREE.Group();
132
+ model.rotation.y = yawCorrection; // 0, ±Math.PI/2, or Math.PI — per MODEL, found by looking
133
+ wrapper.add(model);
134
+ return wrapper; // enemy code does wrapper.lookAt(...) / aims the wrapper only
135
+ }
136
+ ```
137
+
138
+ The verification is human and takes ten seconds per enemy TYPE: stand in
139
+ front of it once — it must face you. This is part of the milestone smoke
140
+ pass once enemies exist (an enemy in frame, facing the player). Set the
141
+ `yawCorrection` constant per model and move on.
142
+
143
+ Two hard rules alongside it: **never mirror a rig with negative scale** —
144
+ `scale.x = -1` is a 2D-sprite trick that flips winding and normals on a
145
+ SkinnedMesh and does NOT turn a 3D body; turning is always a yaw
146
+ (`rotation.y`), set explicitly from the creature's role. And in any
147
+ **duel / side-view / two-character scene**, the combatants face EACH OTHER
148
+ along the duel axis — a fighter staring into the camera is a bug, not a
149
+ pose, and the smoke capture is where it gets caught.
150
+
151
+ ### 3. Hit reaction — damage reads on the body
152
+
153
+ Rigged: the `hit` clip above. Procedural: a 100–150 ms flinch — scale pulse
154
+ (`1 → 0.92 → 1`), a brief emissive/color flash, and a small recoil along the
155
+ hit direction. Pair it with the HUD hit marker; a bullet that changes nothing
156
+ on the body reads as a miss even when the numbers moved.
157
+
158
+ ### 4. A death moment — never blink out of existence
159
+
160
+ Rigged: play `death`, hold the final frame (~0.5 s), THEN dissolve/embers and
161
+ remove. Procedural: collapse (scale Y toward 0 with a topple rotation) into
162
+ the same dissolve. Either way the death VFX is a `$genex-threejs-procedural-vfx`
163
+ moment that EARNS its beat (the target dissolves and awards score) — one
164
+ pooled burst, not a particle bath.
165
+
166
+ ## Procedural motion recipes (the static lane, done well)
167
+
168
+ Give an unrigged body three layered motions — enough life that "static +
169
+ procedural" is a real choice, not a downgrade: a **gait bob** (body
170
+ `position.y += sin(t * stride) * 0.05` with a slight roll for quadrupeds), a
171
+ **lunge stretch** (scale Z up 8% during attack windup, snap back on strike),
172
+ and an **idle sway** (low-amplitude yaw/pitch noise so nothing stands
173
+ morgue-still). Author them against the wrapper from rule 2 so facing math
174
+ stays clean. `$genex-threejs-procedural-animation` has the timeline tools for
175
+ anything staged.
176
+
177
+ ## Multiplayer
178
+
179
+ Enemies are host-simulated shared objects (`$genex-threejs-multiplayer` —
180
+ the host owns `room.objects` for every enemy; remotes render interpolated
181
+ state). The collider rule applies on every client — bodies are solid locally
182
+ even when the HOST owns the movement; clip/state changes ride the shared
183
+ object's state field, never a per-frame broadcast.
184
+
185
+ ## Troubleshooting
186
+
187
+ - **"Out of credits" (`insufficient_credits`)** — tell the user the facts the
188
+ CLI printed (balance, cost, refill), continue with a procedural-placeholder
189
+ enemy body, and mark the spot with
190
+ `// TODO(genex): regenerate when credits refill`. Do not stop the session.
191
+ - **"Email not verified" (`email_verification_required`)** — hand over the
192
+ verify link the CLI printed, wait, re-run.
193
+ - **The creature came back standing when you wanted four legs** — that is the
194
+ documented platform limit, not a bad roll: re-rolling the prompt will not
195
+ produce a rigged quadruped. Switch that creature to the static + procedural
196
+ lane and say so in the Assets table.
197
+ - **Clips look wrong on the body** (arms clip the torso on a bulky model) —
198
+ pick a different library action id (`animations search`); never patch limbs
199
+ post-mixer.
200
+ - **Every instance animates in sync** — you shared one mixer or one clip
201
+ instance; clone per creature (`SkeletonUtils.clone` + a fresh mixer each).
@@ -27,7 +27,7 @@ in another.
27
27
  | Pause | always — opens on the Escape key | 1 — menu backdrop under a dark overlay |
28
28
  | Fail / retry | always | 1 — a *graded* variant of the menu screen |
29
29
  | Win / next | always | 1 — graded variant, warm |
30
- | Settings | always — every game carries the Quality picker (Auto/Low/Medium/High, `$genex-threejs-adaptive-quality`), plus whatever else it has to set | 1 |
30
+ | Settings | always — every game carries the Quality picker (Auto/Low/Medium/High, `$genex-threejs-adaptive-quality`), and any game with generated audio carries **Music + SFX volume sliders** (persisted, applied live; music default 0.30, sfx ~0.7 — `$genex-ai-music`; a paid track with no volume control is a failure mode), plus whatever else it has to set | 1 |
31
31
  | Lobby / waiting | multiplayer only | 1 over the menu backdrop |
32
32
  | HUD | always | 2 — generated sprite HUD (`$genex-ai-hud`), enqueued at this gate for EVERY game; plain CSS is the placeholder until the sprites land, never the final HUD |
33
33
 
@@ -71,66 +71,62 @@ and how the space reads (route, scale) — plus the brief's palette,
71
71
  materials, and light. A beautiful empty vista with nothing to fight and
72
72
  nowhere to go is a FAILED concept; so is one that invents mechanics the
73
73
  game doesn't have (a lap counter in a game without laps). Generate it
74
- `--size 2560x1440 --quality high --candidates 2 --no-wait`, enqueued FIRST
75
- of all art; the picked candidate's URL goes into the style-brief comment.
76
-
77
- **Describe the concept, show it, then get a YES before the style-dependent
78
- work fans out.** First lay the concept out in WORDS the playable moment
79
- (the verb), what threatens the player, what they chase, how the space reads,
80
- and the brief's palette / materials / light / references — so the user is
81
- weighing a stated direction, not guessing at a picture. Generate the mockup
82
- FIRST of all art (`--candidates 2`) and get it in front of the user AS FAST
83
- AS POSSIBLE: pick the stronger candidate yourself, pick it up with
84
- `genex wait <id> --open` (or generate it with `--open`) so it opens in the
85
- user's browser AND prints the links, and paste BOTH candidates' URLs as
86
- clickable links saying which one you picked and why a URL is invisible in a
87
- terminal, and "do you like it?" with no picture in front of the user is the
88
- #1 way this checkpoint fails (they end up digging logs for the file path).
89
-
90
- **Then ask for the yes with your question tool** the one that shows the
91
- user clickable options; a short numbered list in chat only where there is
92
- none. ONE question "this is roughly
93
- how the game and its HUD will look keep this direction, or change
94
- something?" — with concrete keep / change options. This confirmation is
95
- REQUIRED for every game: the concept sets the STYLE every later asset
96
- inherits, so the user gets a real say before that style is committed. This
97
- reverses the old "advisory, never gate" rulethe concept now gates, but
98
- ONLY the style-dependent work (below), never the whole build.
99
-
100
- **The yes gates the STYLE-DEPENDENT work nothing else.** Until the user
101
- approves a frame, do NOT fan out the art or subagents that build ON the
102
- chosen look: the HUD Stage-2 deconstruct (from the picked candidate), the
103
- menu still + video (`--edit`-anchored to the mockup), and the logotype. (The core asset set — hero model, ground texture, skybox,
104
- sfx is prompted from the game IDEA, not the picked image, and mostly
105
- survives a style change, so it does NOT wait: launch it up front with
106
- placeholders, re-rolling only the few that don't survive if the look shifts.)
107
- Everything else that does NOT depend on the look
108
- keeps moving at full speed IN PARALLEL the scaffold and boot wiring, the
109
- core gameplay / network loop, the controller, and the gameplay-LOGIC subagent
110
- modules (world, quests, enemies, itemstheir structure comes from the
111
- contract, not the picture). The wait is therefore never idle: a slow-to-answer
112
- user still gets a walkable first version, and the instant they say yes the
113
- style pipeline launches against the frame they approved. (A user who vanishes
114
- entirely leaves the LOOK pending, not the game — the deliberate trade for
115
- never committing a style behind their back.)
74
+ `--size 2560x1440 --quality high --no-wait`, enqueued FIRST of all art —
75
+ ONE image, no candidate variants unless the user asks; its URL goes into
76
+ the style-brief comment.
77
+
78
+ **Describe the concept in words while it renders.** Lay it out in chat
79
+ the playable moment (the verb), what threatens the player, what they chase,
80
+ how the space reads, and the brief's palette / materials / light /
81
+ references — so the user is weighing a stated direction, not guessing at a
82
+ picture.
83
+
84
+ **The moment the mockup lands, the style chain fires then the user sees
85
+ the frame.** In this order, no waiting between the steps: decide the HUD
86
+ lane as art director and record the `HUD lane:` line in DESIGN.md
87
+ (`$genex-game-director` §5 owns the criteria), enqueue the style-dependent
88
+ chain `--no-wait` the HUD Stage-2 deconstruct (from the mockup), the menu
89
+ still (`--edit`-anchored to it), and the logotype — and THEN show the frame:
90
+ pick it up with `genex wait <id> --open` (or generate with `--open`) so it
91
+ opens in the user's browser AND prints the link, and paste the URL as a
92
+ clickable linka URL is invisible in a terminal, and "do you like it?"
93
+ with no picture in front of the user is the #1 way this checkpoint fails.
94
+
95
+ **Ask keep-or-change with your question tool as INFORMATION, never a
96
+ gate.** The one that shows clickable options; a short numbered list in chat
97
+ only where there is none. ONE question"this is roughly how the game and
98
+ its HUD will look — keep this direction, or change something?" — with
99
+ concrete keep / change options. The chain is already running while they
100
+ read it: silence means the concept stands; nothing except the menu VIDEO
101
+ ever waits for the answer. The user still gets a real say a "change" at
102
+ any time loops the concept with their notes at image prices (below). The
103
+ menu video (the one expensive item) fires at the FIRST of: the user's yes ·
104
+ the next `genex preview` after the menu still landed · style work being the
105
+ only work left and never while a user objection is open
106
+ (`$genex-ai-menu` owns the trigger). (The core asset set hero model,
107
+ ground texture, skybox, sfx is prompted from the game IDEA, not the
108
+ image, and mostly survives a style change: launch it up front with
109
+ placeholders. Everything style-independent scaffold, boot wiring, the
110
+ core loop, the gameplay-LOGIC subagent modules keeps moving at full speed
111
+ in parallel throughout.)
116
112
 
117
113
  **Change reopens the loop, same shape.** If the user picks "change" — or
118
114
  comes back with notes immediately or an hour later — re-run Stage 1 (the
119
- concept mockup itself) with their exact notes (`--candidates 2–3` gives them
120
- options to choose from), open + link the new frame, and ask again the same
121
- structured way. Carry every note forward so each round compounds; if two
122
- rounds don't converge, offer 2–3 distinct directions instead of re-rolling
123
- blind. Each frame the user approves becomes the working style, and the
124
- style-dependent pipeline stays gated on the latest yes (strictly CHEAPER than
125
- it used to be: one image carries scene + HUD, there is no separate concept to
126
- redo). When the style actually changes after downstream art already ran,
127
- re-anchor it: the menu still is re-edited (`--edit`) against the new mockup
128
- and its video re-run once from the new still (`$genex-ai-menu` — a
129
- user-driven style change re-opens its one-video rule), and the HUD deconstruct
130
- (Stage 2 onward, `$genex-ai-hud`) restarts from the new mockup. Style-neutral
131
- assets (most textures, sfx, models) usually survive — judge each in one line.
132
- The same "open it + paste the link" rule covers every image the user weighs
133
- in on — the menu still, the HUD mockup candidates.
115
+ concept mockup itself) with their exact notes, open + link the new frame,
116
+ ask again the same structured way, and re-run the cheap chain from the new
117
+ frame (image-priced that is the design: the correction lane is cheap
118
+ because the expensive item waited). Carry every note forward so each round
119
+ compounds; if two rounds don't converge, offer 2–3 distinct directions
120
+ (that's the one moment `--candidates` earns its place) instead of
121
+ re-rolling blind. Each standing frame is the working style. When the style
122
+ changes after downstream art already ran, re-anchor it: the menu still is
123
+ re-edited (`--edit`) against the new mockup and its video re-run once from
124
+ the new still (`$genex-ai-menu` — a user-driven style change re-opens its
125
+ one-video rule), and the HUD deconstruct (Stage 2 onward, `$genex-ai-hud`)
126
+ restarts from the new mockup. Style-neutral assets (most textures, sfx,
127
+ models) usually survive — judge each in one line. The same "open it + paste
128
+ the link" rule covers every image the user weighs in on — the menu still,
129
+ the HUD mockup.
134
130
 
135
131
  **The concept anchors STYLE, not truth.** Palette, materials, light, and
136
132
  register come from the frame; CONTENT comes from the game contract. This
@@ -165,13 +161,16 @@ rule explicitly does not apply to this one message):
165
161
  ```
166
162
  UI plan
167
163
  • Screens: <list with tiers — loader / menu / pause (Esc) / win/lose / …>
168
- • Style: <4–5 named hues> · fonts <display> / <body>
164
+ • Style: <4–5 named hues> · fonts <display> / <body> (from $genex-ai-menu's
165
+ genre table, or a one-line reason)
169
166
  • References: <2–3 AAA games — one line on what's borrowed>
170
167
  • Menu: <archetype + button treatment, one-line reason from the brief>
171
- Concept (HUD mockup): <generation id 2 candidates> — awaiting your keep / change
172
- Queued ON YOUR YES (style-dependent): HUD sheet (Stage 2, from the picked
173
- mockup) · menu still video <or "no menu: reason"> · logotype <or
174
- "skipped: reason">
168
+ • HUD lane: <sprites (…) | CSS (…, one-line justification)> — recorded in DESIGN.md
169
+ Concept (HUD mockup): <generation id> shown for keep / change
170
+ (informational the chain below is already queued; silence = it stands)
171
+ • Queued on concept landing: HUD sheet (Stage 2) · menu still · logotype
172
+ <or "skipped: reason">; menu VIDEO waits for: your yes / the next preview
173
+ after the still lands / style work being all that's left <or "no menu: reason">
175
174
  • Building now (style-independent): <core loop · logic modules already moving>
176
175
  • Deferred from mockup: <widgets the image invented but the game lacks — or "none">
177
176
  ```
@@ -190,8 +189,9 @@ A message missing any line means the gate did not run — go back and run it.
190
189
  every game), and the generated **logotype** — one `--transparent` wordmark
191
190
  in the brief's display register (`$genex-ai-menu`'s logotype step), default
192
191
  YES for every game with a menu; skipping it needs a one-line stated reason.
193
- Enqueue this chain the instant the user approves the concept
194
- (`--no-wait`) it is style-dependent, so it waits on the yes then
192
+ Enqueue this chain the instant the concept mockup LANDS (`--no-wait`) —
193
+ the keep/change answer never gates it; only the menu VIDEO waits, for its
194
+ event triple (`$genex-ai-menu`) — then
195
195
  keep building, pick results up with `npx genex wait <id>`, swap them in as
196
196
  they land. **Tier 2 must never block a playable v0 — but the game is NOT
197
197
  DONE until its Tier-2 assets have landed and been wired in** (the only
@@ -200,7 +200,9 @@ A message missing any line means the gate did not run — go back and run it.
200
200
  Run `npx genex wait` on every enqueued ID before any publish and before
201
201
  the final handoff of a session — never park landed assets for "later".
202
202
  Shipping the placeholder CSS HUD as the final HUD is a failure, not a
203
- tier choice.
203
+ tier choice — the ONE exception is a DESIGN.md-recorded `HUD lane: CSS`
204
+ decision (`$genex-game-director` §5), where the CSS build, finished to
205
+ its brief, IS the production HUD.
204
206
  - **Tier 3 — offer, don't build.** Video layers over the HUD, 9-slice panel
205
207
  sprites, animated menu sprites. Offer in one line
206
208
  after the player has seen Tier 1+2 working; build on request.
@@ -522,15 +524,21 @@ architecture and consume the shared style brief.
522
524
  - Hard-cut phase swaps, a menu whose elements just appear, numbers that
523
525
  teleport.
524
526
  - A silent menu; a bare "Loading…" over black.
525
- - Style-dependent art fanned out before the user approved the concept — the
526
- concept confirmation is REQUIRED and gates the look-dependent work (HUD
527
- Stage 2, menu still/video, logotype, style-matched assets); OR the whole
528
- build stalled waiting on that yes, when concept-INDEPENDENT work (scaffold,
529
- core loop, logic subagents) must keep moving in parallel while it is pending.
527
+ - The style chain parked behind the keep/change question the HUD Stage-2
528
+ sheet, menu still, and logotype enqueue the moment the mockup LANDS, and
529
+ silence means the concept stands; OR the menu VIDEO fired while a user
530
+ objection was still open (its event triple is the only wait in the lane);
531
+ OR the whole build stalled on the concept at all, when concept-INDEPENDENT
532
+ work (scaffold, core loop, logic subagents) must keep moving in parallel
533
+ throughout.
530
534
  - A CSS-cut corner (`clip-path`/`mask`) that shears its own content — clipped
531
535
  text or padding, a lost focus ring or glow, a jagged aliased edge, or a
532
536
  border/frame that stops at the cut instead of following it — the
533
537
  technique is fine; the sloppy cut is the defect.
538
+ - A plate shaped by `npx genex ui plate` (the frame's traced silhouette as
539
+ the plate's `mask-image`) is the fix for shaped backing — see
540
+ `$genex-ai-hud`'s silhouette-plate rule; a bare rounded rectangle behind
541
+ generated art is the defect below.
534
542
  - A rectangular semi-transparent plate protruding past an opaque/angular
535
543
  widget frame — a dark box floating over the scene. The frame's own art is
536
544
  the backing; a plate is only for bare-text/outline widgets and stays inside