@genex-ai/cli-demo 0.22.0 → 0.24.0
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 +13 -11
- package/package.json +1 -1
- package/templates/skills/genex-ai-model/SKILL.md +7 -2
- package/templates/skills/genex-explore/SKILL.md +10 -3
- package/templates/skills/genex-threejs-embed-auth/SKILL.md +7 -4
- package/templates/skills/genex-threejs-vehicle-controllers/references/car.md +26 -15
- package/templates/skills/genex-threejs-visual-validation/SKILL.md +6 -0
package/dist/index.js
CHANGED
|
@@ -1668,7 +1668,7 @@ async function poll(apiUrl, token, id, onProgress) {
|
|
|
1668
1668
|
function printHint(kind, files, log) {
|
|
1669
1669
|
const url = files[0]?.url ?? "";
|
|
1670
1670
|
const hint = {
|
|
1671
|
-
model: `
|
|
1671
|
+
model: `Meshopt-compressed GLB \u2014 wire the decoder once (loader.setMeshoptDecoder(MeshoptDecoder)), then load with GLTFLoader from the URL \u2014 see the genex-ai-model skill. url = "${url}"`,
|
|
1672
1672
|
skybox: `Load as an equirectangular texture \u2192 scene.background + scene.environment \u2014 see genex-ai-skybox. url = "${url}"`,
|
|
1673
1673
|
sfx: `Load with AudioLoader into a THREE.PositionalAudio (camera needs an AudioListener) \u2014 see genex-ai-sfx. url = "${url}"`,
|
|
1674
1674
|
texture: `Load each map with TextureLoader (RepeatWrapping) into a MeshStandardMaterial \u2014 see genex-ai-texture. Use the URLs above by role.`
|
|
@@ -1870,11 +1870,6 @@ async function exists2(p) {
|
|
|
1870
1870
|
async function runExplore(opts) {
|
|
1871
1871
|
const log = createLogger({ quiet: opts.quiet });
|
|
1872
1872
|
const query = opts.query?.trim();
|
|
1873
|
-
if (!query) {
|
|
1874
|
-
log.error('Missing query. Usage: genex explore "<what you need>"');
|
|
1875
|
-
process.exitCode = 1;
|
|
1876
|
-
return;
|
|
1877
|
-
}
|
|
1878
1873
|
const apiUrl = getApiUrl(opts.apiUrl);
|
|
1879
1874
|
let res;
|
|
1880
1875
|
try {
|
|
@@ -1890,17 +1885,21 @@ async function runExplore(opts) {
|
|
|
1890
1885
|
return;
|
|
1891
1886
|
}
|
|
1892
1887
|
const { items } = await res.json();
|
|
1893
|
-
const ranked = rank(items, query).slice(0, 5);
|
|
1888
|
+
const ranked = query ? rank(items, query).slice(0, 5) : [...items].sort((a, b) => b.playsCount - a.playsCount);
|
|
1894
1889
|
if (opts.json) {
|
|
1895
1890
|
console.log(JSON.stringify(ranked, null, 2));
|
|
1896
1891
|
return;
|
|
1897
1892
|
}
|
|
1898
1893
|
if (ranked.length === 0) {
|
|
1899
1894
|
log.plain(
|
|
1900
|
-
`No curated projects matched "${query}".
|
|
1895
|
+
query ? `No curated projects matched "${query}". Run \`genex explore\` with no arguments to browse the whole catalog, or try a broader term (terrain, grass, vehicle, water, building, dungeon, fish, shader).` : `The curated catalog is empty right now \u2014 check back soon.`
|
|
1901
1896
|
);
|
|
1902
1897
|
return;
|
|
1903
1898
|
}
|
|
1899
|
+
if (!query) {
|
|
1900
|
+
log.plain(c.bold(`The full curated catalog (${ranked.length} project${ranked.length === 1 ? "" : "s"}):`));
|
|
1901
|
+
log.plain("");
|
|
1902
|
+
}
|
|
1904
1903
|
for (const [i, p] of ranked.entries()) {
|
|
1905
1904
|
const meta = [
|
|
1906
1905
|
p.categories.join(", "),
|
|
@@ -1960,8 +1959,9 @@ ${c.bold("Usage")}
|
|
|
1960
1959
|
genex texture "<prompt>" [options] Generate a PBR texture into public/assets/textures.
|
|
1961
1960
|
genex controller <type> [--force] Install a physics controller (character|car|drone)
|
|
1962
1961
|
into src/controllers (+ assets into public/assets).
|
|
1963
|
-
genex explore "<query>" [options]
|
|
1964
|
-
Three.js systems you can clone or borrow parts
|
|
1962
|
+
genex explore ["<query>"] [options] Search the curated community gallery \u2014 proven
|
|
1963
|
+
Three.js systems you can clone or borrow parts
|
|
1964
|
+
from. No query lists the whole catalog.
|
|
1965
1965
|
|
|
1966
1966
|
${c.bold("Options for the generators (`model` `skybox` `sfx` `texture`)")}
|
|
1967
1967
|
--terrain (texture) seamless tiling surface for terrain/ground.
|
|
@@ -2008,8 +2008,9 @@ ${c.bold("Options for `preview` / `publish`")}
|
|
|
2008
2008
|
--env <path> Token env file (default: ~/.genex/env).
|
|
2009
2009
|
|
|
2010
2010
|
${c.bold("Options for `explore`")}
|
|
2011
|
-
--json Print the
|
|
2011
|
+
--json Print the matches as JSON (for tools/agents).
|
|
2012
2012
|
--api-url <url> Override the API base URL.
|
|
2013
|
+
(No query at all lists the entire curated catalog.)
|
|
2013
2014
|
|
|
2014
2015
|
${c.bold("Global")}
|
|
2015
2016
|
--quiet Reduce output.
|
|
@@ -2036,6 +2037,7 @@ ${c.bold("Examples")}
|
|
|
2036
2037
|
genex texture "mossy cracked cobblestone" --terrain
|
|
2037
2038
|
genex controller character
|
|
2038
2039
|
genex explore "grass"
|
|
2040
|
+
genex explore
|
|
2039
2041
|
`;
|
|
2040
2042
|
function parseArgs(argv) {
|
|
2041
2043
|
const parsed = {
|
package/package.json
CHANGED
|
@@ -63,13 +63,18 @@ side — reads as broken at a glance.
|
|
|
63
63
|
|
|
64
64
|
## Load it into the scene
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
Generated model GLBs are **meshopt-compressed** on the Genex servers before
|
|
67
|
+
storage (same visuals, several times smaller — faster loads on every play).
|
|
68
|
+
Wire the decoder once — it's harmless for uncompressed files — then use
|
|
69
|
+
Three.js `GLTFLoader` with the URL the command printed (R2 sends the right
|
|
70
|
+
CORS headers, so cross-origin loading just works):
|
|
68
71
|
|
|
69
72
|
```ts
|
|
70
73
|
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
|
|
74
|
+
import { MeshoptDecoder } from "three/addons/libs/meshopt_decoder.module.js";
|
|
71
75
|
|
|
72
76
|
const loader = new GLTFLoader();
|
|
77
|
+
loader.setMeshoptDecoder(MeshoptDecoder); // required for genex model GLBs
|
|
73
78
|
// the URL `npx genex model` printed:
|
|
74
79
|
const MODEL_URL = "https://assets.genex.technology/generations/<id>/model-glb";
|
|
75
80
|
const gltf = await loader.loadAsync(MODEL_URL);
|
|
@@ -23,6 +23,13 @@ Examples: `npx genex explore "grass"`, `npx genex explore "vehicle physics"`,
|
|
|
23
23
|
`npx genex explore "procedural building"`. No sign-in needed — this works even
|
|
24
24
|
before `genex init`.
|
|
25
25
|
|
|
26
|
+
**Not sure what exists?** Run it with no arguments to browse the whole curated
|
|
27
|
+
catalog first — it's small and every entry is proven:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npx genex explore
|
|
31
|
+
```
|
|
32
|
+
|
|
26
33
|
Each result prints everything you need to act on it:
|
|
27
34
|
|
|
28
35
|
- `play:` — open it in the browser to judge whether it fits.
|
|
@@ -36,8 +43,7 @@ Add `--json` for machine-readable output.
|
|
|
36
43
|
**As a NEW game (start from the whole project):**
|
|
37
44
|
|
|
38
45
|
1. `git clone <clone URL from the output> <name>` — pick a short one-word name.
|
|
39
|
-
2. `cd <name>`, then `npx @genex-ai/cli-demo@latest init <name>` —
|
|
40
|
-
"Ignore files and continue" if it warns the folder isn't empty; never use
|
|
46
|
+
2. `cd <name>`, then `npx @genex-ai/cli-demo@latest init <name>` — never use
|
|
41
47
|
`--force`. This creates your own project; the original is untouched.
|
|
42
48
|
3. `npm install`, keep `base: './'` in `vite.config`, then build your changes
|
|
43
49
|
and ship with `npx genex preview`.
|
|
@@ -64,6 +70,7 @@ build from one:
|
|
|
64
70
|
- keep any in-game credits screens or notices in place;
|
|
65
71
|
- carry the credit into anything you publish or remix from it.
|
|
66
72
|
|
|
67
|
-
If nothing matches your query,
|
|
73
|
+
If nothing matches your query, run `npx genex explore` with no arguments to
|
|
74
|
+
see everything available, or try a broader term (terrain, grass, vehicle,
|
|
68
75
|
water, building, dungeon, fish, shader) — or build it with the regular
|
|
69
76
|
`genex-threejs-*` skills instead.
|
|
@@ -273,10 +273,13 @@ and a gate capture is NOT visual evidence.
|
|
|
273
273
|
- Do NOT work around the gate: don't dig through the SDK's internals for
|
|
274
274
|
undocumented URL fragments, and don't drive the user's own signed-in
|
|
275
275
|
browser.
|
|
276
|
-
- For the visual pass on a draft,
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
276
|
+
- For the visual pass on a draft, the owner IS the QA loop — not a fallback:
|
|
277
|
+
push `genex preview` at each playable milestone and hand it off plainly
|
|
278
|
+
("check the draft — you can now X; ping me if something feels off"), then
|
|
279
|
+
keep building while they look. Their run-around catches exactly what the
|
|
280
|
+
gate hides from you: facing, proportions, feel. Once the game is
|
|
281
|
+
**published**, any fresh browser gets in as a guest, so your own test
|
|
282
|
+
browser works again for full visual validation.
|
|
280
283
|
|
|
281
284
|
## Checklist
|
|
282
285
|
|
|
@@ -96,21 +96,32 @@ treat the player as drivable ground.
|
|
|
96
96
|
## Custom generated bodies (`npx genex model`)
|
|
97
97
|
|
|
98
98
|
A generated GLB works as the visual chassis — add it under `car.chassisObject`
|
|
99
|
-
exactly like `carBodyMesh` above.
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
`wheel.modelObject
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
99
|
+
exactly like `carBodyMesh` above. Generated car models arrive as ONE mesh with
|
|
100
|
+
the wheels baked in (prompting "no wheels" does not reliably remove them) —
|
|
101
|
+
that is the expected input. Three rules make it read right:
|
|
102
|
+
|
|
103
|
+
- **Never add visible wheel meshes to a generated body.** Leave every
|
|
104
|
+
`wheel.modelObject` empty — the suspension shapecasts drive the body
|
|
105
|
+
correctly with no wheel visuals, and code wheels next to the baked-in ones
|
|
106
|
+
read as a six-wheeled monster truck. The baked wheels simply don't spin;
|
|
107
|
+
at game speed that's the accepted look. (The cylinder wheels in the wiring
|
|
108
|
+
above are for hand-built box-chassis cars only.)
|
|
109
|
+
- **Fit the invisible wheels to the body, not the body to the preset.**
|
|
110
|
+
Scale the GLB by LENGTH toward the preset's footprint (body length ≈
|
|
111
|
+
wheelbase + 1.5 m; race-grip/muscle-drift wheelbase is 3.0 m, track
|
|
112
|
+
1.7 m) — never a min-axis bounding-box fit, which shrinks the body and
|
|
113
|
+
strands the wheel slots outside its silhouette. Then move the wheel slots
|
|
114
|
+
to the model's own wheel arches (from its bounding box: axles at roughly
|
|
115
|
+
±0.33 × body length on z, x at ±(half width − 0.1)) and set
|
|
116
|
+
`rayShapeR`/`wheelModelRadius` so the body STANDS on the road — baked
|
|
117
|
+
tires touching the ground, nothing floating.
|
|
118
|
+
- **Verify the facing before anything else.** +Z must be the nose:
|
|
119
|
+
generation regularly comes back rotated 180° (the classic "car drives
|
|
120
|
+
backward" bug) — apply the one-time yaw wrapper from `$genex-ai-model`,
|
|
121
|
+
then confirm in your smoke test that the NOSE leads under forward input.
|
|
122
|
+
|
|
123
|
+
Center the GLB over the chassis colliders. Collider strategy for GLBs lives
|
|
124
|
+
in `$genex-threejs-physics-rapier`.
|
|
114
125
|
|
|
115
126
|
## Presets and provenance
|
|
116
127
|
|
|
@@ -41,6 +41,12 @@ this is the whole acceptance gate, and it is also the minimum for every game:
|
|
|
41
41
|
direction, and NPCs driven by chase/aim code face their target. A model
|
|
42
42
|
rotated 90° reads as broken — `$genex-ai-model` has the one-time facing
|
|
43
43
|
fix.
|
|
44
|
+
5. Vehicles get one extra pass: drive forward once and confirm the NOSE
|
|
45
|
+
leads (a 180° body is this bug's favorite disguise), and check the body
|
|
46
|
+
stands ON the road with its wheels inside the silhouette — a body
|
|
47
|
+
floating above detached wheels means the model was box-fit against the
|
|
48
|
+
preset's wheelbase (the vehicle skill's "Custom generated bodies" rules
|
|
49
|
+
fix it).
|
|
44
50
|
|
|
45
51
|
Everything deeper (baselines, seed sweeps, mosaics, budgets) belongs to
|
|
46
52
|
visual-system work — the sequence above.
|