@genex-ai/cli-demo 1.30.0-dev.644 → 1.31.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/README.md +0 -18
- package/dist/index.js +2839 -4768
- package/package.json +3 -3
- package/templates/controllers/character/follow-camera.ts +1 -16
- package/templates/controllers/character/meshy/meshy-loader.ts +2 -3
- package/templates/controllers/quality/pick-asset.ts +16 -49
- package/templates/controllers/shared/physics-world.ts +4 -6
- package/templates/skills/genex-ai-character/SKILL.md +15 -77
- package/templates/skills/genex-ai-menu/SKILL.md +11 -15
- package/templates/skills/genex-ai-model/SKILL.md +7 -45
- package/templates/skills/genex-ai-texture/SKILL.md +1 -1
- package/templates/skills/genex-ai-video/SKILL.md +17 -75
- package/templates/skills/genex-game-director/SKILL.md +46 -112
- package/templates/skills/genex-game-director/references/design-contract.md +5 -13
- package/templates/skills/genex-game-director/references/routing-map.md +45 -30
- package/templates/skills/genex-getting-started/SKILL.md +2 -2
- package/templates/skills/genex-monetization/SKILL.md +171 -0
- package/templates/skills/genex-threejs-adaptive-quality/SKILL.md +0 -21
- package/templates/skills/genex-threejs-character-controller/SKILL.md +5 -17
- package/templates/skills/genex-threejs-creatures/SKILL.md +1 -8
- package/templates/skills/genex-threejs-embed-auth/SKILL.md +52 -8
- package/templates/skills/genex-threejs-game-ui/SKILL.md +6 -55
- package/templates/skills/genex-threejs-procedural-assets/SKILL.md +10 -17
- package/templates/skills/genex-threejs-visual-validation/SKILL.md +2 -12
- package/templates/skills/genex-tool-audio/SKILL.md +2 -3
- package/templates/skills/genex-tool-character/SKILL.md +5 -36
- package/templates/skills/genex-tool-image/SKILL.md +2 -4
- package/templates/skills/genex-tool-model/SKILL.md +6 -32
- package/templates/skills/genex-tool-texture/SKILL.md +1 -1
- package/templates/skills/genex-tool-video/SKILL.md +5 -28
- package/templates/skills/genex-tool-workflow/SKILL.md +1 -4
- package/templates/skills/genex-updates/SKILL.md +1 -1
- package/dist/blender-mcp-Q6PSFYSE.js +0 -241
- package/dist/blender-serve-BF4FZ55Z.js +0 -244
- package/dist/chunk-2COG4P3T.js +0 -968
- package/dist/chunk-HYCSNWYX.js +0 -126
- package/templates/blender-service/demo/castle.py +0 -117
- package/templates/blender-service/gpu_witness.py +0 -245
- package/templates/blender-service/ops.py +0 -225
- package/templates/blender-service/pool.py +0 -910
- package/templates/blender-service/server.py +0 -611
- package/templates/blender-service/supervisor.py +0 -221
- package/templates/blender-service/views.py +0 -281
- package/templates/controllers/quality/deadline.ts +0 -117
- package/templates/skills/genex-blender-scene/SKILL.md +0 -243
- package/templates/skills/genex-lane-card/SKILL.md +0 -78
- package/templates/skills/genex-tool-publish/SKILL.md +0 -100
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: genex-blender-scene
|
|
3
|
-
description: Compose a level, arena, interior, building or map — a SPACE of rooms, lanes, walls and sites that must relate — in a live Blender with `npx genex blender`, then export one GLB the game walks through. Use for places to move through, floor plans, or explicit Blender authoring including standalone assets. Probe the lane first; code is the fallback only when Blender was not explicitly required.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Genex Blender · Scene
|
|
7
|
-
|
|
8
|
-
Build the game's SPACE in a real Blender that answers over HTTP: write a Python
|
|
9
|
-
script, run it, read the numbers, look at the four-view sheet, repeat — then
|
|
10
|
-
export one GLB and load it like any model. The scene persists between steps, so a
|
|
11
|
-
level grows the way a level is actually built: shell, then zones, then dressing.
|
|
12
|
-
|
|
13
|
-
## When this lane owns the work
|
|
14
|
-
|
|
15
|
-
- An explicit request to author or edit **in Blender**, even one standalone
|
|
16
|
-
asset. This overrides the default single-object route below. Keep Python
|
|
17
|
-
source under `blender/`, export the requested GLB and show it in a simple
|
|
18
|
-
browser preview; add gameplay only when requested. In hosted creation use
|
|
19
|
-
the CLI through Bash and open contact sheets with Read: the Blender MCP
|
|
20
|
-
server is not registered in the hosted harness.
|
|
21
|
-
If Blender is unavailable, report that limitation and keep the authored
|
|
22
|
-
scripts; the code fallback below is for requests that did not require Blender.
|
|
23
|
-
|
|
24
|
-
- A **space**: a level, arena, interior, building, map, dungeon, station — several
|
|
25
|
-
rooms, lanes, walls or sites that must relate to each other, and a player who
|
|
26
|
-
moves through them.
|
|
27
|
-
- A **floor plan or reference** to trace (a sketch, an ASCII plan, a photo of a room).
|
|
28
|
-
- A **blockout**: the playable shape first, dressing later.
|
|
29
|
-
|
|
30
|
-
Default routes when the player did not explicitly request Blender:
|
|
31
|
-
|
|
32
|
-
- One recognisable object (a barrel, a cart, a statue) → `$genex-ai-model`.
|
|
33
|
-
- One parameterized object placed many times with variation, or a stylized shader
|
|
34
|
-
material → `$genex-threejs-procedural-assets`.
|
|
35
|
-
- The player's body, creatures, animation → `$genex-ai-character`,
|
|
36
|
-
`$genex-threejs-creatures`. Terrain from a heightmap → code.
|
|
37
|
-
|
|
38
|
-
Mixing all three in one scene is normal: the Blender level is the architecture, a
|
|
39
|
-
generated GLB is the hero piece, code is the repeated dressing.
|
|
40
|
-
|
|
41
|
-
## Is the lane on? Probe by doing
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
npx genex blender scene
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
Read the answer literally — there are three:
|
|
48
|
-
|
|
49
|
-
1. **A scene JSON prints** → the lane is on. Continue.
|
|
50
|
-
2. `Warming up a Blender seat…` and then `The Blender seat is still warming up. Run
|
|
51
|
-
the same command again in a minute.` → **not done yet**, even though the command
|
|
52
|
-
exited cleanly. A GPU is booting for you (about 20 s on a warm pod, ~2 minutes
|
|
53
|
-
on a cold one, up to ~20 minutes on a host that has never pulled the image).
|
|
54
|
-
Between re-runs keep building everything that does not need Blender — the game
|
|
55
|
-
code, the markers plan, the scripts themselves — and run the command again every
|
|
56
|
-
couple of minutes; the wait never counts against you. Never read this line as
|
|
57
|
-
success, and never read it as failure.
|
|
58
|
-
3. `The Blender lane is off on this stand`, `No Blender seat: fleet_full` or
|
|
59
|
-
`No Blender seat: pod_unavailable` → build
|
|
60
|
-
the same space **in code** with `$genex-threejs-procedural-assets`, say so in one
|
|
61
|
-
plain line to the player, and keep going. Do not wait, do not ask.
|
|
62
|
-
|
|
63
|
-
The seat, once granted, is remembered in `.genex/blender-seat.json` — later
|
|
64
|
-
commands are silent about it.
|
|
65
|
-
|
|
66
|
-
## The loop
|
|
67
|
-
|
|
68
|
-
Scripts are the level's source. Keep them in the project, one per zone:
|
|
69
|
-
|
|
70
|
-
```
|
|
71
|
-
blender/01-shell.py walls, floor, towers
|
|
72
|
-
blender/02-gatehouse.py
|
|
73
|
-
blender/03-courtyard.py
|
|
74
|
-
…
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
Run one:
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
npx genex blender exec --in blender/01-shell.py
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
Every run prints two things and writes one file:
|
|
84
|
-
|
|
85
|
-
- **The numbers** — `objects N meshes N tris N materials N radius N`. This is
|
|
86
|
-
the gate. Before you run, know what the script should produce (twelve objects,
|
|
87
|
-
about 4k tris, radius ≈ 40); after, compare. A render judge is unreliable for
|
|
88
|
-
pass/fail; the numbers are not.
|
|
89
|
-
- **The sheet** — `assets/blender/contact-sheet.webp`, four fixed views (front,
|
|
90
|
-
side, TOP, hero) from cameras derived from the scene bounds, so two steps compare
|
|
91
|
-
pixel for pixel. **Open it with your file-reading tool after every step.** The
|
|
92
|
-
TOP view is the floor-plan check; the hero view is the mood check. Nothing shows
|
|
93
|
-
it to you unless you look.
|
|
94
|
-
- Script `print()` output comes back as stdout; a raised exception comes back with
|
|
95
|
-
its traceback AND the sheet of the half-built scene, which is usually where the
|
|
96
|
-
bug is visible.
|
|
97
|
-
|
|
98
|
-
The Python namespace **persists between runs** (`bpy`, `bmesh`, `mathutils`,
|
|
99
|
-
`math`, `random` are preloaded): define `mat()` and `box()` helpers once in the
|
|
100
|
-
first script and use them in every later one. If a run says the service restarted
|
|
101
|
-
and the scene was restored from a checkpoint, re-read the numbers — your last step
|
|
102
|
-
may be missing; re-run that one script.
|
|
103
|
-
|
|
104
|
-
Other verbs:
|
|
105
|
-
|
|
106
|
-
```bash
|
|
107
|
-
npx genex blender snap --mode wireframe # topology; also normals | solid | lit
|
|
108
|
-
npx genex blender scene # the full graph as JSON, when a number surprises you
|
|
109
|
-
npx genex blender reset # empty scene (the namespace resets too)
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
Keep each step under about 90 seconds of Blender time: a script that loops
|
|
113
|
-
hundreds of boolean cuts is killed at the deadline and the scene comes back from
|
|
114
|
-
the last checkpoint. Split heavy work across scripts. A level is 8–15 steps, not 50.
|
|
115
|
-
|
|
116
|
-
## Craft rules that decide whether the export works
|
|
117
|
-
|
|
118
|
-
- **Metres.** Floor at `z = 0`, the map's centre at the origin. Blender is Z-up;
|
|
119
|
-
the export converts to Y-up, so the floor is the XZ plane in Three.js and a
|
|
120
|
-
Blender `(x, y, z)` lands at `(x, z, -y)`.
|
|
121
|
-
- **Name everything** `<zone>_<thing>` (`gate_portcullis`, `hall_table_1`). Names
|
|
122
|
-
survive the export and are how the game finds parts.
|
|
123
|
-
- **Materials: few and flat.** Six to eight for a whole level, one per surface
|
|
124
|
-
family (stone, dark stone, wood, roof, iron, glow). Set the Principled BSDF base
|
|
125
|
-
colour **and** `material.diffuse_color` — the sheet's fallback renderer reads the
|
|
126
|
-
second, and a scene that sets only the first exports with correct colours and
|
|
127
|
-
renders entirely grey. No image textures: they do not fit the export ceiling, and
|
|
128
|
-
an asset URL does not export.
|
|
129
|
-
- **Repetition by loop, never by an unapplied modifier.** Crenellations, columns,
|
|
130
|
-
pews: a Python `for`. An Array modifier that is not applied is not in the GLB.
|
|
131
|
-
- **Tri budget.** Keep the whole level under ~150k triangles and use 12–16 segments
|
|
132
|
-
on cylinders — phones load this file too. The export refuses above 6 MB; treat
|
|
133
|
-
that as "no longer a game asset", not as a limit to work around.
|
|
134
|
-
- **Markers.** Empties export as named nodes: `bpy.data.objects.new("spawn", None)`
|
|
135
|
-
placed and linked into the scene collection, likewise `key_1`, `door_crypt`,
|
|
136
|
-
`patrol_1`. The level tells the game where things go; the game reads them with
|
|
137
|
-
`scene.getObjectByName("spawn")`.
|
|
138
|
-
- **Lights stay in the game.** Blender lights do not export usefully; light the
|
|
139
|
-
level in Three.js (a hemisphere + a sun, point lights at torches and hearths).
|
|
140
|
-
- **Collision is the game's.** Static level geometry gets Rapier trimesh colliders
|
|
141
|
-
per mesh — `$genex-threejs-physics-rapier`. If a mesh is too dense to collide
|
|
142
|
-
against, add a simplified `col_<zone>` box in Blender and keep the visual one out
|
|
143
|
-
of physics.
|
|
144
|
-
|
|
145
|
-
A minimal first script, the shape every later one follows:
|
|
146
|
-
|
|
147
|
-
```python
|
|
148
|
-
import bpy
|
|
149
|
-
bpy.ops.wm.read_factory_settings(use_empty=True)
|
|
150
|
-
|
|
151
|
-
def mat(name, rgb, rough=0.85):
|
|
152
|
-
m = bpy.data.materials.new(name)
|
|
153
|
-
m.use_nodes = True
|
|
154
|
-
b = m.node_tree.nodes["Principled BSDF"]
|
|
155
|
-
b.inputs["Base Color"].default_value = (*rgb, 1.0)
|
|
156
|
-
b.inputs["Roughness"].default_value = rough
|
|
157
|
-
m.diffuse_color = (*rgb, 1.0) # BOTH, or the sheet renders grey
|
|
158
|
-
return m
|
|
159
|
-
|
|
160
|
-
def box(name, loc, half, m):
|
|
161
|
-
bpy.ops.mesh.primitive_cube_add(size=2.0, location=loc)
|
|
162
|
-
o = bpy.context.active_object
|
|
163
|
-
o.name, o.scale = name, half
|
|
164
|
-
o.data.materials.append(m)
|
|
165
|
-
return o
|
|
166
|
-
|
|
167
|
-
STONE = mat("Stone", (0.46, 0.44, 0.41))
|
|
168
|
-
box("yard_floor", (0, 0, -0.25), (35, 35, 0.25), mat("Ground", (0.30, 0.28, 0.24)))
|
|
169
|
-
for sx, sy in ((1, 1), (1, -1), (-1, 1), (-1, -1)):
|
|
170
|
-
bpy.ops.mesh.primitive_cylinder_add(radius=3, depth=14, vertices=16,
|
|
171
|
-
location=(sx * 35, sy * 35, 7))
|
|
172
|
-
t = bpy.context.active_object
|
|
173
|
-
t.name = f"tower_{sx}_{sy}"
|
|
174
|
-
t.data.materials.append(STONE)
|
|
175
|
-
print("shell:", len(bpy.context.scene.objects), "objects")
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
## Hero pieces from `genex model`
|
|
179
|
-
|
|
180
|
-
```bash
|
|
181
|
-
npx genex model "weathered stone knight effigy on a tomb, medieval" # prints a URL
|
|
182
|
-
npx genex blender import https://assets.genex.technology/generations/<id>/model-glb
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
`import` prints the object names it added and renders a fresh sheet; place and
|
|
186
|
-
scale them in the next `exec` (`bpy.data.objects["…"].location = (…)`). Import
|
|
187
|
-
when the piece must be composed WITH the architecture (a gate in a wall, a statue
|
|
188
|
-
in a niche). When it is dressing, skip the import: drop a marker in Blender and
|
|
189
|
-
load the GLB in Three.js at that marker — it keeps the level file small.
|
|
190
|
-
|
|
191
|
-
## Export and load
|
|
192
|
-
|
|
193
|
-
```bash
|
|
194
|
-
npx genex blender export --out public/assets/level.glb
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
Load it like any GLB. The quality kit's rung ladder applies only to generated
|
|
198
|
-
`/generations/` URLs, so this file loads as-is — the tri and material budgets
|
|
199
|
-
above are what keep it phone-safe.
|
|
200
|
-
|
|
201
|
-
```ts
|
|
202
|
-
import { createGltfLoader } from "./controllers/quality/gltf-loader.ts";
|
|
203
|
-
|
|
204
|
-
const gltfLoader = createGltfLoader(renderer);
|
|
205
|
-
const level = await gltfLoader.loader.loadAsync("/assets/level.glb");
|
|
206
|
-
level.scene.traverse((o) => {
|
|
207
|
-
if ((o as THREE.Mesh).isMesh) { o.castShadow = true; o.receiveShadow = true; }
|
|
208
|
-
});
|
|
209
|
-
scene.add(level.scene);
|
|
210
|
-
const spawn = level.scene.getObjectByName("spawn");
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
Then colliders (`$genex-threejs-physics-rapier`), the player
|
|
214
|
-
(`$genex-threejs-character-controller`), lights, and a real screenshot check
|
|
215
|
-
(`$genex-threejs-visual-validation`). Record the level in `DESIGN.md`'s Assets as
|
|
216
|
-
`local Blender build — scripts under blender/`, never a provider generation id.
|
|
217
|
-
|
|
218
|
-
## Money
|
|
219
|
-
|
|
220
|
-
A **hosted session's** seat bills a few credits per minute while it is held, idle
|
|
221
|
-
or not, and ends with the session — there is no close command for it. So build
|
|
222
|
-
the level in one sitting: shell → zones → hero pieces → export, then move on to
|
|
223
|
-
the game. Batch changes into fewer, larger scripts; every step renders one sheet.
|
|
224
|
-
|
|
225
|
-
At a **terminal with no Blender installed**, `npx genex blender seat` rents the
|
|
226
|
-
same pooled GPU on your own credits (the price and the idle timeout print on
|
|
227
|
-
open); it ends itself after 15 idle minutes, or run `npx genex blender release`
|
|
228
|
-
when you are done. Prefer `npx genex blender serve` against your own Blender
|
|
229
|
-
when one is available — the measurements favour it, and it costs nothing.
|
|
230
|
-
|
|
231
|
-
## Troubleshooting
|
|
232
|
-
|
|
233
|
-
- `payload_too_large` on export → fewer cylinder segments, delete faces the player
|
|
234
|
-
never sees, or export two GLBs (`--out public/assets/level-a.glb`).
|
|
235
|
-
- The sheet is grey → `material.diffuse_color` was not set (see above).
|
|
236
|
-
- `refused the seat token (401)` → the rejected cached grant has been removed.
|
|
237
|
-
In hosted creation, run `npx genex blender scene` to acquire a new seat and
|
|
238
|
-
inspect the restored scene before deciding whether to rerun the failed script.
|
|
239
|
-
At a terminal, run `npx genex blender seat` first. Recovery never automatically
|
|
240
|
-
replays scene changes; a replaced pod restores the latest saved checkpoint.
|
|
241
|
-
- `seat_not_ready` → the pod is still booting; run again shortly.
|
|
242
|
-
- The numbers are right but the top view is wrong → coordinates: `y` in Blender is
|
|
243
|
-
depth, and `scale` on a 2-unit cube is the half-size.
|
|
@@ -1,78 +0,0 @@
|
|
|
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.
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: genex-tool-publish
|
|
3
|
-
description: Put the game in this folder on the web with Genex — the draft page, `npx genex preview`, then `promote` / `publish`; the link you hand the user, the size limits, and what to do with the preflight lines. Installed once the folder is connected to a hosted Genex game (`npx genex init --convert`). Load it before the first preview.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Genex Tools · Publish
|
|
7
|
-
|
|
8
|
-
The user built this game themselves and asked for it online. Your job is to
|
|
9
|
-
put it there **as it is** — the code, the structure and the assets stay
|
|
10
|
-
exactly what they are. Publishing adds glue and nothing else; it never starts
|
|
11
|
-
a rework, a design document or a build plan.
|
|
12
|
-
|
|
13
|
-
## The glue (all of it)
|
|
14
|
-
|
|
15
|
-
1. **A static build.** The game must build to files with its own build
|
|
16
|
-
command — `npm run build` into `dist/`, or an `index.html` at the root
|
|
17
|
-
with no build step. Asset paths must work from the game's own hosted URL,
|
|
18
|
-
so prefer relative ones (Vite: `base: './'`). Files the game loads at
|
|
19
|
-
runtime — everything in `./assets` — must end up inside the build (Vite:
|
|
20
|
-
a `public/` folder, or copy `assets/` into `dist/` in the build).
|
|
21
|
-
2. **Player identity.** Load `$genex-threejs-embed-auth` and add the one
|
|
22
|
-
`initEmbed(...)` call at the very top of the boot code. Create the
|
|
23
|
-
renderer and draw a frame BEFORE any `await waitForPlayer()` — on a hosted
|
|
24
|
-
page identity takes seconds, and a game that awaits it first ships black.
|
|
25
|
-
3. **The CLI as a dev dependency** so plain `npx genex` keeps resolving here
|
|
26
|
-
(setup already did this; check `package.json` if in doubt).
|
|
27
|
-
|
|
28
|
-
Commit the glue as its own small commit when the folder is a git repo, so the
|
|
29
|
-
line between the user's game and what publishing added stays visible.
|
|
30
|
-
|
|
31
|
-
## Preview
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
npx genex preview
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Builds, uploads and puts the build on the game's **draft page** — unlisted,
|
|
38
|
-
only the user can open it. When it reports live, open the hosted build once
|
|
39
|
-
yourself and confirm it loads with no missing files (the dev server forgives
|
|
40
|
-
paths the hosted build will not), then hand over the link.
|
|
41
|
-
|
|
42
|
-
**The link is always the game's page on Genex, never the raw play address,
|
|
43
|
-
never localhost, never a file path:**
|
|
44
|
-
|
|
45
|
-
- draft: `<dashboard>/draft/<slug>`
|
|
46
|
-
- public, once published: `<dashboard>/world/<slug>`
|
|
47
|
-
|
|
48
|
-
`<dashboard>` is the first `dashboardOrigins` entry in `.genex/project.json`
|
|
49
|
-
and `<slug>` is the `slug` there. `preview` prints the exact page link as
|
|
50
|
-
"your game's page" — use that line verbatim.
|
|
51
|
-
|
|
52
|
-
## The preflight is a report, not a to-do list
|
|
53
|
-
|
|
54
|
-
`preview` prints warning lines before it uploads — an estimated phone GPU
|
|
55
|
-
budget, a music track with no volume slider, a paid asset nobody wired, a
|
|
56
|
-
viewport meta line. None of them blocks the deploy, and none of them was
|
|
57
|
-
asked for. So: **ship first**, hand over the link, then relay each line to
|
|
58
|
-
the user in one plain sentence with an offer ("phones will struggle with the
|
|
59
|
-
textures — want me to shrink them?"). Fix one only on the user's yes. Never
|
|
60
|
-
turn the report into a milestone before the link.
|
|
61
|
-
|
|
62
|
-
## Draft and public version
|
|
63
|
-
|
|
64
|
-
`preview` updates the **draft** and never touches what players are on. The
|
|
65
|
-
first release lists the game:
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
npx genex publish --categories games
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
Pick 1–3 categories that fit (`games`, `assets`, `physics`, `terrain`,
|
|
72
|
-
`lighting`, `vfx`); `games` when unsure. Ask before the first publish — "This
|
|
73
|
-
is a private draft only you can open. Say the word and I'll publish it for
|
|
74
|
-
anyone to play." — and celebrate the public page link when it lands.
|
|
75
|
-
|
|
76
|
-
After that first release the game is two versions, and the user only ever
|
|
77
|
-
hears these two words for them: the **draft** (updated by `preview`) and the
|
|
78
|
-
**public version** (what everyone plays). "Publish it", "update it" and "yes"
|
|
79
|
-
after the first release ALL mean:
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
npx genex promote # the exact draft build goes public — no rebuild
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
Never run `publish` a second time (it would ship an untried rebuild). If
|
|
86
|
-
anything changed since the last `preview`, preview again before promoting.
|
|
87
|
-
Ask once per round of work, in one line, and keep working while you wait.
|
|
88
|
-
|
|
89
|
-
## Limits and refusals
|
|
90
|
-
|
|
91
|
-
- **Upload size**: ~95 MB per file, ~500 MB in total. Over that, tell the user
|
|
92
|
-
plainly which part is too large (usually a video, model or audio file) and by
|
|
93
|
-
roughly how much; ask before compressing or removing anything.
|
|
94
|
-
- **Terms refusal**: the CLI prints a link, waits for the user's click and
|
|
95
|
-
re-sends by itself — hand the link over and let it finish.
|
|
96
|
-
- **`preview` says the folder is behind another machine** (`stale_source`):
|
|
97
|
-
`npx genex pull` takes the newer draft, then redo the change — never
|
|
98
|
-
`--force` over somebody else's work.
|
|
99
|
-
- **Out of credits or a lane down**: `npx genex doctor` says which; publishing
|
|
100
|
-
itself costs nothing.
|