@genex-ai/cli-demo 1.31.1 → 1.32.0-dev.650
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 +18 -0
- package/dist/blender-mcp-Q6PSFYSE.js +241 -0
- package/dist/blender-serve-BF4FZ55Z.js +244 -0
- package/dist/chunk-2COG4P3T.js +968 -0
- package/dist/chunk-HYCSNWYX.js +126 -0
- package/dist/index.js +4759 -2830
- package/package.json +3 -3
- package/templates/blender-service/demo/castle.py +117 -0
- package/templates/blender-service/gpu_witness.py +245 -0
- package/templates/blender-service/ops.py +225 -0
- package/templates/blender-service/pool.py +910 -0
- package/templates/blender-service/server.py +611 -0
- package/templates/blender-service/supervisor.py +221 -0
- package/templates/blender-service/views.py +281 -0
- package/templates/controllers/character/follow-camera.ts +16 -1
- package/templates/controllers/character/meshy/meshy-loader.ts +3 -2
- package/templates/controllers/quality/deadline.ts +117 -0
- package/templates/controllers/quality/pick-asset.ts +49 -16
- package/templates/controllers/shared/physics-world.ts +6 -4
- package/templates/skills/genex-ai-character/SKILL.md +77 -15
- package/templates/skills/genex-ai-menu/SKILL.md +15 -11
- package/templates/skills/genex-ai-model/SKILL.md +45 -7
- package/templates/skills/genex-ai-texture/SKILL.md +1 -1
- package/templates/skills/genex-ai-video/SKILL.md +75 -17
- package/templates/skills/genex-blender-scene/SKILL.md +243 -0
- package/templates/skills/genex-game-director/SKILL.md +112 -46
- package/templates/skills/genex-game-director/references/design-contract.md +13 -5
- package/templates/skills/genex-game-director/references/routing-map.md +30 -45
- package/templates/skills/genex-getting-started/SKILL.md +2 -2
- package/templates/skills/genex-lane-card/SKILL.md +78 -0
- package/templates/skills/genex-threejs-adaptive-quality/SKILL.md +21 -0
- package/templates/skills/genex-threejs-character-controller/SKILL.md +17 -5
- package/templates/skills/genex-threejs-creatures/SKILL.md +8 -1
- package/templates/skills/genex-threejs-embed-auth/SKILL.md +8 -0
- package/templates/skills/genex-threejs-game-ui/SKILL.md +55 -6
- package/templates/skills/genex-threejs-procedural-assets/SKILL.md +17 -10
- package/templates/skills/genex-threejs-visual-validation/SKILL.md +12 -2
- package/templates/skills/genex-tool-audio/SKILL.md +3 -2
- package/templates/skills/genex-tool-character/SKILL.md +36 -5
- package/templates/skills/genex-tool-image/SKILL.md +4 -2
- package/templates/skills/genex-tool-model/SKILL.md +32 -6
- package/templates/skills/genex-tool-publish/SKILL.md +100 -0
- package/templates/skills/genex-tool-texture/SKILL.md +1 -1
- package/templates/skills/genex-tool-video/SKILL.md +28 -5
- package/templates/skills/genex-tool-workflow/SKILL.md +4 -1
- package/templates/skills/genex-updates/SKILL.md +1 -1
|
@@ -161,7 +161,7 @@ downloads the game too, binary assets and all:
|
|
|
161
161
|
|
|
162
162
|
```bash
|
|
163
163
|
mkdir my-game && cd my-game
|
|
164
|
-
npx @genex-ai/cli-demo@
|
|
164
|
+
npx @genex-ai/cli-demo@dev link <slug> # slug = the name in the play URL
|
|
165
165
|
npm install
|
|
166
166
|
```
|
|
167
167
|
|
|
@@ -225,7 +225,7 @@ Safe to run any time — genex-owned skills are refreshed to the latest version,
|
|
|
225
225
|
and your own files are never touched:
|
|
226
226
|
|
|
227
227
|
```bash
|
|
228
|
-
npx @genex-ai/cli-demo@
|
|
228
|
+
npx @genex-ai/cli-demo@dev init
|
|
229
229
|
```
|
|
230
230
|
|
|
231
231
|
Use `--force` only if you intentionally want your own existing files overwritten
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: genex-lane-card
|
|
3
|
+
description: The asset belt on one page — the command, what comes back, how to place it so it is not a speck or a wall, and what to do when a lane is dead. Read this before your first `npx genex model` or `npx genex character`. The full lanes are `$genex-ai-model` and `$genex-ai-character`; this card is what you need to not get it wrong.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Genex · Lane card
|
|
7
|
+
|
|
8
|
+
## Object → mesh
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npx genex model "weathered oak barrel, iron bands, damp staves" --no-wait
|
|
12
|
+
npx genex wait --all # prints every id this project enqueued, with its URL
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
A specific prompt beats a noun: "barrel" gives you a barrel-shaped guess, the
|
|
16
|
+
line above gives you the one in your scene. The URL is permanent — paste it into
|
|
17
|
+
the loader, never download it into the repo.
|
|
18
|
+
|
|
19
|
+
## Player body → character
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx genex character "stylized desert courier, layered dust-worn cloth"
|
|
23
|
+
npx genex character preview <concept-id> --candidate 1 --user-approved
|
|
24
|
+
npx genex character finalize <preview-id> --user-approved --approve-remesh 10000
|
|
25
|
+
npx genex controller character --character <id> # the whole integration
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Look at the three concepts, pick the strongest yourself, say which and why, and
|
|
29
|
+
keep going. Never foreground-`wait` on a character stage — they take minutes.
|
|
30
|
+
|
|
31
|
+
## Place it — a GLB arrives at any scale, with any origin
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
const o = gltf.scene;
|
|
35
|
+
const box = new THREE.Box3().setFromObject(o);
|
|
36
|
+
const size = new THREE.Vector3();
|
|
37
|
+
box.getSize(size);
|
|
38
|
+
o.scale.multiplyScalar(TARGET_HEIGHT_M / size.y); // the metres you want
|
|
39
|
+
box.setFromObject(o); // re-measure, then ground it
|
|
40
|
+
o.position.y -= box.min.y;
|
|
41
|
+
scene.add(o);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Skip this and the mesh is a speck or a wall — it is the single most common way a
|
|
45
|
+
generated asset ships broken. Rigged bodies mismeasure here; those go through
|
|
46
|
+
the controller's own boot path, not this snippet.
|
|
47
|
+
|
|
48
|
+
## Generate in batches you can finish
|
|
49
|
+
|
|
50
|
+
The belt has a **shipping ratchet**: generations that have not been shown to the
|
|
51
|
+
player are counted, and the count resets to zero every time you `npx genex
|
|
52
|
+
preview`. Hit it and the command refuses with the number and the fix.
|
|
53
|
+
|
|
54
|
+
It is not a spend limit and there is no total — preview between batches and
|
|
55
|
+
generate as much as the game needs. What it stops is one thing: fanning out a
|
|
56
|
+
whole cast or a shelf of props before the player has seen any of it. If you are
|
|
57
|
+
refused, you are not out of anything. You have work that nobody has looked at.
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx genex model "..." --no-wait # a batch you can finish
|
|
61
|
+
npx genex wait --all # collect it
|
|
62
|
+
# wire it, then:
|
|
63
|
+
npx genex preview # free, seconds — and the count is zero again
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## The one rule
|
|
67
|
+
|
|
68
|
+
An asset is not done when the command exits. It is done when something in
|
|
69
|
+
`src/` loads it, you have run the game, and you have LOOKED at it. A generation
|
|
70
|
+
nobody wired is money spent on nothing — `npx genex wait --all` marks a row
|
|
71
|
+
`wired` only once its URL appears in your source.
|
|
72
|
+
|
|
73
|
+
## When a lane is dead
|
|
74
|
+
|
|
75
|
+
A lane whose provider wallet is empty fails every call and refunds every one.
|
|
76
|
+
`npx genex doctor` prints each lane live/mock/paused with its credit state. If a
|
|
77
|
+
lane is red: **build that thing in code and move on** — do not re-run it, and do
|
|
78
|
+
not stall the game waiting for it. Say in chat what you fell back to.
|
|
@@ -217,6 +217,27 @@ the same ladder through
|
|
|
217
217
|
KTX2-capable games can also pass `ktx2Load` to `loadTextureWithFallback` so
|
|
218
218
|
textures use their `.ktx2` variants.
|
|
219
219
|
|
|
220
|
+
**A texture that arrived through a `.ktx2` rung is NOT drawable.** Its `.image`
|
|
221
|
+
is `{ width, height, mipmaps }`, never an `HTMLImageElement` — so
|
|
222
|
+
`ctx.drawImage(tex.image, …)` throws *"The provided value is not of type
|
|
223
|
+
'(CSSImageValue or HTMLCanvasElement or …)'"*. MEASURED 2026-09-07: a village
|
|
224
|
+
build wrote its own `capTextures()` pass to cap every texture's long edge and
|
|
225
|
+
cast `tex.image as CanvasImageSource` to silence the type error. All ten of its
|
|
226
|
+
generated buildings and both villager bodies then failed to load behind a
|
|
227
|
+
swallowed warning — a fully generated, fully wired world that rendered EMPTY,
|
|
228
|
+
and scored 1/9 with the assets sitting in R2. **Do not hand-roll a texture
|
|
229
|
+
downscaler: the rungs ARE the downscaler**, and `@1024` already did it before
|
|
230
|
+
the bytes left our side. If you must touch pixels, skip the compressed ones
|
|
231
|
+
first — `if ((tex as THREE.CompressedTexture).isCompressedTexture) return;`.
|
|
232
|
+
|
|
233
|
+
Every generated GLB ladders — `genex model` including its `segment` / `rig` /
|
|
234
|
+
`animate` outputs, and generated characters. If `pickModel` hands a generated
|
|
235
|
+
model URL back unchanged, this game's vendored kit predates that role: the
|
|
236
|
+
quality kit is copied into the game ONCE and is yours from then on, so it
|
|
237
|
+
never updates itself. Re-vendor it with `npx genex controller quality --force`
|
|
238
|
+
(that overwrites the kit files — keep your own edits, if any, before running
|
|
239
|
+
it), and the ladder starts resolving for those models.
|
|
240
|
+
|
|
220
241
|
## Quality picker in settings
|
|
221
242
|
|
|
222
243
|
The pause/settings screen (see `$genex-threejs-game-ui`) always carries a
|
|
@@ -85,7 +85,8 @@ npx genex controller character --character <character-id>
|
|
|
85
85
|
|
|
86
86
|
Meshy Image-to-3D first produces an unremeshed high-detail model. Show its
|
|
87
87
|
front, back, left, and right views and report its measured face count. Preserve
|
|
88
|
-
that model in R2. The
|
|
88
|
+
that model in R2. The triangle remesh at the approved face budget (10,000
|
|
89
|
+
by default; up to 100,000 for a hero)—not the high-detail
|
|
89
90
|
source—is rigged and animated. In the default lane proceed to it directly;
|
|
90
91
|
for a player-requested custom character, ask for their explicit approval
|
|
91
92
|
first (question tool when you have one; a short numbered list in chat
|
|
@@ -135,6 +136,9 @@ fork as a migration strategy. Install a fresh copy elsewhere and port only the n
|
|
|
135
136
|
## Minimal wiring
|
|
136
137
|
|
|
137
138
|
```ts
|
|
139
|
+
import { initEmbed, waitForPlayer } from "@genex-ai/embed-sdk";
|
|
140
|
+
import { GENEX } from "./genex.config";
|
|
141
|
+
import * as THREE from "three";
|
|
138
142
|
import { PhysicsWorld } from "./controllers/shared/physics-world.ts";
|
|
139
143
|
import { CharacterController } from "./controllers/character/character-controller.ts";
|
|
140
144
|
import { CharacterAnimations } from "./controllers/character/character-animations.ts";
|
|
@@ -145,7 +149,15 @@ import { createAimCue } from "./controllers/character/aim-cue.ts";
|
|
|
145
149
|
import { KeyboardInput } from "./controllers/character/keyboard-input.ts";
|
|
146
150
|
import { loadPlayerCharacter } from "./controllers/character/player-character.ts";
|
|
147
151
|
import { capsuleFromModel } from "./controllers/character/vrm/capsule-fit.ts";
|
|
148
|
-
|
|
152
|
+
|
|
153
|
+
initEmbed({ slug: GENEX.slug, apiUrl: GENEX.apiUrl, dashboardOrigins: GENEX.dashboardOrigins }); // FIRST — before any await
|
|
154
|
+
|
|
155
|
+
// draw first; identity takes seconds on a hosted page
|
|
156
|
+
const renderer = new THREE.WebGLRenderer({ antialias: tier.antialias, ...depthRendererOptions() }); // tier + depthRendererOptions: the quality kit
|
|
157
|
+
const scene = new THREE.Scene();
|
|
158
|
+
const camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, near, far);
|
|
159
|
+
document.body.appendChild(renderer.domElement);
|
|
160
|
+
renderer.render(scene, camera); // a frame is on screen before anything below is awaited
|
|
149
161
|
|
|
150
162
|
const physics = await PhysicsWorld.create(); // nothing RAPIER-related may run before this resolves
|
|
151
163
|
|
|
@@ -154,13 +166,13 @@ const physics = await PhysicsWorld.create(); // nothing RAPIER-related may run b
|
|
|
154
166
|
// (with that character's exact-rig clips and locomotion profile), and falls
|
|
155
167
|
// back to the visiting player's own profile avatar when it isn't — retargeting
|
|
156
168
|
// the bundled core library plus any packs installed by `genex controller
|
|
157
|
-
// anims`. `user.avatarUrl` comes from the embed identity
|
|
158
|
-
//
|
|
169
|
+
// anims`. `user.avatarUrl` comes from the embed identity (the `initEmbed`
|
|
170
|
+
// call above — $genex-threejs-embed-auth owns it) and is used only in that
|
|
159
171
|
// fallback lane; the baked `./assets/avatar.vrm` covers local dev and load
|
|
160
172
|
// failures. WRITE THIS ONCE: when the generated character lands mid-build,
|
|
161
173
|
// `genex controller character --character <id>` drops the manifest in and the
|
|
162
174
|
// next reload swaps the body. Nothing below changes.
|
|
163
|
-
const { user } = await waitForPlayer(); //
|
|
175
|
+
const { user } = await waitForPlayer(); // identity, awaited HERE — where the avatar is needed, never as the first line of the boot
|
|
164
176
|
const player = await loadPlayerCharacter({ avatarUrl: user.avatarUrl });
|
|
165
177
|
|
|
166
178
|
const fit = capsuleFromModel(player.scene); // collider fits THIS body's bounds
|
|
@@ -29,6 +29,10 @@ the rig). Route by silhouette:
|
|
|
29
29
|
locomotion clips for exactly the shapes Meshy refuses — see
|
|
30
30
|
`$genex-ai-model` for the full flow, presets, and honest limits (avian rigs
|
|
31
31
|
have no preset clips; drive those bones in code).
|
|
32
|
+
- **A mesh the player already has** (their own creature file): `npx genex
|
|
33
|
+
model import <file.glb>` first — free — then the same routing by
|
|
34
|
+
silhouette: biped → `npx genex character import` (Uthana auto-rig),
|
|
35
|
+
anything else → `npx genex model rig`. Never rebuild what they handed you.
|
|
32
36
|
- **Everything outside both** (swarms, blobs, amorphous things — no body plan
|
|
33
37
|
to rig): the **static + procedural lane** — `npx genex model` for the body,
|
|
34
38
|
motion authored in code. Say it honestly in the Assets table:
|
|
@@ -53,7 +57,10 @@ npx genex creature "hulking bone seraph, tattered wing membranes, upright stance
|
|
|
53
57
|
```
|
|
54
58
|
|
|
55
59
|
Each creature is one Assets-table row (visible spend — the usual budget
|
|
56
|
-
rules).
|
|
60
|
+
rules). It runs Meshy 7 like the player body; the knobs are yours: a crowd
|
|
61
|
+
enemy is `--polycount 10000 --no-ultra --texture 2k`, a boss seen in close-up
|
|
62
|
+
`--polycount 30000` (`--texture 8k` if the camera lingers), `--pose t-pose`
|
|
63
|
+
when a rig keeps failing structural QA in a-pose. The result is a rigged GLB whose clips play on a standard
|
|
57
64
|
`THREE.AnimationMixer`; Meshy limb rotations play unchanged — never apply
|
|
58
65
|
post-mixer limb corrections. Prompt the body UPRIGHT and unpropped (held
|
|
59
66
|
props fuse into bodies); prompt "facing the viewer" but never trust it —
|
|
@@ -54,6 +54,14 @@ initEmbed({
|
|
|
54
54
|
});
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
+
**Create the renderer and draw a frame BEFORE you await identity; `await
|
|
58
|
+
waitForPlayer()` only where you need the name or the token.** On a hosted page
|
|
59
|
+
identity takes seconds (the dashboard handshake, or the standalone bounce), so
|
|
60
|
+
a `main.ts` whose first statement is `const { user } = await waitForPlayer()`
|
|
61
|
+
shows black for all of them — and forever when `initEmbed()` was never called,
|
|
62
|
+
because nothing else resolves that promise. Renderer, scene, camera, first
|
|
63
|
+
frame, then the await, down where the name or the avatar is actually used.
|
|
64
|
+
|
|
57
65
|
Also give `<body>` a dark background in `index.html` (e.g.
|
|
58
66
|
`<body style="margin:0;background:#080a14">`) — it makes the pre-boot frame
|
|
59
67
|
(before any JS runs) match the SDK's own loading overlay instead of flashing
|
|
@@ -134,14 +134,55 @@ overlay — HTML/CSS on top of the canvas, not text sprites inside the scene:
|
|
|
134
134
|
|
|
135
135
|
```css
|
|
136
136
|
#ui { position: fixed; inset: 0; pointer-events: none; font-variant-numeric: tabular-nums; }
|
|
137
|
-
|
|
137
|
+
/* Layout belongs to the SHOWN screen only. Never `#ui .screen { display: … }`:
|
|
138
|
+
that overrides the browser's `[hidden] { display: none }`, and every hidden
|
|
139
|
+
screen is laid out full-viewport, invisible, on top of the one that is up. */
|
|
140
|
+
#ui .screen:not([hidden]) { display: flex; }
|
|
141
|
+
/* Clickable only while shown (`.is-on` is the shown class — Motion, below). */
|
|
142
|
+
#ui .screen.is-on, #ui #hud button { pointer-events: auto; }
|
|
138
143
|
```
|
|
139
144
|
|
|
140
145
|
`pointer-events: none` on the root keeps the canvas playable; re-enable it only
|
|
141
|
-
on elements that are actually clickable
|
|
142
|
-
position UI by mutating inline pixel styles per
|
|
143
|
-
a health bar floating over an enemy, a
|
|
144
|
-
exception for things that belong to the
|
|
146
|
+
on elements that are actually clickable — and only while they are on screen.
|
|
147
|
+
Keep ALL layout in CSS — never position UI by mutating inline pixel styles per
|
|
148
|
+
frame. In-world (diegetic) UI — a health bar floating over an enemy, a
|
|
149
|
+
scoreboard mesh in a stadium — is the exception for things that belong to the
|
|
150
|
+
world, not the default.
|
|
151
|
+
|
|
152
|
+
### Inactive screens are gone, not see-through
|
|
153
|
+
|
|
154
|
+
An invisible screen that is still laid out is a click trap nobody can see: the
|
|
155
|
+
title's Start button renders, the pointer hovers it, and the click lands on a
|
|
156
|
+
transparent pause card sitting last in DOM order. Three rules:
|
|
157
|
+
|
|
158
|
+
1. **An inactive screen is `display: none`** — via `hidden` or a class — never
|
|
159
|
+
merely `opacity: 0`. And NEVER set `display` on the `.screen` selector
|
|
160
|
+
itself: `.screen { display: flex }` beats the browser's `[hidden]` rule, so
|
|
161
|
+
`hidden` stops hiding anything. Put `display: flex` on
|
|
162
|
+
`.screen:not([hidden])` or on the shown class.
|
|
163
|
+
2. **`pointer-events: auto` belongs only to the screen that is currently
|
|
164
|
+
shown.** An invisible screen with clickable descendants swallows every click
|
|
165
|
+
meant for the screen under it, so scope `pointer-events` to `.screen.is-on`
|
|
166
|
+
(and to HUD controls) — never to `#ui .screen` or `#ui button` at large.
|
|
167
|
+
3. **The smoke check for every boot/title/pause screen:** for each visible
|
|
168
|
+
button, `document.elementFromPoint(cx, cy)` at its centre must return the
|
|
169
|
+
button or one of its descendants. A top hit whose effective (inherited)
|
|
170
|
+
opacity is 0 is a defect, not a styling choice — some screen is laid out
|
|
171
|
+
over the one the player sees. One paste in the console:
|
|
172
|
+
|
|
173
|
+
```js
|
|
174
|
+
[...document.querySelectorAll("#ui button")].filter((b) => b.getClientRects().length).map((b) => {
|
|
175
|
+
const r = b.getBoundingClientRect(), top = document.elementFromPoint(r.x + r.width / 2, r.y + r.height / 2);
|
|
176
|
+
let o = 1; for (let e = top; e; e = e.parentElement) o *= +getComputedStyle(e).opacity;
|
|
177
|
+
const ok = !!top && b.contains(top);
|
|
178
|
+
return { button: b.textContent.trim(), ok, coveredBy: ok ? null : top?.closest(".screen")?.id ?? top?.tagName ?? "offscreen", topOpacity: o };
|
|
179
|
+
})
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Every row reads `ok: true`; a `coveredBy` naming a screen with
|
|
183
|
+
`topOpacity: 0` is rule 1 or 2 broken. Run it on the title screen and again
|
|
184
|
+
with the pause screen up — `$genex-threejs-visual-validation` carries the
|
|
185
|
+
same check in its smoke pass.
|
|
145
186
|
|
|
146
187
|
## The states every game needs
|
|
147
188
|
|
|
@@ -279,7 +320,8 @@ black reads as a broken page. The branded version costs nothing:
|
|
|
279
320
|
## Motion — screens move or the game feels dead
|
|
280
321
|
|
|
281
322
|
Phase changes animate. `hidden` alone hard-cuts; pair it with a class so
|
|
282
|
-
opacity can transition
|
|
323
|
+
opacity can transition — the class owns opacity and `pointer-events`, `hidden`
|
|
324
|
+
keeps owning `display`:
|
|
283
325
|
|
|
284
326
|
```ts
|
|
285
327
|
function setPhase(phase: "loading" | "playing" | "paused" | "over" | "won") {
|
|
@@ -298,6 +340,8 @@ function setPhase(phase: "loading" | "playing" | "paused" | "over" | "won") {
|
|
|
298
340
|
```
|
|
299
341
|
|
|
300
342
|
```css
|
|
343
|
+
/* Opacity only — `display` stays with `hidden` (Architecture, above). Setting
|
|
344
|
+
`display` here would lay every hidden screen out over the shown one. */
|
|
301
345
|
#ui .screen { opacity: 0; transition: opacity 280ms ease; }
|
|
302
346
|
#ui .screen.is-on { opacity: 1; }
|
|
303
347
|
|
|
@@ -431,6 +475,11 @@ widget gets its numbers.
|
|
|
431
475
|
HUD — pick the 2–3 numbers that matter and style them by hierarchy.
|
|
432
476
|
- Hard-cut phase swaps, a menu whose elements just appear, numbers that
|
|
433
477
|
teleport.
|
|
478
|
+
- An invisible screen still laid out over the one the player sees — `display`
|
|
479
|
+
set on `.screen` (defeating `hidden`), or an `opacity: 0` screen that kept
|
|
480
|
+
`pointer-events: auto` — so the title's Start button never receives its
|
|
481
|
+
click; the hit-test in "Inactive screens are gone, not see-through" catches
|
|
482
|
+
it.
|
|
434
483
|
- A silent menu; a bare "Loading…" over black.
|
|
435
484
|
- Generated UI art enqueued and then left on the shelf — a landed sprite sheet
|
|
436
485
|
that never got extracted, masked, and wired is worse than never running the
|
|
@@ -1,30 +1,34 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: genex-threejs-procedural-assets
|
|
3
|
-
description: Build editable, parameterized Three.js objects in code —
|
|
3
|
+
description: Build editable, parameterized Three.js objects in code — modular kits, structural pieces, repeated or varied props, and any object code will honestly make read as the thing it is — or whenever the user asks for procedural/parametric work. A first-class lane alongside generated GLBs, held to the same bar; mix both freely.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Genex Three.js Procedural Assets
|
|
7
7
|
|
|
8
8
|
Build a recognizable asset as local, editable Three.js code. This lane is a
|
|
9
|
-
first-class engine, not a fallback
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
first-class engine, not a fallback — and it is held to the same bar as a
|
|
10
|
+
generated GLB: the result must read as the thing it is when the player looks at
|
|
11
|
+
it, in the game's own style. A coloured box or a flat grey block is a blockout,
|
|
12
|
+
never a landed asset. Mixing procedural pieces with generated pieces in the
|
|
13
|
+
same scene is the normal way to build a detailed, lively world.
|
|
13
14
|
|
|
14
15
|
## Choose the route
|
|
15
16
|
|
|
16
17
|
- Start directly when the user says procedural, parametric, code-built,
|
|
17
18
|
customizable, seeded, or asks for controlled variations.
|
|
18
|
-
- Also start directly
|
|
19
|
-
|
|
20
|
-
placed many times with variation.
|
|
19
|
+
- Also start directly for what is structural, repeated, distant, or
|
|
20
|
+
parametric: terrain, modular environment kits, fences, pipes, rails, walls,
|
|
21
|
+
paving, and anything placed many times with variation.
|
|
22
|
+
- For anything the player looks at up close, walks into, or interacts with — a
|
|
23
|
+
named building, a signature prop, a vehicle — code is a choice, not a
|
|
24
|
+
default: take it only when you will honestly reach the bar above, and confirm
|
|
25
|
+
it in a capture at gameplay distance before the row reads `landed`. Otherwise
|
|
26
|
+
`$genex-ai-model` owns it.
|
|
21
27
|
- An attached or available image does not activate this skill by itself.
|
|
22
28
|
- If “make this image 3D” could honestly mean either route, ask exactly one
|
|
23
29
|
question: **“Do you want a generated textured GLB, or editable procedural
|
|
24
30
|
Three.js code?”**
|
|
25
31
|
- Use `$genex-ai-model` when the user chooses a generated textured GLB.
|
|
26
|
-
- Use this skill for props, hard-surface objects, modular decorations, and
|
|
27
|
-
simple structures or environment pieces.
|
|
28
32
|
- Do not use it for characters, creatures, rigging, skeletal animation, or
|
|
29
33
|
character likeness. Keep those in their existing specialist lanes.
|
|
30
34
|
|
|
@@ -60,6 +64,9 @@ proposed → planned → building (blockout | detail | material | runtime)
|
|
|
60
64
|
→ landed (<local TypeScript path>) → wired
|
|
61
65
|
```
|
|
62
66
|
|
|
67
|
+
`landed` means a capture at gameplay distance showed it reads as the thing it
|
|
68
|
+
is — not that the file exists.
|
|
69
|
+
|
|
63
70
|
A Genex-generated reference keeps its separate image row and normal paid
|
|
64
71
|
generation status. Note that the procedural-code row is derived from that
|
|
65
72
|
image. A private user reference is not a paid generation row.
|
|
@@ -37,7 +37,8 @@ overlapping props or straps can fuse into the character or hide a limb.
|
|
|
37
37
|
|
|
38
38
|
Meshy Image-to-3D first produces an unremeshed high-detail model. Show its
|
|
39
39
|
front, back, left, and right views and report its measured face count. Preserve
|
|
40
|
-
that model in R2. The
|
|
40
|
+
that model in R2. The triangle remesh at the approved face budget (10,000
|
|
41
|
+
by default; up to 100,000 for a hero)—not the high-detail
|
|
41
42
|
source—is rigged and animated. In the default lane the remesh proceeds
|
|
42
43
|
directly; for a player-requested custom character, wait for their explicit
|
|
43
44
|
approval first (question tool when you have one; a short numbered list in
|
|
@@ -72,7 +73,13 @@ everything twice.
|
|
|
72
73
|
console errors). For an unpublished draft, open the dev server in local
|
|
73
74
|
test mode — `http://localhost:5173/?genex_local_test=1` (the embed-auth
|
|
74
75
|
skill's "Self-testing a draft" section) — so you see the game, not the
|
|
75
|
-
sign-in gate.
|
|
76
|
+
sign-in gate. Then hit-test the screen that is up (title now, pause later):
|
|
77
|
+
for every visible button, `document.elementFromPoint(cx, cy)` at its centre
|
|
78
|
+
must return the button or one of its descendants — a top hit whose
|
|
79
|
+
effective (inherited) opacity is 0 is an invisible screen still laid out
|
|
80
|
+
over this one (a `display` rule on `.screen` defeating `hidden`, or an
|
|
81
|
+
`opacity: 0` screen keeping `pointer-events: auto`), and nobody can enter
|
|
82
|
+
the game. `$genex-threejs-game-ui` has the one-paste check and the fix.
|
|
76
83
|
2. Press each documented control once (keys, pointer); assert a **visible
|
|
77
84
|
response in its labeled direction** — this is the input-direction pass, and
|
|
78
85
|
it is part of THIS check, not an extra testing loop. Hold `KeyD`/ArrowRight
|
|
@@ -359,6 +366,9 @@ visual-system work — the sequence above.
|
|
|
359
366
|
- a non-cursor-core game that leaves the OS cursor visible during play;
|
|
360
367
|
- a menu or settings click locks the pointer (or the cursor vanishes) while a
|
|
361
368
|
menu screen is still up;
|
|
369
|
+
- a title, boot, or pause button whose centre hit-test returns an element of a
|
|
370
|
+
screen that is not visibly up (effective opacity 0) — an invisible overlay is
|
|
371
|
+
swallowing the click;
|
|
362
372
|
- approval relies on a single frame;
|
|
363
373
|
- post-processing cannot be disabled per pass;
|
|
364
374
|
- random seeds are not reproducible;
|
|
@@ -53,8 +53,9 @@ and let the player skip.
|
|
|
53
53
|
|
|
54
54
|
## Cost
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
From **2 credits** an sfx · **27** a 90 s music track · **2** a short voice line
|
|
57
|
+
(voice bills per character, up to 12 at the 1000-character cap; 1 credit = $0.01).
|
|
58
|
+
Longer `--duration`s cost more. Live prices and your balance: `npx genex doctor`.
|
|
58
59
|
|
|
59
60
|
## Waiting
|
|
60
61
|
|
|
@@ -24,13 +24,28 @@ npx genex character preview <concept-id> --candidate 2 --user-approved
|
|
|
24
24
|
# → a 3D preview of that one, four views. Show it; wait for approval.
|
|
25
25
|
|
|
26
26
|
npx genex character finalize <preview-id> --user-approved --approve-remesh 10000
|
|
27
|
-
# → the rigged, game-ready character.
|
|
27
|
+
# → the rigged, game-ready character at that face budget.
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
Each step needs the previous step's generation id. The approval flags are not
|
|
31
31
|
ceremony: they record that a person actually looked and chose, and each step
|
|
32
32
|
costs credits.
|
|
33
33
|
|
|
34
|
+
## The knobs (Meshy 7 on every lane)
|
|
35
|
+
|
|
36
|
+
Ultra and 4k textures are the defaults; every knob is priced in the quote.
|
|
37
|
+
Pick per role and say so in one line:
|
|
38
|
+
|
|
39
|
+
- `--approve-remesh <faces>` (finalize) / `--polycount <faces>` (one shot):
|
|
40
|
+
the rigging copy's face budget, 10000-100000 — 10000 for crowds and
|
|
41
|
+
distance, 20000-30000 for a third-person player body, 50000+ only for a
|
|
42
|
+
close-up hero. Moves no cost.
|
|
43
|
+
- `--texture 2k|4k|8k` (preview / one shot): 8k is +5 credits, for close-ups.
|
|
44
|
+
- `--no-ultra` (preview / one shot): −5 credits, less surface detail — stand-ins
|
|
45
|
+
and crowd enemies.
|
|
46
|
+
- `--pose a-pose|t-pose` (one shot): the preferred rest pose.
|
|
47
|
+
- `--height <metres>`: 0.5-3, default 1.7.
|
|
48
|
+
|
|
34
49
|
## One shot
|
|
35
50
|
|
|
36
51
|
When nobody is choosing — a background NPC, a quick test:
|
|
@@ -41,7 +56,21 @@ npx genex creature "hulking bone seraph, upright stance"
|
|
|
41
56
|
```
|
|
42
57
|
|
|
43
58
|
`creature` is the same lane with enemy defaults: no approval steps, no player
|
|
44
|
-
controller pack. Biped-shaped bodies only.
|
|
59
|
+
controller pack (and priced without one). Biped-shaped bodies only. The knobs
|
|
60
|
+
above apply: a crowd enemy is `--polycount 10000 --no-ultra --texture 2k`.
|
|
61
|
+
|
|
62
|
+
## Import a character the user already has
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx genex character import ./knight.glb --height 1.8 # free upload + Uthana auto-rig (finger joints; --no-fingers skips them)
|
|
66
|
+
npx genex character animate <id> --locomotion # then the walk/run set — an import has no clips yet
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Biped humanoid, T- or A-pose, feet on the ground, facing +Z, `.glb` ≤ 30 MB.
|
|
70
|
+
**Never rebuild a mesh the user gives you** — import it. The result is a
|
|
71
|
+
Uthana-rigged body: verbs, `--locomotion` and `--video` work; the Meshy
|
|
72
|
+
catalog and controller pack do not. Non-biped bodies: `npx genex model
|
|
73
|
+
import` + `npx genex model rig`.
|
|
45
74
|
|
|
46
75
|
## Animating it
|
|
47
76
|
|
|
@@ -75,9 +104,11 @@ look here first — a library clip costs nothing to generate.
|
|
|
75
104
|
|
|
76
105
|
## Cost
|
|
77
106
|
|
|
78
|
-
Typical: **
|
|
79
|
-
character · **
|
|
80
|
-
|
|
107
|
+
Typical: **32** concept · **41** preview · **29** finalize · **64** one-shot
|
|
108
|
+
character · **46** creature · **18** import (Uthana auto-rig; the upload is
|
|
109
|
+
free) · **46 per clip** for a generated move · **free** for a library search
|
|
110
|
+
(1 credit = $0.01). `--texture 8k` adds 6, `--no-ultra`
|
|
111
|
+
takes 6 off. Live prices and your balance: `npx genex doctor`.
|
|
81
112
|
|
|
82
113
|
## Waiting
|
|
83
114
|
|
|
@@ -43,8 +43,10 @@ Wire the **local path**. The URL is provenance — never fetch it at runtime.
|
|
|
43
43
|
|
|
44
44
|
## Cost
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
From **4 credits** per image at default quality (1 credit = $0.01);
|
|
47
|
+
`--transparent`, `--quality high`, `--edit` and 4K canvases cost more, and
|
|
48
|
+
`--candidates` bills per variant - the command prints the exact quote. Live
|
|
49
|
+
prices and your balance: `npx genex doctor`.
|
|
48
50
|
|
|
49
51
|
## Waiting
|
|
50
52
|
|
|
@@ -21,6 +21,17 @@ npx genex model --image ./reference-photo.jpg # build it FROM an image; pr
|
|
|
21
21
|
Blocks until ready, saves the GLB into `./assets`, and prints the path. Wire the
|
|
22
22
|
local path; the URL printed beside it is provenance, not hosting.
|
|
23
23
|
|
|
24
|
+
## Bring your own mesh
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx genex model import ./hero-cart.glb # free — a file you already have becomes a model of yours
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`.glb` only, ≤ 64 MB (export a `.gltf`/FBX as one binary `.glb` first). The
|
|
31
|
+
import is free and checked before it completes; after it, `segment`, `rig`,
|
|
32
|
+
`animate` and `character import` all take its id. **Never rebuild a mesh the
|
|
33
|
+
user hands you** — import it.
|
|
34
|
+
|
|
24
35
|
## Mesh lanes
|
|
25
36
|
|
|
26
37
|
Each takes the **generation id** of a previous model — never a URL.
|
|
@@ -31,29 +42,44 @@ npx genex model rig <model-id> --type quadruped
|
|
|
31
42
|
npx genex model animate <rig-id> --preset walk,run
|
|
32
43
|
```
|
|
33
44
|
|
|
34
|
-
- **`segment`** — one GLB
|
|
45
|
+
- **`segment`** — one GLB split into addressable parts: doors, turrets, magazines, destructibles. `--granularity simple|balanced|detailed`. The parts are named by index (`tripo_part_0`, `tripo_part_1`, …), not by what they are — find the one you want by its bounds (the sails are the part with the widest extent, the door the lowest thin one), then keep that index in your manifest.
|
|
35
46
|
- **`rig`** — a skeleton for any mesh, across 7 body plans: `biped`, `quadruped`, `hexapod`, `octopod`, `avian`, `serpentine`, `aquatic`. The plan is auto-detected; `--type` picks it. A mesh that cannot be rigged is refused and refunded before the paid step.
|
|
36
47
|
- **`animate`** — retarget ready-made clips onto a rig, billed per clip. biped: `idle|walk|run|dive|climb|jump|slash|shoot|hurt|fall|turn`; quadruped/hexapod/octopod: `walk`; serpentine/aquatic: `march`.
|
|
37
48
|
|
|
38
49
|
## Options
|
|
39
50
|
|
|
40
51
|
- `--image <path|url>` — build the model from a reference image (local file ≤ 4 MB, or a previous generation's URL). The prompt becomes optional.
|
|
52
|
+
- **Quality knobs** (Tripo H3.1, each priced in the quote — pick per asset, say it in one line): `--texture standard|detailed|none` (detailed default, +10 over standard; none = geometry only), `--geometry detailed` (+20, hero pieces only), `--quad` (+5, for meshes you will edit; face limit ≤150000), `--low-poly` (+10, game-ready topology for props in numbers — it holds `--face-limit` to 1000-20000, 500-10000 with `--quad`; omit the flag to take 20000; it runs a post-process after the mesh, so allow up to 30 minutes), `--parts` (+20, named parts at generation), `--face-limit <n>` (1000-2000000, default 150000; see `--low-poly` for its band), `--auto-size` (real-world metres).
|
|
41
53
|
- `--out-dir <dir>` — where the file lands (default `./assets`).
|
|
42
54
|
- `--no-download` — print the URL only.
|
|
43
55
|
- `--no-wait` — enqueue and return; pick it up with `npx genex wait <id>`.
|
|
44
56
|
|
|
45
57
|
## Cost
|
|
46
58
|
|
|
47
|
-
|
|
48
|
-
|
|
59
|
+
From **35 credits** a model (**46** from a reference image; `--texture standard`
|
|
60
|
+
**23**, `--geometry detailed` **58**, `--low-poly` **46**, `--parts` **58**) ·
|
|
61
|
+
**46** segment · **29** rig · **12 per clip** for animate (1 credit = $0.01).
|
|
62
|
+
Live prices and your balance: `npx genex doctor`.
|
|
49
63
|
|
|
50
64
|
## Waiting
|
|
51
65
|
|
|
52
66
|
Models take the longest of any lane. `--no-wait` is the normal way to run
|
|
53
67
|
several at once: enqueue them all, keep building, then `npx genex wait --all`
|
|
54
|
-
for one status line each
|
|
55
|
-
|
|
56
|
-
|
|
68
|
+
for one status line each — in a tools workspace it also downloads every
|
|
69
|
+
finished model that is not in `./assets` yet, so one call after a break (or a
|
|
70
|
+
restarted session) delivers the whole batch. `npx genex wait <id>` picks one
|
|
71
|
+
up. **Re-running the model command bills a NEW model** — never use it as a
|
|
72
|
+
status check. Five or so in flight at a time is the provider's comfortable
|
|
73
|
+
concurrency; a burst beyond that waits on the server side rather than failing.
|
|
74
|
+
|
|
75
|
+
## Placing a model
|
|
76
|
+
|
|
77
|
+
A generated GLB has no shared "front": one building's door faces −x, the next
|
|
78
|
+
one's +z. Do not guess and do not spend a render per side — read the mesh once
|
|
79
|
+
on load (bounding box, and where the detail is: the door, the counter, the
|
|
80
|
+
opening) or check it in a viewer, then record a per-model `front` (a yaw in
|
|
81
|
+
your manifest) beside its path and apply it when you place it. Ask for a facing
|
|
82
|
+
in the prompt too (`"…front toward +Z"`) — it helps, it does not guarantee.
|
|
57
83
|
|
|
58
84
|
## Troubleshooting
|
|
59
85
|
|