@genex-ai/cli-demo 0.43.0 → 0.44.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/package.json
CHANGED
|
@@ -58,8 +58,10 @@ side — reads as broken at a glance.
|
|
|
58
58
|
- **Verify it, don't assume it.** Orientation **is** visible in a still — in your
|
|
59
59
|
self-check screenshot confirm the hero faces its travel direction AND that NPCs driven
|
|
60
60
|
by chase/aim code face their target (an enemy rotated 90° from its victim is this
|
|
61
|
-
pipeline's most common visible bug).
|
|
62
|
-
|
|
61
|
+
pipeline's most common visible bug). On an unpublished draft, capture real gameplay in
|
|
62
|
+
local test mode (`?genex_local_test=1` on the dev server — the embed-auth skill's
|
|
63
|
+
"Self-testing a draft" section); if you still can't capture gameplay, say so plainly
|
|
64
|
+
instead of skipping the check silently.
|
|
63
65
|
|
|
64
66
|
## Load it into the scene
|
|
65
67
|
|
|
@@ -23,6 +23,9 @@ for both, using the SDK's token. The SDK handles every context with one
|
|
|
23
23
|
zero clicks; everyone else arrives as a guest with a small dismissible
|
|
24
24
|
"sign in to save progress" popover (rendered by the SDK — don't build your
|
|
25
25
|
own). Nobody ever hits a login wall on a published game.
|
|
26
|
+
- **Local test mode (your own self-testing):** `?genex_local_test=1` on the
|
|
27
|
+
local dev server boots a credential-less local session — see "Self-testing
|
|
28
|
+
a draft" below.
|
|
26
29
|
|
|
27
30
|
While identity is resolving (or blocked) the SDK shows its own full-screen
|
|
28
31
|
overlay over the game, so never build a separate "connecting" screen for auth.
|
|
@@ -102,7 +105,7 @@ boot-path gate; `waitForAuth()` guards saves only.
|
|
|
102
105
|
- `getAuthState()` → `"pending" | "authenticated" | "guest" | "blocked"` —
|
|
103
106
|
synchronous.
|
|
104
107
|
- `getUser()` → `{ id, name, image? } | null` — non-null once authenticated OR
|
|
105
|
-
guest. Guest ids are prefixed `guest
|
|
108
|
+
guest. Guest ids are prefixed `guest:` (local test mode: `local:test`).
|
|
106
109
|
- `getEmbedToken()` → `string | undefined` — the raw token, for the RARE
|
|
107
110
|
advanced case of calling the Genex API by hand. The state/leaderboard
|
|
108
111
|
helpers below attach it automatically — prefer them; never hand-roll fetch
|
|
@@ -138,7 +141,8 @@ session is blocked):
|
|
|
138
141
|
- `getLeaderboard({ board?, limit?, order? }?)` → `Promise<{ items, me }>` —
|
|
139
142
|
top entries (verified display names — never trust client-side name input
|
|
140
143
|
for this) + the signed-in player's own `{ rank, score }`. Works for guests
|
|
141
|
-
too (`me: null`). `limit` caps at 100 server-side.
|
|
144
|
+
too (`me: null`). `limit` caps at 100 server-side. Local test mode resolves
|
|
145
|
+
`{ items: [], me: null }` locally.
|
|
142
146
|
|
|
143
147
|
Server write limits (per player, per minute): **60 player-saves, 120
|
|
144
148
|
world-saves, 30 score submits**. A debounced ~1/sec checkpoint never gets near
|
|
@@ -256,34 +260,63 @@ SDK's own top-right "sign in to save progress" popover. The return trip
|
|
|
256
260
|
carries a one-time pass (or an inert guest marker) in the URL that the SDK
|
|
257
261
|
consumes and removes immediately. Unpublished drafts are the exception:
|
|
258
262
|
strangers can't play them, so a draft link shows the SDK's sign-in gate
|
|
259
|
-
instead. Don't code around any
|
|
260
|
-
be affected, and `isEmbedded()`
|
|
261
|
-
concerns.
|
|
263
|
+
instead (for self-testing, see local test mode below). Don't code around any
|
|
264
|
+
of this: no `?`/`#` URL params of yours will be affected, and `isEmbedded()`
|
|
265
|
+
/ the return-trip handling are internal SDK concerns.
|
|
262
266
|
|
|
263
|
-
###
|
|
267
|
+
### Self-testing a draft: local test mode
|
|
264
268
|
|
|
265
269
|
An unpublished draft shows the sign-in gate to any browser that isn't signed
|
|
266
270
|
in as the owner — **including your own test browser** (Playwright, headless
|
|
267
|
-
Chrome)
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
271
|
+
Chrome) — and the hosted draft URL applies the same identity rule. The one
|
|
272
|
+
supported way to see and play the game yourself is **local test mode**: open
|
|
273
|
+
the local dev server with the explicit opt-in marker —
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
http://localhost:5173/?genex_local_test=1
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
(any port; append with `&` if the URL already has a query). On an exact http
|
|
280
|
+
loopback origin (`localhost`, `127.0.0.1`, `[::1]`) the SDK skips the
|
|
281
|
+
identity flow entirely and boots a guest-like session: no redirect, no
|
|
282
|
+
overlay, `waitForPlayer()` resolves with the unmistakable local identity
|
|
283
|
+
`{ id: "local:test", name: "Local Tester" }`, and the console prints a
|
|
284
|
+
"local test mode" notice. Requires `@genex-ai/embed-sdk` 0.5.0+ — on an older
|
|
285
|
+
project the marker does nothing; apply the pending platform update first (any
|
|
286
|
+
`genex` command prints the update nudge and how to apply it), then retry.
|
|
287
|
+
|
|
288
|
+
**It validates:** rendering, camera, controls, HUD, game feel, and real
|
|
289
|
+
gameplay screenshots — everything local.
|
|
290
|
+
|
|
291
|
+
**It does NOT validate** (nothing online exists in this mode; no credential
|
|
292
|
+
is ever minted): real sign-in (`waitForAuth()` stays pending, exactly like a
|
|
293
|
+
guest), saves (they queue in memory), leaderboards (`getLeaderboard()`
|
|
294
|
+
resolves `{ items: [], me: null }` locally), score submits, and multiplayer
|
|
295
|
+
(`getColyseusAuth()` is `undefined`, so `connect()` fails at the relay —
|
|
296
|
+
expected in this mode, not a bug to chase).
|
|
297
|
+
|
|
298
|
+
Rules:
|
|
299
|
+
|
|
300
|
+
- **Label the evidence** in your handoff: "validated in local test mode —
|
|
301
|
+
auth, saves, and multiplayer not exercised." Presenting a local-test
|
|
302
|
+
capture as full validation is an over-claim.
|
|
303
|
+
- Pointer lock still can't be acquired headlessly (`requestPointerLock`
|
|
304
|
+
throws in headless Chromium): for aim games validate the unlocked "click
|
|
305
|
+
to aim" cue and the wiring, not the lock itself (see
|
|
306
|
+
`$genex-threejs-visual-validation` step 6).
|
|
307
|
+
- The marker is inert on any hosted URL, on https, and inside any iframe —
|
|
308
|
+
local test mode cannot open the hosted draft; hosted draft access stays
|
|
309
|
+
owner-only. Do NOT work around that gate: no undocumented URL fragments,
|
|
310
|
+
no auth mocks, and never drive the user's own signed-in browser.
|
|
311
|
+
- Opening localhost WITHOUT the marker keeps the normal real-auth flow (the
|
|
312
|
+
identity bounce) — that's for testing real sign-in, not for self-testing.
|
|
313
|
+
- The owner's draft run-through stays a required beat, not a fallback: push
|
|
314
|
+
`genex preview` at each playable milestone and hand it off plainly ("check
|
|
315
|
+
the draft — you can now X; ping me if something feels off"), then keep
|
|
316
|
+
building while they look. Hosted QA catches what local test mode can't:
|
|
317
|
+
real identity, saves, multiplayer, feel. Once the game is **published**,
|
|
318
|
+
any fresh browser gets in as a guest, so full visual validation also works
|
|
319
|
+
without the marker.
|
|
287
320
|
|
|
288
321
|
## Checklist
|
|
289
322
|
|
|
@@ -304,6 +337,8 @@ and a gate capture is NOT visual evidence.
|
|
|
304
337
|
- [ ] No token value is ever logged or sent to analytics.
|
|
305
338
|
- [ ] No custom sign-in prompt, guest badge, or auth overlay — the SDK popover/
|
|
306
339
|
overlay and the dashboard own all of that UX.
|
|
340
|
+
- [ ] Self-test evidence captured in local test mode is labeled as such in the
|
|
341
|
+
handoff ("local test mode — auth, saves, and multiplayer not exercised").
|
|
307
342
|
|
|
308
343
|
## Troubleshooting
|
|
309
344
|
|
|
@@ -316,7 +351,15 @@ and a gate capture is NOT visual evidence.
|
|
|
316
351
|
- **State is `"blocked"` / `waitForPlayer()` rejects** — an unpublished draft
|
|
317
352
|
opened by a non-owner, or auth infrastructure was unreachable. The SDK
|
|
318
353
|
overlay (or the dashboard, when embedded) shows the sign-in prompt; the game
|
|
319
|
-
just stays paused behind it. Don't retry in a loop.
|
|
354
|
+
just stays paused behind it. Don't retry in a loop. Self-testing a draft
|
|
355
|
+
locally? Use local test mode (`?genex_local_test=1`) instead.
|
|
356
|
+
- **Local test mode doesn't activate** — check all four: the value is exactly
|
|
357
|
+
`genex_local_test=1`, the origin is http loopback (`localhost`/`127.0.0.1`/
|
|
358
|
+
`[::1]` — not https, not a LAN IP), the page is not inside an iframe, and
|
|
359
|
+
`@genex-ai/embed-sdk` is 0.5.0+ (older: apply the pending platform update).
|
|
360
|
+
- **Multiplayer `connect()` fails in local test mode** — by design: no relay
|
|
361
|
+
credential exists there. Validate multiplayer on the hosted draft (the
|
|
362
|
+
owner's session) or the published game, and say plainly when it wasn't.
|
|
320
363
|
- **Multiplayer join rejected with 401** — `connect()` ran before
|
|
321
364
|
`waitForPlayer()` resolved, without `auth: getColyseusAuth()!`, or with a
|
|
322
365
|
stale cached token on reconnect (read it fresh each call).
|
|
@@ -451,7 +451,11 @@ from any still capture whether movement feels smooth.** Don't try — it leads t
|
|
|
451
451
|
|
|
452
452
|
1. **Trust the SDK's smoothing.** Draw `state` directly; don't add your own.
|
|
453
453
|
2. **Verify it *runs*:** two clients, distinct meshes, both move, no console errors, each sees the
|
|
454
|
-
other (and the ball, if any). That's all a capture can prove.
|
|
454
|
+
other (and the ball, if any). That's all a capture can prove. Local test mode (the embed-auth
|
|
455
|
+
skill's `?genex_local_test=1`) can NOT do this: it mints no relay credential, so `connect()`
|
|
456
|
+
fails there by design and two local-test tabs never see each other — run the two-client check
|
|
457
|
+
on the published game (or have the owner open their draft), and if multiplayer wasn't
|
|
458
|
+
exercised, say exactly that in your handoff instead of implying it was.
|
|
455
459
|
3. **Then say plainly:** *"Multiplayer smoothness depends on your network and can only be felt by a
|
|
456
460
|
person — open it in two tabs or with a friend and tell me how it feels."* Stop there.
|
|
457
461
|
|
|
@@ -25,18 +25,26 @@ evidence, temporal checks, budgets, and explicit rejection criteria.
|
|
|
25
25
|
## Interaction smoke check (the game fast path)
|
|
26
26
|
|
|
27
27
|
For plain game tasks — nothing from the procedural/visual-system pack loaded —
|
|
28
|
-
this is the whole acceptance gate, and it is also the
|
|
28
|
+
this is the whole acceptance gate, and it is also the *ceiling*: a smoke check,
|
|
29
|
+
not a certification. Run it ONCE per milestone to catch obvious breakage, fix
|
|
30
|
+
what's clearly broken, and hand the feel/polish judgment to the player — don't
|
|
31
|
+
loop re-testing the same build, and don't try to exercise every button and edge
|
|
32
|
+
case yourself. The player deciding "does it feel right?" is faster and truer
|
|
33
|
+
than you clicking everything twice.
|
|
29
34
|
|
|
30
35
|
1. Load the page in a real browser; the canvas renders (no black screen, no
|
|
31
|
-
console errors).
|
|
36
|
+
console errors). For an unpublished draft, open the dev server in local
|
|
37
|
+
test mode — `http://localhost:5173/?genex_local_test=1` (the embed-auth
|
|
38
|
+
skill's "Self-testing a draft" section) — so you see the game, not the
|
|
39
|
+
sign-in gate.
|
|
32
40
|
2. Press each documented control once (keys, pointer); assert a **visible
|
|
33
41
|
response** to every one — the player moves, the camera turns, the button
|
|
34
42
|
fires.
|
|
35
43
|
3. Capture one screenshot of live gameplay — of the **game**, not a sign-in
|
|
36
44
|
gate or loading screen. A capture of the SDK's "Sign in to play" overlay is
|
|
37
|
-
NOT gameplay evidence
|
|
38
|
-
|
|
39
|
-
|
|
45
|
+
NOT gameplay evidence. Evidence captured in local test mode must be labeled
|
|
46
|
+
as such in the handoff ("local test mode — auth, saves, and multiplayer not
|
|
47
|
+
exercised"); presenting it as full validation is an over-claim.
|
|
40
48
|
4. In that screenshot, check oriented models: the hero faces its travel
|
|
41
49
|
direction, and NPCs driven by chase/aim code face their target. A model
|
|
42
50
|
rotated 90° reads as broken — `$genex-ai-model` has the one-time facing
|