@genex-ai/cli-demo 0.71.0 → 0.74.0-dev.190
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +354 -8
- package/package.json +2 -1
- package/templates/controllers/character/follow-camera.ts +15 -4
- package/templates/controllers/character/vrm/vrm-loader.ts +74 -11
- package/templates/controllers/quality/governor.ts +147 -0
- package/templates/controllers/quality/pick-asset.ts +57 -0
- package/templates/controllers/quality/tier.ts +170 -0
- package/templates/skills/genex-ai-hud/SKILL.md +11 -2
- package/templates/skills/genex-ai-menu/SKILL.md +18 -2
- package/templates/skills/genex-ai-skybox/SKILL.md +15 -4
- package/templates/skills/genex-ai-texture/SKILL.md +1 -1
- package/templates/skills/genex-ai-video/SKILL.md +1 -1
- package/templates/skills/genex-explore/SKILL.md +1 -1
- package/templates/skills/genex-getting-started/SKILL.md +2 -2
- package/templates/skills/genex-threejs-adaptive-quality/SKILL.md +141 -0
- package/templates/skills/genex-threejs-adaptive-quality/references/adaptive-quality.md +105 -0
- package/templates/skills/genex-threejs-bloom/SKILL.md +4 -1
- package/templates/skills/genex-threejs-bloom/references/bloom.md +1 -1
- package/templates/skills/genex-threejs-camera-direction/SKILL.md +62 -12
- package/templates/skills/genex-threejs-camera-direction/references/camera-rigs.md +62 -0
- package/templates/skills/genex-threejs-character-controller/references/wiring.md +9 -3
- package/templates/skills/genex-threejs-embed-auth/SKILL.md +4 -1
- package/templates/skills/genex-threejs-game-feel/SKILL.md +4 -1
- package/templates/skills/genex-threejs-game-ui/SKILL.md +113 -30
- package/templates/skills/genex-threejs-game-ui/references/style-capsules.md +4 -1
- package/templates/skills/genex-threejs-image-pipeline/SKILL.md +5 -0
- package/templates/skills/genex-threejs-image-pipeline/references/image-pipeline.md +1 -1
- package/templates/skills/genex-threejs-lighting-design/SKILL.md +5 -1
- package/templates/skills/genex-threejs-multiplayer/SKILL.md +7 -1
- package/templates/skills/genex-threejs-multiplayer/references/host-physics.md +6 -3
- package/templates/skills/genex-threejs-physics-rapier/references/colliders-from-assets.md +1 -0
- package/templates/skills/genex-threejs-screen-space-ambient-occlusion/references/ambient-occlusion.md +1 -1
- package/templates/skills/genex-threejs-shadow-systems/SKILL.md +6 -0
- package/templates/skills/genex-threejs-shadow-systems/references/shadow-systems.md +1 -1
- package/templates/skills/genex-threejs-skill-router/SKILL.md +26 -5
- package/templates/skills/genex-threejs-skill-router/references/routing-map.md +25 -9
- package/templates/skills/genex-threejs-spectral-ocean/references/spectral-ocean.md +1 -1
- package/templates/skills/genex-threejs-touch-controls/SKILL.md +11 -0
- package/templates/skills/genex-threejs-vehicle-controllers/references/enter-exit.md +7 -0
- package/templates/skills/genex-threejs-visual-validation/SKILL.md +36 -12
- package/templates/skills/genex-threejs-water-optics/references/water-optics.md +1 -1
- package/templates/skills/genex-updates/SKILL.md +1 -1
|
@@ -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 |
|
|
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 |
|
|
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
|
|
|
@@ -79,25 +79,40 @@ lap counter in a game without laps). `--aspect 16:9 --quality high
|
|
|
79
79
|
--no-wait`, enqueued FIRST of all art; the URL goes into the style-brief
|
|
80
80
|
comment.
|
|
81
81
|
|
|
82
|
-
**Share it
|
|
83
|
-
When the concept lands,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
82
|
+
**Share it the moment it lands — queue first, show immediately, never wait.**
|
|
83
|
+
When the concept lands, enqueue the Tier-2 UI jobs and the core asset set
|
|
84
|
+
against it in the same breath — the frame you just generated IS the working
|
|
85
|
+
style until the user says otherwise. Then pick it up with
|
|
86
|
+
`genex wait <id> --open` (or generate it with `--open`): it opens in the
|
|
87
|
+
user's browser AND prints the link. Paste that URL as a clickable link in
|
|
88
|
+
your message — a URL is invisible in a terminal, and "do you like it?" with
|
|
89
|
+
no picture in front of the user is the #1 way this checkpoint fails (they end
|
|
90
|
+
up digging logs for the file path). Ask ONE keep-or-change question — "this
|
|
91
|
+
is roughly how the game will look: keep it, or change something?" — **as
|
|
92
|
+
plain chat text, never via the blocking structured-question tool: a suspended
|
|
93
|
+
turn is a gate, and this question must not gate anything.** Silence is
|
|
94
|
+
acceptance; only explicit notes reopen the style. An unanswered style
|
|
95
|
+
question that parks the art pipeline is how a finished game ships bare walls
|
|
96
|
+
and a placeholder HUD — strictly worse than re-rolling a few assets later.
|
|
97
|
+
**Feedback triggers a LOOP whenever it arrives:** if the user comes back
|
|
98
|
+
disliking ANYTHING — immediately or an hour later — regenerate with their
|
|
99
|
+
exact notes (`--candidates 2–3` gives them options to choose from), open +
|
|
100
|
+
link the new frame, and ask again the same non-blocking way. Carry every note
|
|
95
101
|
forward so each round compounds; if two rounds don't converge, offer 2–3
|
|
96
|
-
distinct directions
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
the
|
|
102
|
+
distinct directions instead of re-rolling blind (plain chat, same rule).
|
|
103
|
+
Every shown frame becomes the working style exactly like the first did:
|
|
104
|
+
silence after a shown regeneration accepts THAT frame, and when
|
|
105
|
+
`--candidates` goes unanswered, pick the strongest yourself and say so. When
|
|
106
|
+
the style actually changes, re-anchor the style-carrying art made against
|
|
107
|
+
the old frame: the menu still is re-edited (`--edit`) against the new frame
|
|
108
|
+
and its video re-run once from the new still (`$genex-ai-menu` — a
|
|
109
|
+
user-driven style change re-opens its one-video rule), and the HUD chrome
|
|
110
|
+
re-runs its pipeline from Stage 1 with the new frame as the `--edit` anchor
|
|
111
|
+
(`$genex-ai-hud` — budget the full serial chain; it is the most expensive
|
|
112
|
+
re-anchor in the set). Style-neutral assets (most textures, sfx, models)
|
|
113
|
+
usually survive — judge each in one line. The same "open it + paste the
|
|
114
|
+
link" rule covers every image the user weighs in on — the menu still, the
|
|
115
|
+
HUD mockup candidates.
|
|
101
116
|
|
|
102
117
|
**The concept anchors STYLE, not truth.** Palette, materials, light, and
|
|
103
118
|
register come from the frame; CONTENT comes from the game contract. When
|
|
@@ -241,17 +256,28 @@ document.addEventListener("keydown", (e) => {
|
|
|
241
256
|
|
|
242
257
|
- **On the bundled `FollowCamera`, it owns the lock — don't fight it.** Do NOT
|
|
243
258
|
call `document.exitPointerLock()` / `canvas.requestPointerLock()` yourself; that
|
|
244
|
-
desyncs its aim state (the cue flips wrong). Instead pause/resume through it
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
259
|
+
desyncs its aim state (the cue flips wrong). Instead pause/resume through it —
|
|
260
|
+
and bind it **on phase transitions, never per frame**: put
|
|
261
|
+
`followCam?.setPaused(phase !== "playing")` inside `setPhase()` (below) and it
|
|
262
|
+
covers everything at once — the BOOT menu parks aim, Escape's
|
|
263
|
+
`setPhase("paused")` frees the cursor, and the Play/Resume click's
|
|
264
|
+
`setPhase("playing")` re-locks inside the gesture. Read `onAimChange` for the
|
|
265
|
+
cue. The raw calls above are only for a hand-rolled camera with no bundled
|
|
266
|
+
controller.
|
|
248
267
|
- **Degradation is built in.** Where Keyboard Lock is absent (Safari, Firefox) or
|
|
249
268
|
the game isn't fullscreen, the browser still releases pointer lock on Escape —
|
|
250
269
|
so ALSO keep the pointer-lock-loss → pause path (`pointerlockchange`: if
|
|
251
270
|
unlocked while `playing`, `setPhase("paused")`). Escape then always pauses; it
|
|
252
271
|
only *also* drops fullscreen on browsers without the lock — unavoidable there.
|
|
253
|
-
- **
|
|
254
|
-
|
|
272
|
+
- **Skip Keyboard Lock + fullscreen only when the cursor stays a tool.**
|
|
273
|
+
Cursor-core / top-down / menu-driven games never capture the pointer — skip
|
|
274
|
+
`enterImmersive` and Keyboard Lock entirely. But ANY game that locks the
|
|
275
|
+
pointer during play — aim games AND keyboard-only racers/platformers/runners
|
|
276
|
+
under the lock-or-tool rule (next section) — keeps the Escape → pause path and
|
|
277
|
+
the `pointerlockchange` fallback (if unlocked while `playing`, pause): without
|
|
278
|
+
it, Esc frees the cursor while the game keeps running. Keyboard-only games may
|
|
279
|
+
still skip Keyboard Lock + fullscreen; the lock + pause/resume path is the
|
|
280
|
+
non-negotiable part.
|
|
255
281
|
- **Dashboard embed:** no setup needed — the platform's game frame grants keyboard
|
|
256
282
|
lock (and pointer lock + fullscreen), so Escape-to-pause works the same inside
|
|
257
283
|
`/world/` + `/draft/` as it does standalone (`<slug>.genex.technology`).
|
|
@@ -261,6 +287,34 @@ menu — trackpads feel slower than mice, so let the player tune it. On the bund
|
|
|
261
287
|
camera the setter is live: `slider.oninput = () => { followCam.aimSensitivity = +slider.value; };`
|
|
262
288
|
(radians per pixel; default `0.0023`, a usable range is ~`0.0008`–`0.005`).
|
|
263
289
|
|
|
290
|
+
## The cursor during play: locked or a tool
|
|
291
|
+
|
|
292
|
+
During play the OS cursor is either the gameplay tool (cursor-core: click-to-move,
|
|
293
|
+
tower defense, builders, card/board — it stays visible, that's correct) or it is
|
|
294
|
+
**locked away — including keyboard-only games** (racer, platformer, runner): an
|
|
295
|
+
arrow parked over the action for the whole session is a shipped defect. Games on
|
|
296
|
+
the bundled `FollowCamera` get the lock free (on by default). A hand-rolled game
|
|
297
|
+
locks with ~6 lines, reusing this section's Escape flow:
|
|
298
|
+
|
|
299
|
+
```ts
|
|
300
|
+
// Once at setup (NOT inside the click handler — a fresh listener on every
|
|
301
|
+
// Resume stacks and multi-fires setPhase on a single unlock):
|
|
302
|
+
document.addEventListener("pointerlockchange", () => {
|
|
303
|
+
if (!document.pointerLockElement && phase === "playing") setPhase("paused");
|
|
304
|
+
});
|
|
305
|
+
// In the Play/Start/Resume CLICK handler (lock needs a user gesture):
|
|
306
|
+
canvas.requestPointerLock?.(); // hides the cursor, focuses the game
|
|
307
|
+
// Required (not optional): without Keyboard Lock, the browser consumes Esc to
|
|
308
|
+
// exit pointer lock and the keydown never reaches the page — the listener
|
|
309
|
+
// above is what pauses. The Resume click re-locks. Keyboard games need nothing
|
|
310
|
+
// more — no reticle, no aim code; the lock just parks the cursor.
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
If the lock is genuinely unavailable (a third-party embed without
|
|
314
|
+
`allow="pointer-lock"`), fall back to hiding the idle cursor over the canvas:
|
|
315
|
+
`canvas.style.cursor = "none"` after ~2s without `pointermove`, restored
|
|
316
|
+
instantly on move. Menus and pause screens always keep their cursor.
|
|
317
|
+
|
|
264
318
|
## The loader
|
|
265
319
|
|
|
266
320
|
The loader is the first thing every player sees — a bare "Loading… 3/5" over
|
|
@@ -292,6 +346,11 @@ function setPhase(phase: "loading" | "playing" | "paused" | "over" | "won") {
|
|
|
292
346
|
if (on) s.hidden = false; // show immediately, then fade in
|
|
293
347
|
else setTimeout(() => { if (!s.classList.contains("is-on")) s.hidden = true; }, 300);
|
|
294
348
|
}
|
|
349
|
+
// The camera's lock lifecycle rides the SAME transition — never the render loop
|
|
350
|
+
// (optional-chained: the camera may not exist yet at the first "loading" call).
|
|
351
|
+
followCam?.setPaused(phase !== "playing");
|
|
352
|
+
// (Vehicle games combine conditions instead:
|
|
353
|
+
// followCam.setPaused(phase !== "playing" || activeId !== CHARACTER_ID).)
|
|
295
354
|
}
|
|
296
355
|
```
|
|
297
356
|
|
|
@@ -362,6 +421,19 @@ Order the HUD by what the player loses the game for ignoring:
|
|
|
362
421
|
- **Contrast against the real scene.** Test text over the brightest AND
|
|
363
422
|
darkest areas of actual gameplay; a soft dark plate or text-shadow beats
|
|
364
423
|
restyling per level.
|
|
424
|
+
- **CSS-shaped corners must survive their contents.** `border-radius`,
|
|
425
|
+
`clip-path`, and `mask` are all fair ways to shape a panel or button —
|
|
426
|
+
including a chamfered/notched "hi-tech" corner in pure CSS. What is
|
|
427
|
+
non-negotiable is the execution: the cut must never shear off anything
|
|
428
|
+
that sits near the corner (text, padding, the focus ring, a glow) — keep
|
|
429
|
+
enough inner padding that content clears the cut shape — and the result
|
|
430
|
+
must be clean, not crooked: no jagged aliased diagonals, no half-clipped
|
|
431
|
+
borders or shadows, no text colliding with an edge or truncating. The
|
|
432
|
+
same bar applies to CSS plates. Verify the corners at real sizes over
|
|
433
|
+
real gameplay. When the art direction wants a genuinely ornamented
|
|
434
|
+
frame, a generated frame sprite (`$genex-ai-hud` chrome, or a Tier-3
|
|
435
|
+
9-slice panel) is still the richer tool. The masked-fill HUD reveal and
|
|
436
|
+
`genex ui` masks remain the other established uses of `mask`/`clip-path`.
|
|
365
437
|
- **One cohesion layer.** A single full-screen vignette div (a subtle radial
|
|
366
438
|
gradient darkening the corners, optionally faint grain) over canvas + UI is
|
|
367
439
|
the cheapest way to make DOM-over-WebGL read as one composed image instead
|
|
@@ -372,11 +444,13 @@ Order the HUD by what the player loses the game for ignoring:
|
|
|
372
444
|
`vUv` grain shimmers.
|
|
373
445
|
- **Desktop first.** Verify at desktop sizes and survive window resizes
|
|
374
446
|
without clipping; don't design phone layouts or test mobile viewports unless
|
|
375
|
-
the user asks.
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
`navigator.maxTouchPoints > 0`,
|
|
379
|
-
|
|
447
|
+
the user asks. Two exceptions ship by default precisely BECAUSE you don't
|
|
448
|
+
test on phones: touch *input* when a recipe fits — a bundled controller's
|
|
449
|
+
built-in touch controls, or the touch kit + recipes in
|
|
450
|
+
`$genex-threejs-touch-controls` — behind `navigator.maxTouchPoints > 0`,
|
|
451
|
+
invisible on desktop (skipping needs a one-line reason, not silence); and
|
|
452
|
+
the adaptive-quality tier at boot (`$genex-threejs-adaptive-quality`), which
|
|
453
|
+
keeps the shared link from being a dead OR crashing link on a phone.
|
|
380
454
|
|
|
381
455
|
## Wire UI to game state, never the reverse
|
|
382
456
|
|
|
@@ -399,6 +473,9 @@ architecture and consume the shared style brief.
|
|
|
399
473
|
- HUD sprites never enqueued at the gate — the placeholder CSS shipped as the
|
|
400
474
|
final HUD.
|
|
401
475
|
- No pause screen, or a pause that isn't bound to Escape.
|
|
476
|
+
- The OS arrow parked over the action for the whole session in a keyboard-driven
|
|
477
|
+
game (the cursor is either a gameplay tool or locked away — see the cursor
|
|
478
|
+
section).
|
|
402
479
|
- A style brief whose fonts were never actually loaded (a system-stack display
|
|
403
480
|
font at runtime).
|
|
404
481
|
- A micro-element (reticle, cue, toast, damage number) left as default CSS
|
|
@@ -408,6 +485,12 @@ architecture and consume the shared style brief.
|
|
|
408
485
|
- Hard-cut phase swaps, a menu whose elements just appear, numbers that
|
|
409
486
|
teleport.
|
|
410
487
|
- A silent menu; a bare "Loading…" over black.
|
|
488
|
+
- The art pipeline parked on an unanswered look question — the question is
|
|
489
|
+
advisory: queue Tier-2 + the asset set against the shown frame and keep
|
|
490
|
+
moving; silence is acceptance.
|
|
491
|
+
- A CSS-cut corner (`clip-path`/`mask`) that shears its own content — clipped
|
|
492
|
+
text or padding, a lost focus ring or glow, a jagged aliased edge — the
|
|
493
|
+
technique is fine; the sloppy cut is the defect.
|
|
411
494
|
- UI panels covering the player or the thing about to kill them.
|
|
412
495
|
- Layout shifting as numbers grow.
|
|
413
496
|
- A fail state with no visible restart key, or a restart that reloads the page.
|
|
@@ -10,7 +10,10 @@ says what it's made of in THIS game.
|
|
|
10
10
|
|
|
11
11
|
Every capsule below assumes the base rules from the skill: corners/edges for
|
|
12
12
|
UI, one display + one body font, tabular numerals, contrast plates over
|
|
13
|
-
arbitrary scenes
|
|
13
|
+
arbitrary scenes, and panel/button corners executed cleanly — `border-radius`,
|
|
14
|
+
a CSS `clip-path`/`mask` shape, or a generated frame all work, as long as the
|
|
15
|
+
cut never clips content (text, padding, glow), stays free of jagged-edge
|
|
16
|
+
artifacts, and text never collides or truncates.
|
|
14
17
|
|
|
15
18
|
## Fantasy / action RPG
|
|
16
19
|
|
|
@@ -43,6 +43,11 @@ ownership boundaries between whole-scene and effect-local graphs.
|
|
|
43
43
|
- Build pass toggles and effect-only views before tuning.
|
|
44
44
|
- UI rendered in the same target needs an explicit protection strategy.
|
|
45
45
|
- Do not load all atomic post skills by default. Route only the effects actually requested.
|
|
46
|
+
- Budget the pipeline per device tier (`$genex-threejs-adaptive-quality`):
|
|
47
|
+
phone pixel budget ≈ 1,000,000 px at DPR ≤ 1.25–1.5, desktop ≈ 1,650,000 px —
|
|
48
|
+
every full-res pass target multiplies that cost, so phone tiers run the light
|
|
49
|
+
post level and per-pass resolution scales (0.4–0.5 DPR blurs) are the norm,
|
|
50
|
+
not an optimization.
|
|
46
51
|
|
|
47
52
|
## Routing boundary
|
|
48
53
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Use this reference to compose shared scene buffers, lighting effects, atmosphere, bloom, exposure, tone mapping, grading, and feature-local render targets with explicit ownership.
|
|
4
4
|
|
|
5
|
-
> **Renderer note:** this reference assumes `WebGPURenderer` + TSL node materials. Check the project's actual renderer first — the Genex scaffold ships vanilla WebGL three.js. On WebGL, adapt the technique with standard materials / `EffectComposer` passes or pick a simpler alternative; never switch renderers mid-project.
|
|
5
|
+
> **Renderer note:** this reference assumes `WebGPURenderer` + TSL node materials. Check the project's actual renderer first — the Genex scaffold ships vanilla WebGL three.js. On WebGL, adapt the technique with standard materials / `EffectComposer` passes or pick a simpler alternative; never switch renderers mid-project. Either way the effect obeys the device tier (`$genex-threejs-adaptive-quality`): expensive passes are desktop-tier, and on WebGPU the per-target MSAA sample count is a runtime knob the governor may drive.
|
|
6
6
|
|
|
7
7
|
## Contents
|
|
8
8
|
|
|
@@ -107,7 +107,11 @@ kill-switch diagnostic.
|
|
|
107
107
|
whole rig after a tone-mapping change is self-inflicted.
|
|
108
108
|
- Never repair unbalanced light ratios with exposure — fix the lights.
|
|
109
109
|
- Flicker from elapsed time, never per-frame randomness.
|
|
110
|
-
- Dispose lights and their shadow maps with the level that spawned them
|
|
110
|
+
- Dispose lights and their shadow maps with the level that spawned them — and
|
|
111
|
+
the rest of the level with them: traverse the outgoing scene and dispose
|
|
112
|
+
geometry, materials, AND textures separately (three frees nothing; material
|
|
113
|
+
dispose does not touch textures). Leaked levels march phones toward the
|
|
114
|
+
OS memory kill — `$genex-threejs-adaptive-quality` owns the budget watch.
|
|
111
115
|
- The rig must read with post off: time of day and where-to-go, before bloom.
|
|
112
116
|
|
|
113
117
|
## Routing boundary
|
|
@@ -536,7 +536,13 @@ fights (many writers). A ball on `objects` glides and has one owner. That's the
|
|
|
536
536
|
`stateRaw` is the raw latest (hit-tests, discrete values). A reconnect-grace seat remains in this
|
|
537
537
|
map with `connected: false`. `avatarUrl` is that player's verified VRM pick (server-set, `''`
|
|
538
538
|
when unknown) — in a VRM-lane game render each remote with
|
|
539
|
-
`
|
|
539
|
+
`loadVrmClone(p.avatarUrl || "./assets/avatar.vrm")` (the vendored loader's shared-GPU clone:
|
|
540
|
+
N remotes share one set of geometry/textures instead of re-parsing per player — retarget
|
|
541
|
+
clips once on `loadVrmClone.base(url)` and play them on each clone's own mixer); never
|
|
542
|
+
publish avatar URLs through `me.set`. On phone tiers, animate and fully draw only the
|
|
543
|
+
nearest `tier.remoteAvatarCap` remotes (`$genex-threejs-adaptive-quality`) — freeze the
|
|
544
|
+
mixer and billboard or hide the rest; a room allows up to 64 players and 64 live avatars
|
|
545
|
+
is a real phone memory kill on its own.
|
|
540
546
|
- `room.activePlayers` — the connected-only subset of `room.players`; use its size for live quorum.
|
|
541
547
|
- `room.objects` — shared objects nobody owns until claimed (a ball, an NPC):
|
|
542
548
|
- `claim(id)` — **legacy** optimistic request. It flips local ownership immediately and is corrected
|
|
@@ -275,9 +275,12 @@ room.me.set({
|
|
|
275
275
|
|
|
276
276
|
// Remote players: a VISUAL-ONLY avatar — NO Rapier body, NO controller instance for remotes.
|
|
277
277
|
// Build each remote's visual from THEIR OWN model: in a VRM-lane game that is
|
|
278
|
-
//
|
|
279
|
-
// replicates ('' = unknown → fall back; deepDispose the
|
|
280
|
-
//
|
|
278
|
+
// loadVrmClone(pl.avatarUrl || "./assets/avatar.vrm") — the verified per-player pick the
|
|
279
|
+
// relay replicates ('' = unknown → fall back; deepDispose the clone on 'leave'). The clone
|
|
280
|
+
// shares parsed GPU geometry/textures across remotes with the same file (most rooms: all of
|
|
281
|
+
// them) — retarget clips once against loadVrmClone.base(url).vrm and drive each clone's own
|
|
282
|
+
// AnimationMixer. Never reuse your own avatar OBJECT for a remote (clones, not references).
|
|
283
|
+
// Phone tiers animate only the nearest tier.remoteAvatarCap remotes (adaptive-quality skill). Position/rotation from smoothed state; animation from the
|
|
281
284
|
// synced flags via the avatar's own update(flags, dt). The character-controller skill's
|
|
282
285
|
// animations reference owns the flag set.
|
|
283
286
|
const pl = room.players.get(id)!;
|
|
@@ -26,6 +26,7 @@ already resolved — constructing a collider before WASM init throws.
|
|
|
26
26
|
| tall dynamic props, posts | `capsuleCollider` / `cylinderCollider` | stable standing shapes |
|
|
27
27
|
| pickups, triggers, zones | any shape + `{ sensor: true, mass: 0 }` | overlap events, no contact forces |
|
|
28
28
|
| the player, cars, drones | none of the above — `npx genex controller` | controllers own their collider recipes |
|
|
29
|
+
| any prop on a PHONE tier (`$genex-threejs-adaptive-quality`) | prefer `cuboidCollider`/hull over trimesh | trimesh contacts scale with triangle count — a phone CPU/memory tax; keep trimesh for static level geometry only |
|
|
29
30
|
|
|
30
31
|
## Explicit primitive helpers
|
|
31
32
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Use this reference for a bounded-cost WebGPU/TSL ambient-visibility pass with half-resolution horizon integration, bent normals, bilateral reconstruction, and directional ambient tint.
|
|
4
4
|
|
|
5
|
-
> **Renderer note:** this reference assumes `WebGPURenderer` + TSL node materials. Check the project's actual renderer first — the Genex scaffold ships vanilla WebGL three.js. On WebGL, adapt the technique with standard materials / `EffectComposer` passes or pick a simpler alternative; never switch renderers mid-project.
|
|
5
|
+
> **Renderer note:** this reference assumes `WebGPURenderer` + TSL node materials. Check the project's actual renderer first — the Genex scaffold ships vanilla WebGL three.js. On WebGL, adapt the technique with standard materials / `EffectComposer` passes or pick a simpler alternative; never switch renderers mid-project. Either way the effect obeys the device tier (`$genex-threejs-adaptive-quality`): expensive passes are desktop-tier, and on WebGPU the per-target MSAA sample count is a runtime knob the governor may drive.
|
|
6
6
|
|
|
7
7
|
## Contents
|
|
8
8
|
|
|
@@ -12,6 +12,12 @@ and shadows shimmer, swim, or run out of coverage.
|
|
|
12
12
|
|
|
13
13
|
Use a single shadow map only when its receiver region is genuinely bounded. For large moving views, make shadow coverage an explicit spatial hierarchy.
|
|
14
14
|
|
|
15
|
+
**Phone budgets ride the quality tier** (`$genex-threejs-adaptive-quality`):
|
|
16
|
+
shadow maps ≤1024² on phones (512² on the low tier — a 4096² map alone is
|
|
17
|
+
~67 MB of the phone's whole GPU budget), at most 2 cascades where desktop runs
|
|
18
|
+
4, and `shadowMap.autoUpdate = false` for static scenes (re-render on demand:
|
|
19
|
+
a shadow pass is a full extra scene render every frame otherwise).
|
|
20
|
+
|
|
15
21
|
## Cached clipmap workflow
|
|
16
22
|
|
|
17
23
|
1. Define concentric light-space square levels.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Use this reference for stable directional shadows across a large procedural scene using committed light-space centers, texel snapping, bounded refresh budgets, cross-level blending, and targeted invalidation.
|
|
4
4
|
|
|
5
|
-
> **Renderer note:** this reference assumes `WebGPURenderer` + TSL node materials. Check the project's actual renderer first — the Genex scaffold ships vanilla WebGL three.js. On WebGL, adapt the technique with standard materials / `EffectComposer` passes or pick a simpler alternative; never switch renderers mid-project.
|
|
5
|
+
> **Renderer note:** this reference assumes `WebGPURenderer` + TSL node materials. Check the project's actual renderer first — the Genex scaffold ships vanilla WebGL three.js. On WebGL, adapt the technique with standard materials / `EffectComposer` passes or pick a simpler alternative; never switch renderers mid-project. Either way the effect obeys the device tier (`$genex-threejs-adaptive-quality`): expensive passes are desktop-tier, and on WebGPU the per-target MSAA sample count is a runtime knob the governor may drive.
|
|
6
6
|
|
|
7
7
|
## Contents
|
|
8
8
|
|
|
@@ -15,11 +15,12 @@ map, execution order, and acceptance gate.
|
|
|
15
15
|
|
|
16
16
|
| Work needed | Load |
|
|
17
17
|
| --- | --- |
|
|
18
|
-
| 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, floating origins | `$genex-threejs-camera-direction` |
|
|
18
|
+
| 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` |
|
|
19
19
|
| 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` |
|
|
20
20
|
| 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` |
|
|
21
21
|
| the player drives or flies something: cars, drones, vehicle physics, gearbox, enter/exit between character and vehicle | `$genex-threejs-vehicle-controllers` |
|
|
22
22
|
| 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` |
|
|
23
|
+
| 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` |
|
|
23
24
|
| anything falls, collides, gets pushed, or needs physics: Rapier world setup, colliders for meshes and GLBs, collision events | `$genex-threejs-physics-rapier` |
|
|
24
25
|
| launch and docking timelines, procedural transform phases, springs, staging, rotating-frame alignment, debris motion | `$genex-threejs-procedural-animation` |
|
|
25
26
|
| reusable scalar/vector fields, domain warping, causal masks, procedural normals | `$genex-threejs-procedural-fields` |
|
|
@@ -58,6 +59,14 @@ map, execution order, and acceptance gate.
|
|
|
58
59
|
mentions sign-in, saves, progress, per-player state, a persistent world, or
|
|
59
60
|
leaderboards. Multiplayer auth (`getColyseusAuth`) comes from it too.
|
|
60
61
|
|
|
62
|
+
**Adaptive quality is mandatory routing:** every game wires the device tier at
|
|
63
|
+
boot — `$genex-threejs-adaptive-quality` (three lines: `detectTier()` before the
|
|
64
|
+
renderer, tier-capped `setPixelRatio`, the governor in the loop; generated
|
|
65
|
+
skyboxes/textures load through their rungs). Phones enforce a hard GPU-memory
|
|
66
|
+
kill desktops never show you; the tier is what keeps a phone boot alive while
|
|
67
|
+
desktop keeps the full look. This is a completion gate like the post stack —
|
|
68
|
+
cheap to wire, not a new testing burden (desktop-only verification stands).
|
|
69
|
+
|
|
61
70
|
**Character-animation routing:** use the existing VRM + UAL character
|
|
62
71
|
controller by default. Use `npx genex character` when the game needs a custom
|
|
63
72
|
generated humanoid or an action unavailable in UAL. Before generating a Meshy
|
|
@@ -122,7 +131,11 @@ stack this game ships — read off the concept frame's OWN look (the grade, bloo
|
|
|
122
131
|
level, haze, grain it already shows) and which post the 2–3 AAA references lean
|
|
123
132
|
on, not a default single bloom; ONE built render-pass effect is the FLOOR
|
|
124
133
|
against no-post for EVERY game, never the target — ship the richness the concept
|
|
125
|
-
implies
|
|
134
|
+
implies. The floor is TIER-AWARE (`$genex-threejs-adaptive-quality`): on phone
|
|
135
|
+
tiers it is satisfied by the built tone-mapping/output pass with the light
|
|
136
|
+
additions the tier allows (FXAA/vignette), while the full named stack remains
|
|
137
|
+
the desktop floor — never ship the heavy stack undropped to phones (the UI
|
|
138
|
+
vignette div or a CSS canvas filter does not count on any tier;
|
|
126
139
|
`$genex-threejs-image-pipeline` owns ordering when 2+ compose), a decision for
|
|
127
140
|
**every primitive surface** the game builds — walls, barriers, kerbs and
|
|
128
141
|
platforms each get a real texture or a **shader** where that surface wants motion
|
|
@@ -204,8 +217,16 @@ concept-driven — a richer first build beats a grey-box one.
|
|
|
204
217
|
drag-orbit (`pointerLockAim: false`) only with a stated reason (e.g. a
|
|
205
218
|
cursor-heavy UI core). **Never** — cursor-core games (click-to-move, tower
|
|
206
219
|
defense, builder, card/puzzle), orbit showcases, touch-only; these MUST pass
|
|
207
|
-
`pointerLockAim: false`.
|
|
208
|
-
|
|
220
|
+
`pointerLockAim: false`. Keyboard-only games (racer, platformer) lock too —
|
|
221
|
+
the cursor is either a gameplay tool or locked away during play. The mechanism
|
|
222
|
+
and the full aim contract live in `$genex-threejs-camera-direction`.
|
|
223
|
+
- Input direction (always — every game that moves with keys or pointer):
|
|
224
|
+
D/ArrowRight must move or turn the player screen-RIGHT, mouse-right must turn
|
|
225
|
+
the view right, drag-pan axes share one convention. The screen-direction
|
|
226
|
+
contract and verified copy-paste bases live in
|
|
227
|
+
`$genex-threejs-camera-direction` — hand-rolled steering/pan/look math copies
|
|
228
|
+
one instead of deriving signs, and the smoke check's input-direction pass
|
|
229
|
+
verifies it.
|
|
209
230
|
- Art direction follows THIS game's concept. The style examples inside skills
|
|
210
231
|
are examples, not defaults — never default to neon/cyberpunk/synthwave (or any
|
|
211
232
|
other single register) unless the concept calls for it.
|
|
@@ -222,7 +243,7 @@ concept-driven — a richer first build beats a grey-box one.
|
|
|
222
243
|
- Use `$genex-threejs-visual-validation` before declaring graphics/procedural-system
|
|
223
244
|
work done. **Game fast path:** for game tasks that loaded no procedural/visual-system
|
|
224
245
|
skill, done = a screenshot plus an interaction smoke check (load the page, press each
|
|
225
|
-
control, see the visible response) — don't run the full diagnostic gate — PLUS the
|
|
246
|
+
control, see the visible response in its labeled direction) — don't run the full diagnostic gate — PLUS the
|
|
226
247
|
floors from the routing-map's acceptance gate: the generated sprite HUD wired in
|
|
227
248
|
(not the CSS placeholder), pause on Escape, the branded loader with its key-art
|
|
228
249
|
background, the brief's fonts actually loaded, the renderer baseline + at least one
|
|
@@ -52,8 +52,10 @@ Three.js release or branch, and do not blindly copy demo architecture.
|
|
|
52
52
|
while you build the game. FIRST of all art: the gate's **concept frame** —
|
|
53
53
|
a playable-moment shot (verb + threat + objective in frame, per the
|
|
54
54
|
game-ui gate), shown to the user for a keep-or-change answer the moment
|
|
55
|
-
it lands
|
|
56
|
-
the game
|
|
55
|
+
it lands — the answer is advisory, never a gate: the art pipeline starts
|
|
56
|
+
against the frame as-is, and the game-ui skill owns the re-anchor loop
|
|
57
|
+
when notes arrive; later `--edit`-able generations anchor to it for STYLE
|
|
58
|
+
while the game contract owns content. Then the `$genex-ai-hud` Stage-1 mockup, enqueued
|
|
57
59
|
here for EVERY game; and the `$genex-ai-menu` video whenever the menu
|
|
58
60
|
decision is yes (the default for every game — "it's only a draft" is not a
|
|
59
61
|
reason to decide no). Skipping this enqueue is
|
|
@@ -180,7 +182,10 @@ Three.js release or branch, and do not blindly copy demo architecture.
|
|
|
180
182
|
(`$genex-threejs-visual-validation` owns the capture discipline).
|
|
181
183
|
7. Add camera direction when framing, controls, transitions, or scale perception
|
|
182
184
|
affect play — or the game aims with the mouse (shooter/FPS/turret): the
|
|
183
|
-
step-4 bucket decision executes here.
|
|
185
|
+
step-4 bucket decision executes here. And before ANY hand-rolled
|
|
186
|
+
steering/pan/look math: the screen-direction contract (D → screen-right,
|
|
187
|
+
mouse-right → view right, drag axes one convention) with verified copy-paste
|
|
188
|
+
bases lives there — signs are copied, never derived.
|
|
184
189
|
8. Add procedural animation when object motion needs authored phases,
|
|
185
190
|
convergence, looping, or deterministic timelines.
|
|
186
191
|
9. Add shared fields before writing multiple independent noise layers.
|
|
@@ -191,7 +196,11 @@ Three.js release or branch, and do not blindly copy demo architecture.
|
|
|
191
196
|
step-4 post plan, not inventing one now. This is a completion gate: the
|
|
192
197
|
named post stack must be BUILT before the game is called done, published,
|
|
193
198
|
or handed off — a game rendering on stock three.js defaults is not done,
|
|
194
|
-
and the gate does not wait for the word "done" to be said.
|
|
199
|
+
and the gate does not wait for the word "done" to be said. The stack is
|
|
200
|
+
tier-gated (`$genex-threejs-adaptive-quality`): full on desktop, the built
|
|
201
|
+
tone-mapping pass + the tier's light additions on phones — wire the
|
|
202
|
+
governor's post toggle so phone tiers drop the heavy passes, never ship
|
|
203
|
+
them undropped.
|
|
195
204
|
12. Once the loop is playable, build the planned interface states via
|
|
196
205
|
`$genex-threejs-game-ui` (HUD, pause on Escape, fail/retry, win, and the
|
|
197
206
|
full loading state grown from the step-6 loader), then `npx genex wait`
|
|
@@ -250,7 +259,7 @@ module — a corrupted entry point costs more than the minutes saved.
|
|
|
250
259
|
|
|
251
260
|
**Game fast path:** for a game task that loaded no procedural/visual-system skill,
|
|
252
261
|
done = a screenshot plus an interaction smoke check (load the page, press each
|
|
253
|
-
control, assert a visible response — `$genex-threejs-visual-validation` has the
|
|
262
|
+
control, assert a visible response in its labeled direction — `$genex-threejs-visual-validation` has the
|
|
254
263
|
procedure), **plus the UI floor from `$genex-threejs-game-ui` (the generated
|
|
255
264
|
sprite HUD wired in — not the CSS placeholder — pause on Escape, the branded
|
|
256
265
|
loader with its key-art background, the brief's font pair actually loaded)
|
|
@@ -277,7 +286,11 @@ A routed Genex scene is incomplete until it exposes:
|
|
|
277
286
|
- named perceptual parameters for the important visual systems;
|
|
278
287
|
- debug views for generated fields, masks, or passes;
|
|
279
288
|
- a no-post baseline that still communicates the subject;
|
|
280
|
-
- a clear quality tier or render-budget knob when the effect is expensive
|
|
289
|
+
- a clear quality tier or render-budget knob when the effect is expensive —
|
|
290
|
+
and for every GAME, the adaptive-quality tier wired at boot
|
|
291
|
+
(`$genex-threejs-adaptive-quality`): tier-capped pixel ratio, tier shadow
|
|
292
|
+
budget, the runtime governor in the loop, and generated skybox/texture
|
|
293
|
+
loads routed through their rungs;
|
|
281
294
|
- when physics or controllers are in play, a fixed-timestep loop: per-frame
|
|
282
295
|
work (platforms, enter/exit, controller updates) runs inside the physics
|
|
283
296
|
world's before-step hook, then the world steps — never in the render loop;
|
|
@@ -287,9 +300,12 @@ A routed Genex scene is incomplete until it exposes:
|
|
|
287
300
|
|
|
288
301
|
**Publishing IS calling it done.** Before `npx genex publish`, every completion
|
|
289
302
|
gate above must pass — sprite HUD wired, Escape pause working, branded loader
|
|
290
|
-
with its key art, fonts loaded, renderer baseline + one built post effect
|
|
291
|
-
|
|
292
|
-
|
|
303
|
+
with its key art, fonts loaded, renderer baseline + one built post effect
|
|
304
|
+
(tier-aware), the adaptive-quality tier wired at boot, world dressing placed
|
|
305
|
+
or validly waived, and the content contract's countables present or
|
|
306
|
+
explicitly re-scoped by the user. `genex preview`/`publish` print a mobile
|
|
307
|
+
preflight (estimated phone GPU memory vs budget) — treat a warning there as a
|
|
308
|
+
gate item too. If any is still
|
|
293
309
|
pending, say which and publish only after an explicit go-ahead.
|
|
294
310
|
|
|
295
311
|
Do not invent unavailable Genex service APIs. When preparing a game for Genex
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Use this reference for a large, unbounded-looking ocean whose identity comes from directional spectral synthesis, staged inverse FFTs, derivative maps, Jacobian whitecaps, and coherent optical shading.
|
|
4
4
|
|
|
5
|
-
> **Renderer note:** this reference assumes `WebGPURenderer` + TSL node materials. Check the project's actual renderer first — the Genex scaffold ships vanilla WebGL three.js. On WebGL, adapt the technique with standard materials / `EffectComposer` passes or pick a simpler alternative; never switch renderers mid-project.
|
|
5
|
+
> **Renderer note:** this reference assumes `WebGPURenderer` + TSL node materials. Check the project's actual renderer first — the Genex scaffold ships vanilla WebGL three.js. On WebGL, adapt the technique with standard materials / `EffectComposer` passes or pick a simpler alternative; never switch renderers mid-project. Either way the effect obeys the device tier (`$genex-threejs-adaptive-quality`): expensive passes are desktop-tier, and on WebGPU the per-target MSAA sample count is a runtime knob the governor may drive.
|
|
6
6
|
|
|
7
7
|
## Contents
|
|
8
8
|
|
|
@@ -75,6 +75,10 @@ Pick what matches the game; most games need exactly one or two of these.
|
|
|
75
75
|
lives on the stick; the static circle is fine for slower games. On the
|
|
76
76
|
bundled character controller, pass it through instead — see
|
|
77
77
|
`$genex-threejs-character-controller` (`joystick: { x: joy.x, y: joy.y }`).
|
|
78
|
+
Touch axes obey the same screen-direction contract as WASD and the mouse
|
|
79
|
+
(`$genex-threejs-camera-direction`): stick-right must move the player
|
|
80
|
+
screen-right, drag-right must turn the view right — a flipped feel is a sign
|
|
81
|
+
bug in the mapping, never a device quirk.
|
|
78
82
|
- **Camera look → drag zone on the right half.** Default `DragZone()` is
|
|
79
83
|
exactly that; per frame `const { dx, dy } = look.consumeDelta()` then apply
|
|
80
84
|
to yaw/pitch with the same sensitivity scale as the mouse path. Games on the
|
|
@@ -149,6 +153,13 @@ z-order stays: drag zone (5) under joystick/buttons (10) under pause menus.
|
|
|
149
153
|
canvas. If the game also needs taps there (tap to shoot), read them from the
|
|
150
154
|
zone (`onChange` + a small-movement threshold) or shrink the zone.
|
|
151
155
|
|
|
156
|
+
## Input is half of phone-playable
|
|
157
|
+
|
|
158
|
+
This skill is INPUT only. A phone that can steer a game that then runs out of
|
|
159
|
+
GPU memory still loses the player — the rendering half (device tiers, DPR and
|
|
160
|
+
shadow budgets, the runtime governor, per-tier asset rungs) lives in
|
|
161
|
+
`$genex-threejs-adaptive-quality` and is wired at boot for every game.
|
|
162
|
+
|
|
152
163
|
## When you skip
|
|
153
164
|
|
|
154
165
|
Say it in one plain line — *"skipped touch controls: the game is
|
|
@@ -212,6 +212,13 @@ aim" cue stays up, and the next gesture (a click OR any keypress — the walk ke
|
|
|
212
212
|
count) re-locks automatically. So it recovers on its own; just don't expect the lock
|
|
213
213
|
back on the exact exit frame. Vehicle cameras keep their `alignHeading` behavior.
|
|
214
214
|
|
|
215
|
+
If the game also has a menu phase (most do), fold both signals into ONE derived
|
|
216
|
+
boolean recomputed from `setPhase` AND `onHandoff` —
|
|
217
|
+
`followCam.setPaused(phase !== "playing" || activeId !== CHARACTER_ID)` — so
|
|
218
|
+
neither wiring overwrites the other's pause. Both call sites fire on real
|
|
219
|
+
transitions only; `setPaused` is idempotent, so an occasional repeated value is
|
|
220
|
+
harmless (but never drive it from the render loop).
|
|
221
|
+
|
|
215
222
|
## Multiplayer
|
|
216
223
|
|
|
217
224
|
Occupancy uses confirmed object ownership — remote players must see who is in what. With
|