incanto 0.46.0 → 0.48.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/bin/incanto-check.mjs +5 -1
- package/bin/incanto-feel.mjs +5 -1
- package/bin/incanto-frame.mjs +115 -7
- package/bin/incanto-logs.mjs +127 -0
- package/bin/incanto-model.mjs +79 -10
- package/bin/incanto-playtest.mjs +5 -1
- package/bin/incanto-verify.mjs +245 -0
- package/dist/3d.d.ts +89 -4
- package/dist/3d.js +90 -3
- package/dist/{create-game-BtCNdkjI.js → create-game-akjPkFv5.js} +99 -3
- package/dist/{frame-report-Ct8XgsmV.d.ts → frame-report-DZ70IY26.d.ts} +25 -0
- package/dist/{frame-report-Lr3VO24R.js → frame-report-njybhZon.js} +130 -3
- package/dist/index.d.ts +101 -1
- package/dist/index.js +3 -2
- package/dist/log-report-lxrQY9cH.js +0 -0
- package/dist/react.js +1 -1
- package/dist/{src-B43b6bZo.js → src-Bl1Kire1.js} +1 -1
- package/dist/{test-BboGNQr-.js → test-E4-otKqK.js} +51 -4
- package/dist/test.d.ts +55 -1
- package/dist/test.js +2 -2
- package/dist/vite.d.ts +13 -2
- package/dist/vite.js +65 -10
- package/editor/assets/{agent8-Dl5ZZLu-.js → agent8-_007gPF8.js} +1 -1
- package/editor/assets/{debug-j9Pi6RvO.js → debug-0DI_MJaq.js} +1 -1
- package/editor/assets/{index-Y-93awAL.js → index-B-6eYZEi.js} +92 -92
- package/editor/index.html +1 -1
- package/package.json +4 -2
- package/skills/incanto-3d-models.md +30 -0
- package/skills/incanto-verifying-your-game.md +113 -1
- package/templates-app/beacon-isle-3d/package.json +1 -1
- package/templates-app/tps-3d/package.json +1 -1
- package/templates-app/village-quest-3d/package.json +1 -1
package/editor/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Incanto Scene Editor</title>
|
|
7
7
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><rect width='16' height='16' rx='3' fill='%236ee7dc'/><text x='8' y='12' text-anchor='middle' font-size='11' font-family='monospace' fill='%230e1018'>i</text></svg>" />
|
|
8
|
-
<script type="module" crossorigin src="./assets/index-
|
|
8
|
+
<script type="module" crossorigin src="./assets/index-B-6eYZEi.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="./assets/GameServer-C56iOUgF.js">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "incanto",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.48.0",
|
|
4
4
|
"description": "Vibe-coding-first web game engine SDK — JSON-driven scenes on three.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"game-engine",
|
|
@@ -98,6 +98,8 @@
|
|
|
98
98
|
"incanto-playtest": "bin/incanto-playtest.mjs",
|
|
99
99
|
"incanto-feel": "bin/incanto-feel.mjs",
|
|
100
100
|
"incanto-new": "bin/incanto-new.mjs",
|
|
101
|
-
"incanto-frame": "bin/incanto-frame.mjs"
|
|
101
|
+
"incanto-frame": "bin/incanto-frame.mjs",
|
|
102
|
+
"incanto-verify": "./bin/incanto-verify.mjs",
|
|
103
|
+
"incanto-logs": "./bin/incanto-logs.mjs"
|
|
102
104
|
}
|
|
103
105
|
}
|
|
@@ -19,6 +19,7 @@ bunx incanto-model public/models/knight.glb
|
|
|
19
19
|
# anim Idle: 2.4s
|
|
20
20
|
# anim Run: 0.8s ← exact clip names for `animation`
|
|
21
21
|
bunx incanto-model avatar.vrm --json # full machine-readable report
|
|
22
|
+
bunx incanto-model https://.../goblin.glb # a URL works anywhere a path does
|
|
22
23
|
```
|
|
23
24
|
|
|
24
25
|
The report gives you: the TRANSFORMED scene bounding box (size/center/min/max — skinned
|
|
@@ -63,6 +64,35 @@ tint), `castShadow`/`receiveShadow`, plus the usual Node3D transform.
|
|
|
63
64
|
|
|
64
65
|
## Animating named sub-nodes (wheels, turrets, doors) — `poseNode`
|
|
65
66
|
|
|
67
|
+
## What the file will DO here
|
|
68
|
+
|
|
69
|
+
`incanto-model` ends with a verdict, and it answers the three questions that
|
|
70
|
+
cost the most time. Finding an asset is the agent8 library's job — its search
|
|
71
|
+
matches meaning. This says whether what it found works in YOUR scene:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
mixamorig rig — the 3d/animations clips play on this as they are
|
|
75
|
+
stands 1.5 units tall
|
|
76
|
+
```
|
|
77
|
+
```
|
|
78
|
+
skinned, but NOT a mixamorig rig — the 3d/animations clips will not bind to it
|
|
79
|
+
(bones are matched by name; a mismatch keeps the bind pose and only warns)
|
|
80
|
+
stands 28.45 units tall — not a character's size; set targetHeight (1.7) to fix it
|
|
81
|
+
clips in the file: die, idle, walk, normal_attack, … (play by name, no asset needed)
|
|
82
|
+
```
|
|
83
|
+
```
|
|
84
|
+
does NOT stand on its own origin — it sits 10.1 units above the origin. A node at
|
|
85
|
+
[0,0,0] puts it there too; offset the node, or expect an empty-looking frame
|
|
86
|
+
```
|
|
87
|
+
```
|
|
88
|
+
an animation CLIP — no mesh of its own. It plays ON a character: declare it as
|
|
89
|
+
{"type":"animation"} and point a ModelInstance3D's `animation` at it. Used as a
|
|
90
|
+
`model` it draws nothing at all, with no error
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
It then prints the scene JSON to paste — the asset entry and the node, with
|
|
94
|
+
`targetHeight` already set when the raw size calls for it.
|
|
95
|
+
|
|
66
96
|
Many GLBs ship articulated parts as NAMED nodes (`bunx incanto-model <file>` lists them —
|
|
67
97
|
e.g. the Kenney vehicles have `wheel-front-left` … `wheel-back-right`). From a behavior,
|
|
68
98
|
rotate one per frame with `poseNode(name, [rxDeg, ryDeg, rzDeg])` (local Euler XYZ):
|
|
@@ -26,6 +26,34 @@ A run that finishes is not a run that worked. `runScript()` fails the run when
|
|
|
26
26
|
`stats().errors` is non-zero, and prints the engine's warnings under the
|
|
27
27
|
failures — but `framing` and `assetErrors()` you have to ASK for.
|
|
28
28
|
|
|
29
|
+
## 0. The whole ladder, one command: `incanto-verify`
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
$ bunx incanto-verify # finds your scene
|
|
33
|
+
✓ loads — the scene is legal and its assets resolve
|
|
34
|
+
? plays — nothing declares a win — 8 runs played without error, and there was no end to reach
|
|
35
|
+
? draws — the dev server is running on :5173, but no page answered
|
|
36
|
+
|
|
37
|
+
passes what was measured — plays, draws not measured.
|
|
38
|
+
next: if it is meant to be finishable, emit `won` (GameFlow, ScoreKeeper, or your own behaviour)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Runs the rungs below in order and says the ONE thing to do next. Three rules it
|
|
42
|
+
encodes so you do not have to remember them:
|
|
43
|
+
|
|
44
|
+
- a **failed** rung makes the ones above it meaningless, so only the first is
|
|
45
|
+
worth reading — the rest are marked `·` skipped;
|
|
46
|
+
- an **unmeasured** rung (`?`) is not a failure. "No dev server" means the
|
|
47
|
+
question was never asked; treating that as a broken game sends you editing a
|
|
48
|
+
scene that is fine;
|
|
49
|
+
- a scene that declares **no win** is not a scene that cannot be won. A
|
|
50
|
+
walkabout has no end, and that is reported as unmeasured, not failed.
|
|
51
|
+
|
|
52
|
+
Exit 1 only when a rung actually failed. `--behaviors src/behaviors.ts` matters:
|
|
53
|
+
without it your game logic is stubbed and only the structure is played.
|
|
54
|
+
|
|
55
|
+
The sections below are the same rungs one at a time, for when you need the detail.
|
|
56
|
+
|
|
29
57
|
## 1. After EVERY scene edit: `incanto-check`
|
|
30
58
|
|
|
31
59
|
```bash
|
|
@@ -320,6 +348,32 @@ ceiling — drive `engine.timeScale`, with `0.25× 0.5× 1× 2×` presets:
|
|
|
320
348
|
number is refused and negatives clamp to 0: the scale multiplies every dt in
|
|
321
349
|
the engine, so one NaN would take physics, timers and animation with it.
|
|
322
350
|
|
|
351
|
+
### `bunx incanto-logs` — what the game is SAYING
|
|
352
|
+
|
|
353
|
+
`incanto-frame` gets the pixels out of the browser; this gets the words. The
|
|
354
|
+
engine writes diagnostics for exactly this — and until they had a channel out,
|
|
355
|
+
they reached a human only, in the debug overlay's logs panel.
|
|
356
|
+
|
|
357
|
+
```
|
|
358
|
+
$ bunx incanto-logs
|
|
359
|
+
asset $characters/base never loaded: … responded with 404
|
|
360
|
+
[error] incanto: failed to load model '…/NO-SUCH-MODEL.glb'
|
|
361
|
+
82 nodes · frame rate not measurable — the page is hidden (a window covered by
|
|
362
|
+
another counts), and the browser throttles it. Bring it to the front
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
That game's grass, water and trees all rendered — `incanto-frame` called it
|
|
366
|
+
healthy (`subject fills 84.2%`) because they ARE there. Only the player was
|
|
367
|
+
missing. **Pixels and words answer different questions; a game can pass one and
|
|
368
|
+
fail the other**, which is why both are rungs.
|
|
369
|
+
|
|
370
|
+
It needs no render, so it answers from a page the browser has stopped drawing.
|
|
371
|
+
Exit 1 when something is wrong: an error logged, an error swallowed to keep the
|
|
372
|
+
game alive, or an asset that never loaded.
|
|
373
|
+
|
|
374
|
+
A repeated warning is folded into one line with a count (`×600`) — a game
|
|
375
|
+
shouting the same thing every frame has one problem, not six hundred.
|
|
376
|
+
|
|
323
377
|
### `bunx incanto-frame` — what is actually on screen
|
|
324
378
|
|
|
325
379
|
The rung above framing. `framing` PREDICTS what the camera should see from the
|
|
@@ -329,6 +383,22 @@ black screen, a material that failed, or a shader drawing where it should not.
|
|
|
329
383
|
```
|
|
330
384
|
$ bunx incanto-frame
|
|
331
385
|
frame 1280×720 · luminance 0.62
|
|
386
|
+
subject 412×690 at 434,18 · fills 21.4% of frame
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
`subject` is what the frame is OF: everything that is not the background,
|
|
390
|
+
measured from the frame's own edges. It answers the question `black` and
|
|
391
|
+
`uniform` cannot — **is the thing IN the shot, and can you see it**:
|
|
392
|
+
|
|
393
|
+
```
|
|
394
|
+
nothing but background — the camera is pointed away from everything in the scene
|
|
395
|
+
```
|
|
396
|
+
```
|
|
397
|
+
the subject fills almost nothing (0.3%) — the camera is too far back, or what
|
|
398
|
+
you meant to see is not what got drawn
|
|
399
|
+
```
|
|
400
|
+
```
|
|
401
|
+
subject 1280×720 at 0,0 · fills 84.1% of frame · CLIPPED by the frame edge
|
|
332
402
|
```
|
|
333
403
|
|
|
334
404
|
```
|
|
@@ -342,7 +412,49 @@ browser, not in the dev server.** You do not have to tell it where anything is
|
|
|
342
412
|
it reads the ports that are actually listening, asks each one whether it is an
|
|
343
413
|
incanto dev server, and asks that page for a frame over vite's own HMR channel.
|
|
344
414
|
|
|
345
|
-
|
|
415
|
+
#### Drive it somewhere first
|
|
416
|
+
|
|
417
|
+
Every interesting state in a game is downstream of input, and the boot screen is
|
|
418
|
+
the only frame anything could capture before this:
|
|
419
|
+
|
|
420
|
+
```
|
|
421
|
+
$ bunx incanto-frame --do "vector move 0 1; step 3000; vector move 0 0" --out bridge.png
|
|
422
|
+
frame 1280×720 · luminance 0.68
|
|
423
|
+
subject fills 21.4% of frame
|
|
424
|
+
drove 180 frames before capturing
|
|
425
|
+
wrote bridge.png — open it, or read it
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
The same words `incanto-play` takes — `press`/`release ACTION`, `vector ACTION X Y`,
|
|
429
|
+
`key CODE down|up`, `pointer DX DY`, `step MS`, separated by semicolons or
|
|
430
|
+
newlines. `--do-file` reads a longer plan from a file. One vocabulary for the
|
|
431
|
+
headless gamepad and the live one.
|
|
432
|
+
|
|
433
|
+
`step` waits on the REAL clock: this is the running game, with its own loop, its
|
|
434
|
+
own physics and its own animation, and stepping it by hand would fight all three.
|
|
435
|
+
|
|
436
|
+
**`drove N frames` is the number to check.** A browser stops animating a tab it
|
|
437
|
+
considers hidden — including a window merely covered by another — and the inputs
|
|
438
|
+
then land on a game that never advances: the capture comes back UNCHANGED and
|
|
439
|
+
looks perfectly healthy. `drove 0 frames` is refused with an error rather than
|
|
440
|
+
handed over as a picture.
|
|
441
|
+
|
|
442
|
+
#### Look at it
|
|
443
|
+
|
|
444
|
+
```
|
|
445
|
+
$ bunx incanto-frame --out shot.png
|
|
446
|
+
frame 1280×720 · luminance 0.62
|
|
447
|
+
subject 412×690 at 434,18 · fills 21.4% of frame
|
|
448
|
+
wrote shot.png — open it, or read it
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
`--out` writes the frame as a PNG (`--size N` sets the longest side, default
|
|
452
|
+
512). Read it like any other image. The numbers above are cheaper and are what
|
|
453
|
+
you should assert on, but when a report says a scene is fine and it plainly is
|
|
454
|
+
not, a picture settles it in one look — and there is still no browser to install
|
|
455
|
+
and nothing headless involved: the page that is already open does the drawing.
|
|
456
|
+
|
|
457
|
+
Without `--out` it writes **no files**. `--json` gives the full report, including a 16×9 grid of
|
|
346
458
|
mean cell colours — enough to answer *where* the frame changed, small enough to
|
|
347
459
|
read. From game code or the console, `game.frame()` returns the same object.
|
|
348
460
|
|