incanto 0.53.0 → 0.55.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 +56 -1
- package/bin/incanto-verify.mjs +46 -0
- package/dist/2d.d.ts +46 -3
- package/dist/2d.js +3 -3
- package/dist/3d.d.ts +105 -6
- package/dist/3d.js +10 -6
- package/dist/{behavior-Do0Da56m.d.ts → behavior-CyQoSu4n.d.ts} +114 -10
- package/dist/{create-game-9D87XaiX.js → create-game-BRt6XKmP.js} +10 -6
- package/dist/{create-game-CDJ1lVqK.js → create-game-CzK9_pzg.js} +10 -6
- package/dist/debug.d.ts +1 -1
- package/dist/debug.js +4 -2
- package/dist/editor.js +7 -0
- package/dist/{environment-presets-SkGanr2s.js → environment-presets-DAbEdEwh.js} +326 -11
- package/dist/{gameplay-CRYw_Q-T.js → gameplay-CZ2yq37J.js} +30 -21
- package/dist/gameplay.d.ts +8 -3
- package/dist/gameplay.js +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.js +5 -5
- package/dist/{loader-Cu_7kJDy.d.ts → loader-DhI1jFW_.d.ts} +1 -1
- package/dist/net.d.ts +2 -2
- package/dist/net.js +1 -1
- package/dist/{particle-sim-BzJ1yxoE.d.ts → particle-sim-C5OfBbmU.d.ts} +11 -0
- package/dist/{pathfinding-HNGFqGUZ.d.ts → pathfinding-CXGCpRQe.d.ts} +1 -1
- package/dist/{physics-2d-BhZZ-HAp.js → physics-2d-CfWAggJ1.js} +1 -1
- package/dist/{physics-3d-DmyO2oaN.js → physics-3d-C_ZJ6f_d.js} +2 -2
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/{register-DROK2l7J.js → register-en63AEZO.js} +163 -4
- package/dist/{register-BTomIiYG.js → register-p48lHE2o.js} +130 -13
- package/dist/{replay-9Fy6C10F.d.ts → replay-ePMz26jw.d.ts} +1 -1
- package/dist/{replay-DYNUL4BU.js → replay-t1pP0gQg.js} +1 -1
- package/dist/{split-screen-DNmcX1Pz.d.ts → split-screen-BsdOHbzP.d.ts} +1 -1
- package/dist/{split-screen-CaF9hO7g.js → split-screen-CSb_uZ6W.js} +1 -1
- package/dist/{sprite-animation-D_p28jwU.js → sprite-animation-7qvUxF6Z.js} +19 -0
- package/dist/{src-C9xyZW7M.js → src-BVOVHRL0.js} +1 -1
- package/dist/{teardown-Bw2aeyGI.js → teardown-C7uVSJvx.js} +1 -1
- package/dist/{test-CJRsciFk.js → test-Ca5eqELC.js} +49 -14
- package/dist/test.d.ts +20 -4
- package/dist/test.js +2 -2
- package/dist/vite.js +2 -2
- package/editor/assets/{agent8-PlFHzJsh.js → agent8-Cz4oHPtm.js} +1 -1
- package/editor/assets/{debug-CebV7CDW.js → debug-r-Fi9nZh.js} +2 -2
- package/editor/assets/{index-CdbsY31G.js → index-BfqmvXYD.js} +91 -91
- package/editor/index.html +1 -1
- package/package.json +1 -1
- package/schemas/scene.schema.json +185 -0
- package/skills/incanto-assets.md +45 -2
- package/skills/incanto-building-2d-games.md +35 -0
- package/skills/incanto-building-3d-games.md +28 -3
- package/skills/incanto-environment.md +3 -1
- package/skills/incanto-gameplay-behaviors.md +51 -4
- package/skills/incanto-node-reference.md +31 -0
- package/skills/incanto-performance.md +51 -0
- package/skills/incanto-verifying-your-game.md +38 -0
- 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/bin/incanto-check.mjs
CHANGED
|
@@ -58,6 +58,61 @@ function collectScenes(entry) {
|
|
|
58
58
|
return out;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Local art the project does not contain.
|
|
63
|
+
*
|
|
64
|
+
* A scene asset pointing at a file nobody copied loads fine, validates fine and
|
|
65
|
+
* draws NOTHING — the failure exists only in a browser, in `assetErrors()`,
|
|
66
|
+
* which needs a running game and someone to look at it. This command has the
|
|
67
|
+
* scene's path and runs after every edit, and the file is either there or it is
|
|
68
|
+
* not. A WARNING, not an error: a url can legitimately be produced at runtime,
|
|
69
|
+
* and refusing to load a scene over a guess would be worse than the bug.
|
|
70
|
+
*/
|
|
71
|
+
function missingArt(file, json) {
|
|
72
|
+
const assets = json && typeof json === 'object' ? json.assets : null;
|
|
73
|
+
if (!assets || typeof assets !== 'object') return [];
|
|
74
|
+
const sceneDir = dirname(file);
|
|
75
|
+
const root = projectRoot(sceneDir);
|
|
76
|
+
const out = [];
|
|
77
|
+
for (const [key, decl] of Object.entries(assets)) {
|
|
78
|
+
const url = decl && typeof decl === 'object' ? decl.url : null;
|
|
79
|
+
if (typeof url !== 'string' || url === '') continue;
|
|
80
|
+
// Remote and inline are not this command's business to guess about.
|
|
81
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(url) || url.startsWith('//')) continue;
|
|
82
|
+
const rel = url.replace(/^\//, '');
|
|
83
|
+
const candidates = [
|
|
84
|
+
join(root, 'public', rel),
|
|
85
|
+
join(root, rel),
|
|
86
|
+
join(sceneDir, rel),
|
|
87
|
+
join(sceneDir, '..', rel),
|
|
88
|
+
];
|
|
89
|
+
if (candidates.some((p) => existsSync(p))) continue;
|
|
90
|
+
out.push(
|
|
91
|
+
`$${key} → ${url} is not in the project ` +
|
|
92
|
+
`(looked in ${relativeish(root, join(root, 'public'))}, ${relativeish(root, root)}` +
|
|
93
|
+
`, and beside the scene). It will draw nothing.`,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Nearest ancestor with a package.json, else the scene's own directory. */
|
|
100
|
+
function projectRoot(from) {
|
|
101
|
+
let dir = resolve(from);
|
|
102
|
+
for (let i = 0; i < 8; i++) {
|
|
103
|
+
if (existsSync(join(dir, 'package.json'))) return dir;
|
|
104
|
+
const up = dirname(dir);
|
|
105
|
+
if (up === dir) break;
|
|
106
|
+
dir = up;
|
|
107
|
+
}
|
|
108
|
+
return resolve(from);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function relativeish(root, p) {
|
|
112
|
+
const r = p.slice(root.length).replace(/^[\\/]/, '');
|
|
113
|
+
return r === '' ? './' : `${r}/`;
|
|
114
|
+
}
|
|
115
|
+
|
|
61
116
|
const roots = args.files.length > 0 ? args.files : ['.'];
|
|
62
117
|
for (const r of roots) {
|
|
63
118
|
if (!existsSync(resolve(r))) {
|
|
@@ -84,7 +139,7 @@ const results = files.map((file) => {
|
|
|
84
139
|
strictBehaviors: args.strict,
|
|
85
140
|
resolveScene: (p) => JSON.parse(readFileSync(resolve(dirname(file), p), 'utf-8')),
|
|
86
141
|
});
|
|
87
|
-
if (res.ok) return { file, ok: true, warnings: auditScene(json) };
|
|
142
|
+
if (res.ok) return { file, ok: true, warnings: [...auditScene(json), ...missingArt(file, json)] };
|
|
88
143
|
return {
|
|
89
144
|
file,
|
|
90
145
|
ok: false,
|
package/bin/incanto-verify.mjs
CHANGED
|
@@ -122,12 +122,16 @@ const rungs = [];
|
|
|
122
122
|
);
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
/** The playtest's JSON, shared by the `plays` and `feels` rungs. */
|
|
126
|
+
let playtestReport = null;
|
|
127
|
+
|
|
125
128
|
// ---- plays ---------------------------------------------------------------
|
|
126
129
|
if (rungs[0].status === 'pass') {
|
|
127
130
|
const args = [scene, '--json', '--runs', '8'];
|
|
128
131
|
if (behaviors) args.push('--behaviors', behaviors);
|
|
129
132
|
const r = run('playtest', args);
|
|
130
133
|
const out = safeJson(r.stdout);
|
|
134
|
+
playtestReport = out;
|
|
131
135
|
const won = out?.runs?.filter((x) => x.outcome === 'won').length ?? 0;
|
|
132
136
|
const total = out?.runs?.length ?? 0;
|
|
133
137
|
// A scene that declares no win is not a scene that cannot be won: a
|
|
@@ -158,6 +162,48 @@ if (rungs[0].status === 'pass') {
|
|
|
158
162
|
rungs.push({ name: 'plays', status: 'skipped', summary: 'not run — the scene does not load' });
|
|
159
163
|
}
|
|
160
164
|
|
|
165
|
+
// ---- feels ---------------------------------------------------------------
|
|
166
|
+
// Sound and effects, from the same playtest that just ran. A game whose
|
|
167
|
+
// feedback is wired but never triggered plays perfectly and feels dead, and
|
|
168
|
+
// every other rung here calls it healthy.
|
|
169
|
+
{
|
|
170
|
+
const fb = playtestReport?.feedback;
|
|
171
|
+
const declared = (fb?.declaredAudio?.length ?? 0) + (fb?.declaredEffects?.length ?? 0);
|
|
172
|
+
const fired = new Set([...(fb?.heard ?? []), ...(fb?.shown ?? [])]);
|
|
173
|
+
if (!fb) {
|
|
174
|
+
rungs.push({
|
|
175
|
+
name: 'feels',
|
|
176
|
+
status: 'skipped',
|
|
177
|
+
summary: 'not run — the playtest did not report',
|
|
178
|
+
});
|
|
179
|
+
} else if (declared === 0) {
|
|
180
|
+
rungs.push({
|
|
181
|
+
name: 'feels',
|
|
182
|
+
status: 'skipped',
|
|
183
|
+
summary: 'this game declares no sound and no effects',
|
|
184
|
+
});
|
|
185
|
+
} else if (fired.size === 0) {
|
|
186
|
+
rungs.push({
|
|
187
|
+
name: 'feels',
|
|
188
|
+
status: 'fail',
|
|
189
|
+
summary: `${declared} sound/effect node(s) declared, and not one fired in any run`,
|
|
190
|
+
fix: 'connect them — a signal to `play` on an AudioPlayer, or `replay()` on a one-shot; `engine.audio.recent()` and `engine.effects.recent()` say what did fire',
|
|
191
|
+
});
|
|
192
|
+
} else {
|
|
193
|
+
const silent = [...(fb.declaredAudio ?? []), ...(fb.declaredEffects ?? [])].filter(
|
|
194
|
+
(path) => !fired.has(path),
|
|
195
|
+
);
|
|
196
|
+
rungs.push({
|
|
197
|
+
name: 'feels',
|
|
198
|
+
status: 'pass',
|
|
199
|
+
summary:
|
|
200
|
+
silent.length === 0
|
|
201
|
+
? `every one of the ${declared} sound/effect nodes fired`
|
|
202
|
+
: `${fired.size} of ${declared} fired — silent: ${silent.slice(0, 3).join(', ')}${silent.length > 3 ? ` +${silent.length - 3}` : ''}`,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
161
207
|
// ---- draws ---------------------------------------------------------------
|
|
162
208
|
{
|
|
163
209
|
const r = run('frame', ['--json']);
|
package/dist/2d.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { At as Node, P as Scene$1, S as Scheduler, T as RendererStats, b as Engine, d as PropSchema, n as BehaviorCtor, w as GameStats } from "./behavior-CyQoSu4n.js";
|
|
2
2
|
import { n as DiagnosticSink, t as EditorSwitchOptions } from "./editor-switch-DAvWQeld.js";
|
|
3
3
|
import { i as SceneJson, s as JsonObject } from "./schema-CFeioQRE.js";
|
|
4
|
-
import { t as LoadSceneOptions } from "./loader-
|
|
4
|
+
import { t as LoadSceneOptions } from "./loader-DhI1jFW_.js";
|
|
5
5
|
import { n as AnimationEntry } from "./sprite-animation-CMr6f1K2.js";
|
|
6
|
-
import { t as ParticleSim } from "./particle-sim-
|
|
6
|
+
import { r as ParticleView, t as ParticleSim } from "./particle-sim-C5OfBbmU.js";
|
|
7
7
|
import { Group, Mesh, Object3D, Scene, Texture } from "three";
|
|
8
8
|
import * as RapierNs from "@dimforge/rapier2d-compat";
|
|
9
9
|
|
|
@@ -517,6 +517,16 @@ declare class AnimatedSprite2D extends Sprite2D {
|
|
|
517
517
|
stop(): void;
|
|
518
518
|
override onReady(): void;
|
|
519
519
|
override update(dt: number): void;
|
|
520
|
+
/** Sheets already reported, so a bad grid says so ONCE, not every frame. */
|
|
521
|
+
private gridChecked;
|
|
522
|
+
/**
|
|
523
|
+
* Tell the author their grid does not fit, the first time it is drawn.
|
|
524
|
+
*
|
|
525
|
+
* Both halves of this were silent: a frame size that does not divide the
|
|
526
|
+
* sheet slices every row further off centre, and an animation naming a frame
|
|
527
|
+
* past the end of the grid draws whatever is at the wrong end of the image.
|
|
528
|
+
*/
|
|
529
|
+
private checkGrid;
|
|
520
530
|
protected override resolveTexture(assets: AssetStore2D | null): ResolvedSpriteTexture | null;
|
|
521
531
|
}
|
|
522
532
|
//#endregion
|
|
@@ -699,6 +709,18 @@ declare class Particles2D extends Node2D {
|
|
|
699
709
|
static override readonly props: PropSchema;
|
|
700
710
|
preset: string;
|
|
701
711
|
emitting: boolean;
|
|
712
|
+
/**
|
|
713
|
+
* Where a particle LIVES once it is born.
|
|
714
|
+
*
|
|
715
|
+
* `false` (default) — the emitter's local space: the plume moves with the
|
|
716
|
+
* node, which is what a torch on a moving platform wants.
|
|
717
|
+
*
|
|
718
|
+
* `true` — the world: a particle keeps the place it was born, so dust is left
|
|
719
|
+
* BEHIND a running player instead of glued to it, and moving a one-shot to
|
|
720
|
+
* the next explosion (the documented `p.position = …; p.replay()` recipe)
|
|
721
|
+
* stops dragging the previous one across the level.
|
|
722
|
+
*/
|
|
723
|
+
worldSpace: boolean;
|
|
702
724
|
rate: number;
|
|
703
725
|
burst: number;
|
|
704
726
|
lifetime: number[];
|
|
@@ -728,9 +750,30 @@ declare class Particles2D extends Node2D {
|
|
|
728
750
|
private finishedEmitted;
|
|
729
751
|
/** @internal Lazily applies the preset + builds the deterministic sim. */
|
|
730
752
|
_ensureSim(): ParticleSim;
|
|
753
|
+
/** Particles alive this frame — an emitter that is running, told from one
|
|
754
|
+
* that is not. `framing()` says where it IS; this says whether it is going. */
|
|
755
|
+
get aliveCount(): number;
|
|
756
|
+
/** A snapshot of the live particles — positions are in whichever space
|
|
757
|
+
* `worldSpace` selects, relative to the emitter. */
|
|
758
|
+
particles(): ParticleView[];
|
|
759
|
+
/** The emitter's world position last frame, for world-space counter-motion. */
|
|
760
|
+
private lastWorld;
|
|
761
|
+
/** Last frame's `emitting`, so turning one ON is a reportable event. */
|
|
762
|
+
private wasEmitting;
|
|
731
763
|
override update(dt: number): void;
|
|
764
|
+
/**
|
|
765
|
+
* Undo the emitter's own motion on everything already alive.
|
|
766
|
+
*
|
|
767
|
+
* Ancestor-summed like the physics helpers, so it follows a moving PARENT
|
|
768
|
+
* (dust under a player) as well as the node's own position.
|
|
769
|
+
*/
|
|
770
|
+
private holdWorldSpace;
|
|
771
|
+
/** Tell the engine an effect fired — the visual half of the audio record. */
|
|
772
|
+
private report;
|
|
732
773
|
/** Restart a one-shot (re-burst + allow finished to fire again). */
|
|
733
774
|
replay(): void;
|
|
775
|
+
/** `replay()` asked for this burst, so `emitting: false` does not hold it. */
|
|
776
|
+
private armedByReplay;
|
|
734
777
|
private mesh;
|
|
735
778
|
/** Parsed `paletteColors`, reused; rebuilt only when the hex list changes. */
|
|
736
779
|
private paletteCache;
|
package/dist/2d.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
2
|
-
import { a as AssetStore2D, i as syncTree2D, r as Renderer2D, t as createGame2D } from "./create-game-
|
|
3
|
-
import { _ as RigidBody2D, a as parseCells, c as ColorRect2D, d as AnimatedSprite2D, f as Sprite2D, g as PhysicsBody2D, h as CharacterBody2D, i as mergeSolidRects, l as CharacterController2D, m as Area2D, n as UILayer, o as Particles2D, p as Joint2D, r as TileMap2D, s as Label, t as registerNodes2D, u as Camera2D, v as StaticBody2D, y as Node2D } from "./register-
|
|
4
|
-
import { n as enablePhysics2D, t as Physics2D } from "./physics-2d-
|
|
2
|
+
import { a as AssetStore2D, i as syncTree2D, r as Renderer2D, t as createGame2D } from "./create-game-BRt6XKmP.js";
|
|
3
|
+
import { _ as RigidBody2D, a as parseCells, c as ColorRect2D, d as AnimatedSprite2D, f as Sprite2D, g as PhysicsBody2D, h as CharacterBody2D, i as mergeSolidRects, l as CharacterController2D, m as Area2D, n as UILayer, o as Particles2D, p as Joint2D, r as TileMap2D, s as Label, t as registerNodes2D, u as Camera2D, v as StaticBody2D, y as Node2D } from "./register-en63AEZO.js";
|
|
4
|
+
import { n as enablePhysics2D, t as Physics2D } from "./physics-2d-CfWAggJ1.js";
|
|
5
5
|
//#region src/2d/library-sprite.ts
|
|
6
6
|
/**
|
|
7
7
|
* What a `CharacterController2D`/`3D` will ask a skin to play, and the clip in
|
package/dist/3d.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { At as Node, D as QualityCaps, P as Scene$1, S as Scheduler, T as RendererStats, b as Engine, d as PropSchema, n as BehaviorCtor, w as GameStats } from "./behavior-CyQoSu4n.js";
|
|
2
2
|
import { n as DiagnosticSink, t as EditorSwitchOptions } from "./editor-switch-DAvWQeld.js";
|
|
3
3
|
import { i as SceneJson$1, s as JsonObject } from "./schema-CFeioQRE.js";
|
|
4
|
-
import { t as LoadSceneOptions } from "./loader-
|
|
5
|
-
import { t as ParticleSim } from "./particle-sim-
|
|
4
|
+
import { t as LoadSceneOptions } from "./loader-DhI1jFW_.js";
|
|
5
|
+
import { r as ParticleView, t as ParticleSim } from "./particle-sim-C5OfBbmU.js";
|
|
6
6
|
import { a as GridCell, c as diffText, d as frameText, i as FrameStatsOptions, l as frameSignature, n as FrameSignature, o as SIGNATURE_GRID, r as FrameStats, s as diffSignatures, t as FrameDiff, u as frameStats } from "./frame-report-DZ70IY26.js";
|
|
7
|
-
import { n as PathGrid, s as SpatialPose } from "./pathfinding-
|
|
7
|
+
import { n as PathGrid, s as SpatialPose } from "./pathfinding-CXGCpRQe.js";
|
|
8
8
|
import { AnimationClip, AnimationMixer, BufferGeometry, Color, DirectionalLight, Group, InstancedMesh, Mesh, MeshPhysicalMaterial, Object3D, PerspectiveCamera, Scene, ShaderMaterial, Texture, Vector3, WebGLRenderer } from "three";
|
|
9
9
|
import { VRM } from "@pixiv/three-vrm";
|
|
10
10
|
import { Sky } from "three/examples/jsm/objects/Sky.js";
|
|
@@ -61,6 +61,15 @@ declare class TextureCache3D {
|
|
|
61
61
|
*/
|
|
62
62
|
acquireOwn(url: string, spec?: TextureSpec): Texture | null;
|
|
63
63
|
/**
|
|
64
|
+
* File a failure this store did not load itself.
|
|
65
|
+
*
|
|
66
|
+
* `Tree3D` keeps its own cache on purpose (it decodes off-thread and its
|
|
67
|
+
* page-session lifetime is load-bearing for the editor), which left its bark
|
|
68
|
+
* and leaf textures outside the one place `assetErrors()` reads. A 404'd leaf
|
|
69
|
+
* texture is a forest of bare branches and no message anywhere.
|
|
70
|
+
*/
|
|
71
|
+
noteError(url: string, error: unknown): void;
|
|
72
|
+
/**
|
|
64
73
|
* What 404'd, by URL — reported raw, never by cache key, because an agent
|
|
65
74
|
* greps this against the URL it wrote.
|
|
66
75
|
*/
|
|
@@ -1859,6 +1868,15 @@ declare class LoftMesh3D extends Node3D {
|
|
|
1859
1868
|
private geometryKey;
|
|
1860
1869
|
protected override _createObject3D(): Object3D;
|
|
1861
1870
|
override _syncObject3D(): void;
|
|
1871
|
+
/**
|
|
1872
|
+
* Hand the GPU back.
|
|
1873
|
+
*
|
|
1874
|
+
* Every other node that builds geometry disposes it here; these four did not,
|
|
1875
|
+
* so a scene swap left their buffers and materials resident and a game with
|
|
1876
|
+
* level transitions climbed until the tab died — with `stats().geometries` the
|
|
1877
|
+
* only witness, and only if someone was watching it.
|
|
1878
|
+
*/
|
|
1879
|
+
override free(): void;
|
|
1862
1880
|
}
|
|
1863
1881
|
//#endregion
|
|
1864
1882
|
//#region src/3d/nodes/model-instance-3d.d.ts
|
|
@@ -2030,6 +2048,18 @@ declare class Particles3D extends Node3D {
|
|
|
2030
2048
|
static override readonly props: PropSchema;
|
|
2031
2049
|
preset: string;
|
|
2032
2050
|
emitting: boolean;
|
|
2051
|
+
/**
|
|
2052
|
+
* Where a particle LIVES once it is born.
|
|
2053
|
+
*
|
|
2054
|
+
* `false` (default) — the emitter's local space: the plume moves with the
|
|
2055
|
+
* node, which is what a torch on a moving platform wants.
|
|
2056
|
+
*
|
|
2057
|
+
* `true` — the world: a particle keeps the place it was born, so dust is left
|
|
2058
|
+
* BEHIND a running player instead of glued to it, and moving a one-shot to
|
|
2059
|
+
* the next explosion (the documented `p.position = …; p.replay()` recipe)
|
|
2060
|
+
* stops dragging the previous one across the level.
|
|
2061
|
+
*/
|
|
2062
|
+
worldSpace: boolean;
|
|
2033
2063
|
rate: number;
|
|
2034
2064
|
burst: number;
|
|
2035
2065
|
lifetime: number[];
|
|
@@ -2065,9 +2095,30 @@ declare class Particles3D extends Node3D {
|
|
|
2065
2095
|
private finishedEmitted;
|
|
2066
2096
|
/** @internal */
|
|
2067
2097
|
_ensureSim(): ParticleSim;
|
|
2098
|
+
/** Particles alive this frame — an emitter that is running, told from one
|
|
2099
|
+
* that is not. `framing()` says where it IS; this says whether it is going. */
|
|
2100
|
+
get aliveCount(): number;
|
|
2101
|
+
/** A snapshot of the live particles — positions are in whichever space
|
|
2102
|
+
* `worldSpace` selects, relative to the emitter. */
|
|
2103
|
+
particles(): ParticleView[];
|
|
2104
|
+
/** The emitter's world position last frame, for world-space counter-motion. */
|
|
2105
|
+
private lastWorld;
|
|
2106
|
+
/** Last frame's `emitting`, so turning one ON is a reportable event. */
|
|
2107
|
+
private wasEmitting;
|
|
2068
2108
|
override update(dt: number): void;
|
|
2109
|
+
/**
|
|
2110
|
+
* Undo the emitter's own motion on everything already alive.
|
|
2111
|
+
*
|
|
2112
|
+
* Ancestor-summed like the physics helpers, so it follows a moving PARENT
|
|
2113
|
+
* (dust under a player) as well as the node's own position.
|
|
2114
|
+
*/
|
|
2115
|
+
private holdWorldSpace;
|
|
2116
|
+
/** Tell the engine an effect fired — the visual half of the audio record. */
|
|
2117
|
+
private report;
|
|
2069
2118
|
/** Restart a one-shot (re-burst + allow finished to fire again). */
|
|
2070
2119
|
replay(): void;
|
|
2120
|
+
/** `replay()` asked for this burst, so `emitting: false` does not hold it. */
|
|
2121
|
+
private armedByReplay;
|
|
2071
2122
|
private points;
|
|
2072
2123
|
private positions;
|
|
2073
2124
|
private colors;
|
|
@@ -2080,6 +2131,15 @@ declare class Particles3D extends Node3D {
|
|
|
2080
2131
|
* uses the colorStart→colorEnd ramp. */
|
|
2081
2132
|
private refreshPalette;
|
|
2082
2133
|
private syncParticles;
|
|
2134
|
+
/**
|
|
2135
|
+
* Hand the GPU back.
|
|
2136
|
+
*
|
|
2137
|
+
* Every other node that builds geometry disposes it here; these four did not,
|
|
2138
|
+
* so a scene swap left their buffers and materials resident and a game with
|
|
2139
|
+
* level transitions climbed until the tab died — with `stats().geometries` the
|
|
2140
|
+
* only witness, and only if someone was watching it.
|
|
2141
|
+
*/
|
|
2142
|
+
override free(): void;
|
|
2083
2143
|
}
|
|
2084
2144
|
//#endregion
|
|
2085
2145
|
//#region src/3d/terrain/heightmap.d.ts
|
|
@@ -2756,10 +2816,30 @@ declare class Trail3D extends Node3D {
|
|
|
2756
2816
|
private mesh;
|
|
2757
2817
|
private lastColor;
|
|
2758
2818
|
protected override _createObject3D(): Object3D;
|
|
2819
|
+
/** Last frame's `emitting`, so laying ribbon is a reportable event. */
|
|
2820
|
+
private wasEmitting;
|
|
2759
2821
|
override update(dt: number): void;
|
|
2760
2822
|
_onRender3D(ctx: RenderContext3D): void;
|
|
2761
|
-
/**
|
|
2823
|
+
/**
|
|
2824
|
+
* How many points the ribbon is made of.
|
|
2825
|
+
*
|
|
2826
|
+
* ZERO with no renderer, and that is not a bug: the ribbon is laid in the
|
|
2827
|
+
* render sync, because each point needs the node's real world transform (a
|
|
2828
|
+
* sword arc is a ROTATING parent, which an ancestor position sum cannot see).
|
|
2829
|
+
* Assert it from a browser check; read a headless 0 as "nothing rendered"
|
|
2830
|
+
* rather than "my trail is broken", and use the `trail` effect record for the
|
|
2831
|
+
* wiring question.
|
|
2832
|
+
*/
|
|
2762
2833
|
get pointCount(): number;
|
|
2834
|
+
/**
|
|
2835
|
+
* Hand the GPU back.
|
|
2836
|
+
*
|
|
2837
|
+
* Every other node that builds geometry disposes it here; these four did not,
|
|
2838
|
+
* so a scene swap left their buffers and materials resident and a game with
|
|
2839
|
+
* level transitions climbed until the tab died — with `stats().geometries` the
|
|
2840
|
+
* only witness, and only if someone was watching it.
|
|
2841
|
+
*/
|
|
2842
|
+
override free(): void;
|
|
2763
2843
|
}
|
|
2764
2844
|
//#endregion
|
|
2765
2845
|
//#region src/3d/vegetation/tree-blueprint.d.ts
|
|
@@ -2859,7 +2939,17 @@ declare class Tree3D extends Node3D {
|
|
|
2859
2939
|
/** @internal Every grown variant (medium/high tiers; empty for 'simple'). */
|
|
2860
2940
|
_variantMeshes(): TreeVariant[];
|
|
2861
2941
|
override update(dt: number): void;
|
|
2862
|
-
|
|
2942
|
+
/** The scene's asset store, so a 404'd bark or leaf reaches assetErrors(). */
|
|
2943
|
+
private assets;
|
|
2944
|
+
override _syncObject3D(alpha?: number, assets?: AssetStore3D | null): void;
|
|
2945
|
+
/**
|
|
2946
|
+
* File a texture failure where the ladder reads it.
|
|
2947
|
+
*
|
|
2948
|
+
* This node keeps its own cache on purpose, and that left its textures
|
|
2949
|
+
* outside the one place `assetErrors()` looks — so a leaf URL that 404s was a
|
|
2950
|
+
* forest of bare branches with no message anywhere.
|
|
2951
|
+
*/
|
|
2952
|
+
private noteTextureError;
|
|
2863
2953
|
/** Re-grow only when a grove-shaping prop changed (the JSON IS the grove). */
|
|
2864
2954
|
private rebuildIfNeeded;
|
|
2865
2955
|
/** Resolve the drape target + cache the grove's world position for `bedY`. */
|
|
@@ -2930,6 +3020,15 @@ declare class VoxelGrid3D extends Node3D {
|
|
|
2930
3020
|
blocks(): VoxelBlock[];
|
|
2931
3021
|
protected override _createObject3D(): Object3D;
|
|
2932
3022
|
override update(): void;
|
|
3023
|
+
/**
|
|
3024
|
+
* Hand the GPU back.
|
|
3025
|
+
*
|
|
3026
|
+
* Every other node that builds geometry disposes it here; these four did not,
|
|
3027
|
+
* so a scene swap left their buffers and materials resident and a game with
|
|
3028
|
+
* level transitions climbed until the tab died — with `stats().geometries` the
|
|
3029
|
+
* only witness, and only if someone was watching it.
|
|
3030
|
+
*/
|
|
3031
|
+
override free(): void;
|
|
2933
3032
|
}
|
|
2934
3033
|
//#endregion
|
|
2935
3034
|
//#region src/3d/water/interaction.d.ts
|
package/dist/3d.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { F as CharacterBody3D, H as WATER_MAX_RIPPLES, I as PhysicsBody3D, L as RigidBody3D, M as WATER_CUTOUT_MAX, N as WaterCutout3D, P as Area3D, R as StaticBody3D, j as Water3D, z as Node3D } from "./gameplay-
|
|
2
|
-
import { A as Terrain3D, B as keyboardIntensity, C as resolveFlowerDensity, D as BoneLookAt3D, E as Camera3D, F as InstancedMesh3D, G as acquireTexture, H as rigPose, I as MeshInstance3D, M as TERRAIN_THEMES, N as terrainThemeLayers, O as BoneAttachment3D, P as Joint3D, R as QUARTER_PITCH, S as Flowers3D, T as CharacterController3D, U as TextureCache3D, V as movementState, W as acquireOwnTexture, _ as LoftMesh3D, a as Tree3D, b as Foliage3D, c as buildRiverRings, d as riverCarveChannels, f as riverStepFor, g as ModelInstance3D, h as Particles3D, i as VoxelGrid3D, j as DEFAULT_TERRAIN_TEXTURE_BASE, k as Billboard3D, l as findRiverCoverageGaps, m as traceDownhillPath, n as registerNodes3D, o as Trail3D, p as smoothCourse, r as VOXEL_PALETTE, s as River3D, u as projectToRiver, v as DirectionalLight3D, w as FLOWER_VARIETIES, x as DENSITY_PRESETS, y as OmniLight3D, z as cameraRelative } from "./environment-presets-
|
|
3
|
-
import { a as Environment3D, c as parseEnvironment3D, d as AssetStore3D, i as syncTree, l as sunDirectionFromElevationAzimuth, o as setEnvironment3D, r as Renderer3D, s as horizonColorFromSky, t as createGame3D, u as sunDirectionFromSky } from "./create-game-
|
|
1
|
+
import { F as CharacterBody3D, H as WATER_MAX_RIPPLES, I as PhysicsBody3D, L as RigidBody3D, M as WATER_CUTOUT_MAX, N as WaterCutout3D, P as Area3D, R as StaticBody3D, j as Water3D, z as Node3D } from "./gameplay-CZ2yq37J.js";
|
|
2
|
+
import { A as Terrain3D, B as keyboardIntensity, C as resolveFlowerDensity, D as BoneLookAt3D, E as Camera3D, F as InstancedMesh3D, G as acquireTexture, H as rigPose, I as MeshInstance3D, M as TERRAIN_THEMES, N as terrainThemeLayers, O as BoneAttachment3D, P as Joint3D, R as QUARTER_PITCH, S as Flowers3D, T as CharacterController3D, U as TextureCache3D, V as movementState, W as acquireOwnTexture, _ as LoftMesh3D, a as Tree3D, b as Foliage3D, c as buildRiverRings, d as riverCarveChannels, f as riverStepFor, g as ModelInstance3D, h as Particles3D, i as VoxelGrid3D, j as DEFAULT_TERRAIN_TEXTURE_BASE, k as Billboard3D, l as findRiverCoverageGaps, m as traceDownhillPath, n as registerNodes3D, o as Trail3D, p as smoothCourse, r as VOXEL_PALETTE, s as River3D, u as projectToRiver, v as DirectionalLight3D, w as FLOWER_VARIETIES, x as DENSITY_PRESETS, y as OmniLight3D, z as cameraRelative } from "./environment-presets-DAbEdEwh.js";
|
|
3
|
+
import { a as Environment3D, c as parseEnvironment3D, d as AssetStore3D, i as syncTree, l as sunDirectionFromElevationAzimuth, o as setEnvironment3D, r as Renderer3D, s as horizonColorFromSky, t as createGame3D, u as sunDirectionFromSky } from "./create-game-CzK9_pzg.js";
|
|
4
4
|
import { a as frameSignature, n as diffSignatures, o as frameStats, r as diffText, s as frameText, t as SIGNATURE_GRID } from "./frame-report-njybhZon.js";
|
|
5
5
|
import { n as splatWeights, t as buildHeightmap } from "./heightmap-CRK0M4jT.js";
|
|
6
|
-
import { n as enablePhysics3D, t as Physics3D } from "./physics-3d-
|
|
6
|
+
import { n as enablePhysics3D, t as Physics3D } from "./physics-3d-C_ZJ6f_d.js";
|
|
7
7
|
//#region src/3d/model-verdict.ts
|
|
8
8
|
/** Mixamo exports every bone as `mixamorigX`; the retargeter binds by that name. */
|
|
9
9
|
const MIXAMO = /^mixamorig[:_]?/i;
|
|
@@ -50,6 +50,10 @@ const BODY = {
|
|
|
50
50
|
radius: .34,
|
|
51
51
|
height: 1
|
|
52
52
|
};
|
|
53
|
+
/** Three decimals — enough for millimetres, and no float dust in pasted JSON. */
|
|
54
|
+
function round3(n) {
|
|
55
|
+
return Math.round(n * 1e3) / 1e3;
|
|
56
|
+
}
|
|
53
57
|
/**
|
|
54
58
|
* A found character, as a thing that walks.
|
|
55
59
|
*
|
|
@@ -122,10 +126,10 @@ function characterJson(target) {
|
|
|
122
126
|
type: "ModelInstance3D",
|
|
123
127
|
props: {
|
|
124
128
|
model: `$${target.key}`,
|
|
125
|
-
targetHeight: BODY.height + 2 * BODY.radius,
|
|
129
|
+
targetHeight: round3(BODY.height + 2 * BODY.radius),
|
|
126
130
|
position: [
|
|
127
131
|
0,
|
|
128
|
-
-(BODY.height / 2 + BODY.radius),
|
|
132
|
+
round3(-(BODY.height / 2 + BODY.radius)),
|
|
129
133
|
0
|
|
130
134
|
],
|
|
131
135
|
castShadow: true
|
|
@@ -718,6 +718,57 @@ declare class SfxEngine {
|
|
|
718
718
|
play(params: SfxParams, gain: number, opts?: SfxPlayOptions): void;
|
|
719
719
|
}
|
|
720
720
|
//#endregion
|
|
721
|
+
//#region src/core/effects-log.d.ts
|
|
722
|
+
/**
|
|
723
|
+
* What SHOWED — the visual half of the audio record.
|
|
724
|
+
*
|
|
725
|
+
* A game's feedback is sound and vision, and only one of them could be checked.
|
|
726
|
+
* `engine.audio.countOf('coin')` answers "did the coin sound fire?"; nothing
|
|
727
|
+
* answered "did the explosion?". `framing()` says where an emitter IS, which is
|
|
728
|
+
* a different question — a particle system that never fired and one that fired
|
|
729
|
+
* a hundred times sit at the same coordinates.
|
|
730
|
+
*
|
|
731
|
+
* Nothing here renders, so nothing here is measured in pixels. It records that
|
|
732
|
+
* the effect WAS ASKED FOR, which is the wiring question a game actually has:
|
|
733
|
+
* the burst that never happened because the signal was never connected looks
|
|
734
|
+
* exactly like the burst that happened off-screen, and this tells them apart.
|
|
735
|
+
*
|
|
736
|
+
* ```ts
|
|
737
|
+
* session.engine.effects.clearLog();
|
|
738
|
+
* smashTheCrystal();
|
|
739
|
+
* session.step(200);
|
|
740
|
+
* session.engine.effects.countOf('explosion'); // 1
|
|
741
|
+
* session.engine.effects.countFrom('/Game/Crystal/Boom'); // 1
|
|
742
|
+
* ```
|
|
743
|
+
*/
|
|
744
|
+
/** The kinds of thing a game does to say "that happened". */
|
|
745
|
+
type EffectKind = "burst" | "emit" | "trail" | "shake" | "flash" | "hitstop";
|
|
746
|
+
/** One effect that fired. */
|
|
747
|
+
interface EffectEvent {
|
|
748
|
+
kind: EffectKind;
|
|
749
|
+
/** The preset name, the flash colour, or `''` when the effect has no name. */
|
|
750
|
+
name: string;
|
|
751
|
+
/** Node path, or `engine` for the screen-wide ones. */
|
|
752
|
+
from: string;
|
|
753
|
+
/** Particles in the burst, shake magnitude, seconds frozen — the amount. */
|
|
754
|
+
amount: number;
|
|
755
|
+
/** `engine.time` when it fired, in seconds. */
|
|
756
|
+
at: number;
|
|
757
|
+
}
|
|
758
|
+
declare class EffectLog {
|
|
759
|
+
private readonly events;
|
|
760
|
+
/** @internal Called by the effects themselves; games read `recent()`. */
|
|
761
|
+
record(event: EffectEvent): void;
|
|
762
|
+
/** The last `limit` effects, oldest first. */
|
|
763
|
+
recent(limit?: number): EffectEvent[];
|
|
764
|
+
/** How many times an effect with this name fired (`explosion`, `#ff0000`). */
|
|
765
|
+
countOf(name: string): number;
|
|
766
|
+
/** How many effects this node fired — the question a wiring check has. */
|
|
767
|
+
countFrom(path: string): number;
|
|
768
|
+
/** Forget what has fired so far (between scenes, or between assertions). */
|
|
769
|
+
clearLog(): void;
|
|
770
|
+
}
|
|
771
|
+
//#endregion
|
|
721
772
|
//#region src/core/input.d.ts
|
|
722
773
|
/**
|
|
723
774
|
* Declarative input from scene JSON `input{}` — DOM-free logic (feed key state
|
|
@@ -1404,12 +1455,36 @@ interface QualityCaps {
|
|
|
1404
1455
|
minReflectionIntervalMs: number;
|
|
1405
1456
|
}
|
|
1406
1457
|
//#endregion
|
|
1407
|
-
//#region src/core/
|
|
1458
|
+
//#region src/core/phase-timing.d.ts
|
|
1408
1459
|
/**
|
|
1409
|
-
*
|
|
1410
|
-
*
|
|
1411
|
-
*
|
|
1460
|
+
* Where the frame went — the breakdown `stats()` could not give.
|
|
1461
|
+
*
|
|
1462
|
+
* fps and frameMs are a TOTAL, and a total has no next question. This engine
|
|
1463
|
+
* has already lost a day to that: a frame drop everyone attributed to the GPU
|
|
1464
|
+
* turned out to be garbage collection, and nothing on screen could have said
|
|
1465
|
+
* so. Three of a frame's four parts are the engine's own work, and the fourth
|
|
1466
|
+
* is what is left — which is exactly where GC and browser work hide.
|
|
1467
|
+
*
|
|
1468
|
+
* Means over the same rolling window as `frameMs`, so the numbers are
|
|
1469
|
+
* comparable to each other and to the whole.
|
|
1412
1470
|
*/
|
|
1471
|
+
/** One frame's own accounting, in milliseconds. */
|
|
1472
|
+
interface FramePhases {
|
|
1473
|
+
/** Fixed steps: physics, and anything on `fixedUpdate`. */
|
|
1474
|
+
fixedMs: number;
|
|
1475
|
+
/** The variable update: behaviors, node logic, tweens. */
|
|
1476
|
+
updateMs: number;
|
|
1477
|
+
/** Whatever renders, as reported by it. 0 when nothing does (headless). */
|
|
1478
|
+
renderMs: number;
|
|
1479
|
+
/**
|
|
1480
|
+
* The frame minus the three above. GC, browser layout, input handling,
|
|
1481
|
+
* anything outside the engine's own loop — and the one to look at when the
|
|
1482
|
+
* others are small and the frame is not.
|
|
1483
|
+
*/
|
|
1484
|
+
otherMs: number;
|
|
1485
|
+
}
|
|
1486
|
+
//#endregion
|
|
1487
|
+
//#region src/core/stats.d.ts
|
|
1413
1488
|
/** Loop-side counters from `engine.stats()` — queryable at any time. */
|
|
1414
1489
|
interface EngineStats {
|
|
1415
1490
|
/** Frames per second over the last ~60 REAL ticks (headless runs: 0). */
|
|
@@ -1427,6 +1502,11 @@ interface EngineStats {
|
|
|
1427
1502
|
* this counter exists for.
|
|
1428
1503
|
*/
|
|
1429
1504
|
errors: number;
|
|
1505
|
+
/**
|
|
1506
|
+
* Where the frame went: fixed (physics), update (behaviors), render, and
|
|
1507
|
+
* everything else. Means over the same window as `frameMs`.
|
|
1508
|
+
*/
|
|
1509
|
+
phases: FramePhases;
|
|
1430
1510
|
}
|
|
1431
1511
|
/** GPU-side counters from `renderer.stats()` — the LAST rendered frame. */
|
|
1432
1512
|
interface RendererStats {
|
|
@@ -1491,6 +1571,12 @@ declare class Engine {
|
|
|
1491
1571
|
* routes its volume through this; games set it for global volume/mute. */
|
|
1492
1572
|
readonly audio: AudioBuses;
|
|
1493
1573
|
/**
|
|
1574
|
+
* What SHOWED — the visual half of the audio record. Particle bursts, camera
|
|
1575
|
+
* shake, screen flash and freeze frames land here, so "did the explosion
|
|
1576
|
+
* fire?" is answerable in a run with no renderer.
|
|
1577
|
+
*/
|
|
1578
|
+
readonly effects: EffectLog;
|
|
1579
|
+
/**
|
|
1494
1580
|
* Persisted player settings — volume, quality, sensitivity.
|
|
1495
1581
|
*
|
|
1496
1582
|
* `createSaveStore` was good and had zero callers, so every game's volume
|
|
@@ -1533,6 +1619,10 @@ declare class Engine {
|
|
|
1533
1619
|
private accumulator;
|
|
1534
1620
|
private disposeScheduler;
|
|
1535
1621
|
private readonly frameStats;
|
|
1622
|
+
/** Where each frame's time went — the breakdown `frameMs` alone cannot give. */
|
|
1623
|
+
private readonly phaseTimings;
|
|
1624
|
+
/** This frame's render cost, as reported by whoever renders. */
|
|
1625
|
+
private renderMs;
|
|
1536
1626
|
/**
|
|
1537
1627
|
* Game-time multiplier: 1 = realtime, 0.5 = slow motion, 0 = frozen
|
|
1538
1628
|
* (hit-stop / pause). Scales BOTH variable and fixed updates — physics,
|
|
@@ -1626,6 +1716,15 @@ declare class Engine {
|
|
|
1626
1716
|
erroredNodes(): Node[];
|
|
1627
1717
|
/** Un-skip every quarantined node — the "try again" after you fix the code. */
|
|
1628
1718
|
resumeErroredNodes(): number;
|
|
1719
|
+
/**
|
|
1720
|
+
* How long the last render took, in ms — called by whoever renders.
|
|
1721
|
+
*
|
|
1722
|
+
* The engine does not render, so this is the one slice it cannot measure for
|
|
1723
|
+
* itself; without it the cost lands in `otherMs` beside the GC and the two
|
|
1724
|
+
* are indistinguishable, which is the confusion this whole breakdown exists
|
|
1725
|
+
* to end.
|
|
1726
|
+
*/
|
|
1727
|
+
noteRenderMs(ms: number): void;
|
|
1629
1728
|
stop(): void;
|
|
1630
1729
|
/**
|
|
1631
1730
|
* Live performance counters, queryable at ANY time. fps/frameMs come from a
|
|
@@ -1651,12 +1750,17 @@ declare class Engine {
|
|
|
1651
1750
|
dispose(): void;
|
|
1652
1751
|
/**
|
|
1653
1752
|
* Advance exactly ONE fixed step and one variable update (both dt = the
|
|
1654
|
-
* fixed step), bypassing the wall-clock accumulator
|
|
1655
|
-
* by construction — the unit of time for headless
|
|
1656
|
-
* runScript): every input edge is visible to BOTH
|
|
1657
|
-
* exactly once.
|
|
1753
|
+
* fixed step scaled by `timeScale`), bypassing the wall-clock accumulator
|
|
1754
|
+
* entirely. Drift-free by construction — the unit of time for headless
|
|
1755
|
+
* harnesses (incanto/test runScript): every input edge is visible to BOTH
|
|
1756
|
+
* fixedUpdate and update exactly once.
|
|
1757
|
+
*
|
|
1758
|
+
* `ignorePause: true` steps a frame at full scale even while the game is
|
|
1759
|
+
* paused — the debug overlay's single-step button, and nothing else.
|
|
1658
1760
|
*/
|
|
1659
|
-
step(
|
|
1761
|
+
step(opts?: {
|
|
1762
|
+
ignorePause?: boolean;
|
|
1763
|
+
}): void;
|
|
1660
1764
|
/** Advance the loop manually. First call after (re)start only primes the clock. */
|
|
1661
1765
|
tick(nowMs: number): void;
|
|
1662
1766
|
}
|
|
@@ -1824,4 +1928,4 @@ declare function registeredBehaviors(): string[];
|
|
|
1824
1928
|
/** Test isolation helper. */
|
|
1825
1929
|
declare function clearBehaviors(): void;
|
|
1826
1930
|
//#endregion
|
|
1827
|
-
export { T_PREFIX as $, SettingsValues as A,
|
|
1931
|
+
export { T_PREFIX as $, SettingsValues as A, Node as At, captureBehaviors as B, EngineStats as C, synthSfx as Ct, QualityCaps as D, PlayMusicOptions as Dt, DeviceHints as E, MusicTrack as Et, BehaviorState as F, LogManager as Ft, ORDER_GROUP_BASE as G, savesWithoutUid as H, RestoreReport as I, Signal as It, effectiveOrder as J, OrderGroup as K, SaveSlot as L, SignalListener as Lt, readDeviceHints as M, SceneTree as Mt, suggestQuality as N, LogEntry as Nt, QualityTier as O, AudioBuses as Ot, Scene as P, LogLevel as Pt, Localization as Q, SaveSlots as R, Scheduler as S, SynthOptions as St, RendererStats as T, MusicManager as Tt, SaveStore as U, restoreBehaviors as V, createSaveStore as W, BASE_LOCALE as X, resolveOrderGroups as Y, LocaleTables as Z, mergeStaticSignals as _, spatialPan as _t, clearBehaviors as a, EffectLog as at, Engine as b, SfxParams as bt, registeredBehaviors as c, isAudioContextAvailable as ct, PropSchema as d, Listener as dt, suggestLocale as et, clearRegistry as f, ROLLOFF_MODELS as ft, getNodeType as g, spatialGain as gt, getNodeSignals as h, Vec3 as ht, behaviorSignals as i, EffectKind as it, qualityEnvironment as j, NodeLifecycle as jt, Settings as k, BusName as kt, NodeCtor as l, Voice as lt, getNodeSchema as m, SpatialParams as mt, BehaviorCtor as n, InputMap as nt, getBehavior as o, SfxEngine as ot, createNode as p, RolloffModel as pt, OrderGroupTable as q, behaviorSchema as r, EffectEvent as rt, registerBehavior as s, SfxPlayOptions as st, Behavior as t, translationKey as tt, PropDef as u, VoicePreset as ut, registerNode as v, SFX_PRESETS as vt, GameStats as w, MusicBackend as wt, EngineOptions as x, SfxWave as xt, registeredTypes as y, SFX_PRESET_NAMES as yt, behaviorsWithoutSave as z };
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
2
|
import { A as registerBehavior, C as diagnose, n as loadScene, o as computeViewport, s as resolveViewport } from "./loader-BTkHYrQn.js";
|
|
3
|
-
import { b as AudioPlayer, x as Engine } from "./register-
|
|
3
|
+
import { b as AudioPlayer, x as Engine } from "./register-p48lHE2o.js";
|
|
4
4
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
5
5
|
import { i as resolveRendering, n as attachTouchControls } from "./touch-BnMyy9tr.js";
|
|
6
|
-
import { a as openBundledEditor, c as audioErrors, i as devServerLibrary, n as pauseWhenHidden, r as crossFade, s as claimCanvasGestures, t as teardown } from "./teardown-
|
|
7
|
-
import { n as registerGameplayBehaviors } from "./gameplay-
|
|
8
|
-
import { g as PhysicsBody2D, n as UILayer, t as registerNodes2D, u as Camera2D, y as Node2D } from "./register-
|
|
6
|
+
import { a as openBundledEditor, c as audioErrors, i as devServerLibrary, n as pauseWhenHidden, r as crossFade, s as claimCanvasGestures, t as teardown } from "./teardown-C7uVSJvx.js";
|
|
7
|
+
import { n as registerGameplayBehaviors } from "./gameplay-CZ2yq37J.js";
|
|
8
|
+
import { g as PhysicsBody2D, n as UILayer, t as registerNodes2D, u as Camera2D, y as Node2D } from "./register-en63AEZO.js";
|
|
9
9
|
import { t as debugSources } from "./debug-draw-BM3DsvtT.js";
|
|
10
|
-
import { n as enablePhysics2D } from "./physics-2d-
|
|
10
|
+
import { n as enablePhysics2D } from "./physics-2d-CfWAggJ1.js";
|
|
11
11
|
import { Box3, BufferAttribute, BufferGeometry, Color, LineBasicMaterial, LineSegments, LinearFilter, NearestFilter, OrthographicCamera, Raycaster, SRGBColorSpace, Scene, TextureLoader, Vector2, Vector3, WebGLRenderer } from "three";
|
|
12
12
|
//#region src/2d/assets.ts
|
|
13
13
|
/**
|
|
@@ -333,7 +333,11 @@ var Renderer2D = class {
|
|
|
333
333
|
this.selectionLines.renderOrder = 1e4;
|
|
334
334
|
this.selectionLines.visible = false;
|
|
335
335
|
this.worldScene.add(this.selectionLines);
|
|
336
|
-
this.disconnect = this.engine.updated.connect(() =>
|
|
336
|
+
this.disconnect = this.engine.updated.connect(() => {
|
|
337
|
+
const started = performance.now();
|
|
338
|
+
this.render();
|
|
339
|
+
this.engine.noteRenderMs(performance.now() - started);
|
|
340
|
+
});
|
|
337
341
|
}
|
|
338
342
|
debugLines;
|
|
339
343
|
selectionLines;
|