@genex-ai/cli-demo 0.84.0-dev.215 → 0.86.0-dev.217

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.
@@ -40,8 +40,8 @@ the bottom._
40
40
 
41
41
  ## Concept
42
42
  One paragraph: what the game is, what playing it feels like.
43
- Concept image: <asset URL> (candidate <n> my pick, approved by the player
44
- on <date>)
43
+ Concept image: <asset URL> (standingshown <date>; player said
44
+ <yes | nothing — pick stands | change → looped>)
45
45
 
46
46
  ## Core loop
47
47
  - **You do:** <primary verb — drive, shoot, build…>
@@ -61,19 +61,35 @@ Every plural noun from the request becomes a countable line:
61
61
  ## Screens & UI
62
62
  Screens: <loader, menu, HUD, pause, win/lose…> · Style brief: <one line>
63
63
  References: <2–3 named games> · Menu archetype: <name>
64
+ HUD lane: <sprites (…) | CSS (…, one-line justification)> — mandatory line;
65
+ the concept decides it (director §5) and the preview preflight checks for it
66
+ Menu video: <yes (the default for every game) | declined (player's reason)>
64
67
 
65
68
  ## Assets — the generation plan AND the budget
66
69
  | Asset | Kind | Status | Wired? |
67
70
  |------------------|-------------|---------------------------------|--------|
68
- | Concept + HUD | image | landed → <URL> (candidate <n>) | n/a |
71
+ | Concept + HUD | image | landed → <URL> | n/a |
69
72
  | <main surface> | texture | generating (<id>) | — |
70
73
  | <hero model> | model | planned | — |
71
74
  | Background music | music | planned (one ~90s looping track)| — |
72
- | Menu still+video | image+video | blocked on concept yes queued | — |
75
+ | Menu still | image | enqueued on concept landing (<id>) | — |
76
+ | Menu video | video | waits: yes / next preview after still / style-only-left | — |
77
+ | Logotype | image | enqueued on concept landing (<id>) | — |
73
78
  Status flow: proposed → planned → generating (id) → landed (URL) → wired.
74
79
  (Optionally note the prompt gist per row — it makes style-change re-rolls one
75
80
  command.)
76
81
 
82
+ **HUD pipeline state (sprites lane) — keep this current; it is how the
83
+ pipeline survives a context compaction.** One row per stage with its
84
+ generation id / output path, so a resumed session knows exactly where the
85
+ chain stopped and what fires next:
86
+ - Stage-1 mockup: <id → URL>
87
+ - Stage-2 sheet: <id → URL>
88
+ - Cleaned sheet: <id → URL>
89
+ - Extracted sprites: <public/assets/hud/…>
90
+ - Masks: <public/assets/hud/…-mask.png + sidecars>
91
+ - Next stage: <what fires next, one line>
92
+
77
93
  ## World & scale
78
94
  <Size in numbers if open world; arena bounds otherwise. Streamed terrain? y/n>
79
95
 
@@ -89,7 +105,7 @@ click (when a Play screen exists).
89
105
  | World/terrain | src/world/** | sub-agent when available | walkable, matches World & scale |
90
106
  | Quests & dialogue data | src/content/** | sub-agent when available | counts match Content lines |
91
107
  | Enemies/AI | src/enemies/** | sub-agent when available | roster matches Content |
92
- | HUD chain (style-dependent) | src/ui/** | sub-agent AFTER concept yes | all screens from Screens & UI |
108
+ | HUD chain (style-dependent) | src/ui/** | sub-agent on concept landing | all screens from Screens & UI |
93
109
 
94
110
  ## Decisions & changes
95
111
  - <date> — <one-liner per decision, including anything the player said no or
@@ -106,7 +122,7 @@ A scrap-robot arena shooter: you skate a magnetized junkyard bot around a
106
122
  crusher pit, blasting rival bots into spare parts before the magnet cycle
107
123
  pulls everything in. Fast, crunchy, thirty-second lives.
108
124
  Concept image: https://assets.genex.technology/g/rustyard/concept.png
109
- (candidate 2 approved 2026-07-20)
125
+ (standingshown 2026-07-20; player said yes)
110
126
 
111
127
  ## Core loop
112
128
  - **You do:** skate + shoot
@@ -121,17 +137,26 @@ Concept image: https://assets.genex.technology/g/rustyard/concept.png
121
137
  Screens: loader, title menu, HUD (health, scrap, cycle timer), pause,
122
138
  win/lose. Style brief: oily metal, warning-stripe accents, stencil type.
123
139
  References: <three named AAA games>. Menu archetype: hangar pan.
140
+ HUD lane: sprites (stencil-cut metal meters + riveted scrap counter — ornate
141
+ material chrome, CSS can't pass for it)
142
+ Menu video: yes
124
143
 
125
144
  ## Assets
126
145
  | Asset | Kind | Status | Wired? |
127
146
  |------------------|---------|----------------------------|--------|
128
- | Concept + HUD | image | landed → <URL> (cand. 2) | n/a |
147
+ | Concept + HUD | image | landed → <URL> | n/a |
129
148
  | Junkyard ground | texture | landed → <URL> | yes |
130
149
  | Player bot | model | generating (gen_8f2k) | — |
131
150
  | Rival bot | model | planned | — |
132
151
  | Overcast sky | skybox | landed → <URL> | yes |
133
152
  | Blaster zap | sfx | landed → <URL> | yes |
134
- | Menu still+video | image+video | blocked on concept yes | — |
153
+ | Menu still | image | landed <URL> | — |
154
+ | Menu video | video | waiting (still landed — fires at yes / next preview / style-only-left) | — |
155
+ | Logotype | image | generating (gen_9t3m) | — |
156
+
157
+ HUD pipeline state: Stage-1 mockup gen_7a1x → URL · Stage-2 sheet gen_7b2y →
158
+ URL · cleaned gen_7c3z → URL · extracted public/assets/hud/ · masks derived ·
159
+ next: wire masked fills
135
160
 
136
161
  ## World & scale
137
162
  One 60×60 m arena, walled; no streaming.
@@ -88,24 +88,28 @@ Three.js release or branch, and do not blindly copy demo architecture.
88
88
  decided silently. FIRST of all art, generate the gate's **concept mockup** —
89
89
  a playable-moment shot (verb + threat + objective in frame, per the
90
90
  game-ui gate) WITH the full HUD composited over it: the `$genex-ai-hud`
91
- Stage-1 image, one generation serving as concept, style checkpoint, and
92
- HUD blueprint (never a separate UI-free concept first). Show it to the user
93
- the moment it lands and get a keep-or-change answer through your question
94
- tool (a short numbered list in chat when you have none). This answer
95
- GATES but only the style-dependent pipeline: until the user approves a
96
- frame, do NOT enqueue the Tier-2 art that builds on the look (the
97
- `$genex-ai-hud` Stage-2 chain, and the `$genex-ai-menu` still + video
98
- whenever the menu decision is yes the default for every game, "it's only
99
- a draft" is not a reason to decide no plus the logotype). The instant
100
- they say yes, fire those with `--no-wait` (pick them up with
101
- `npx genex wait <id>`); the game-ui skill owns the re-anchor loop when notes
102
- arrive, and later `--edit`-able generations anchor to the approved frame for
103
- STYLE while the game contract owns content. Everything that does NOT depend
104
- on the look scaffold, boot wiring, the core loop, and the
105
- concept-independent worker lanes (the director's Delegate section)
106
- keeps building in parallel while the answer is pending, so the wait is
107
- never idle. Skipping this enqueue is the #1 way a finished game ships an
108
- 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.
109
113
  4. Lock the visual direction — the same plan-first logic as the UI gate, in
110
114
  the same plan block, before any rendering code:
111
115
  - **camera**: the rig type and the pointer bucket
@@ -250,12 +254,15 @@ Three.js release or branch, and do not blindly copy demo architecture.
250
254
  `$genex-threejs-game-ui` (HUD, pause on Escape, fail/retry, win, and the
251
255
  full loading state grown from the step-6 loader), then `npx genex wait`
252
256
  the step-3 UI generations and wire them in — the sprite HUD replaces the
253
- placeholder CSS, the menu video replaces the still frame (wired with the
254
- menu skill's loop crossfade), and the scene's planned generated models
255
- replace their placeholder primitives a shipped wave of enemies may not
256
- be untextured boxes. This swap is a
257
- completion gate, not an option: a game still on the placeholder CSS HUD,
258
- 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
259
266
  `$genex-threejs-game-feel` (input response, camera, impact feedback,
260
267
  retry speed).
261
268
  13. Validate in a real browser with fixed seeds, captures, interaction checks,
@@ -264,8 +271,9 @@ Three.js release or branch, and do not blindly copy demo architecture.
264
271
  ## Delegation
265
272
 
266
273
  Fan-out is owned by the director: sub-agents own DESIGN.md Modules rows,
267
- concept-DEPENDENT lanes wait for the player's yes on the concept, one writer
268
- 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 —
269
277
  the full rules and the worker prompt shape live in the Delegate section of
270
278
  `$genex-game-director`. This map adds no separate delegation rules; it is the
271
279
  routing source the director and its workers read.
@@ -285,7 +293,9 @@ routing source the director and its workers read.
285
293
  done = a screenshot plus an interaction smoke check (load the page, press each
286
294
  control, assert a visible response in its labeled direction — `$genex-threejs-visual-validation` has the
287
295
  procedure), **plus the UI floor from `$genex-threejs-game-ui` (the generated
288
- 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
289
299
  loader with its key-art background, the brief's font pair actually loaded)
290
300
  and the look floor (the step-4 renderer baseline + named post stack actually
291
301
  built; every placed 2D/media piece — decals, posters, in-world screens —
@@ -323,7 +333,9 @@ A routed Genex scene is incomplete until it exposes:
323
333
  ## Publish and multiplayer awareness
324
334
 
325
335
  **Publishing IS calling it done.** Before `npx genex publish`, every completion
326
- 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
327
339
  with its key art, fonts loaded, renderer baseline + one built post effect
328
340
  (tier-aware), the adaptive-quality tier wired at boot, world dressing placed
329
341
  or validly waived, and the content contract's countables present or
@@ -339,6 +339,25 @@ exempt — the local player may be invisible to themselves
339
339
  - Load `$genex-threejs-multiplayer` before writing any networking code; it is
340
340
  mandatory for any 2+ player game.
341
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
+
342
361
  ## If the user asks for ecctrl
343
362
 
344
363
  ecctrl is a React / React Three Fiber component; a Genex game is plain
@@ -257,7 +257,34 @@ addEventListener("pointerdown", () => {
257
257
  ```
258
258
 
259
259
  `options`: `fadeIn` (default 0.1 s), `timeScale`, `clamp` (hold the final pose —
260
- for deaths), `onDone`.
260
+ for deaths), `interruptible` (grounded movement cancels the clip), `onDone`.
261
+
262
+ **Every one-shot is FULL-BODY** (there is no upper-body layering), so it freezes
263
+ the legs — a moving character SLIDES across the ground in a frozen pose for the
264
+ clip's whole length. Two rules keep that from ever being visible:
265
+
266
+ - **Reactions and gestures a player can walk out of get `interruptible: true`**
267
+ (hit flinches, casts, taunts, celebrations). Movement intent releases the clip
268
+ and locomotion takes over the same frame. A 2.9 s hit reaction without it
269
+ locks the player's animation for 2.9 s *per hit taken*.
270
+ - **`clamp: true` holds the lock FOREVER by design** — nothing releases it
271
+ automatically, not even the clip ending. Every clamped one-shot needs a
272
+ guaranteed paired release: call `anims.clearOneShot()` on the transition out
273
+ (respawn, revive, action aborted). Audit every early-return on the path
274
+ between "clamped one-shot started" and "the replacing clip plays" — an abort
275
+ branch that skips the replacement strands the pose and the character slides
276
+ around locked until something else clears it.
277
+
278
+ `anims.clearOneShot()` cancels the active one-shot and crossfades locomotion
279
+ back in with no T-pose frame; it is safe to call when nothing is held. Call it
280
+ on TRANSITIONS only — per-frame calls cancel every in-flight reaction clip. To
281
+ cancel one SPECIFIC one-shot without clobbering whatever replaced it, check
282
+ `anims.currentOneShotName` first:
283
+
284
+ ```ts
285
+ // abort a held charge wind-up, but never a death pose that replaced it:
286
+ if (anims.currentOneShotName === WINDUP_CLIP) anims.clearOneShot();
287
+ ```
261
288
 
262
289
  The 12 core clips are always available; everything else comes from
263
290
  `npx genex controller anims <selectors…>` — selectors are **tags** (install a
@@ -140,6 +140,14 @@ front of it once — it must face you. This is part of the milestone smoke
140
140
  pass once enemies exist (an enemy in frame, facing the player). Set the
141
141
  `yawCorrection` constant per model and move on.
142
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
+
143
151
  ### 3. Hit reaction — damage reads on the body
144
152
 
145
153
  Rigged: the `hit` clip above. Procedural: a 100–150 ms flinch — scale pulse
@@ -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,11 +524,13 @@ 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
@@ -658,6 +658,25 @@ Corollary: **cap top speeds against the network, not just the physics** — an o
658
658
  crossing time should stay above ~2× the smoothing delay (~0.25 s), or receivers are reacting to
659
659
  history no matter how correct the code is.
660
660
 
661
+ **Packed animation-flag bitfields are the sneakiest violation.** Smoothing lerps EVERY numeric
662
+ field — there is no integer exemption — and a lerped bitfield decodes to garbage: with
663
+ `moving=1, running=2, grounded=8`, walking is `f=9` and running is `f=11`, and the interpolation
664
+ passes through `10`, where `10 & moving === 0` — the sprinting opponent renders as *standing
665
+ still*. Worse, the exponential ease approaches an increasing target from below, so truncation
666
+ reads `target - 1` for the whole approach (~1.5 s median before RUN appears; at a vsync-locked
667
+ frame rate it can stick one ULP below the target *forever*). A field-verified failure: a
668
+ playtester swore he was running while his opponent's screen showed him walking — both were right.
669
+ Always drive remote animation from `stateRaw`:
670
+
671
+ ```js
672
+ avatar.updateFromFlags(p.stateRaw.f ?? 0, dt); // flags are DISCRETE — never p.state.f
673
+ ```
674
+
675
+ **Reaction one-shots on remotes fire on EDGES, never per frame.** If you replay a remote's
676
+ death/hit pose from their published `out`/`hp` state, track the previous value and act only on
677
+ the transition — a per-frame `reset()`/`playDown()` restarts or cancels every in-flight reaction
678
+ clip (and re-writing ghost/material flags 60×/s is pure churn).
679
+
661
680
  ## Shared objects (the ball, the NPC) — use `objects`, never `shared`
662
681
 
663
682
  A ball belongs to no player. Put it on `objects`: exactly one client owns it at a time (the SDK +
@@ -56,9 +56,9 @@ translation may be normalized for Rapier.
56
56
 
57
57
  For plain game tasks — nothing from the procedural/visual-system pack loaded —
58
58
  this is the whole acceptance gate, and it is also the *ceiling*: a smoke check,
59
- not a certification. Run it ONCE per milestone, and only AFTER that milestone's
60
- `genex preview` is pushed ship the rough draft first, then check it; the
61
- player may already be walking around your build while you do. Catch obvious
59
+ not a certification. Run it ONCE per milestone, against that milestone's
60
+ `genex preview` build — the player may already be walking around it while
61
+ you check. Catch obvious
62
62
  breakage, fix what's clearly broken, and hand the feel/polish judgment to the
63
63
  player — don't loop re-testing the same build, don't re-test after cosmetic
64
64
  tweaks (sounds, colors, tuning values), and don't try to exercise every button
@@ -106,7 +106,12 @@ everything twice.
106
106
  4. In that screenshot, check oriented models: the hero faces its travel
107
107
  direction, and NPCs driven by chase/aim code face their target. A model
108
108
  rotated 90° reads as broken — `$genex-ai-model` has the one-time facing
109
- fix.
109
+ fix. **In any two-character or enemy-encounter capture, the characters
110
+ face their TARGET, not the camera** — Meshy/Mixamo/VRM rigs rest facing
111
+ +Z (straight at a side camera), so an unset yaw ships duelists staring
112
+ at the lens; and a rig "turned" with `scale.x = -1` is a defect even
113
+ when it looks right from one angle (negative scale flips a SkinnedMesh's
114
+ winding and normals — the character-controller skill has the rules).
110
115
  5. Vehicles get one extra pass: drive forward once and confirm the NOSE
111
116
  leads (a 180° body is this bug's favorite disguise), and check the body
112
117
  stands ON the road with its wheels inside the silhouette — a body