@genex-ai/cli-demo 0.92.0 → 0.93.0-dev.235
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/skills/genex-ai-skybox/SKILL.md +1 -1
- package/templates/skills/genex-ai-texture/SKILL.md +1 -1
- package/templates/skills/genex-ai-video/SKILL.md +1 -1
- package/templates/skills/genex-getting-started/SKILL.md +2 -2
- package/templates/skills/genex-threejs-multiplayer/SKILL.md +46 -0
- package/templates/skills/genex-updates/SKILL.md +1 -1
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import fs from "fs";
|
|
|
8
8
|
import os from "os";
|
|
9
9
|
import path from "path";
|
|
10
10
|
import { fileURLToPath } from "url";
|
|
11
|
-
var RAW_CHANNEL = "
|
|
11
|
+
var RAW_CHANNEL = "dev";
|
|
12
12
|
var CLI_CHANNEL = RAW_CHANNEL === "dev" ? "dev" : "latest";
|
|
13
13
|
var STANDS = {
|
|
14
14
|
prod: { api: "https://api.genex.games", dashboard: "https://genex.games" },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genex-ai/cli-demo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.93.0-dev.235",
|
|
4
4
|
"description": "Set up your project's agent workspace (.claude/.codex/.cursor in the game folder), authorize, create a game project, generate AI assets, and publish (genex CLI).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -116,7 +116,7 @@ scene.background = texture; // keep the raw texture for the visible sky
|
|
|
116
116
|
|
|
117
117
|
## Troubleshooting
|
|
118
118
|
|
|
119
|
-
- **"Not authorized"** — run `npx @genex-ai/cli-demo@
|
|
119
|
+
- **"Not authorized"** — run `npx @genex-ai/cli-demo@dev init` first (it writes your `GENEX_TOKEN`).
|
|
120
120
|
- **"Out of credits" (`insufficient_credits`)** — the account has no credits left for
|
|
121
121
|
this skybox generation. Tell the user the facts the CLI printed: their balance, this
|
|
122
122
|
generation's cost, and when their credits refill. Then offer to continue the build
|
|
@@ -225,7 +225,7 @@ first one is the one a screenshot of the whole arena will not show you.
|
|
|
225
225
|
|
|
226
226
|
## Troubleshooting
|
|
227
227
|
|
|
228
|
-
- **"Not authorized"** — run `npx @genex-ai/cli-demo@
|
|
228
|
+
- **"Not authorized"** — run `npx @genex-ai/cli-demo@dev init` first (it writes your `GENEX_TOKEN`).
|
|
229
229
|
- **"Out of credits" (`insufficient_credits`)** — the account has no credits left for
|
|
230
230
|
this texture generation. Tell the user the facts the CLI printed: their balance,
|
|
231
231
|
this generation's cost, and when their credits refill. Then offer to continue the
|
|
@@ -151,7 +151,7 @@ set belongs to `$genex-ai-hud` — both build on `npx genex image`/`video`.
|
|
|
151
151
|
|
|
152
152
|
## Troubleshooting
|
|
153
153
|
|
|
154
|
-
- **"Not authorized"** — run `npx @genex-ai/cli-demo@
|
|
154
|
+
- **"Not authorized"** — run `npx @genex-ai/cli-demo@dev init` first (it writes your `GENEX_TOKEN`).
|
|
155
155
|
- **"Prompt rejected"** — the provider's content-safety filter blocked the prompt.
|
|
156
156
|
This is non-retryable; retrying the same wording fails again. Rewrite the prompt.
|
|
157
157
|
- **Nothing plays / black surface** — the first `video.play()` must run inside a user
|
|
@@ -131,7 +131,7 @@ and re-link the clone to the same live game:
|
|
|
131
131
|
```bash
|
|
132
132
|
git clone <the game's repo url> my-game && cd my-game
|
|
133
133
|
npm install
|
|
134
|
-
npx @genex-ai/cli-demo@
|
|
134
|
+
npx @genex-ai/cli-demo@dev link <slug> # slug = the name in the play URL
|
|
135
135
|
```
|
|
136
136
|
|
|
137
137
|
Don't know the slug? **`npx genex list`** prints every game on your account —
|
|
@@ -158,7 +158,7 @@ Safe to run any time — genex-owned skills are refreshed to the latest version,
|
|
|
158
158
|
and your own files are never touched:
|
|
159
159
|
|
|
160
160
|
```bash
|
|
161
|
-
npx @genex-ai/cli-demo@
|
|
161
|
+
npx @genex-ai/cli-demo@dev init
|
|
162
162
|
```
|
|
163
163
|
|
|
164
164
|
Use `--force` only if you intentionally want your own existing files overwritten
|
|
@@ -331,6 +331,23 @@ halves of this rule are non-negotiable:
|
|
|
331
331
|
`minPlayers: 2, maxPlayers: 2`: the instant the second player joins). If it doesn't close on
|
|
332
332
|
both, the lobby is broken — fix it; do not ship a waiting room you haven't watched close.
|
|
333
333
|
|
|
334
|
+
**While `status === 'searching'` the roster is EMPTY — count the queue, not `players`.** The
|
|
335
|
+
matchmaker never parks a searcher in a room as a non-player: until it can seat you, you are in the
|
|
336
|
+
search line and in no room at all, so `players`/`connectedPlayers` are `[]`. A pre-match screen that
|
|
337
|
+
counts `players.length` there shows `0 / 2` to a player who is sitting in it, forever. Use the queue
|
|
338
|
+
count — it includes YOU, so it reads `1 / 2` when you are alone — and switch to the roster the moment
|
|
339
|
+
you are seated:
|
|
340
|
+
|
|
341
|
+
```ts
|
|
342
|
+
const v = mm.matchmaking;
|
|
343
|
+
const lobbyCount = v.status === "searching" ? Math.max(v.queue.size, 1) : v.connectedPlayers.length;
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
This bites hardest in the commonest co-op shape: with `minPlayers === maxPlayers` (e.g. `2` and `2`)
|
|
347
|
+
the room can only be formed once BOTH searchers exist, so you go `searching → playing` and **never
|
|
348
|
+
pass through `waiting`** — the screen the player stares at is the SEARCHING screen, and driving it
|
|
349
|
+
off `players.length` pins it at `0 / target` for its entire life.
|
|
350
|
+
|
|
334
351
|
Two ways to present the lobby:
|
|
335
352
|
|
|
336
353
|
- **A) UI lobby (Dota-style).** While `status === 'waiting'`, render an OVERLAY from `mm.matchmaking`
|
|
@@ -552,6 +569,35 @@ fights (many writers). A ball on `objects` glides and has one owner. That's the
|
|
|
552
569
|
nearest `tier.remoteAvatarCap` remotes (`$genex-threejs-adaptive-quality`) — freeze the
|
|
553
570
|
mixer and billboard or hide the rest; a room allows up to 64 players and 64 live avatars
|
|
554
571
|
is a real phone memory kill on its own.
|
|
572
|
+
- **Build each remote's body exactly ONCE — reserve the id BEFORE the first `await`.** You read
|
|
573
|
+
`room.players` every frame, but loading a body is async and slow (seconds). If the only guard is
|
|
574
|
+
the map you fill *after* the await, every frame in that window passes it: you spawn one body per
|
|
575
|
+
frame, each stranded where it spawned — a trail of frozen clones behind the moving player — plus
|
|
576
|
+
dozens of wasted loads. Mark the id synchronously, and drop the body if that player left mid-load:
|
|
577
|
+
|
|
578
|
+
```ts
|
|
579
|
+
const bodies = new Map<string, Body>();
|
|
580
|
+
const loading = new Set<string>(); // the seat reservation
|
|
581
|
+
function ensureBody(p: Player) {
|
|
582
|
+
if (bodies.has(p.id) || loading.has(p.id)) return; // BOTH — checked before any await
|
|
583
|
+
loading.add(p.id);
|
|
584
|
+
void (async () => {
|
|
585
|
+
try {
|
|
586
|
+
const body = await loadVrmClone(p.avatarUrl || "./assets/avatar.vrm");
|
|
587
|
+
if (!room.activePlayers.has(p.id)) return; // left while loading — never add it
|
|
588
|
+
scene.add(body.scene);
|
|
589
|
+
bodies.set(p.id, body);
|
|
590
|
+
} finally { loading.delete(p.id); } // always release, success or throw
|
|
591
|
+
})();
|
|
592
|
+
}
|
|
593
|
+
// Each frame: ensureBody for every remote, then drop bodies whose id is gone.
|
|
594
|
+
for (const [id, body] of bodies) {
|
|
595
|
+
if (!room.activePlayers.has(id)) { scene.remove(body.scene); bodies.delete(id); }
|
|
596
|
+
}
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
The same rule covers anything else you lazily load per player or per object (nameplates, weapon
|
|
600
|
+
models, audio): a check that straddles an `await` is not a guard.
|
|
555
601
|
- `room.activePlayers` — the connected-only subset of `room.players`; use its size for live quorum.
|
|
556
602
|
- `room.objects` — shared objects nobody owns until claimed (a ball, an NPC):
|
|
557
603
|
- `claim(id)` — **legacy** optimistic request. It flips local ownership immediately and is corrected
|
|
@@ -38,7 +38,7 @@ update, so update immediately.)
|
|
|
38
38
|
Run exactly the command the nudge printed, from the game project root:
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
-
npm i -D @genex-ai/cli-demo@
|
|
41
|
+
npm i -D @genex-ai/cli-demo@dev # the genex CLI (a dev dependency)
|
|
42
42
|
npm i @genex-ai/embed-sdk@latest # identity/saves SDK (ships inside the game)
|
|
43
43
|
npm i @genex-ai/multiplayer@latest # multiplayer SDK (only if the game uses it)
|
|
44
44
|
```
|