incanto 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/2d.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { s as JsonObject } from "./schema-CcoWb32N.js";
2
- import { C as RendererStats, S as GameStats, T as Node, b as Scheduler, l as PropSchema, n as BehaviorCtor, v as Engine, w as Scene$1 } from "./behavior-e3kAmPGC.js";
3
- import { t as LoadSceneOptions } from "./loader-y_X4zYO0.js";
2
+ import { C as RendererStats, S as GameStats, Z as Node, b as Scheduler, l as PropSchema, n as BehaviorCtor, v as Engine, w as Scene$1 } from "./behavior-q3cejJgs.js";
3
+ import { t as LoadSceneOptions } from "./loader-DnLMMRy8.js";
4
4
  import { t as ParticleSim } from "./particle-sim-CwJ5rI_P.js";
5
5
  import { Group, Mesh, Object3D, Scene, Texture } from "three";
6
6
  import * as RapierNs from "@dimforge/rapier2d-compat";
@@ -655,6 +655,8 @@ declare class Renderer2D {
655
655
  private readonly canvas;
656
656
  constructor(opts: Renderer2DOptions);
657
657
  private readonly debugLines;
658
+ private readonly selectionLines;
659
+ private syncSelectionOutline;
658
660
  private syncDebugLines;
659
661
  private render;
660
662
  private lastViewport;
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-X5iRu6pf.js";
3
- import { a as ColorRect2D, c as AnimatedSprite2D, d as Area2D, f as CharacterBody2D, g as Node2D, h as StaticBody2D, i as Label, l as Sprite2D, m as RigidBody2D, n as UILayer, o as CharacterController2D, p as PhysicsBody2D, r as Particles2D, s as Camera2D, t as registerNodes2D, u as Joint2D } from "./register-ClKnoILk.js";
4
- import { n as enablePhysics2D, t as Physics2D } from "./physics-2d-DmQ540uR.js";
2
+ import { a as AssetStore2D, i as syncTree2D, r as Renderer2D, t as createGame2D } from "./create-game-DuDkqnjl.js";
3
+ import { a as ColorRect2D, c as AnimatedSprite2D, d as Area2D, f as CharacterBody2D, g as Node2D, h as StaticBody2D, i as Label, l as Sprite2D, m as RigidBody2D, n as UILayer, o as CharacterController2D, p as PhysicsBody2D, r as Particles2D, s as Camera2D, t as registerNodes2D, u as Joint2D } from "./register-Cl3pAxX-.js";
4
+ import { n as enablePhysics2D, t as Physics2D } from "./physics-2d-CZM5Y90X.js";
5
5
  //#region src/2d/library-sprite.ts
6
6
  /**
7
7
  * Turn a library sprite-animation JSON into a scene-ready spritesheet asset
package/dist/3d.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { s as JsonObject } from "./schema-CcoWb32N.js";
2
- import { C as RendererStats, S as GameStats, T as Node, b as Scheduler, l as PropSchema, n as BehaviorCtor, v as Engine, w as Scene$1 } from "./behavior-e3kAmPGC.js";
3
- import { t as LoadSceneOptions } from "./loader-y_X4zYO0.js";
2
+ import { C as RendererStats, S as GameStats, Z as Node, b as Scheduler, l as PropSchema, n as BehaviorCtor, v as Engine, w as Scene$1 } from "./behavior-q3cejJgs.js";
3
+ import { t as LoadSceneOptions } from "./loader-DnLMMRy8.js";
4
4
  import { t as ParticleSim } from "./particle-sim-CwJ5rI_P.js";
5
- import { r as SpatialPose } from "./audio-player-VSjk_vG8.js";
5
+ import { r as SpatialPose } from "./audio-player-C3bH_eZ5.js";
6
6
  import { AnimationClip, BufferGeometry, Color, DirectionalLight, InstancedMesh, MeshPhysicalMaterial, Object3D, PerspectiveCamera, Scene, Vector3, WebGLRenderer } from "three";
7
7
  import { VRM } from "@pixiv/three-vrm";
8
8
  import { Sky } from "three/examples/jsm/objects/Sky.js";
@@ -1969,6 +1969,8 @@ declare class Renderer3D {
1969
1969
  private bloomCompositeUniforms;
1970
1970
  constructor(opts: Renderer3DOptions);
1971
1971
  private readonly debugLines;
1972
+ private readonly selectionLines;
1973
+ private syncSelectionOutline;
1972
1974
  private syncDebugLines;
1973
1975
  private render;
1974
1976
  /**
package/dist/3d.js CHANGED
@@ -1,5 +1,5 @@
1
- import { a as Environment3D, c as sunDirectionFromElevationAzimuth, i as syncTree, l as sunDirectionFromSky, o as horizonColorFromSky, r as Renderer3D, s as parseEnvironment3D, t as createGame3D, u as AssetStore3D } from "./create-game-CEFoFN8d.js";
2
- import { A as StaticBody3D, C as TERRAIN_THEMES, D as CharacterBody3D, E as Area3D, F as keyboardIntensity, I as movementState, L as rigPose, N as QUARTER_PITCH, O as PhysicsBody3D, P as cameraRelative, S as DEFAULT_TERRAIN_TEXTURE_BASE, T as Joint3D, _ as FLOWER_VARIETIES, a as VoxelGrid3D, b as Billboard3D, c as ModelInstance3D, d as DirectionalLight3D, f as OmniLight3D, g as resolveFlowerDensity, h as Flowers3D, i as VOXEL_PALETTE, j as Node3D, k as RigidBody3D, l as LoftMesh3D, m as DENSITY_PRESETS, n as Water3D, o as Tree3D, p as Foliage3D, r as WATER_MAX_RIPPLES, s as Particles3D, t as registerNodes3D, u as MeshInstance3D, v as CharacterController3D, w as terrainThemeLayers, x as Terrain3D, y as Camera3D } from "./register-CscQqB7V.js";
1
+ import { a as Environment3D, c as sunDirectionFromElevationAzimuth, i as syncTree, l as sunDirectionFromSky, o as horizonColorFromSky, r as Renderer3D, s as parseEnvironment3D, t as createGame3D, u as AssetStore3D } from "./create-game-rFulaS3s.js";
2
+ import { A as StaticBody3D, C as TERRAIN_THEMES, D as CharacterBody3D, E as Area3D, F as keyboardIntensity, I as movementState, L as rigPose, N as QUARTER_PITCH, O as PhysicsBody3D, P as cameraRelative, S as DEFAULT_TERRAIN_TEXTURE_BASE, T as Joint3D, _ as FLOWER_VARIETIES, a as VoxelGrid3D, b as Billboard3D, c as ModelInstance3D, d as DirectionalLight3D, f as OmniLight3D, g as resolveFlowerDensity, h as Flowers3D, i as VOXEL_PALETTE, j as Node3D, k as RigidBody3D, l as LoftMesh3D, m as DENSITY_PRESETS, n as Water3D, o as Tree3D, p as Foliage3D, r as WATER_MAX_RIPPLES, s as Particles3D, t as registerNodes3D, u as MeshInstance3D, v as CharacterController3D, w as terrainThemeLayers, x as Terrain3D, y as Camera3D } from "./register-CpXcMiEk.js";
3
3
  import { n as splatWeights, t as buildHeightmap } from "./heightmap-CroQPEER.js";
4
- import { n as enablePhysics3D, t as Physics3D } from "./physics-3d-CDjuhtt_.js";
4
+ import { n as enablePhysics3D, t as Physics3D } from "./physics-3d-DT5e8izo.js";
5
5
  export { Area3D, AssetStore3D, Billboard3D, Camera3D, CharacterBody3D, CharacterController3D, DEFAULT_TERRAIN_TEXTURE_BASE, DirectionalLight3D, Environment3D, DENSITY_PRESETS as FLOWER_DENSITY_PRESETS, FLOWER_VARIETIES, Flowers3D, Foliage3D, Joint3D, LoftMesh3D, MeshInstance3D, ModelInstance3D, Node3D, OmniLight3D, Particles3D, Physics3D, PhysicsBody3D, QUARTER_PITCH, Renderer3D, RigidBody3D, StaticBody3D, TERRAIN_THEMES, Terrain3D, Tree3D, VOXEL_PALETTE, VoxelGrid3D, WATER_MAX_RIPPLES, Water3D, buildHeightmap, cameraRelative, createGame3D, enablePhysics3D, horizonColorFromSky, keyboardIntensity, movementState, parseEnvironment3D, registerNodes3D, resolveFlowerDensity, rigPose, splatWeights, sunDirectionFromElevationAzimuth, sunDirectionFromSky, syncTree, terrainThemeLayers };
@@ -1,4 +1,4 @@
1
- import { F as Listener, T as Node, l as PropSchema } from "./behavior-e3kAmPGC.js";
1
+ import { M as Listener, Z as Node, l as PropSchema } from "./behavior-q3cejJgs.js";
2
2
 
3
3
  //#region src/core/nodes/audio-player.d.ts
4
4
  /**
@@ -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";
@@ -477,179 +650,6 @@ declare class LogManager {
477
650
  private push;
478
651
  }
479
652
  //#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
653
  //#region src/core/scene/scene.d.ts
654
654
  /**
655
655
  * A loaded, live scene: the node tree plus everything needed to round-trip
@@ -773,6 +773,13 @@ declare class Engine {
773
773
  * timers, behaviors all breathe together. See `gameplay` `hitStop()`.
774
774
  */
775
775
  timeScale: number;
776
+ /**
777
+ * The node the dev overlay has selected (renderers draw its bounding box
778
+ * as an orange outline in the game view so you can SEE what you picked).
779
+ * Null when nothing is selected; cleared automatically when it leaves the
780
+ * tree. Set by the debug overlay — games normally never touch this.
781
+ */
782
+ debugSelection: Node | null;
776
783
  private _time;
777
784
  private _unscaledTime;
778
785
  /**
@@ -913,4 +920,4 @@ declare function registeredBehaviors(): string[];
913
920
  /** Test isolation helper. */
914
921
  declare function clearBehaviors(): void;
915
922
  //#endregion
916
- export { BusName as $, LogManager as A, spatialGain as B, RendererStats as C, SceneTree as D, NodeLifecycle as E, Listener as F, SfxWave as G, SFX_PRESETS as H, ROLLOFF_MODELS as I, MusicBackend as J, SynthOptions as K, RolloffModel as L, SfxEngine as M, SfxPlayOptions as N, LogEntry as O, isAudioContextAvailable as P, AudioBuses as Q, SpatialParams as R, GameStats as S, Node as T, SFX_PRESET_NAMES as U, spatialPan as V, SfxParams as W, MusicTrack as X, MusicManager as Y, PlayMusicOptions as Z, registeredTypes as _, registerBehavior as a, Scheduler as b, PropDef as c, createNode as d, Signal as et, getNodeSchema as f, registerNode as g, mergeStaticSignals as h, getBehavior as i, InputMap as j, LogLevel as k, PropSchema as l, getNodeType as m, BehaviorCtor as n, registeredBehaviors as o, getNodeSignals as p, synthSfx as q, clearBehaviors as r, NodeCtor as s, Behavior as t, SignalListener as tt, clearRegistry as u, Engine as v, Scene as w, EngineStats as x, EngineOptions as y, Vec3 as z };
923
+ export { Signal as $, SfxPlayOptions as A, SFX_PRESET_NAMES as B, RendererStats as C, LogManager as D, LogLevel as E, SpatialParams as F, MusicBackend as G, SfxWave as H, Vec3 as I, PlayMusicOptions as J, MusicManager as K, spatialGain as L, Listener as M, ROLLOFF_MODELS as N, InputMap as O, RolloffModel as P, NodeLifecycle as Q, spatialPan as R, GameStats as S, LogEntry as T, SynthOptions as U, SfxParams as V, synthSfx as W, BusName as X, AudioBuses as Y, Node as Z, registeredTypes as _, registerBehavior as a, Scheduler as b, PropDef as c, createNode as d, SignalListener 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, registeredBehaviors as o, getNodeSignals as p, MusicTrack as q, clearBehaviors as r, NodeCtor as s, Behavior as t, SceneTree as tt, clearRegistry as u, Engine as v, Scene as w, EngineStats as x, EngineOptions as y, SFX_PRESETS as z };
@@ -1,13 +1,13 @@
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 { s as Engine } from "./particle-sim-CrTE7c02.js";
3
+ import { s as Engine } from "./particle-sim-m3CdTGSl.js";
4
4
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
5
5
  import { s as AudioPlayer } from "./register-Dl_ixIJe.js";
6
6
  import { i as resolveRendering, n as attachTouchControls } from "./touch-031PxtCR.js";
7
7
  import { n as registerGameplayBehaviors } from "./gameplay-CDFgSG6z.js";
8
- import { g as Node2D, n as UILayer, p as PhysicsBody2D, s as Camera2D, t as registerNodes2D } from "./register-ClKnoILk.js";
8
+ import { g as Node2D, n as UILayer, p as PhysicsBody2D, s as Camera2D, t as registerNodes2D } from "./register-Cl3pAxX-.js";
9
9
  import { t as debugSources } from "./debug-draw-CZmOYjL2.js";
10
- import { n as enablePhysics2D } from "./physics-2d-DmQ540uR.js";
10
+ import { n as enablePhysics2D } from "./physics-2d-CZM5Y90X.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
  /**
@@ -101,6 +101,58 @@ function worldFromScreen(view, sx, sy) {
101
101
  };
102
102
  }
103
103
  //#endregion
104
+ //#region src/2d/selection-outline.ts
105
+ /** 2D twin of the 3D selection outline: a world-space (px, y-down) rectangle
106
+ * around the selected node's rendered extent, or a marker square. */
107
+ const box = new Box3();
108
+ const size = new Vector3();
109
+ const MARKER_HALF = 12;
110
+ /** 4 rect edges = 8 points × xy. */
111
+ const OUT = new Float32Array(16);
112
+ function selectionOutline2D(node) {
113
+ if (!(node instanceof Node2D)) return null;
114
+ const obj = node._ensureObject2D();
115
+ obj.updateWorldMatrix(true, true);
116
+ box.setFromObject(obj);
117
+ box.getSize(size);
118
+ let minX;
119
+ let minY;
120
+ let maxX;
121
+ let maxY;
122
+ if (!Number.isFinite(size.x) || size.x === 0 && size.y === 0) {
123
+ const p = new Vector3().setFromMatrixPosition(obj.matrixWorld);
124
+ minX = p.x - MARKER_HALF;
125
+ maxX = p.x + MARKER_HALF;
126
+ minY = p.y - MARKER_HALF;
127
+ maxY = p.y + MARKER_HALF;
128
+ } else {
129
+ minX = box.min.x - 2;
130
+ maxX = box.max.x + 2;
131
+ minY = box.min.y - 2;
132
+ maxY = box.max.y + 2;
133
+ }
134
+ const pts = [
135
+ minX,
136
+ minY,
137
+ maxX,
138
+ minY,
139
+ maxX,
140
+ minY,
141
+ maxX,
142
+ maxY,
143
+ maxX,
144
+ maxY,
145
+ minX,
146
+ maxY,
147
+ minX,
148
+ maxY,
149
+ minX,
150
+ minY
151
+ ];
152
+ OUT.set(pts);
153
+ return OUT;
154
+ }
155
+ //#endregion
104
156
  //#region src/2d/sync.ts
105
157
  function createSync2DScratch() {
106
158
  return {
@@ -217,14 +269,44 @@ var Renderer2D = class {
217
269
  });
218
270
  this.webgl.setPixelRatio(rendering.pixelRatio);
219
271
  this.webgl.info.autoReset = false;
220
- this.debugLines = new LineSegments(new BufferGeometry(), new LineBasicMaterial({ color: "#00ff6e" }));
272
+ this.debugLines = new LineSegments(new BufferGeometry(), new LineBasicMaterial({
273
+ color: "#00ff6e",
274
+ transparent: true,
275
+ depthTest: false
276
+ }));
221
277
  this.debugLines.frustumCulled = false;
222
278
  this.debugLines.renderOrder = 9999;
223
279
  this.debugLines.visible = false;
224
280
  this.worldScene.add(this.debugLines);
281
+ this.selectionLines = new LineSegments(new BufferGeometry(), new LineBasicMaterial({
282
+ color: "#ffb020",
283
+ transparent: true,
284
+ depthTest: false
285
+ }));
286
+ this.selectionLines.frustumCulled = false;
287
+ this.selectionLines.renderOrder = 1e4;
288
+ this.selectionLines.visible = false;
289
+ this.worldScene.add(this.selectionLines);
225
290
  this.disconnect = this.engine.updated.connect(() => this.render());
226
291
  }
227
292
  debugLines;
293
+ selectionLines;
294
+ syncSelectionOutline() {
295
+ const node = this.engine.debugSelection;
296
+ if (node && node.tree !== this.engine.scene?.tree) this.engine.debugSelection = null;
297
+ const current = this.engine.debugSelection;
298
+ const vertices = current ? selectionOutline2D(current) : null;
299
+ this.selectionLines.visible = vertices !== null;
300
+ if (!vertices) return;
301
+ const xyz = new Float32Array(vertices.length / 2 * 3);
302
+ for (let i = 0, j = 0; i < vertices.length; i += 2, j += 3) {
303
+ xyz[j] = vertices[i];
304
+ xyz[j + 1] = vertices[i + 1];
305
+ xyz[j + 2] = 0;
306
+ }
307
+ this.selectionLines.geometry.setAttribute("position", new BufferAttribute(xyz, 3));
308
+ this.selectionLines.geometry.getAttribute("position").needsUpdate = true;
309
+ }
228
310
  syncDebugLines() {
229
311
  let vertices = null;
230
312
  for (const source of debugSources("2d")) {
@@ -246,6 +328,7 @@ var Renderer2D = class {
246
328
  if (!scene) return;
247
329
  this.webgl.info.reset();
248
330
  this.syncDebugLines();
331
+ this.syncSelectionOutline();
249
332
  if (scene.assets && !this.loadedAssetScenes.has(scene)) {
250
333
  this.assets.load(scene.assets);
251
334
  this.loadedAssetScenes.add(scene);