incanto 0.7.0 → 0.8.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 +6 -4
- package/dist/2d.d.ts +93 -3
- package/dist/2d.js +4 -4
- package/dist/3d.d.ts +45 -4
- package/dist/3d.js +4 -4
- package/dist/{audio-player-VSjk_vG8.d.ts → audio-player-Dyjg5k92.d.ts} +1 -1
- package/dist/audit-C6rMyict.js +58 -0
- package/dist/{behavior-e3kAmPGC.d.ts → behavior-Bod1AyJS.d.ts} +211 -174
- package/dist/{create-game-CEFoFN8d.js → create-game-66c4iYJE.js} +76 -6
- package/dist/{create-game-X5iRu6pf.js → create-game-BNDSbhy-.js} +88 -6
- package/dist/debug.d.ts +1 -1
- package/dist/debug.js +3 -0
- package/dist/{errors-BMFaY68Q.d.ts → errors-1dXlIwoR.d.ts} +7 -1
- package/dist/{gameplay-CDFgSG6z.js → gameplay-DPMgZk9W.js} +108 -1
- package/dist/gameplay.d.ts +44 -3
- package/dist/gameplay.js +2 -2
- package/dist/index.d.ts +151 -9
- package/dist/index.js +189 -4
- package/dist/{loader-y_X4zYO0.d.ts → loader-BcUDfNHn.d.ts} +1 -1
- package/dist/net.d.ts +46 -2
- package/dist/net.js +54 -2
- package/dist/particle-sim-CyUU7HVU.js +281 -0
- package/dist/{physics-2d-DmQ540uR.js → physics-2d-q2N362ph.js} +45 -4
- package/dist/{physics-3d-CDjuhtt_.js → physics-3d-CvHr31d4.js} +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/{register-CscQqB7V.js → register-Cbs7QxoV.js} +139 -4
- package/dist/{register-ClKnoILk.js → register-Cqjxrfq0.js} +254 -4
- package/dist/{register-C35HDZpm.js → register-CxmuI9FL.js} +1 -1
- package/dist/{particle-sim-CrTE7c02.js → register-DRPIjrKG.js} +1185 -278
- package/dist/test.d.ts +4 -10
- package/dist/test.js +11 -16
- package/editor/assets/{agent8-1WJU-yXr.js → agent8-B8QnWCeP.js} +1 -1
- package/editor/assets/{index-DzYFgZbl.js → index-CVhnNkb3.js} +81 -81
- package/editor/index.html +1 -1
- package/package.json +1 -1
- package/schemas/scene.schema.json +427 -0
- package/skills/incanto-3d-character.md +14 -0
- package/skills/incanto-audio.md +23 -0
- package/skills/incanto-building-2d-games.md +31 -0
- package/skills/incanto-building-3d-games.md +21 -0
- package/skills/incanto-gameplay-behaviors.md +28 -0
- package/skills/incanto-hud.md +24 -0
- package/skills/incanto-multiplayer.md +27 -0
- package/skills/incanto-node-reference.md +73 -0
- package/skills/incanto-physics-and-input.md +9 -0
- package/skills/incanto-verifying-your-game.md +40 -0
- package/dist/register-Dl_ixIJe.js +0 -834
|
@@ -1,5 +1,68 @@
|
|
|
1
1
|
import { a as Rng, c as JsonValue, i as SceneJson, s as JsonObject } from "./schema-CcoWb32N.js";
|
|
2
2
|
|
|
3
|
+
//#region src/core/scene-tree.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Owns a node tree and drives its lifecycle:
|
|
6
|
+
*
|
|
7
|
+
* - `setRoot` → onEnterTree parent-first, then onReady children-first (once per instance)
|
|
8
|
+
* - `update`/`fixedUpdate` → parent-first traversal, then flush of queued frees
|
|
9
|
+
* - group queries across attached nodes
|
|
10
|
+
*
|
|
11
|
+
* Headless by design — tests step it manually; the render loop (M2) calls it.
|
|
12
|
+
*/
|
|
13
|
+
declare class SceneTree {
|
|
14
|
+
private _root;
|
|
15
|
+
private _engine;
|
|
16
|
+
private readonly freeQueue;
|
|
17
|
+
/**
|
|
18
|
+
* name → attached nodes with that name. Maintained by Node enter/exit/rename
|
|
19
|
+
* so `%name` targeting and root-level getNodesByName are O(1) — behaviors
|
|
20
|
+
* resolve targets every frame and a full-tree walk per chaser melted horde
|
|
21
|
+
* scenes (N chasers × whole tree, 60×/s).
|
|
22
|
+
*/
|
|
23
|
+
private readonly _nameIndex;
|
|
24
|
+
/**
|
|
25
|
+
* Bumped whenever ANY node attaches or detaches — cheap "did the tree
|
|
26
|
+
* change shape?" check for per-step body gathers and similar caches.
|
|
27
|
+
*/
|
|
28
|
+
_structureVersion: number;
|
|
29
|
+
private _frameId;
|
|
30
|
+
/**
|
|
31
|
+
* Monotonic update-frame counter — bumped once per `update()`. Per-frame
|
|
32
|
+
* caches (e.g. the 3d grass-bender body gather) key off this so they rebuild
|
|
33
|
+
* at most once a frame regardless of node visitation order.
|
|
34
|
+
*/
|
|
35
|
+
get frameId(): number;
|
|
36
|
+
/** @internal Node attach hook. */
|
|
37
|
+
_indexName(node: Node): void;
|
|
38
|
+
/** @internal Node detach/rename hook (`name` = the entry to remove). */
|
|
39
|
+
_unindexName(node: Node, name?: string): void;
|
|
40
|
+
/** @internal Every ATTACHED node named `name` (undefined = none). */
|
|
41
|
+
_nodesNamed(name: string): ReadonlySet<Node> | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* @internal Opaque per-frame scratch the 3d layer parks its shared moving-body
|
|
44
|
+
* snapshot on (kept here so it is per-tree-instance, never a module global —
|
|
45
|
+
* core stays three-free, the 3d resolver owns the shape).
|
|
46
|
+
*/
|
|
47
|
+
_frameScratch: unknown;
|
|
48
|
+
get root(): Node | null;
|
|
49
|
+
/** The engine driving this tree (set by Engine.setScene), or null. */
|
|
50
|
+
get engine(): Engine | null;
|
|
51
|
+
/** @internal */
|
|
52
|
+
_setEngine(engine: Engine | null): void;
|
|
53
|
+
setRoot(node: Node): void;
|
|
54
|
+
update(dt: number): void;
|
|
55
|
+
fixedUpdate(dt: number): void;
|
|
56
|
+
getNodesInGroup(group: string): Node[];
|
|
57
|
+
/** Call `method(...args)` on every group member that implements it. */
|
|
58
|
+
callGroup(group: string, method: string, ...args: unknown[]): void;
|
|
59
|
+
/** @internal */
|
|
60
|
+
_queueFree(node: Node): void;
|
|
61
|
+
/** @internal Called by Node.free(): a freed root must not be re-drivable. */
|
|
62
|
+
_detachRoot(node: Node): void;
|
|
63
|
+
private flushFreeQueue;
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
3
66
|
//#region src/core/signal.d.ts
|
|
4
67
|
/**
|
|
5
68
|
* Minimal typed observer used for every engine event (Godot signal semantics).
|
|
@@ -20,6 +83,116 @@ declare class Signal<Args extends unknown[] = unknown[]> {
|
|
|
20
83
|
get connectionCount(): number;
|
|
21
84
|
}
|
|
22
85
|
//#endregion
|
|
86
|
+
//#region src/core/node.d.ts
|
|
87
|
+
/** Lifecycle hooks a SceneTree drives. Wired in scene-tree.ts. */
|
|
88
|
+
interface NodeLifecycle {
|
|
89
|
+
onEnterTree(): void;
|
|
90
|
+
onReady(): void;
|
|
91
|
+
onExitTree(): void;
|
|
92
|
+
update(dt: number): void;
|
|
93
|
+
fixedUpdate(dt: number): void;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Base class of everything in an Incanto scene (Godot's Node model).
|
|
97
|
+
*
|
|
98
|
+
* Pure data + tree structure: no rendering, no DOM, no three.js — renderer
|
|
99
|
+
* adapters subscribe from the outside.
|
|
100
|
+
*/
|
|
101
|
+
declare class Node implements NodeLifecycle {
|
|
102
|
+
static readonly typeName: string;
|
|
103
|
+
/**
|
|
104
|
+
* Signals this node type can emit, declared statically (merged up the class
|
|
105
|
+
* hierarchy). A behavior's `static signals` are declared onto its node at
|
|
106
|
+
* load. Emitting or subscribing an UNDECLARED signal is a hard error —
|
|
107
|
+
* a typo'd signal name must fail loudly, never silently never-fire.
|
|
108
|
+
*/
|
|
109
|
+
static readonly signals?: readonly string[];
|
|
110
|
+
private _name;
|
|
111
|
+
private _parent;
|
|
112
|
+
private readonly _children;
|
|
113
|
+
private readonly _groups;
|
|
114
|
+
private readonly _signals;
|
|
115
|
+
private _declared;
|
|
116
|
+
private _tree;
|
|
117
|
+
private _ready;
|
|
118
|
+
/**
|
|
119
|
+
* Optional STABLE identifier (scene JSON `uid`) — unlike names (unique only
|
|
120
|
+
* among siblings) a uid is unique across the whole scene, so scripts and
|
|
121
|
+
* tools can address a node no matter where it moves.
|
|
122
|
+
*/
|
|
123
|
+
uid: string | null;
|
|
124
|
+
/** Free-form JSON identity for game logic (e.g. `{kind: 'ITEM', value: 10}`). */
|
|
125
|
+
tags: Record<string, unknown>;
|
|
126
|
+
/** Behavior attachment blob from scene JSON (resolved by the loader). */
|
|
127
|
+
script: JsonObject | null;
|
|
128
|
+
/** The resolved behavior instance (set by the loader from `script`). */
|
|
129
|
+
behavior: Behavior | null;
|
|
130
|
+
/** Replication config blob from scene JSON (interpreted in M6; preserved until then). */
|
|
131
|
+
network: JsonObject | null;
|
|
132
|
+
constructor(name?: string);
|
|
133
|
+
get name(): string;
|
|
134
|
+
set name(value: string);
|
|
135
|
+
get parent(): Node | null;
|
|
136
|
+
get children(): readonly Node[];
|
|
137
|
+
get groups(): ReadonlySet<string>;
|
|
138
|
+
/** The SceneTree this node is attached to, or null while detached. */
|
|
139
|
+
get tree(): SceneTree | null;
|
|
140
|
+
/** Whether onReady has run (it runs at most once per instance). */
|
|
141
|
+
get isReady(): boolean;
|
|
142
|
+
addChild<T extends Node>(child: T): T;
|
|
143
|
+
removeChild(child: Node): void;
|
|
144
|
+
reparent(newParent: Node): void;
|
|
145
|
+
findChild(name: string, recursive?: boolean): Node | null;
|
|
146
|
+
/** Topmost ancestor (the node itself when detached). */
|
|
147
|
+
getRoot(): Node;
|
|
148
|
+
/** Depth-first search of THIS subtree for the node carrying `uid`. */
|
|
149
|
+
getNodeByUid(uid: string): Node | null;
|
|
150
|
+
/** Every node in THIS subtree named `name` — names repeat, so a list. */
|
|
151
|
+
getNodesByName(name: string): Node[];
|
|
152
|
+
getPath(): string;
|
|
153
|
+
getNode(path: string): Node;
|
|
154
|
+
getNodeOrNull(path: string): Node | null;
|
|
155
|
+
private resolve;
|
|
156
|
+
addToGroup(group: string): void;
|
|
157
|
+
removeFromGroup(group: string): void;
|
|
158
|
+
isInGroup(group: string): boolean;
|
|
159
|
+
private declaredSignals;
|
|
160
|
+
/** Declare an ad-hoc signal on THIS instance (static `signals` covers types). */
|
|
161
|
+
declareSignal(name: string): void;
|
|
162
|
+
/** Every signal this instance may emit (static + behavior + ad-hoc). */
|
|
163
|
+
declaredSignalNames(): string[];
|
|
164
|
+
private assertDeclared;
|
|
165
|
+
/** Get the named DECLARED signal (creating its Signal object on demand). */
|
|
166
|
+
signal(name: string): Signal<unknown[]>;
|
|
167
|
+
on(signal: string, fn: SignalListener<unknown[]>, opts?: {
|
|
168
|
+
once?: boolean;
|
|
169
|
+
}): () => void;
|
|
170
|
+
off(signal: string, fn: SignalListener<unknown[]>): void;
|
|
171
|
+
emit(signal: string, ...args: unknown[]): void;
|
|
172
|
+
/**
|
|
173
|
+
* Defer destruction to the end of the current update pass (flushed by the
|
|
174
|
+
* SceneTree). Frees immediately when detached from any tree.
|
|
175
|
+
*/
|
|
176
|
+
queueFree(): void;
|
|
177
|
+
/** Immediately detach and tear down this node and its children. */
|
|
178
|
+
free(): void;
|
|
179
|
+
/** @internal */
|
|
180
|
+
_propagateEnterTree(tree: SceneTree): void;
|
|
181
|
+
/** @internal */
|
|
182
|
+
_propagateReady(): void;
|
|
183
|
+
/** @internal */
|
|
184
|
+
_propagateExitTree(): void;
|
|
185
|
+
/** @internal */
|
|
186
|
+
_propagateUpdate(dt: number): void;
|
|
187
|
+
/** @internal */
|
|
188
|
+
_propagateFixedUpdate(dt: number): void;
|
|
189
|
+
onEnterTree(): void;
|
|
190
|
+
onReady(): void;
|
|
191
|
+
onExitTree(): void;
|
|
192
|
+
update(_dt: number): void;
|
|
193
|
+
fixedUpdate(_dt: number): void;
|
|
194
|
+
}
|
|
195
|
+
//#endregion
|
|
23
196
|
//#region src/core/audio/buses.d.ts
|
|
24
197
|
/** The two volume buses every sound routes through (plus the global `master`). */
|
|
25
198
|
type BusName = "sfx" | "music";
|
|
@@ -264,6 +437,30 @@ declare function spatialGain(distance: number, params: SpatialParams): number;
|
|
|
264
437
|
*/
|
|
265
438
|
declare function spatialPan(sourcePos: Vec3, listener: Listener): number;
|
|
266
439
|
//#endregion
|
|
440
|
+
//#region src/core/audio/voice.d.ts
|
|
441
|
+
/**
|
|
442
|
+
* Continuous parametric voices — the engine hum, wind rush and thruster
|
|
443
|
+
* roar that one-shot SFX can't do (racing-3d hand-built exactly this graph).
|
|
444
|
+
* A voice is a small WebAudio patch you retune every frame:
|
|
445
|
+
*
|
|
446
|
+
* const voice = engine.sfx.startVoice('engine');
|
|
447
|
+
* voice.set({ pitch: rpm / 4000, volume: throttle * 0.6 });
|
|
448
|
+
* voice.stop(); // fades out and frees the graph
|
|
449
|
+
*
|
|
450
|
+
* Headless (no AudioContext) the handle is inert — same call sites, no ifs.
|
|
451
|
+
*/
|
|
452
|
+
type VoicePreset = "engine" | "wind" | "hum" | "noise";
|
|
453
|
+
interface Voice {
|
|
454
|
+
/** Retune live. pitch 1 = the preset's base; volume 0..1. */
|
|
455
|
+
set(params: {
|
|
456
|
+
pitch?: number;
|
|
457
|
+
volume?: number;
|
|
458
|
+
}): void;
|
|
459
|
+
/** Fade out over `seconds` (default 0.15) and free the nodes. */
|
|
460
|
+
stop(seconds?: number): void;
|
|
461
|
+
readonly stopped: boolean;
|
|
462
|
+
}
|
|
463
|
+
//#endregion
|
|
267
464
|
//#region src/core/audio/webaudio-sfx.d.ts
|
|
268
465
|
/** A spatial emitter: where the sound is + where the listener is. */
|
|
269
466
|
interface SpatialPlay {
|
|
@@ -296,6 +493,12 @@ declare class SfxEngine {
|
|
|
296
493
|
/** True once a backend is present (lazily created on first use). */
|
|
297
494
|
get available(): boolean;
|
|
298
495
|
private ensure;
|
|
496
|
+
/**
|
|
497
|
+
* Start a continuous parametric voice (engine hum, wind, thrusters) —
|
|
498
|
+
* retune it per frame with `voice.set({ pitch, volume })`, `stop()` when
|
|
499
|
+
* done. Headless returns an inert handle (same call sites, no ifs).
|
|
500
|
+
*/
|
|
501
|
+
startVoice(preset: VoicePreset, gain?: number): Voice;
|
|
299
502
|
/** Resume a gesture-suspended context (wired to the first user gesture). */
|
|
300
503
|
unlock(): void;
|
|
301
504
|
/**
|
|
@@ -477,179 +680,6 @@ declare class LogManager {
|
|
|
477
680
|
private push;
|
|
478
681
|
}
|
|
479
682
|
//#endregion
|
|
480
|
-
//#region src/core/scene-tree.d.ts
|
|
481
|
-
/**
|
|
482
|
-
* Owns a node tree and drives its lifecycle:
|
|
483
|
-
*
|
|
484
|
-
* - `setRoot` → onEnterTree parent-first, then onReady children-first (once per instance)
|
|
485
|
-
* - `update`/`fixedUpdate` → parent-first traversal, then flush of queued frees
|
|
486
|
-
* - group queries across attached nodes
|
|
487
|
-
*
|
|
488
|
-
* Headless by design — tests step it manually; the render loop (M2) calls it.
|
|
489
|
-
*/
|
|
490
|
-
declare class SceneTree {
|
|
491
|
-
private _root;
|
|
492
|
-
private _engine;
|
|
493
|
-
private readonly freeQueue;
|
|
494
|
-
/**
|
|
495
|
-
* name → attached nodes with that name. Maintained by Node enter/exit/rename
|
|
496
|
-
* so `%name` targeting and root-level getNodesByName are O(1) — behaviors
|
|
497
|
-
* resolve targets every frame and a full-tree walk per chaser melted horde
|
|
498
|
-
* scenes (N chasers × whole tree, 60×/s).
|
|
499
|
-
*/
|
|
500
|
-
private readonly _nameIndex;
|
|
501
|
-
/**
|
|
502
|
-
* Bumped whenever ANY node attaches or detaches — cheap "did the tree
|
|
503
|
-
* change shape?" check for per-step body gathers and similar caches.
|
|
504
|
-
*/
|
|
505
|
-
_structureVersion: number;
|
|
506
|
-
private _frameId;
|
|
507
|
-
/**
|
|
508
|
-
* Monotonic update-frame counter — bumped once per `update()`. Per-frame
|
|
509
|
-
* caches (e.g. the 3d grass-bender body gather) key off this so they rebuild
|
|
510
|
-
* at most once a frame regardless of node visitation order.
|
|
511
|
-
*/
|
|
512
|
-
get frameId(): number;
|
|
513
|
-
/** @internal Node attach hook. */
|
|
514
|
-
_indexName(node: Node): void;
|
|
515
|
-
/** @internal Node detach/rename hook (`name` = the entry to remove). */
|
|
516
|
-
_unindexName(node: Node, name?: string): void;
|
|
517
|
-
/** @internal Every ATTACHED node named `name` (undefined = none). */
|
|
518
|
-
_nodesNamed(name: string): ReadonlySet<Node> | undefined;
|
|
519
|
-
/**
|
|
520
|
-
* @internal Opaque per-frame scratch the 3d layer parks its shared moving-body
|
|
521
|
-
* snapshot on (kept here so it is per-tree-instance, never a module global —
|
|
522
|
-
* core stays three-free, the 3d resolver owns the shape).
|
|
523
|
-
*/
|
|
524
|
-
_frameScratch: unknown;
|
|
525
|
-
get root(): Node | null;
|
|
526
|
-
/** The engine driving this tree (set by Engine.setScene), or null. */
|
|
527
|
-
get engine(): Engine | null;
|
|
528
|
-
/** @internal */
|
|
529
|
-
_setEngine(engine: Engine | null): void;
|
|
530
|
-
setRoot(node: Node): void;
|
|
531
|
-
update(dt: number): void;
|
|
532
|
-
fixedUpdate(dt: number): void;
|
|
533
|
-
getNodesInGroup(group: string): Node[];
|
|
534
|
-
/** Call `method(...args)` on every group member that implements it. */
|
|
535
|
-
callGroup(group: string, method: string, ...args: unknown[]): void;
|
|
536
|
-
/** @internal */
|
|
537
|
-
_queueFree(node: Node): void;
|
|
538
|
-
/** @internal Called by Node.free(): a freed root must not be re-drivable. */
|
|
539
|
-
_detachRoot(node: Node): void;
|
|
540
|
-
private flushFreeQueue;
|
|
541
|
-
}
|
|
542
|
-
//#endregion
|
|
543
|
-
//#region src/core/node.d.ts
|
|
544
|
-
/** Lifecycle hooks a SceneTree drives. Wired in scene-tree.ts. */
|
|
545
|
-
interface NodeLifecycle {
|
|
546
|
-
onEnterTree(): void;
|
|
547
|
-
onReady(): void;
|
|
548
|
-
onExitTree(): void;
|
|
549
|
-
update(dt: number): void;
|
|
550
|
-
fixedUpdate(dt: number): void;
|
|
551
|
-
}
|
|
552
|
-
/**
|
|
553
|
-
* Base class of everything in an Incanto scene (Godot's Node model).
|
|
554
|
-
*
|
|
555
|
-
* Pure data + tree structure: no rendering, no DOM, no three.js — renderer
|
|
556
|
-
* adapters subscribe from the outside.
|
|
557
|
-
*/
|
|
558
|
-
declare class Node implements NodeLifecycle {
|
|
559
|
-
static readonly typeName: string;
|
|
560
|
-
/**
|
|
561
|
-
* Signals this node type can emit, declared statically (merged up the class
|
|
562
|
-
* hierarchy). A behavior's `static signals` are declared onto its node at
|
|
563
|
-
* load. Emitting or subscribing an UNDECLARED signal is a hard error —
|
|
564
|
-
* a typo'd signal name must fail loudly, never silently never-fire.
|
|
565
|
-
*/
|
|
566
|
-
static readonly signals?: readonly string[];
|
|
567
|
-
private _name;
|
|
568
|
-
private _parent;
|
|
569
|
-
private readonly _children;
|
|
570
|
-
private readonly _groups;
|
|
571
|
-
private readonly _signals;
|
|
572
|
-
private _declared;
|
|
573
|
-
private _tree;
|
|
574
|
-
private _ready;
|
|
575
|
-
/**
|
|
576
|
-
* Optional STABLE identifier (scene JSON `uid`) — unlike names (unique only
|
|
577
|
-
* among siblings) a uid is unique across the whole scene, so scripts and
|
|
578
|
-
* tools can address a node no matter where it moves.
|
|
579
|
-
*/
|
|
580
|
-
uid: string | null;
|
|
581
|
-
/** Free-form JSON identity for game logic (e.g. `{kind: 'ITEM', value: 10}`). */
|
|
582
|
-
tags: Record<string, unknown>;
|
|
583
|
-
/** Behavior attachment blob from scene JSON (resolved by the loader). */
|
|
584
|
-
script: JsonObject | null;
|
|
585
|
-
/** The resolved behavior instance (set by the loader from `script`). */
|
|
586
|
-
behavior: Behavior | null;
|
|
587
|
-
/** Replication config blob from scene JSON (interpreted in M6; preserved until then). */
|
|
588
|
-
network: JsonObject | null;
|
|
589
|
-
constructor(name?: string);
|
|
590
|
-
get name(): string;
|
|
591
|
-
set name(value: string);
|
|
592
|
-
get parent(): Node | null;
|
|
593
|
-
get children(): readonly Node[];
|
|
594
|
-
get groups(): ReadonlySet<string>;
|
|
595
|
-
/** The SceneTree this node is attached to, or null while detached. */
|
|
596
|
-
get tree(): SceneTree | null;
|
|
597
|
-
/** Whether onReady has run (it runs at most once per instance). */
|
|
598
|
-
get isReady(): boolean;
|
|
599
|
-
addChild<T extends Node>(child: T): T;
|
|
600
|
-
removeChild(child: Node): void;
|
|
601
|
-
reparent(newParent: Node): void;
|
|
602
|
-
findChild(name: string, recursive?: boolean): Node | null;
|
|
603
|
-
/** Topmost ancestor (the node itself when detached). */
|
|
604
|
-
getRoot(): Node;
|
|
605
|
-
/** Depth-first search of THIS subtree for the node carrying `uid`. */
|
|
606
|
-
getNodeByUid(uid: string): Node | null;
|
|
607
|
-
/** Every node in THIS subtree named `name` — names repeat, so a list. */
|
|
608
|
-
getNodesByName(name: string): Node[];
|
|
609
|
-
getPath(): string;
|
|
610
|
-
getNode(path: string): Node;
|
|
611
|
-
getNodeOrNull(path: string): Node | null;
|
|
612
|
-
private resolve;
|
|
613
|
-
addToGroup(group: string): void;
|
|
614
|
-
removeFromGroup(group: string): void;
|
|
615
|
-
isInGroup(group: string): boolean;
|
|
616
|
-
private declaredSignals;
|
|
617
|
-
/** Declare an ad-hoc signal on THIS instance (static `signals` covers types). */
|
|
618
|
-
declareSignal(name: string): void;
|
|
619
|
-
/** Every signal this instance may emit (static + behavior + ad-hoc). */
|
|
620
|
-
declaredSignalNames(): string[];
|
|
621
|
-
private assertDeclared;
|
|
622
|
-
/** Get the named DECLARED signal (creating its Signal object on demand). */
|
|
623
|
-
signal(name: string): Signal<unknown[]>;
|
|
624
|
-
on(signal: string, fn: SignalListener<unknown[]>, opts?: {
|
|
625
|
-
once?: boolean;
|
|
626
|
-
}): () => void;
|
|
627
|
-
off(signal: string, fn: SignalListener<unknown[]>): void;
|
|
628
|
-
emit(signal: string, ...args: unknown[]): void;
|
|
629
|
-
/**
|
|
630
|
-
* Defer destruction to the end of the current update pass (flushed by the
|
|
631
|
-
* SceneTree). Frees immediately when detached from any tree.
|
|
632
|
-
*/
|
|
633
|
-
queueFree(): void;
|
|
634
|
-
/** Immediately detach and tear down this node and its children. */
|
|
635
|
-
free(): void;
|
|
636
|
-
/** @internal */
|
|
637
|
-
_propagateEnterTree(tree: SceneTree): void;
|
|
638
|
-
/** @internal */
|
|
639
|
-
_propagateReady(): void;
|
|
640
|
-
/** @internal */
|
|
641
|
-
_propagateExitTree(): void;
|
|
642
|
-
/** @internal */
|
|
643
|
-
_propagateUpdate(dt: number): void;
|
|
644
|
-
/** @internal */
|
|
645
|
-
_propagateFixedUpdate(dt: number): void;
|
|
646
|
-
onEnterTree(): void;
|
|
647
|
-
onReady(): void;
|
|
648
|
-
onExitTree(): void;
|
|
649
|
-
update(_dt: number): void;
|
|
650
|
-
fixedUpdate(_dt: number): void;
|
|
651
|
-
}
|
|
652
|
-
//#endregion
|
|
653
683
|
//#region src/core/scene/scene.d.ts
|
|
654
684
|
/**
|
|
655
685
|
* A loaded, live scene: the node tree plus everything needed to round-trip
|
|
@@ -773,6 +803,13 @@ declare class Engine {
|
|
|
773
803
|
* timers, behaviors all breathe together. See `gameplay` `hitStop()`.
|
|
774
804
|
*/
|
|
775
805
|
timeScale: number;
|
|
806
|
+
/**
|
|
807
|
+
* The node the dev overlay has selected (renderers draw its bounding box
|
|
808
|
+
* as an orange outline in the game view so you can SEE what you picked).
|
|
809
|
+
* Null when nothing is selected; cleared automatically when it leaves the
|
|
810
|
+
* tree. Set by the debug overlay — games normally never touch this.
|
|
811
|
+
*/
|
|
812
|
+
debugSelection: Node | null;
|
|
776
813
|
private _time;
|
|
777
814
|
private _unscaledTime;
|
|
778
815
|
/**
|
|
@@ -913,4 +950,4 @@ declare function registeredBehaviors(): string[];
|
|
|
913
950
|
/** Test isolation helper. */
|
|
914
951
|
declare function clearBehaviors(): void;
|
|
915
952
|
//#endregion
|
|
916
|
-
export {
|
|
953
|
+
export { Node as $, SfxPlayOptions as A, spatialPan as B, RendererStats as C, LogManager as D, LogLevel as E, ROLLOFF_MODELS as F, SynthOptions as G, SFX_PRESET_NAMES as H, RolloffModel as I, MusicManager as J, synthSfx as K, SpatialParams as L, Voice as M, VoicePreset as N, InputMap as O, Listener as P, BusName as Q, Vec3 as R, GameStats as S, LogEntry as T, SfxParams as U, SFX_PRESETS as V, SfxWave as W, PlayMusicOptions as X, MusicTrack as Y, AudioBuses as Z, registeredTypes as _, registerBehavior as a, Scheduler as b, PropDef as c, createNode as d, NodeLifecycle as et, getNodeSchema as f, registerNode as g, mergeStaticSignals as h, getBehavior as i, isAudioContextAvailable as j, SfxEngine as k, PropSchema as l, getNodeType as m, BehaviorCtor as n, SignalListener as nt, registeredBehaviors as o, getNodeSignals as p, MusicBackend as q, clearBehaviors as r, SceneTree as rt, NodeCtor as s, Behavior as t, Signal as tt, clearRegistry as u, Engine as v, Scene as w, EngineStats as x, EngineOptions as y, spatialGain as z };
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
2
|
import { _ as registerBehavior, n as loadScene } from "./loader-B4OEXDZ8.js";
|
|
3
|
-
import {
|
|
3
|
+
import { l as AudioPlayer, u as Engine } from "./register-DRPIjrKG.js";
|
|
4
4
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
5
|
-
import { s as AudioPlayer } from "./register-Dl_ixIJe.js";
|
|
6
5
|
import { i as resolveRendering, n as attachTouchControls } from "./touch-031PxtCR.js";
|
|
7
|
-
import { n as registerGameplayBehaviors } from "./gameplay-
|
|
6
|
+
import { n as registerGameplayBehaviors } from "./gameplay-DPMgZk9W.js";
|
|
8
7
|
import { t as debugSources } from "./debug-draw-CZmOYjL2.js";
|
|
9
|
-
import {
|
|
10
|
-
import { n as enablePhysics3D } from "./physics-3d-
|
|
11
|
-
import { ACESFilmicToneMapping, AmbientLight, BufferAttribute, BufferGeometry, Color, DepthTexture, EquirectangularReflectionMapping, FloatType, Fog, HalfFloatType, LineBasicMaterial, LineSegments, Matrix4, Mesh, PCFShadowMap, PMREMGenerator, PerspectiveCamera, PlaneGeometry, Quaternion, Raycaster, Scene, ShaderMaterial, Vector2, Vector3, WebGLRenderTarget, WebGLRenderer } from "three";
|
|
8
|
+
import { M as Node3D, b as Camera3D, f as DirectionalLight3D, k as PhysicsBody3D, l as ModelInstance3D, t as registerNodes3D } from "./register-Cbs7QxoV.js";
|
|
9
|
+
import { n as enablePhysics3D } from "./physics-3d-CvHr31d4.js";
|
|
10
|
+
import { ACESFilmicToneMapping, AmbientLight, Box3, BufferAttribute, BufferGeometry, Color, DepthTexture, EquirectangularReflectionMapping, FloatType, Fog, HalfFloatType, LineBasicMaterial, LineSegments, Matrix4, Mesh, PCFShadowMap, PMREMGenerator, PerspectiveCamera, PlaneGeometry, Quaternion, Raycaster, Scene, ShaderMaterial, Vector2, Vector3, WebGLRenderTarget, WebGLRenderer } from "three";
|
|
12
11
|
import { VRMLoaderPlugin, VRMUtils } from "@pixiv/three-vrm";
|
|
13
12
|
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
|
|
14
13
|
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js";
|
|
@@ -1073,6 +1072,54 @@ function parseIblIntensity(value) {
|
|
|
1073
1072
|
return value;
|
|
1074
1073
|
}
|
|
1075
1074
|
//#endregion
|
|
1075
|
+
//#region src/3d/selection-outline.ts
|
|
1076
|
+
/**
|
|
1077
|
+
* Where IS the node the dev-overlay selected? — world-space outline segments
|
|
1078
|
+
* for the renderer's highlight pass. A renderable node gets its actual
|
|
1079
|
+
* bounding box (children included); a node with no visual extent gets a
|
|
1080
|
+
* small marker cube at its world position so it is still findable.
|
|
1081
|
+
*/
|
|
1082
|
+
const box = new Box3();
|
|
1083
|
+
const size = new Vector3();
|
|
1084
|
+
const MARKER_HALF = .4;
|
|
1085
|
+
/** 12 box edges = 24 points × xyz. */
|
|
1086
|
+
const OUT = new Float32Array(72);
|
|
1087
|
+
function selectionOutline3D(node) {
|
|
1088
|
+
if (!(node instanceof Node3D)) return null;
|
|
1089
|
+
const obj = node._ensureObject3D();
|
|
1090
|
+
obj.updateWorldMatrix(true, true);
|
|
1091
|
+
box.setFromObject(obj);
|
|
1092
|
+
box.getSize(size);
|
|
1093
|
+
if (!Number.isFinite(size.x) || size.x === 0 && size.y === 0 && size.z === 0) {
|
|
1094
|
+
const p = new Vector3().setFromMatrixPosition(obj.matrixWorld);
|
|
1095
|
+
box.min.set(p.x - MARKER_HALF, p.y - MARKER_HALF, p.z - MARKER_HALF);
|
|
1096
|
+
box.max.set(p.x + MARKER_HALF, p.y + MARKER_HALF, p.z + MARKER_HALF);
|
|
1097
|
+
} else box.expandByScalar(.02);
|
|
1098
|
+
const { min, max } = box;
|
|
1099
|
+
let i = 0;
|
|
1100
|
+
const seg = (x1, y1, z1, x2, y2, z2) => {
|
|
1101
|
+
OUT[i++] = x1;
|
|
1102
|
+
OUT[i++] = y1;
|
|
1103
|
+
OUT[i++] = z1;
|
|
1104
|
+
OUT[i++] = x2;
|
|
1105
|
+
OUT[i++] = y2;
|
|
1106
|
+
OUT[i++] = z2;
|
|
1107
|
+
};
|
|
1108
|
+
seg(min.x, min.y, min.z, max.x, min.y, min.z);
|
|
1109
|
+
seg(max.x, min.y, min.z, max.x, min.y, max.z);
|
|
1110
|
+
seg(max.x, min.y, max.z, min.x, min.y, max.z);
|
|
1111
|
+
seg(min.x, min.y, max.z, min.x, min.y, min.z);
|
|
1112
|
+
seg(min.x, max.y, min.z, max.x, max.y, min.z);
|
|
1113
|
+
seg(max.x, max.y, min.z, max.x, max.y, max.z);
|
|
1114
|
+
seg(max.x, max.y, max.z, min.x, max.y, max.z);
|
|
1115
|
+
seg(min.x, max.y, max.z, min.x, max.y, min.z);
|
|
1116
|
+
seg(min.x, min.y, min.z, min.x, max.y, min.z);
|
|
1117
|
+
seg(max.x, min.y, min.z, max.x, max.y, min.z);
|
|
1118
|
+
seg(max.x, min.y, max.z, max.x, max.y, max.z);
|
|
1119
|
+
seg(min.x, min.y, max.z, min.x, max.y, max.z);
|
|
1120
|
+
return OUT;
|
|
1121
|
+
}
|
|
1122
|
+
//#endregion
|
|
1076
1123
|
//#region src/3d/sync.ts
|
|
1077
1124
|
function isSpatialConsumer(node) {
|
|
1078
1125
|
return node.spatial === true && typeof node._setSpatialPose === "function";
|
|
@@ -1449,9 +1496,31 @@ var Renderer3D = class {
|
|
|
1449
1496
|
this.debugLines.renderOrder = 9999;
|
|
1450
1497
|
this.debugLines.visible = false;
|
|
1451
1498
|
this.threeScene.add(this.debugLines);
|
|
1499
|
+
this.selectionLines = new LineSegments(new BufferGeometry(), new LineBasicMaterial({
|
|
1500
|
+
color: "#ffb020",
|
|
1501
|
+
transparent: true,
|
|
1502
|
+
depthTest: false
|
|
1503
|
+
}));
|
|
1504
|
+
this.selectionLines.frustumCulled = false;
|
|
1505
|
+
this.selectionLines.renderOrder = 1e4;
|
|
1506
|
+
this.selectionLines.visible = false;
|
|
1507
|
+
this.threeScene.add(this.selectionLines);
|
|
1452
1508
|
this.disconnect = this.engine.updated.connect(() => this.render());
|
|
1453
1509
|
}
|
|
1454
1510
|
debugLines;
|
|
1511
|
+
selectionLines;
|
|
1512
|
+
syncSelectionOutline() {
|
|
1513
|
+
const node = this.engine.debugSelection;
|
|
1514
|
+
if (node && node.tree !== this.engine.scene?.tree) this.engine.debugSelection = null;
|
|
1515
|
+
const current = this.engine.debugSelection;
|
|
1516
|
+
const vertices = current ? selectionOutline3D(current) : null;
|
|
1517
|
+
this.selectionLines.visible = vertices !== null;
|
|
1518
|
+
if (vertices) {
|
|
1519
|
+
this.selectionLines.geometry.setAttribute("position", new BufferAttribute(vertices, 3));
|
|
1520
|
+
const attr = this.selectionLines.geometry.getAttribute("position");
|
|
1521
|
+
attr.needsUpdate = true;
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1455
1524
|
syncDebugLines() {
|
|
1456
1525
|
let vertices = null;
|
|
1457
1526
|
for (const source of debugSources("3d")) {
|
|
@@ -1465,6 +1534,7 @@ var Renderer3D = class {
|
|
|
1465
1534
|
const scene = this.engine.scene;
|
|
1466
1535
|
if (!scene) return;
|
|
1467
1536
|
this.syncDebugLines();
|
|
1537
|
+
this.syncSelectionOutline();
|
|
1468
1538
|
if (scene.assets && !this.loadedAssetScenes.has(scene)) {
|
|
1469
1539
|
this.assets.load(scene.assets);
|
|
1470
1540
|
this.loadedAssetScenes.add(scene);
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
2
|
import { _ as registerBehavior, n as loadScene, o as computeViewport, s as resolveViewport } from "./loader-B4OEXDZ8.js";
|
|
3
|
-
import {
|
|
3
|
+
import { l as AudioPlayer, u as Engine } from "./register-DRPIjrKG.js";
|
|
4
4
|
import { t as IncantoError } from "./errors-BpWbnbb_.js";
|
|
5
|
-
import { s as AudioPlayer } from "./register-Dl_ixIJe.js";
|
|
6
5
|
import { i as resolveRendering, n as attachTouchControls } from "./touch-031PxtCR.js";
|
|
7
|
-
import { n as registerGameplayBehaviors } from "./gameplay-
|
|
8
|
-
import { g as
|
|
6
|
+
import { n as registerGameplayBehaviors } from "./gameplay-DPMgZk9W.js";
|
|
7
|
+
import { g as PhysicsBody2D, n as UILayer, t as registerNodes2D, u as Camera2D, y as Node2D } from "./register-Cqjxrfq0.js";
|
|
9
8
|
import { t as debugSources } from "./debug-draw-CZmOYjL2.js";
|
|
10
|
-
import { n as enablePhysics2D } from "./physics-2d-
|
|
9
|
+
import { n as enablePhysics2D } from "./physics-2d-q2N362ph.js";
|
|
11
10
|
import { Box3, BufferAttribute, BufferGeometry, Color, LineBasicMaterial, LineSegments, LinearFilter, NearestFilter, OrthographicCamera, Raycaster, SRGBColorSpace, Scene, TextureLoader, Vector2, Vector3, WebGLRenderer } from "three";
|
|
12
11
|
//#region src/2d/assets.ts
|
|
13
12
|
/**
|
|
@@ -101,6 +100,58 @@ function worldFromScreen(view, sx, sy) {
|
|
|
101
100
|
};
|
|
102
101
|
}
|
|
103
102
|
//#endregion
|
|
103
|
+
//#region src/2d/selection-outline.ts
|
|
104
|
+
/** 2D twin of the 3D selection outline: a world-space (px, y-down) rectangle
|
|
105
|
+
* around the selected node's rendered extent, or a marker square. */
|
|
106
|
+
const box = new Box3();
|
|
107
|
+
const size = new Vector3();
|
|
108
|
+
const MARKER_HALF = 12;
|
|
109
|
+
/** 4 rect edges = 8 points × xy. */
|
|
110
|
+
const OUT = new Float32Array(16);
|
|
111
|
+
function selectionOutline2D(node) {
|
|
112
|
+
if (!(node instanceof Node2D)) return null;
|
|
113
|
+
const obj = node._ensureObject2D();
|
|
114
|
+
obj.updateWorldMatrix(true, true);
|
|
115
|
+
box.setFromObject(obj);
|
|
116
|
+
box.getSize(size);
|
|
117
|
+
let minX;
|
|
118
|
+
let minY;
|
|
119
|
+
let maxX;
|
|
120
|
+
let maxY;
|
|
121
|
+
if (!Number.isFinite(size.x) || size.x === 0 && size.y === 0) {
|
|
122
|
+
const p = new Vector3().setFromMatrixPosition(obj.matrixWorld);
|
|
123
|
+
minX = p.x - MARKER_HALF;
|
|
124
|
+
maxX = p.x + MARKER_HALF;
|
|
125
|
+
minY = p.y - MARKER_HALF;
|
|
126
|
+
maxY = p.y + MARKER_HALF;
|
|
127
|
+
} else {
|
|
128
|
+
minX = box.min.x - 2;
|
|
129
|
+
maxX = box.max.x + 2;
|
|
130
|
+
minY = box.min.y - 2;
|
|
131
|
+
maxY = box.max.y + 2;
|
|
132
|
+
}
|
|
133
|
+
const pts = [
|
|
134
|
+
minX,
|
|
135
|
+
minY,
|
|
136
|
+
maxX,
|
|
137
|
+
minY,
|
|
138
|
+
maxX,
|
|
139
|
+
minY,
|
|
140
|
+
maxX,
|
|
141
|
+
maxY,
|
|
142
|
+
maxX,
|
|
143
|
+
maxY,
|
|
144
|
+
minX,
|
|
145
|
+
maxY,
|
|
146
|
+
minX,
|
|
147
|
+
maxY,
|
|
148
|
+
minX,
|
|
149
|
+
minY
|
|
150
|
+
];
|
|
151
|
+
OUT.set(pts);
|
|
152
|
+
return OUT;
|
|
153
|
+
}
|
|
154
|
+
//#endregion
|
|
104
155
|
//#region src/2d/sync.ts
|
|
105
156
|
function createSync2DScratch() {
|
|
106
157
|
return {
|
|
@@ -217,14 +268,44 @@ var Renderer2D = class {
|
|
|
217
268
|
});
|
|
218
269
|
this.webgl.setPixelRatio(rendering.pixelRatio);
|
|
219
270
|
this.webgl.info.autoReset = false;
|
|
220
|
-
this.debugLines = new LineSegments(new BufferGeometry(), new LineBasicMaterial({
|
|
271
|
+
this.debugLines = new LineSegments(new BufferGeometry(), new LineBasicMaterial({
|
|
272
|
+
color: "#00ff6e",
|
|
273
|
+
transparent: true,
|
|
274
|
+
depthTest: false
|
|
275
|
+
}));
|
|
221
276
|
this.debugLines.frustumCulled = false;
|
|
222
277
|
this.debugLines.renderOrder = 9999;
|
|
223
278
|
this.debugLines.visible = false;
|
|
224
279
|
this.worldScene.add(this.debugLines);
|
|
280
|
+
this.selectionLines = new LineSegments(new BufferGeometry(), new LineBasicMaterial({
|
|
281
|
+
color: "#ffb020",
|
|
282
|
+
transparent: true,
|
|
283
|
+
depthTest: false
|
|
284
|
+
}));
|
|
285
|
+
this.selectionLines.frustumCulled = false;
|
|
286
|
+
this.selectionLines.renderOrder = 1e4;
|
|
287
|
+
this.selectionLines.visible = false;
|
|
288
|
+
this.worldScene.add(this.selectionLines);
|
|
225
289
|
this.disconnect = this.engine.updated.connect(() => this.render());
|
|
226
290
|
}
|
|
227
291
|
debugLines;
|
|
292
|
+
selectionLines;
|
|
293
|
+
syncSelectionOutline() {
|
|
294
|
+
const node = this.engine.debugSelection;
|
|
295
|
+
if (node && node.tree !== this.engine.scene?.tree) this.engine.debugSelection = null;
|
|
296
|
+
const current = this.engine.debugSelection;
|
|
297
|
+
const vertices = current ? selectionOutline2D(current) : null;
|
|
298
|
+
this.selectionLines.visible = vertices !== null;
|
|
299
|
+
if (!vertices) return;
|
|
300
|
+
const xyz = new Float32Array(vertices.length / 2 * 3);
|
|
301
|
+
for (let i = 0, j = 0; i < vertices.length; i += 2, j += 3) {
|
|
302
|
+
xyz[j] = vertices[i];
|
|
303
|
+
xyz[j + 1] = vertices[i + 1];
|
|
304
|
+
xyz[j + 2] = 0;
|
|
305
|
+
}
|
|
306
|
+
this.selectionLines.geometry.setAttribute("position", new BufferAttribute(xyz, 3));
|
|
307
|
+
this.selectionLines.geometry.getAttribute("position").needsUpdate = true;
|
|
308
|
+
}
|
|
228
309
|
syncDebugLines() {
|
|
229
310
|
let vertices = null;
|
|
230
311
|
for (const source of debugSources("2d")) {
|
|
@@ -246,6 +327,7 @@ var Renderer2D = class {
|
|
|
246
327
|
if (!scene) return;
|
|
247
328
|
this.webgl.info.reset();
|
|
248
329
|
this.syncDebugLines();
|
|
330
|
+
this.syncSelectionOutline();
|
|
249
331
|
if (scene.assets && !this.loadedAssetScenes.has(scene)) {
|
|
250
332
|
this.assets.load(scene.assets);
|
|
251
333
|
this.loadedAssetScenes.add(scene);
|
package/dist/debug.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as RendererStats,
|
|
1
|
+
import { C as RendererStats, E as LogLevel, v as Engine } from "./behavior-Bod1AyJS.js";
|
|
2
2
|
|
|
3
3
|
//#region src/debug/panel.d.ts
|
|
4
4
|
/** Minimal document surface the overlay needs (injectable for tests). */
|