@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.
- package/README.md +9 -7
- package/dist/index.js +2110 -1871
- package/package.json +1 -1
- package/templates/controllers/character/character-animations.ts +116 -5
- package/templates/skills/genex-ai-hud/SKILL.md +45 -27
- package/templates/skills/genex-ai-hud/references/stage1-prompt-template.md +42 -5
- package/templates/skills/genex-ai-hud/references/stage2-prompt-template.md +5 -1
- package/templates/skills/genex-ai-menu/SKILL.md +12 -5
- package/templates/skills/genex-game-director/SKILL.md +56 -15
- package/templates/skills/genex-game-director/references/design-contract.md +33 -8
- package/templates/skills/genex-game-director/references/routing-map.md +40 -28
- package/templates/skills/genex-threejs-character-controller/SKILL.md +19 -0
- package/templates/skills/genex-threejs-character-controller/references/animations.md +28 -1
- package/templates/skills/genex-threejs-creatures/SKILL.md +8 -0
- package/templates/skills/genex-threejs-game-ui/SKILL.md +74 -70
- package/templates/skills/genex-threejs-multiplayer/SKILL.md +19 -0
- package/templates/skills/genex-threejs-visual-validation/SKILL.md +9 -4
|
@@ -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> (
|
|
44
|
-
|
|
43
|
+
Concept image: <asset URL> (standing — shown <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>
|
|
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
|
|
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
|
|
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
|
-
(
|
|
125
|
+
(standing — shown 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>
|
|
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
|
|
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,
|
|
92
|
-
HUD blueprint (never a separate UI-free concept first
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
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
|
|
268
|
-
|
|
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 —
|
|
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
|
|
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 --
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
(the verb), what threatens the player, what they chase,
|
|
80
|
-
and the brief's palette / materials / light /
|
|
81
|
-
weighing a stated direction, not guessing at a
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
user
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
menu
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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 link — a 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
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
re-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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
|
-
•
|
|
172
|
-
•
|
|
173
|
-
|
|
174
|
-
|
|
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
|
|
194
|
-
|
|
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
|
-
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
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,
|
|
60
|
-
`genex preview`
|
|
61
|
-
|
|
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
|