@genex-ai/cli-demo 0.78.0-dev.200 → 0.80.0-dev.211
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/templates/README.md +1 -1
- package/templates/controllers/quality/pick-asset.ts +12 -7
- package/templates/skills/genex-ai-character/SKILL.md +2 -4
- package/templates/skills/genex-ai-hud/SKILL.md +69 -23
- package/templates/skills/genex-ai-menu/SKILL.md +17 -12
- package/templates/skills/genex-ai-model/SKILL.md +58 -7
- package/templates/skills/genex-game-director/SKILL.md +265 -0
- package/templates/skills/genex-game-director/references/design-contract.md +148 -0
- package/templates/skills/{genex-threejs-skill-router → genex-game-director}/references/routing-map.md +82 -63
- package/templates/skills/genex-getting-started/SKILL.md +3 -2
- package/templates/skills/genex-threejs-adaptive-quality/SKILL.md +23 -8
- package/templates/skills/genex-threejs-adaptive-quality/references/adaptive-quality.md +16 -4
- package/templates/skills/genex-threejs-character-controller/SKILL.md +2 -4
- package/templates/skills/genex-threejs-embed-auth/SKILL.md +6 -48
- package/templates/skills/genex-threejs-game-content/SKILL.md +3 -4
- package/templates/skills/genex-threejs-game-ui/SKILL.md +95 -76
- package/templates/skills/genex-threejs-game-ui/references/style-capsules.md +9 -5
- package/templates/skills/genex-threejs-lighting-design/SKILL.md +7 -0
- package/templates/skills/genex-threejs-multiplayer/SKILL.md +1 -2
- package/templates/skills/genex-threejs-visual-validation/SKILL.md +2 -4
- package/templates/skills/genex-threejs-skill-router/SKILL.md +0 -263
|
@@ -112,11 +112,13 @@ and `$genex-ai-texture` skills show the wiring in place.
|
|
|
112
112
|
|
|
113
113
|
## Generated models: load through the rungs
|
|
114
114
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
115
|
+
Provider-raw GLBs are NOT game assets: one prop is ~500k triangles + several
|
|
116
|
+
4K PBR textures (a pilot scene of them submitted 66M triangles/frame and
|
|
117
|
+
floored an M4 Max). Every model ships a game-ready ladder — `@2048` (the
|
|
118
|
+
desktop rung) and `@1024` (the phone rung), both meshopt-compressed and
|
|
119
|
+
simplified where safe, each with a `.ktx2` sibling whose textures stay
|
|
118
120
|
compressed ON the GPU (~6× less texture VRAM). A plain `GLTFLoader` can decode
|
|
119
|
-
|
|
121
|
+
none of them — wire the decoders once and load through the ladder:
|
|
120
122
|
|
|
121
123
|
```ts
|
|
122
124
|
import { createGltfLoader } from "./controllers/quality/gltf-loader.ts";
|
|
@@ -126,11 +128,24 @@ const gltfLoader = createGltfLoader(renderer); // meshopt always; KTX2 when the
|
|
|
126
128
|
const gltf = await loadModelWithFallback(
|
|
127
129
|
MODEL_URL, tier, (u) => gltfLoader.loader.loadAsync(u), { ktx2: gltfLoader.ktx2 },
|
|
128
130
|
);
|
|
131
|
+
// Provider PBR sometimes ships mirror-metal (metalness~1 + near-zero roughness)
|
|
132
|
+
// that reflects the sky env and swims with camera motion. Tame ONLY that extreme
|
|
133
|
+
// — do NOT flatten every material to 0.6 (it dulls legitimately metallic props):
|
|
134
|
+
gltf.scene.traverse((o) => {
|
|
135
|
+
const m = (o as THREE.Mesh).material as THREE.MeshStandardMaterial;
|
|
136
|
+
if (!m?.isMeshStandardMaterial) return;
|
|
137
|
+
if (m.metalness > 0.85 && m.roughness < 0.2) {
|
|
138
|
+
m.metalness = 0.7;
|
|
139
|
+
m.roughness = Math.max(m.roughness, 0.3);
|
|
140
|
+
}
|
|
141
|
+
m.envMapIntensity = Math.min(m.envMapIntensity, 0.8);
|
|
142
|
+
});
|
|
129
143
|
```
|
|
130
144
|
|
|
131
|
-
Fallback chain: `.ktx2` rung → universal `@
|
|
132
|
-
|
|
133
|
-
|
|
145
|
+
Fallback chain: `.ktx2` rung → the tier's universal rung (`@2048` desktop,
|
|
146
|
+
`@1024` phones) → original — each step warns; the original is archival/remix
|
|
147
|
+
source, fetched only as the fallback of last resort. Meshy characters take
|
|
148
|
+
the same ladder through
|
|
134
149
|
`loadMeshyCharacter(manifestUrl, { loader: gltfLoader.loader, modelUrlCandidates: (u) => [pickModel(u, tier, { ktx2: gltfLoader.ktx2 }), pickModel(u, tier), u] })`.
|
|
135
150
|
KTX2-capable games can also pass `ktx2Load` to `loadTextureWithFallback` so
|
|
136
151
|
skyboxes/textures use their `.ktx2` variants.
|
|
@@ -149,7 +164,7 @@ not the player's account. Default Auto.
|
|
|
149
164
|
at most 2 cascades on phones (`$genex-threejs-shadow-systems`).
|
|
150
165
|
- Post: phone floor is a BUILT tone-mapping/output pass (`postLevel: 'light'`
|
|
151
166
|
adds FXAA/vignette); SSAO, volumetrics, and DoF are desktop-tier only
|
|
152
|
-
(`$genex-
|
|
167
|
+
(`$genex-game-director`'s routing map owns the floor wording).
|
|
153
168
|
- Particles/scatter: multiply counts by `tier.particleScale`; render heavy
|
|
154
169
|
transparency at half resolution and upsample.
|
|
155
170
|
- Animation: distant mixers update at 1/2–1/4 rate; multiplayer remotes above
|
|
@@ -22,7 +22,7 @@ cost of guessing high is a dead page.
|
|
|
22
22
|
| Shadow map | 512 (static-cached) | 1024 | 1024 | 2048 |
|
|
23
23
|
| Post level | tone map only | + FXAA/vignette | + FXAA/vignette | full named stack |
|
|
24
24
|
| Skybox rung | @2048 (~11 MB) | @4096 (~45 MB) | original | original |
|
|
25
|
-
| Model rung | @1024 (+.ktx2 when wired) | @1024 (+.ktx2 when wired) |
|
|
25
|
+
| Model rung | @1024 (+.ktx2 when wired) | @1024 (+.ktx2 when wired) | @2048 (+.ktx2) | @2048 (+.ktx2) |
|
|
26
26
|
| Texture rung (props) | @1024 | @2048 | original | original |
|
|
27
27
|
| Particles/scatter | 0.25× | 0.5× | 0.75× | 1× |
|
|
28
28
|
| Draw distance | 0.5× | 0.75× | 1× | 1× |
|
|
@@ -69,6 +69,12 @@ Getting this wrong produces silent no-ops or a session stuck ugly:
|
|
|
69
69
|
fog, LOD bias, particle counts, mixer update rates, frame cap, remote-avatar
|
|
70
70
|
animation count. Light `intensity` is runtime-free; light COUNT is not (see
|
|
71
71
|
above).
|
|
72
|
+
- **Shadow maps of STATIC lights render once, not per frame:** shadow maps
|
|
73
|
+
default to re-rendering every frame, and a PointLight's is a 6-face cube —
|
|
74
|
+
four static shadow lanterns = 24 redundant passes/frame over the whole
|
|
75
|
+
caster set (measured 66M submitted triangles/frame in a pilot). Freeze them:
|
|
76
|
+
`light.shadow.autoUpdate = false; light.shadow.needsUpdate = true;` — only
|
|
77
|
+
the key light that shadows moving actors stays dynamic.
|
|
72
78
|
|
|
73
79
|
## Governor mechanics
|
|
74
80
|
|
|
@@ -113,9 +119,15 @@ Getting this wrong produces silent no-ops or a session stuck ugly:
|
|
|
113
119
|
- Watch `renderer.info.memory.{textures,geometries}` across swaps in dev; a
|
|
114
120
|
monotonic climb is a leak marching toward the OS kill. The governor
|
|
115
121
|
publishes these counts for the platform's field telemetry.
|
|
116
|
-
- Prefer meshopt/instanced geometry for repeats
|
|
117
|
-
|
|
118
|
-
|
|
122
|
+
- Prefer meshopt/instanced geometry for repeats: 3+ copies of the same
|
|
123
|
+
generated model → `InstancedMesh` (one draw call per source mesh instead of
|
|
124
|
+
per copy — `$genex-ai-model` has the collapse snippet); `BatchedMesh`
|
|
125
|
+
batches HETEROGENEOUS static meshes into one draw where instancing
|
|
126
|
+
(identical meshes only) can't.
|
|
127
|
+
- Distance LOD comes free with the rung ladder: `THREE.LOD` with the phone
|
|
128
|
+
rung (`@1024`) as the far level — `lod.addLevel(near, 0);
|
|
129
|
+
lod.addLevel(far, 25)`. One extra fetch; worth it past ~25 m sightlines,
|
|
130
|
+
skip in small arenas.
|
|
119
131
|
- Half-resolution transparency: render heavy particle/transparency passes to a
|
|
120
132
|
half-size target and composite up — fill-rate is the phone bottleneck.
|
|
121
133
|
|
|
@@ -57,10 +57,8 @@ Meshy Image-to-3D first produces an unremeshed high-detail model. Show its
|
|
|
57
57
|
front, back, left, and right views and report its measured face count. Preserve
|
|
58
58
|
that model in R2. Before rigging, ask the user to approve a separate
|
|
59
59
|
10,000-face triangle remesh. The 10k remesh—not the high-detail source—is
|
|
60
|
-
rigged and animated. (For these approvals, use your
|
|
61
|
-
|
|
62
|
-
`request_user_input`; if it has none, e.g. Cursor, a short numbered list in
|
|
63
|
-
chat.)
|
|
60
|
+
rigged and animated. (For these approvals, use your question tool when you
|
|
61
|
+
have one; if you have none, a short numbered list in chat.)
|
|
64
62
|
|
|
65
63
|
That is a separate, **same-rig Meshy-native lane**. Its animation-only GLBs are
|
|
66
64
|
accepted only when their skeleton signature matches the active character
|
|
@@ -34,26 +34,19 @@ Guest sessions have **no** overlay — the game just plays.
|
|
|
34
34
|
## Install
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
npm i @genex-ai/embed-sdk
|
|
37
|
+
npm i @genex-ai/embed-sdk
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
(
|
|
41
|
-
|
|
42
|
-
installed if you followed Step 3 of the scaffold; repeated here so this skill
|
|
43
|
-
is self-contained.)
|
|
40
|
+
(Already installed if you followed Step 3 of the scaffold; repeated here so
|
|
41
|
+
this skill is self-contained.)
|
|
44
42
|
|
|
45
43
|
## Bootstrap (required, every game)
|
|
46
44
|
|
|
47
45
|
```ts
|
|
48
|
-
// main.ts — the FIRST
|
|
49
|
-
import { initGameSentry } from "@genex-ai/embed-sdk/sentry";
|
|
46
|
+
// main.ts — the FIRST thing in the boot sequence, before any other game code
|
|
50
47
|
import { initEmbed } from "@genex-ai/embed-sdk";
|
|
51
48
|
import { GENEX } from "./genex.config";
|
|
52
49
|
|
|
53
|
-
// Crash reporting + session replay FIRST — so even a failure inside the auth
|
|
54
|
-
// boot below gets reported. One required field; never pass tokens to it.
|
|
55
|
-
initGameSentry({ slug: GENEX.slug });
|
|
56
|
-
|
|
57
50
|
initEmbed({
|
|
58
51
|
slug: GENEX.slug,
|
|
59
52
|
apiUrl: GENEX.apiUrl,
|
|
@@ -153,29 +146,6 @@ Server write limits (per player, per minute): **60 player-saves, 120
|
|
|
153
146
|
world-saves, 30 score submits**. A debounced ~1/sec checkpoint never gets near
|
|
154
147
|
them — only a save-per-frame loop does (it surfaces as HTTP 429).
|
|
155
148
|
|
|
156
|
-
From `@genex-ai/embed-sdk/sentry` (crash reporting; exactly these two):
|
|
157
|
-
|
|
158
|
-
- `initGameSentry({ slug, dsn?, environment? })` — call once, BEFORE
|
|
159
|
-
`initEmbed()`. Only `slug` is required; the shared Genex Sentry project DSN
|
|
160
|
-
is built in. Errors, tracing, and session replay all start here; the current
|
|
161
|
-
player (account or guest) is attached automatically (no code needed).
|
|
162
|
-
- `sentryCanvasSnapshot(canvas)` — session replay records the DOM, not the 3D
|
|
163
|
-
canvas; call this once per frame at the END of the render loop so replays
|
|
164
|
-
show actual gameplay. Works for BOTH WebGL and WebGPU renderers; internally
|
|
165
|
-
throttled, so calling at 60fps is fine. On TOUCH devices it is a deliberate
|
|
166
|
-
no-op (and session replay/tracing sample down): each capture is a full-canvas
|
|
167
|
-
GPU readback, exactly the overhead phones get memory-killed for — mobile
|
|
168
|
-
replays are DOM-only by design, on-error replays still record everywhere:
|
|
169
|
-
|
|
170
|
-
```ts
|
|
171
|
-
function animate() {
|
|
172
|
-
requestAnimationFrame(animate);
|
|
173
|
-
// ...game update...
|
|
174
|
-
renderer.render(scene, camera);
|
|
175
|
-
sentryCanvasSnapshot(renderer.domElement); // AFTER render, same frame
|
|
176
|
-
}
|
|
177
|
-
```
|
|
178
|
-
|
|
179
149
|
## Saving progress (per-player — every player has their own slot)
|
|
180
150
|
|
|
181
151
|
Use the SDK helpers; never hand-roll fetch calls to the state API. Progression,
|
|
@@ -224,16 +194,6 @@ their Genex account) and keep-best — submitting a worse score changes nothing
|
|
|
224
194
|
post when they sign in. Send a consistent `mode` per board. Scores are
|
|
225
195
|
client-reported (arcade-style trust) — don't present them as anti-cheat.
|
|
226
196
|
|
|
227
|
-
## Crash reporting rules
|
|
228
|
-
|
|
229
|
-
- `initGameSentry` has token scrubbing built in (the sign-in return-trip pass
|
|
230
|
-
in URLs is redacted automatically). Never wrap, reimplement, or bypass it —
|
|
231
|
-
and never add Sentry options that capture network request/response bodies.
|
|
232
|
-
- Don't call `Sentry.init` yourself or add a second error reporter —
|
|
233
|
-
`initGameSentry` is the one entry point.
|
|
234
|
-
- Manual capture is fine where a try/catch swallows a real bug:
|
|
235
|
-
`import * as Sentry from "@sentry/browser"; Sentry.captureException(err)`.
|
|
236
|
-
|
|
237
197
|
## NEVER log the tokens
|
|
238
198
|
|
|
239
199
|
**NEVER log the return value of `getEmbedToken()` or `getColyseusAuth()` — not
|
|
@@ -328,10 +288,8 @@ Rules:
|
|
|
328
288
|
|
|
329
289
|
## Checklist
|
|
330
290
|
|
|
331
|
-
- [ ] `
|
|
332
|
-
|
|
333
|
-
- [ ] `sentryCanvasSnapshot(renderer.domElement)` runs after `renderer.render()`
|
|
334
|
-
in the main loop (WebGL and WebGPU alike).
|
|
291
|
+
- [ ] `initEmbed(...)` is the very first call in `main.ts`, with all three
|
|
292
|
+
config fields.
|
|
335
293
|
- [ ] `genex.config.ts` includes `dashboardOrigins` (from `.genex/project.json`).
|
|
336
294
|
- [ ] Multiplayer and player-name UI await `waitForPlayer()` — NEVER
|
|
337
295
|
`waitForAuth()` (guests would hang forever). Both `connect()` and
|
|
@@ -48,11 +48,10 @@ Rules that make the contract real:
|
|
|
48
48
|
- **Scope belongs to the user.** Building a small first slice is the right
|
|
49
49
|
ORDER (`$genex-threejs-game-ui`'s v0 beat still applies) — but the slice is
|
|
50
50
|
a milestone on the way to the contract, never a quiet replacement for it.
|
|
51
|
-
If the full ask genuinely doesn't fit, shrinking any line is a
|
|
51
|
+
If the full ask genuinely doesn't fit, shrinking any line is a
|
|
52
52
|
question to the user with real options — never a silent cut justified as
|
|
53
|
-
"standard practice". (Use your
|
|
54
|
-
|
|
55
|
-
if it has none, e.g. Cursor, a short numbered list in chat.)
|
|
53
|
+
"standard practice". (Use your question tool when you have one; if you
|
|
54
|
+
have none, a short numbered list in chat.)
|
|
56
55
|
- **Minute ten is the design test.** If the honest answer is "the same sixty
|
|
57
56
|
seconds, again", the contract needs another beat (a new area unlocks, a
|
|
58
57
|
quest chain escalates, a build comes online) before any polish work.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: genex-threejs-game-ui
|
|
3
|
-
description: Design the
|
|
3
|
+
description: Design the UI HUD interface of a Genex Three.js game — plan the full screen set up front (loader, menu, HUD, pause/win/lose, lobby) under one shared art direction, then build it as an animated DOM overlay. Use for every new game before writing UI code, and whenever the game needs on-screen text, meters, buttons, or menus, or the interface reads as a generic dashboard, covers the action, or shifts as numbers change.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Genex Three.js Game UI
|
|
@@ -43,10 +43,7 @@ The table lists screens; **elements are inventoried separately**. Walk the
|
|
|
43
43
|
whole loop in your head — loader → menu → spawn → action → pickup → damage →
|
|
44
44
|
death → retry → win — and write down EVERY on-screen element the player will
|
|
45
45
|
ever see: the reticle and each of its states, aim/interact cues, toasts,
|
|
46
|
-
damage numbers, kill feeds, timers, countdowns, pickup popups
|
|
47
|
-
gets a treatment from the brief. **Nothing ships looking like default
|
|
48
|
-
browser CSS** — an element styled like a bare `<div>` or a system button is
|
|
49
|
-
a bug wherever it appears, listed or not.
|
|
46
|
+
damage numbers, kill feeds, timers, countdowns, pickup popups.
|
|
50
47
|
|
|
51
48
|
**2. One shared style brief — for the WHOLE game, not just the UI.** Write it
|
|
52
49
|
once — 4–5 named hues, materials, one display + one body font, mood — and
|
|
@@ -61,17 +58,12 @@ is LOADED for real — a Google Fonts `<link>` (or `@font-face`) in
|
|
|
61
58
|
ships as a system-stack fallback (`Arial Black`, `Impact`) is the same bug in
|
|
62
59
|
type.
|
|
63
60
|
|
|
64
|
-
**3.
|
|
65
|
-
[references/style-capsules.md](references/style-capsules.md), name 2–3 top
|
|
66
|
-
AAA games of the genre, and state in one line which structural conventions
|
|
67
|
-
you're borrowing. The bar is what those games ship, not "good enough for a
|
|
68
|
-
demo". Conventions only — never logos, exact layouts, or trade dress. The
|
|
69
|
-
same 2–3 names carry into the router's visual-direction gate for the scene.
|
|
70
|
-
Then turn references + brief into ONE **concept mockup** — the game concept
|
|
61
|
+
**3. Make ONE concept mockup** — the game concept
|
|
71
62
|
and the HUD Stage-1 mockup are the SAME image, generated once (never a
|
|
72
63
|
separate UI-free concept first): a single image of a PLAYABLE MOMENT of this
|
|
73
64
|
game with its complete HUD composited over it, built with `$genex-ai-hud`'s
|
|
74
|
-
Stage-1 prompt template.
|
|
65
|
+
Stage-1 prompt template. For genre conventions to borrow, skim
|
|
66
|
+
[references/style-capsules.md](references/style-capsules.md). The scene half of the prompt comes from the game
|
|
75
67
|
contract in TEXT, not from a prior image: what the player is DOING
|
|
76
68
|
mid-action (the verb), what threatens them right now (enemy silhouettes),
|
|
77
69
|
what they are chasing (the objective — a finish gate, a goal, a pickup),
|
|
@@ -82,44 +74,63 @@ game doesn't have (a lap counter in a game without laps). Generate it
|
|
|
82
74
|
`--size 2560x1440 --quality high --candidates 2 --no-wait`, enqueued FIRST
|
|
83
75
|
of all art; the picked candidate's URL goes into the style-brief comment.
|
|
84
76
|
|
|
85
|
-
**
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
`--
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
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" rule — the 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, items — their 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.)
|
|
116
|
+
|
|
117
|
+
**Change reopens the loop, same shape.** If the user picks "change" — or
|
|
118
|
+
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.
|
|
123
134
|
|
|
124
135
|
**The concept anchors STYLE, not truth.** Palette, materials, light, and
|
|
125
136
|
register come from the frame; CONTENT comes from the game contract. This
|
|
@@ -136,11 +147,10 @@ an invented mechanic, or the absence of a real one, from a picture.
|
|
|
136
147
|
|
|
137
148
|
**4. Ask only when genuinely ambiguous.** If the concept pins the mood (a
|
|
138
149
|
"gothic horror dungeon crawler" pins it), decide and state the plan in one
|
|
139
|
-
line. Only when the art direction is truly open, ask ONE
|
|
150
|
+
line. Only when the art direction is truly open, ask ONE question
|
|
140
151
|
with 2–3 concrete directions, each naming its palette + font pair — using
|
|
141
|
-
your
|
|
142
|
-
|
|
143
|
-
Cursor), a short numbered list in chat. Never ask about the screen
|
|
152
|
+
your question tool when you have one; if you have none, a short numbered
|
|
153
|
+
list in chat. Never ask about the screen
|
|
144
154
|
inventory — it derives from the game type.
|
|
145
155
|
|
|
146
156
|
**5. Style follows THIS game's concept.** The examples in every Genex skill
|
|
@@ -158,9 +168,11 @@ UI plan
|
|
|
158
168
|
• Style: <4–5 named hues> · fonts <display> / <body>
|
|
159
169
|
• References: <2–3 AAA games — one line on what's borrowed>
|
|
160
170
|
• Menu: <archetype + button treatment, one-line reason from the brief>
|
|
161
|
-
• Concept (HUD mockup): <generation id — 2 candidates>
|
|
162
|
-
• Queued
|
|
163
|
-
video <or "no menu: reason"> · logotype <or
|
|
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">
|
|
175
|
+
• Building now (style-independent): <core loop · logic modules already moving>
|
|
164
176
|
• Deferred from mockup: <widgets the image invented but the game lacks — or "none">
|
|
165
177
|
```
|
|
166
178
|
|
|
@@ -178,7 +190,8 @@ A message missing any line means the gate did not run — go back and run it.
|
|
|
178
190
|
every game), and the generated **logotype** — one `--transparent` wordmark
|
|
179
191
|
in the brief's display register (`$genex-ai-menu`'s logotype step), default
|
|
180
192
|
YES for every game with a menu; skipping it needs a one-line stated reason.
|
|
181
|
-
Enqueue
|
|
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
|
|
182
195
|
keep building, pick results up with `npx genex wait <id>`, swap them in as
|
|
183
196
|
they land. **Tier 2 must never block a playable v0 — but the game is NOT
|
|
184
197
|
DONE until its Tier-2 assets have landed and been wired in** (the only
|
|
@@ -441,19 +454,18 @@ Order the HUD by what the player loses the game for ignoring:
|
|
|
441
454
|
- **Contrast against the real scene.** Test text over the brightest AND
|
|
442
455
|
darkest areas of actual gameplay; a soft dark plate or text-shadow beats
|
|
443
456
|
restyling per level.
|
|
444
|
-
- **
|
|
445
|
-
`clip-path
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
`genex ui` masks remain the other established uses of `mask`/`clip-path`.
|
|
457
|
+
- **Panel and button corners come from `border-radius` or a generated frame
|
|
458
|
+
sprite — never a raw `clip-path`/`mask` chamfer.** A CSS-cut angular corner
|
|
459
|
+
is the recurring "cut corners" defect: the clip shears off borders, shadows,
|
|
460
|
+
and any content that sits near the corner, and it re-breaks the instant the
|
|
461
|
+
padding, font, or value length changes — so it can only be held together by
|
|
462
|
+
a per-build visual check that is easy to skip. It is not worth that fragility.
|
|
463
|
+
For a soft corner use `border-radius` (it keeps its `border`/`box-shadow`
|
|
464
|
+
natively). For a genuinely angular or ornamented "hi-tech" frame, generate it
|
|
465
|
+
as chrome (`$genex-ai-hud`, or a Tier-3 9-slice panel) and lay the DOM over
|
|
466
|
+
it — that reads richer and physically cannot shear. `mask`/`clip-path` stay
|
|
467
|
+
reserved for their ONE established HUD use: the masked-fill progress reveal
|
|
468
|
+
driven by `genex ui` masks. Never for corner shaping.
|
|
457
469
|
- **One cohesion layer.** A single full-screen vignette div (a subtle radial
|
|
458
470
|
gradient darkening the corners, optionally faint grain) over canvas + UI is
|
|
459
471
|
the cheapest way to make DOM-over-WebGL read as one composed image instead
|
|
@@ -510,12 +522,19 @@ architecture and consume the shared style brief.
|
|
|
510
522
|
- Hard-cut phase swaps, a menu whose elements just appear, numbers that
|
|
511
523
|
teleport.
|
|
512
524
|
- A silent menu; a bare "Loading…" over black.
|
|
513
|
-
-
|
|
514
|
-
|
|
515
|
-
|
|
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.
|
|
516
530
|
- A CSS-cut corner (`clip-path`/`mask`) that shears its own content — clipped
|
|
517
|
-
text or padding, a lost focus ring or glow, a jagged aliased edge
|
|
531
|
+
text or padding, a lost focus ring or glow, a jagged aliased edge, or a
|
|
532
|
+
border/frame that stops at the cut instead of following it — the
|
|
518
533
|
technique is fine; the sloppy cut is the defect.
|
|
534
|
+
- A rectangular semi-transparent plate protruding past an opaque/angular
|
|
535
|
+
widget frame — a dark box floating over the scene. The frame's own art is
|
|
536
|
+
the backing; a plate is only for bare-text/outline widgets and stays inside
|
|
537
|
+
the widget silhouette (`$genex-ai-hud`'s plate rule).
|
|
519
538
|
- UI panels covering the player or the thing about to kill them.
|
|
520
539
|
- Layout shifting as numbers grow.
|
|
521
540
|
- A fail state with no visible restart key, or a restart that reloads the page.
|
|
@@ -9,11 +9,15 @@ the capsule says a racing HUD leans oblique and bottom-right-heavy; your brief
|
|
|
9
9
|
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
|
-
UI, one display + one body font, tabular numerals, contrast plates
|
|
13
|
-
arbitrary scenes
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
UI, one display + one body font, tabular numerals, contrast plates for bare
|
|
13
|
+
text over arbitrary scenes (never a second plate stacked behind an opaque
|
|
14
|
+
frame sprite), and panel/button corners done the durable way — `border-radius`
|
|
15
|
+
for soft corners (it keeps its `border`/`box-shadow` natively), or a generated
|
|
16
|
+
frame (`$genex-ai-hud` chrome / a Tier-3 9-slice panel) with the DOM laid over
|
|
17
|
+
it for genuinely angular looks. Raw CSS `clip-path`/`mask` corner cuts are
|
|
18
|
+
banned per the skill — they shear borders, shadows, and near-corner content,
|
|
19
|
+
and re-break on any padding/font change; `mask`/`clip-path` stay reserved for
|
|
20
|
+
their ONE established HUD use, the masked-fill progress reveal.
|
|
17
21
|
|
|
18
22
|
## Fantasy / action RPG
|
|
19
23
|
|
|
@@ -111,6 +111,13 @@ kill-switch diagnostic.
|
|
|
111
111
|
legitimate time the population changes.
|
|
112
112
|
- Couple a practical to its emitter: one color, one envelope, one on/off state.
|
|
113
113
|
- The key owns shadows; practicals cast none until a shot proves they must.
|
|
114
|
+
- **A shadow-casting practical that never moves gets a FROZEN map**: a
|
|
115
|
+
PointLight shadow is a 6-face cube render, re-drawn every frame by default —
|
|
116
|
+
four static lanterns cost 24 shadow passes/frame over your densest props for
|
|
117
|
+
zero visual change (a pilot game submitted 66M triangles/frame this way).
|
|
118
|
+
Set `light.shadow.autoUpdate = false; light.shadow.needsUpdate = true;` so
|
|
119
|
+
the cube renders once; keep only the key (which shadows the movers) dynamic,
|
|
120
|
+
and budget frozen practicals at ≤1024 map size.
|
|
114
121
|
- Tune intensities only after the renderer baseline is locked — retuning the
|
|
115
122
|
whole rig after a tone-mapping change is self-inflicted.
|
|
116
123
|
- Never repair unbalanced light ratios with exposure — fix the lights.
|
|
@@ -67,8 +67,7 @@ Infer this yourself when the experience is clear. Do **not** make the player cho
|
|
|
67
67
|
preset, or config. Ask one plain-language question only when the design genuinely supports both
|
|
68
68
|
models and the answer changes the experience — for example: *"Should this be one ongoing arena
|
|
69
69
|
people drop into, or a fresh fair match that waits for everyone and then starts together?"*
|
|
70
|
-
(Use your
|
|
71
|
-
`AskUserQuestion`; Codex: `request_user_input`; if it has none, e.g. Cursor, a short numbered
|
|
70
|
+
(Use your question tool when you have one; if you have none, a short numbered
|
|
72
71
|
list in chat.)
|
|
73
72
|
|
|
74
73
|
| Player experience | Model | Why |
|
|
@@ -40,10 +40,8 @@ Meshy Image-to-3D first produces an unremeshed high-detail model. Show its
|
|
|
40
40
|
front, back, left, and right views and report its measured face count. Preserve
|
|
41
41
|
that model in R2. Before rigging, ask the user to approve a separate
|
|
42
42
|
10,000-face triangle remesh. The 10k remesh—not the high-detail source—is
|
|
43
|
-
rigged and animated. (For these approvals, use your
|
|
44
|
-
|
|
45
|
-
`request_user_input`; if it has none, e.g. Cursor, a short numbered list in
|
|
46
|
-
chat.)
|
|
43
|
+
rigged and animated. (For these approvals, use your question tool when you
|
|
44
|
+
have one; if you have none, a short numbered list in chat.)
|
|
47
45
|
|
|
48
46
|
The selected high-detail model remains in a neutral A-pose before animation.
|
|
49
47
|
Record evidence that the user saw its four views and face count before
|