incanto 0.35.0 → 0.36.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.
Files changed (50) hide show
  1. package/dist/2d.d.ts +5 -5
  2. package/dist/2d.js +3 -3
  3. package/dist/3d.d.ts +6 -6
  4. package/dist/3d.js +4 -4
  5. package/dist/{audit-C5oZGAru.js → audit-D7F3n3Nt.js} +1 -1
  6. package/dist/{behavior-CGSCWOHB.d.ts → behavior-DibCwrW7.d.ts} +52 -3
  7. package/dist/{create-game-BUD89Kqh.js → create-game-BBD3iUFZ.js} +5 -5
  8. package/dist/{create-game-B0Wfhi2-.js → create-game-WmNFluFz.js} +5 -5
  9. package/dist/debug.d.ts +1 -1
  10. package/dist/debug.js +1 -1
  11. package/dist/{duplicate-C716f-97.js → duplicate-Cvb1BSca.js} +2 -16
  12. package/dist/{editor-switch-DyXEtH36.d.ts → editor-switch-DVwIGZdK.d.ts} +1 -1
  13. package/dist/editor.js +1211 -1126
  14. package/dist/env.d.ts +1 -1
  15. package/dist/{environment-presets-TAGvmM3z.js → environment-presets-fK9oyrrR.js} +3 -3
  16. package/dist/{errors-BY2kL0hv.d.ts → errors-DGRtWlSx.d.ts} +1 -1
  17. package/dist/{gameplay-BvhcQbfJ.js → gameplay-C0MUMSak.js} +3 -3
  18. package/dist/gameplay.d.ts +2 -2
  19. package/dist/gameplay.js +1 -1
  20. package/dist/index.d.ts +7 -24
  21. package/dist/index.js +7 -7
  22. package/dist/{loader-CUcj00M8.d.ts → loader-BqigZsfF.d.ts} +2 -2
  23. package/dist/{loader-Mig5fY4n.js → loader-DAZlgqeC.js} +47 -10
  24. package/dist/net.d.ts +2 -2
  25. package/dist/net.js +3 -3
  26. package/dist/{particle-sim-B-vZBF5R.d.ts → particle-sim-BzJ1yxoE.d.ts} +1 -1
  27. package/dist/{pathfinding-DgOo2KNF.d.ts → pathfinding-B3QtdhvZ.d.ts} +1 -1
  28. package/dist/{physics-2d-DqAclql-.js → physics-2d-B4v39hca.js} +2 -2
  29. package/dist/{physics-3d-DxBH4sIF.js → physics-3d-DFJVMYET.js} +3 -3
  30. package/dist/react.d.ts +2 -2
  31. package/dist/react.js +1 -1
  32. package/dist/{register-BFLg0-_i.js → register-BHAwM4bK.js} +8 -2
  33. package/dist/{register-DSmIRAf7.js → register-COGCNitr.js} +4 -5
  34. package/dist/{register-BjbPMA5B.js → register-DXwtIVqP.js} +3 -3
  35. package/dist/{registry-CJdGpT2V.js → registry-IyWCGe4q.js} +6 -4
  36. package/dist/{schema-3ywbdlrv.d.ts → schema-CFeioQRE.d.ts} +10 -0
  37. package/dist/{test-9EokzbRd.js → test-X_xE6Yay.js} +11 -11
  38. package/dist/test.d.ts +4 -4
  39. package/dist/test.js +2 -2
  40. package/dist/vite.js +1 -1
  41. package/editor/assets/{agent8-D3_GWeuh.js → agent8-BfxUNrEe.js} +1 -1
  42. package/editor/assets/{debug-CX0LDd1r.js → debug-wSa-vYHO.js} +1 -1
  43. package/editor/assets/{index-CMlKFT0C.js → index-BkIuXIjp.js} +181 -96
  44. package/editor/index.html +1 -1
  45. package/package.json +1 -1
  46. package/schemas/scene.schema.json +21 -0
  47. package/skills/incanto-scene-json-authoring.md +30 -0
  48. package/templates-app/beacon-isle-3d/package.json +1 -1
  49. package/templates-app/tps-3d/package.json +1 -1
  50. package/templates-app/village-quest-3d/package.json +1 -1
package/dist/env.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as Rng, i as SceneJson, n as NodeJson, s as JsonObject } from "./schema-3ywbdlrv.js";
1
+ import { a as Rng, i as SceneJson, n as NodeJson, s as JsonObject } from "./schema-CFeioQRE.js";
2
2
 
3
3
  //#region src/env/arena.d.ts
4
4
  /** Valid `generateArena` themes — drives the catalog options AND validation. */
@@ -1,10 +1,10 @@
1
- import { t as registerCoreNodes } from "./register-BFLg0-_i.js";
1
+ import { t as registerCoreNodes } from "./register-BHAwM4bK.js";
2
2
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
3
3
  import { t as Rng } from "./rng-DP-SR7eg.js";
4
- import { i as getNodeSchema, l as registerNode } from "./registry-CJdGpT2V.js";
4
+ import { i as getNodeSchema, l as registerNode } from "./registry-IyWCGe4q.js";
5
5
  import { t as createNoise2D } from "./noise-CGUMx44x.js";
6
6
  import { i as applyParticlePreset, r as PARTICLE_PRESET_NAMES, t as ParticleSim } from "./particle-sim-Bw7hB93B.js";
7
- import { A as Water3D, F as PhysicsBody3D, H as colliderFootDrop, I as RigidBody3D, L as StaticBody3D, M as WaterCutout3D, N as Area3D, P as CharacterBody3D, R as Node3D } from "./gameplay-BvhcQbfJ.js";
7
+ import { A as Water3D, F as PhysicsBody3D, H as colliderFootDrop, I as RigidBody3D, L as StaticBody3D, M as WaterCutout3D, N as Area3D, P as CharacterBody3D, R as Node3D } from "./gameplay-C0MUMSak.js";
8
8
  import { n as splatWeights, t as buildHeightmap } from "./heightmap-CRK0M4jT.js";
9
9
  import { AdditiveBlending, AnimationClip, AnimationMixer, Box3, BoxGeometry, BufferAttribute, BufferGeometry, CanvasTexture, CapsuleGeometry, ClampToEdgeWrapping, Color, ConeGeometry, CylinderGeometry, DataTexture, DirectionalLight, DoubleSide, DynamicDrawUsage, Euler, Group, IcosahedronGeometry, ImageBitmapLoader, InstancedBufferAttribute, InstancedMesh, LinearFilter, LinearMipmapLinearFilter, LoopOnce, LoopRepeat, Matrix4, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshPhysicalMaterial, MeshStandardMaterial, NearestFilter, NoBlending, NoColorSpace, NormalBlending, PerspectiveCamera, PlaneGeometry, PointLight, Points, PointsMaterial, Quaternion, QuaternionKeyframeTrack, RGBADepthPacking, RGBAFormat, RepeatWrapping, SRGBColorSpace, ShaderChunk, ShaderMaterial, SphereGeometry, Texture, TextureLoader, UniformsLib, UniformsUtils, Vector3, Vector4, VectorKeyframeTrack } from "three";
10
10
  import { clone } from "three/addons/utils/SkeletonUtils.js";
@@ -1,4 +1,4 @@
1
- import { s as JsonObject } from "./schema-3ywbdlrv.js";
1
+ import { s as JsonObject } from "./schema-CFeioQRE.js";
2
2
 
3
3
  //#region src/core/audit.d.ts
4
4
  /** Human-readable warnings (empty = clean). Pure JSON walk, no registry. */
@@ -1,7 +1,7 @@
1
- import { f as Node, g as Behavior, n as loadScene, x as registerBehavior } from "./loader-Mig5fY4n.js";
1
+ import { f as Node, h as effectiveOrder, n as loadScene, w as registerBehavior, y as Behavior } from "./loader-DAZlgqeC.js";
2
2
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
3
3
  import { t as jsonClone } from "./json-BLk7H2Qa.js";
4
- import { r as effectiveOrder, t as duplicateNode } from "./duplicate-C716f-97.js";
4
+ import { t as duplicateNode } from "./duplicate-Cvb1BSca.js";
5
5
  import { Color, CubeCamera, DepthTexture, DoubleSide, Euler, FloatType, Frustum, HalfFloatType, LinearMipmapLinearFilter, MathUtils, Matrix4, Mesh, MeshDepthMaterial, Object3D, PerspectiveCamera, Plane, PlaneGeometry, Quaternion, ShaderMaterial, Sphere, Vector2, Vector3, Vector4, WebGLCubeRenderTarget, WebGLRenderTarget } from "three";
6
6
  //#region src/3d/frustum.ts
7
7
  const scratchFrustum = new Frustum();
@@ -2315,7 +2315,7 @@ var Node3D = class Node3D extends Node {
2315
2315
  snapToGround = null;
2316
2316
  /** What three actually sorts by: band base + renderOrder. */
2317
2317
  get effectiveRenderOrder() {
2318
- return effectiveOrder(this.orderGroup, this.renderOrder);
2318
+ return effectiveOrder(this.orderGroup, this.renderOrder, this.tree?.engine?.orderGroups);
2319
2319
  }
2320
2320
  _object3D = null;
2321
2321
  /**
@@ -1,5 +1,5 @@
1
- import { b as Engine, bt as Node, d as PropSchema, n as BehaviorCtor, t as Behavior } from "./behavior-CGSCWOHB.js";
2
- import { c as JsonValue, s as JsonObject } from "./schema-3ywbdlrv.js";
1
+ import { Tt as Node, b as Engine, d as PropSchema, n as BehaviorCtor, t as Behavior } from "./behavior-DibCwrW7.js";
2
+ import { c as JsonValue, s as JsonObject } from "./schema-CFeioQRE.js";
3
3
 
4
4
  //#region src/gameplay/chase.d.ts
5
5
  /**
package/dist/gameplay.js CHANGED
@@ -1,2 +1,2 @@
1
- import { C as FollowCamera, D as Health, E as DamageOnContact, O as Collector, S as restartScene, T as phaseOf, _ as hitStop, a as Wander, b as GameFlow, c as Projectile, d as PathFollow, f as Oscillate, g as Cooldown, h as CameraShake, i as WaveSpawner, k as Chase, l as Pickup, m as Lifetime, n as registerGameplayBehaviors, o as Spawner, p as MoveTo, r as ZombieAI, s as ScoreKeeper, t as GAMEPLAY_BEHAVIORS, u as Patrol, v as screenFlash, w as DayNight, x as goToScene, y as Interactable } from "./gameplay-BvhcQbfJ.js";
1
+ import { C as FollowCamera, D as Health, E as DamageOnContact, O as Collector, S as restartScene, T as phaseOf, _ as hitStop, a as Wander, b as GameFlow, c as Projectile, d as PathFollow, f as Oscillate, g as Cooldown, h as CameraShake, i as WaveSpawner, k as Chase, l as Pickup, m as Lifetime, n as registerGameplayBehaviors, o as Spawner, p as MoveTo, r as ZombieAI, s as ScoreKeeper, t as GAMEPLAY_BEHAVIORS, u as Patrol, v as screenFlash, w as DayNight, x as goToScene, y as Interactable } from "./gameplay-C0MUMSak.js";
2
2
  export { CameraShake, Chase, Collector, Cooldown, DamageOnContact, DayNight, FollowCamera, GAMEPLAY_BEHAVIORS, GameFlow, Health, Interactable, Lifetime, MoveTo, Oscillate, PathFollow, Patrol, Pickup, Projectile, ScoreKeeper, Spawner, Wander, WaveSpawner, ZombieAI, goToScene, hitStop, phaseOf, registerGameplayBehaviors, restartScene, screenFlash };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { $ as Voice, A as qualityEnvironment, B as restoreBehaviors, C as EngineStats, Ct as LogEntry, D as QualityTier, Dt as SignalListener, E as DeviceHints, Et as Signal, F as RestoreReport, G as Localization, H as createSaveStore, I as SaveSlot, J as translationKey, K as T_PREFIX, L as SaveSlots, M as suggestQuality, N as Scene, O as Settings, P as BehaviorState, Q as isAudioContextAvailable, R as behaviorsWithoutSave, S as Scheduler, St as SceneTree, T as RendererStats, Tt as LogManager, U as BASE_LOCALE, V as SaveStore, W as LocaleTables, X as SfxEngine, Y as InputMap, Z as SfxPlayOptions, _ as mergeStaticSignals, _t as PlayMusicOptions, a as clearBehaviors, at as Vec3, b as Engine, bt as Node, c as registeredBehaviors, ct as SFX_PRESETS, d as PropSchema, dt as SfxWave, et as VoicePreset, f as clearRegistry, ft as SynthOptions, g as getNodeType, gt as MusicTrack, h as getNodeSignals, ht as MusicManager, i as behaviorSignals, it as SpatialParams, j as readDeviceHints, k as SettingsValues, l as NodeCtor, lt as SFX_PRESET_NAMES, m as getNodeSchema, mt as MusicBackend, n as BehaviorCtor, nt as ROLLOFF_MODELS, o as getBehavior, ot as spatialGain, p as createNode, pt as synthSfx, q as suggestLocale, r as behaviorSchema, rt as RolloffModel, s as registerBehavior, st as spatialPan, t as Behavior, tt as Listener, u as PropDef, ut as SfxParams, v as registerNode, vt as AudioBuses, w as GameStats, wt as LogLevel, x as EngineOptions, xt as NodeLifecycle, y as registeredTypes, yt as BusName, z as captureBehaviors } from "./behavior-CGSCWOHB.js";
2
- import { a as Rng, c as JsonValue, d as jsonKind, i as SceneJson, l as jsonClone, n as NodeJson, o as JsonKind, r as SCENE_FORMAT, s as JsonObject, t as ConnectionJson, u as jsonEquals } from "./schema-3ywbdlrv.js";
3
- import { n as loadScene, t as LoadSceneOptions } from "./loader-CUcj00M8.js";
4
- import { n as ParticleSimConfig, r as ParticleView, t as ParticleSim } from "./particle-sim-B-vZBF5R.js";
5
- import { a as AudioElementLike, i as gridFromRows, n as PathGrid, o as AudioPlayer, r as findPath, t as FindPathOptions } from "./pathfinding-DgOo2KNF.js";
6
- import { i as auditScene, n as IncantoErrorCode, r as IncantoErrorDetails, t as IncantoError } from "./errors-BY2kL0hv.js";
1
+ import { $ as translationKey, A as qualityEnvironment, At as LogManager, B as restoreBehaviors, C as EngineStats, Ct as AudioBuses, D as QualityTier, Dt as SceneTree, E as DeviceHints, Et as NodeLifecycle, F as RestoreReport, G as OrderGroupTable, H as createSaveStore, I as SaveSlot, J as BASE_LOCALE, K as effectiveOrder, L as SaveSlots, M as suggestQuality, Mt as SignalListener, N as Scene, O as Settings, Ot as LogEntry, P as BehaviorState, Q as suggestLocale, R as behaviorsWithoutSave, S as Scheduler, St as PlayMusicOptions, T as RendererStats, Tt as Node, U as ORDER_GROUP_BASE, V as SaveStore, W as OrderGroup, X as Localization, Y as LocaleTables, Z as T_PREFIX, _ as mergeStaticSignals, _t as SynthOptions, a as clearBehaviors, at as VoicePreset, b as Engine, bt as MusicManager, c as registeredBehaviors, ct as RolloffModel, d as PropSchema, dt as spatialGain, et as InputMap, f as clearRegistry, ft as spatialPan, g as getNodeType, gt as SfxWave, h as getNodeSignals, ht as SfxParams, i as behaviorSignals, it as Voice, j as readDeviceHints, jt as Signal, k as SettingsValues, kt as LogLevel, l as NodeCtor, lt as SpatialParams, m as getNodeSchema, mt as SFX_PRESET_NAMES, n as BehaviorCtor, nt as SfxPlayOptions, o as getBehavior, ot as Listener, p as createNode, pt as SFX_PRESETS, q as resolveOrderGroups, r as behaviorSchema, rt as isAudioContextAvailable, s as registerBehavior, st as ROLLOFF_MODELS, t as Behavior, tt as SfxEngine, u as PropDef, ut as Vec3, v as registerNode, vt as synthSfx, w as GameStats, wt as BusName, x as EngineOptions, xt as MusicTrack, y as registeredTypes, yt as MusicBackend, z as captureBehaviors } from "./behavior-DibCwrW7.js";
2
+ import { a as Rng, c as JsonValue, d as jsonKind, i as SceneJson, l as jsonClone, n as NodeJson, o as JsonKind, r as SCENE_FORMAT, s as JsonObject, t as ConnectionJson, u as jsonEquals } from "./schema-CFeioQRE.js";
3
+ import { n as loadScene, t as LoadSceneOptions } from "./loader-BqigZsfF.js";
4
+ import { n as ParticleSimConfig, r as ParticleView, t as ParticleSim } from "./particle-sim-BzJ1yxoE.js";
5
+ import { a as AudioElementLike, i as gridFromRows, n as PathGrid, o as AudioPlayer, r as findPath, t as FindPathOptions } from "./pathfinding-B3QtdhvZ.js";
6
+ import { i as auditScene, n as IncantoErrorCode, r as IncantoErrorDetails, t as IncantoError } from "./errors-DGRtWlSx.js";
7
7
 
8
8
  //#region src/core/audio/crossfade.d.ts
9
9
  /**
@@ -501,23 +501,6 @@ declare class UiSelect extends HudWidgetBase {
501
501
  */
502
502
  declare function createNoise2D(seed: number): (x: number, y: number) => number;
503
503
  //#endregion
504
- //#region src/core/order-groups.d.ts
505
- /**
506
- * Named draw-order bands — Unity's "sorting layers" for both dimensions.
507
- * A node's effective render order is `base(orderGroup) + renderOrder`, so
508
- * `renderOrder` stays a FINE offset within its band and whole categories
509
- * layer correctly without magic numbers:
510
- *
511
- * background < terrain < default < characters < effects < overlay
512
- *
513
- * Engine type defaults: particles sit in `effects`, Terrain3D in `terrain`;
514
- * everything else is `default` (base 0 — identical to pre-band behavior).
515
- */
516
- type OrderGroup = "background" | "terrain" | "default" | "characters" | "effects" | "overlay";
517
- declare const ORDER_GROUP_BASE: Record<OrderGroup, number>;
518
- /** base + fine offset (unknown group names fall back to `default`). */
519
- declare function effectiveOrder(group: string, renderOrder: number): number;
520
- //#endregion
521
504
  //#region src/core/particle-presets.d.ts
522
505
  /**
523
506
  * Predefined particle looks. A node's `preset` seeds these values UNDER its
@@ -773,4 +756,4 @@ declare function computeViewport(canvasW: number, canvasH: number, viewport: {
773
756
  /** Engine version. Kept in sync with package.json by the release pipeline. */
774
757
  declare const VERSION: string;
775
758
  //#endregion
776
- export { AudioBuses, type AudioElementLike, AudioPlayer, BASE_LOCALE, Behavior, type BehaviorCtor, type BehaviorState, type BusName, CONST_REF_KEY, type ComputedViewport, type ConnectionJson, type CrossfadeGains, type DebugLineSource, type DeviceHints, Engine, type EngineOptions, type EngineStats, type FindPathOptions, type GameStats, type HudAnchor, HudLayer, IncantoError, type IncantoErrorCode, type IncantoErrorDetails, InputMap, type JsonKind, type JsonObject, type JsonValue, type Listener, type LoadSceneOptions, type LocaleTables, Localization, type LogEntry, type LogLevel, LogManager, type MusicBackend, MusicManager, type MusicTrack, Node, type NodeCtor, type NodeJson, type NodeLifecycle, ORDER_GROUP_BASE, type OrderGroup, PARTICLE_PRESETS, PARTICLE_PRESET_NAMES, type ParsedNodePath, type ParticlePresetValues, ParticleSim, type ParticleSimConfig, type ParticleView, type PathGrid, type PlayMusicOptions, type PreloadResult, type PropDef, type PropSchema, type QualityTier, ROLLOFF_MODELS, type Recorder, type RendererStats, type ReplayEvent, type ReplayJson, type ResolvedRendering, type ResolvedViewport, type RestoreReport, Rng, type RolloffModel, SCENE_FORMAT, SFX_PRESETS, SFX_PRESET_NAMES, type SaveSlot, SaveSlots, type SaveStore, Scene, type SceneJson, SceneTree, type Scheduler, Settings, type SettingsValues, SfxEngine, type SfxParams, type SfxPlayOptions, type SfxWave, Signal, type SignalListener, type SpatialParams, type SynthOptions, T_PREFIX, Timer, TouchControls, type TouchControlsOptions, UiBanner, UiBar, UiButton, UiDialogue, UiImage, UiPanel, UiSelect, UiSlider, UiText, UiToggle, VERSION, type Vec3, type ViewportFit, type Voice, type VoicePreset, WebAudioMusicBackend, applyParticlePreset, assetUrls, attachTouchControls, auditScene, behaviorSchema, behaviorSignals, behaviorsWithoutSave, captureBehaviors, clearBehaviors, clearRegistry, computeViewport, createNode, createNoise2D, createSaveStore, crossfadeGains, duplicateNode, effectiveOrder, fadeGain, findPath, getBehavior, getNodeSchema, getNodeSignals, getNodeType, gridFromRows, isAudioContextAvailable, isConstRef, joystickVector, jsonClone, jsonEquals, jsonKind, loadScene, mergeStaticSignals, newUid, parseNodePath, preloadUrls, qualityEnvironment, readDeviceHints, registerBehavior, registerCoreNodes, registerNode, registeredBehaviors, registeredTypes, replay, resolveConstants, resolveRendering, resolveViewport, restoreBehaviors, serializeNode, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
759
+ export { AudioBuses, type AudioElementLike, AudioPlayer, BASE_LOCALE, Behavior, type BehaviorCtor, type BehaviorState, type BusName, CONST_REF_KEY, type ComputedViewport, type ConnectionJson, type CrossfadeGains, type DebugLineSource, type DeviceHints, Engine, type EngineOptions, type EngineStats, type FindPathOptions, type GameStats, type HudAnchor, HudLayer, IncantoError, type IncantoErrorCode, type IncantoErrorDetails, InputMap, type JsonKind, type JsonObject, type JsonValue, type Listener, type LoadSceneOptions, type LocaleTables, Localization, type LogEntry, type LogLevel, LogManager, type MusicBackend, MusicManager, type MusicTrack, Node, type NodeCtor, type NodeJson, type NodeLifecycle, ORDER_GROUP_BASE, type OrderGroup, type OrderGroupTable, PARTICLE_PRESETS, PARTICLE_PRESET_NAMES, type ParsedNodePath, type ParticlePresetValues, ParticleSim, type ParticleSimConfig, type ParticleView, type PathGrid, type PlayMusicOptions, type PreloadResult, type PropDef, type PropSchema, type QualityTier, ROLLOFF_MODELS, type Recorder, type RendererStats, type ReplayEvent, type ReplayJson, type ResolvedRendering, type ResolvedViewport, type RestoreReport, Rng, type RolloffModel, SCENE_FORMAT, SFX_PRESETS, SFX_PRESET_NAMES, type SaveSlot, SaveSlots, type SaveStore, Scene, type SceneJson, SceneTree, type Scheduler, Settings, type SettingsValues, SfxEngine, type SfxParams, type SfxPlayOptions, type SfxWave, Signal, type SignalListener, type SpatialParams, type SynthOptions, T_PREFIX, Timer, TouchControls, type TouchControlsOptions, UiBanner, UiBar, UiButton, UiDialogue, UiImage, UiPanel, UiSelect, UiSlider, UiText, UiToggle, VERSION, type Vec3, type ViewportFit, type Voice, type VoicePreset, WebAudioMusicBackend, applyParticlePreset, assetUrls, attachTouchControls, auditScene, behaviorSchema, behaviorSignals, behaviorsWithoutSave, captureBehaviors, clearBehaviors, clearRegistry, computeViewport, createNode, createNoise2D, createSaveStore, crossfadeGains, duplicateNode, effectiveOrder, fadeGain, findPath, getBehavior, getNodeSchema, getNodeSignals, getNodeType, gridFromRows, isAudioContextAvailable, isConstRef, joystickVector, jsonClone, jsonEquals, jsonKind, loadScene, mergeStaticSignals, newUid, parseNodePath, preloadUrls, qualityEnvironment, readDeviceHints, registerBehavior, registerCoreNodes, registerNode, registeredBehaviors, registeredTypes, replay, resolveConstants, resolveOrderGroups, resolveRendering, resolveViewport, restoreBehaviors, serializeNode, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
package/dist/index.js CHANGED
@@ -1,14 +1,14 @@
1
- import { C as Signal, S as registeredBehaviors, _ as behaviorSchema, a as SCENE_FORMAT, b as getBehavior, c as SceneTree, d as resolveConstants, f as Node, g as Behavior, i as serializeNode, l as CONST_REF_KEY, m as InputMap, n as loadScene, o as computeViewport, p as parseNodePath, r as Scene, s as resolveViewport, u as isConstRef, v as behaviorSignals, x as registerBehavior, y as clearBehaviors } from "./loader-Mig5fY4n.js";
2
- import { A as translationKey, B as WebAudioMusicBackend, C as restoreBehaviors, D as Localization, E as BASE_LOCALE, F as spatialPan, H as fadeGain, I as SFX_PRESETS, L as SFX_PRESET_NAMES, M as isAudioContextAvailable, N as ROLLOFF_MODELS, O as T_PREFIX, P as spatialGain, R as synthSfx, S as captureBehaviors, T as LogManager, U as AudioBuses, V as crossfadeGains, _ as qualityEnvironment, a as UiSlider, b as SaveSlots, c as UiButton, d as UiBanner, f as UiBar, g as Settings, h as Engine, i as UiSelect, j as SfxEngine, k as suggestLocale, l as UiDialogue, m as AudioPlayer, n as UiImage, o as UiToggle, p as UiText, r as UiPanel, s as Timer, t as registerCoreNodes, u as HudLayer, v as readDeviceHints, w as createSaveStore, x as behaviorsWithoutSave, y as suggestQuality, z as MusicManager } from "./register-BFLg0-_i.js";
1
+ import { C as getBehavior, E as Signal, S as clearBehaviors, T as registeredBehaviors, _ as InputMap, a as SCENE_FORMAT, b as behaviorSchema, c as SceneTree, d as resolveConstants, f as Node, g as resolveOrderGroups, h as effectiveOrder, i as serializeNode, l as CONST_REF_KEY, m as ORDER_GROUP_BASE, n as loadScene, o as computeViewport, p as parseNodePath, r as Scene, s as resolveViewport, u as isConstRef, w as registerBehavior, x as behaviorSignals, y as Behavior } from "./loader-DAZlgqeC.js";
2
+ import { A as translationKey, B as WebAudioMusicBackend, C as restoreBehaviors, D as Localization, E as BASE_LOCALE, F as spatialPan, H as fadeGain, I as SFX_PRESETS, L as SFX_PRESET_NAMES, M as isAudioContextAvailable, N as ROLLOFF_MODELS, O as T_PREFIX, P as spatialGain, R as synthSfx, S as captureBehaviors, T as LogManager, U as AudioBuses, V as crossfadeGains, _ as qualityEnvironment, a as UiSlider, b as SaveSlots, c as UiButton, d as UiBanner, f as UiBar, g as Settings, h as Engine, i as UiSelect, j as SfxEngine, k as suggestLocale, l as UiDialogue, m as AudioPlayer, n as UiImage, o as UiToggle, p as UiText, r as UiPanel, s as Timer, t as registerCoreNodes, u as HudLayer, v as readDeviceHints, w as createSaveStore, x as behaviorsWithoutSave, y as suggestQuality, z as MusicManager } from "./register-BHAwM4bK.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
4
  import { t as Rng } from "./rng-DP-SR7eg.js";
5
- import { t as auditScene } from "./audit-C5oZGAru.js";
5
+ import { t as auditScene } from "./audit-D7F3n3Nt.js";
6
6
  import { n as jsonEquals, r as jsonKind, t as jsonClone } from "./json-BLk7H2Qa.js";
7
- import { a as getNodeSignals, c as mergeStaticSignals, i as getNodeSchema, l as registerNode, n as clearRegistry, o as getNodeType, r as createNode, u as registeredTypes } from "./registry-CJdGpT2V.js";
7
+ import { a as getNodeSignals, c as mergeStaticSignals, i as getNodeSchema, l as registerNode, n as clearRegistry, o as getNodeType, r as createNode, u as registeredTypes } from "./registry-IyWCGe4q.js";
8
8
  import { t as createNoise2D } from "./noise-CGUMx44x.js";
9
- import { n as ORDER_GROUP_BASE, r as effectiveOrder, t as duplicateNode } from "./duplicate-C716f-97.js";
10
9
  import { i as applyParticlePreset, n as PARTICLE_PRESETS, r as PARTICLE_PRESET_NAMES, t as ParticleSim } from "./particle-sim-Bw7hB93B.js";
11
10
  import { i as resolveRendering, n as attachTouchControls, r as joystickVector, t as TouchControls } from "./touch-BoNg_MnF.js";
11
+ import { t as duplicateNode } from "./duplicate-Cvb1BSca.js";
12
12
  //#region src/core/pathfinding.ts
13
13
  /**
14
14
  * A* from `from` to `to` (inclusive cell coords). Returns the cell path
@@ -242,6 +242,6 @@ function newUid() {
242
242
  //#endregion
243
243
  //#region src/index.ts
244
244
  /** Engine version. Kept in sync with package.json by the release pipeline. */
245
- const VERSION = "0.35.0";
245
+ const VERSION = "0.36.0";
246
246
  //#endregion
247
- export { AudioBuses, AudioPlayer, BASE_LOCALE, Behavior, CONST_REF_KEY, Engine, HudLayer, IncantoError, InputMap, Localization, LogManager, MusicManager, Node, ORDER_GROUP_BASE, PARTICLE_PRESETS, PARTICLE_PRESET_NAMES, ParticleSim, ROLLOFF_MODELS, Rng, SCENE_FORMAT, SFX_PRESETS, SFX_PRESET_NAMES, SaveSlots, Scene, SceneTree, Settings, SfxEngine, Signal, T_PREFIX, Timer, TouchControls, UiBanner, UiBar, UiButton, UiDialogue, UiImage, UiPanel, UiSelect, UiSlider, UiText, UiToggle, VERSION, WebAudioMusicBackend, applyParticlePreset, assetUrls, attachTouchControls, auditScene, behaviorSchema, behaviorSignals, behaviorsWithoutSave, captureBehaviors, clearBehaviors, clearRegistry, computeViewport, createNode, createNoise2D, createSaveStore, crossfadeGains, duplicateNode, effectiveOrder, fadeGain, findPath, getBehavior, getNodeSchema, getNodeSignals, getNodeType, gridFromRows, isAudioContextAvailable, isConstRef, joystickVector, jsonClone, jsonEquals, jsonKind, loadScene, mergeStaticSignals, newUid, parseNodePath, preloadUrls, qualityEnvironment, readDeviceHints, registerBehavior, registerCoreNodes, registerNode, registeredBehaviors, registeredTypes, replay, resolveConstants, resolveRendering, resolveViewport, restoreBehaviors, serializeNode, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
247
+ export { AudioBuses, AudioPlayer, BASE_LOCALE, Behavior, CONST_REF_KEY, Engine, HudLayer, IncantoError, InputMap, Localization, LogManager, MusicManager, Node, ORDER_GROUP_BASE, PARTICLE_PRESETS, PARTICLE_PRESET_NAMES, ParticleSim, ROLLOFF_MODELS, Rng, SCENE_FORMAT, SFX_PRESETS, SFX_PRESET_NAMES, SaveSlots, Scene, SceneTree, Settings, SfxEngine, Signal, T_PREFIX, Timer, TouchControls, UiBanner, UiBar, UiButton, UiDialogue, UiImage, UiPanel, UiSelect, UiSlider, UiText, UiToggle, VERSION, WebAudioMusicBackend, applyParticlePreset, assetUrls, attachTouchControls, auditScene, behaviorSchema, behaviorSignals, behaviorsWithoutSave, captureBehaviors, clearBehaviors, clearRegistry, computeViewport, createNode, createNoise2D, createSaveStore, crossfadeGains, duplicateNode, effectiveOrder, fadeGain, findPath, getBehavior, getNodeSchema, getNodeSignals, getNodeType, gridFromRows, isAudioContextAvailable, isConstRef, joystickVector, jsonClone, jsonEquals, jsonKind, loadScene, mergeStaticSignals, newUid, parseNodePath, preloadUrls, qualityEnvironment, readDeviceHints, registerBehavior, registerCoreNodes, registerNode, registeredBehaviors, registeredTypes, replay, resolveConstants, resolveOrderGroups, resolveRendering, resolveViewport, restoreBehaviors, serializeNode, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
@@ -1,5 +1,5 @@
1
- import { N as Scene, b as Engine } from "./behavior-CGSCWOHB.js";
2
- import { i as SceneJson } from "./schema-3ywbdlrv.js";
1
+ import { N as Scene, b as Engine } from "./behavior-DibCwrW7.js";
2
+ import { i as SceneJson } from "./schema-CFeioQRE.js";
3
3
 
4
4
  //#region src/core/scene/loader.d.ts
5
5
  interface LoadSceneOptions {
@@ -1,6 +1,6 @@
1
1
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
2
2
  import { n as jsonEquals, t as jsonClone } from "./json-BLk7H2Qa.js";
3
- import { c as mergeStaticSignals, i as getNodeSchema, r as createNode, s as mergeStaticProps, t as applySchemaProps } from "./registry-CJdGpT2V.js";
3
+ import { c as mergeStaticSignals, i as getNodeSchema, r as createNode, s as mergeStaticProps, t as applySchemaProps } from "./registry-IyWCGe4q.js";
4
4
  //#region src/core/signal.ts
5
5
  var Signal = class {
6
6
  connections = [];
@@ -597,6 +597,34 @@ function parseInputDecls(decls) {
597
597
  return out;
598
598
  }
599
599
  //#endregion
600
+ //#region src/core/order-groups.ts
601
+ const ORDER_GROUP_BASE = {
602
+ background: -2e3,
603
+ terrain: -1e3,
604
+ default: 0,
605
+ characters: 1e3,
606
+ effects: 2e3,
607
+ overlay: 3e3
608
+ };
609
+ /** Built-ins with a scene's declarations layered over them. */
610
+ function resolveOrderGroups(declared) {
611
+ return declared ? {
612
+ ...ORDER_GROUP_BASE,
613
+ ...declared
614
+ } : ORDER_GROUP_BASE;
615
+ }
616
+ /**
617
+ * base + fine offset.
618
+ *
619
+ * An unknown name resolves to 0 (`default`) rather than throwing, because this
620
+ * runs per node per frame and a scene that got here has already been validated:
621
+ * `loadScene` hard-fails an `orderGroup` naming a band nothing declares, which
622
+ * is where a typo should be caught.
623
+ */
624
+ function effectiveOrder(group, renderOrder, table = ORDER_GROUP_BASE) {
625
+ return (table[group] ?? 0) + renderOrder;
626
+ }
627
+ //#endregion
600
628
  //#region src/core/node-path.ts
601
629
  function parseNodePath(path) {
602
630
  if (path === "") throw new IncantoError("BAD_NODE_PATH", "Node path must not be empty.");
@@ -1368,6 +1396,8 @@ var Scene = class {
1368
1396
  input;
1369
1397
  /** Translations by locale (merged into `Engine.locale` on setScene). */
1370
1398
  strings;
1399
+ /** Extra draw-order bands (`name → base`), layered over the built-ins. */
1400
+ orderGroups;
1371
1401
  /** Physics config (gravity etc. — interpreted by the physics modules). */
1372
1402
  physics;
1373
1403
  /** Multiplayer config (room etc. — interpreted by incanto/net). */
@@ -1386,6 +1416,7 @@ var Scene = class {
1386
1416
  this.assets = source.assets ? jsonClone(source.assets) : void 0;
1387
1417
  this.constants = source.constants ? jsonClone(source.constants) : void 0;
1388
1418
  this.input = source.input ? jsonClone(source.input) : void 0;
1419
+ this.orderGroups = source.orderGroups ? { ...source.orderGroups } : void 0;
1389
1420
  this.strings = source.strings ? jsonClone(source.strings) : void 0;
1390
1421
  this.physics = source.physics ? jsonClone(source.physics) : void 0;
1391
1422
  this.multiplayer = source.multiplayer ? jsonClone(source.multiplayer) : void 0;
@@ -1403,6 +1434,7 @@ var Scene = class {
1403
1434
  ...this.assets ? { assets: jsonClone(this.assets) } : {},
1404
1435
  ...this.constants ? { constants: jsonClone(this.constants) } : {},
1405
1436
  ...this.input ? { input: jsonClone(this.input) } : {},
1437
+ ...this.orderGroups ? { orderGroups: { ...this.orderGroups } } : {},
1406
1438
  ...this.strings ? { strings: jsonClone(this.strings) } : {},
1407
1439
  ...this.physics ? { physics: jsonClone(this.physics) } : {},
1408
1440
  ...this.multiplayer ? { multiplayer: jsonClone(this.multiplayer) } : {},
@@ -1429,7 +1461,7 @@ function loadScene(json, opts) {
1429
1461
  if (typeof json !== "object" || json === null) throw new IncantoError("BAD_FORMAT", `Scene JSON must be an object, got ${json === null ? "null" : typeof json}.`);
1430
1462
  const sceneJson = json;
1431
1463
  validateHeader(sceneJson);
1432
- const root = buildNode(sceneJson.root, opts, [], "", sceneJson.constants);
1464
+ const root = buildNode(sceneJson.root, opts, [], "", sceneJson.constants, Object.keys(sceneJson.orderGroups ?? {}));
1433
1465
  validateUniqueUids(root);
1434
1466
  const tree = new SceneTree();
1435
1467
  if (opts?.engine) tree._setEngine(opts.engine);
@@ -1454,6 +1486,11 @@ function validateHeader(json) {
1454
1486
  if (typeof json.input !== "object" || json.input === null || Array.isArray(json.input)) throw new IncantoError("BAD_FORMAT", "Scene \"input\" must be an object of action declarations.");
1455
1487
  parseInputDecls(json.input);
1456
1488
  }
1489
+ if (json.orderGroups !== void 0) {
1490
+ const table = json.orderGroups;
1491
+ if (typeof table !== "object" || table === null || Array.isArray(table)) throw new IncantoError("BAD_FORMAT", "Scene \"orderGroups\" must be an object of band name → base offset, e.g. { \"ui-back\": 2500 }.");
1492
+ for (const [name, base] of Object.entries(table)) if (typeof base !== "number" || !Number.isFinite(base)) throw new IncantoError("BAD_FORMAT", `Order group '${name}' must be a finite number (its base draw offset), got ${JSON.stringify(base)}. A band is a NUMBER — a bare name would sort exactly like "default" and mean nothing.`, { prop: name });
1493
+ }
1457
1494
  if (json.assets !== void 0) {
1458
1495
  if (typeof json.assets !== "object" || json.assets === null || Array.isArray(json.assets)) throw new IncantoError("BAD_FORMAT", "Scene \"assets\" must be an object of asset declarations.");
1459
1496
  for (const [key, decl] of Object.entries(json.assets)) {
@@ -1477,22 +1514,22 @@ function withNodeContext(e, path, nj) {
1477
1514
  });
1478
1515
  return e;
1479
1516
  }
1480
- function buildNode(nj, opts, stack, parentPath, constants) {
1517
+ function buildNode(nj, opts, stack, parentPath, constants, bands = []) {
1481
1518
  const path = `${parentPath}/${nj.name}`;
1482
1519
  try {
1483
1520
  if (nj.instance !== void 0 && nj.type !== void 0) throw new IncantoError("BAD_FORMAT", `Node '${nj.name}' declares both "type" and "instance" — they are mutually exclusive.`);
1484
- if (nj.instance !== void 0) return buildInstance(nj, opts, stack, path, constants);
1521
+ if (nj.instance !== void 0) return buildInstance(nj, opts, stack, path, constants, bands);
1485
1522
  if (nj.type === void 0) throw new IncantoError("BAD_FORMAT", `Node '${nj.name}' must declare either "type" or "instance".`);
1486
- const node = createNode(nj.type, resolveConstants(nj.props, constants));
1523
+ const node = createNode(nj.type, resolveConstants(nj.props, constants), { orderGroup: bands });
1487
1524
  applyCommon(node, nj, opts);
1488
1525
  node.constructor.validateJson?.(node);
1489
- for (const childJson of nj.children ?? []) node.addChild(buildNode(childJson, opts, stack, path, constants));
1526
+ for (const childJson of nj.children ?? []) node.addChild(buildNode(childJson, opts, stack, path, constants, bands));
1490
1527
  return node;
1491
1528
  } catch (e) {
1492
1529
  throw withNodeContext(e, path, nj);
1493
1530
  }
1494
1531
  }
1495
- function buildInstance(nj, opts, stack, path, constants) {
1532
+ function buildInstance(nj, opts, stack, path, constants, bands) {
1496
1533
  const instancePath = nj.instance;
1497
1534
  if (!opts?.resolveScene) throw new IncantoError("UNRESOLVED_INSTANCE", `Node '${nj.name}' references instance '${instancePath}' but no resolveScene option was provided.`);
1498
1535
  if (stack.includes(instancePath)) throw new IncantoError("UNRESOLVED_INSTANCE", `Instance cycle detected: ${[...stack, instancePath].join(" → ")}.`);
@@ -1504,13 +1541,13 @@ function buildInstance(nj, opts, stack, path, constants) {
1504
1541
  ...sub.root,
1505
1542
  name: nj.name,
1506
1543
  props: deepMerge(sub.root.props ?? {}, overrides)
1507
- }, opts, [...stack, instancePath], parentOf(path), sub.constants);
1544
+ }, opts, [...stack, instancePath], parentOf(path), sub.constants, Object.keys(sub.orderGroups ?? {}));
1508
1545
  applyCommon(node, {
1509
1546
  ...nj,
1510
1547
  type: void 0,
1511
1548
  props: void 0
1512
1549
  }, opts);
1513
- for (const childJson of nj.children ?? []) node.addChild(buildNode(childJson, opts, stack, path, constants));
1550
+ for (const childJson of nj.children ?? []) node.addChild(buildNode(childJson, opts, stack, path, constants, bands));
1514
1551
  wireConnections(node, sub.connections ?? [], opts?.declareConnectionSignals);
1515
1552
  return node;
1516
1553
  }
@@ -1599,4 +1636,4 @@ function validateUniqueUids(root) {
1599
1636
  walk(root);
1600
1637
  }
1601
1638
  //#endregion
1602
- export { Signal as C, registeredBehaviors as S, behaviorSchema as _, SCENE_FORMAT as a, getBehavior as b, SceneTree as c, resolveConstants as d, Node as f, Behavior as g, diagnose as h, serializeNode as i, CONST_REF_KEY as l, InputMap as m, loadScene as n, computeViewport as o, parseNodePath as p, Scene as r, resolveViewport as s, buildNodeJson as t, isConstRef as u, behaviorSignals as v, registerBehavior as x, clearBehaviors as y };
1639
+ export { getBehavior as C, Signal as E, clearBehaviors as S, registeredBehaviors as T, InputMap as _, SCENE_FORMAT as a, behaviorSchema as b, SceneTree as c, resolveConstants as d, Node as f, resolveOrderGroups as g, effectiveOrder as h, serializeNode as i, CONST_REF_KEY as l, ORDER_GROUP_BASE as m, loadScene as n, computeViewport as o, parseNodePath as p, Scene as r, resolveViewport as s, buildNodeJson as t, isConstRef as u, diagnose as v, registerBehavior as w, behaviorSignals as x, Behavior as y };
package/dist/net.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { Et as Signal, b as Engine, bt as Node, d as PropSchema } from "./behavior-CGSCWOHB.js";
2
- import { c as JsonValue, i as SceneJson, s as JsonObject } from "./schema-3ywbdlrv.js";
1
+ import { Tt as Node, b as Engine, d as PropSchema, jt as Signal } from "./behavior-DibCwrW7.js";
2
+ import { c as JsonValue, i as SceneJson, s as JsonObject } from "./schema-CFeioQRE.js";
3
3
 
4
4
  //#region src/net/types.d.ts
5
5
  type Unsubscribe = () => void;
package/dist/net.js CHANGED
@@ -1,9 +1,9 @@
1
- import { n as loadScene } from "./loader-Mig5fY4n.js";
2
- import { h as Engine } from "./register-BFLg0-_i.js";
1
+ import { n as loadScene } from "./loader-DAZlgqeC.js";
2
+ import { h as Engine } from "./register-BHAwM4bK.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
4
  import { t as jsonClone } from "./json-BLk7H2Qa.js";
5
5
  import { n as createAgent8Server } from "./agent8-CvsfVskX.js";
6
- import { i as applySyncPatch, n as NetworkSpawner, r as NetworkManager, t as registerNodesNet } from "./register-BjbPMA5B.js";
6
+ import { i as applySyncPatch, n as NetworkSpawner, r as NetworkManager, t as registerNodesNet } from "./register-DXwtIVqP.js";
7
7
  //#region src/net/loopback.ts
8
8
  /**
9
9
  * In-memory multiplayer hub implementing the SAME kernel contract as
@@ -1,4 +1,4 @@
1
- import { a as Rng } from "./schema-3ywbdlrv.js";
1
+ import { a as Rng } from "./schema-CFeioQRE.js";
2
2
 
3
3
  //#region src/core/particle-sim.d.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { bt as Node, d as PropSchema, tt as Listener } from "./behavior-CGSCWOHB.js";
1
+ import { Tt as Node, d as PropSchema, ot as Listener } from "./behavior-DibCwrW7.js";
2
2
 
3
3
  //#region src/core/nodes/audio-player.d.ts
4
4
  /**
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { h as diagnose } from "./loader-Mig5fY4n.js";
2
+ import { v as diagnose } from "./loader-DAZlgqeC.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
- import { _ as RigidBody2D, b as validateCollider2D, g as PhysicsBody2D, h as CharacterBody2D, m as Area2D, p as Joint2D, y as Node2D } from "./register-DSmIRAf7.js";
4
+ import { _ as RigidBody2D, b as validateCollider2D, g as PhysicsBody2D, h as CharacterBody2D, m as Area2D, p as Joint2D, y as Node2D } from "./register-COGCNitr.js";
5
5
  import { n as registerDebugSource } from "./debug-draw-BM3DsvtT.js";
6
6
  //#region src/2d/physics/physics-2d.ts
7
7
  var physics_2d_exports = /* @__PURE__ */ __exportAll({
@@ -1,9 +1,9 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { h as diagnose } from "./loader-Mig5fY4n.js";
2
+ import { v as diagnose } from "./loader-DAZlgqeC.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
- import { F as PhysicsBody3D, I as RigidBody3D, N as Area3D, P as CharacterBody3D, R as Node3D, z as validateCollider3D } from "./gameplay-BvhcQbfJ.js";
4
+ import { F as PhysicsBody3D, I as RigidBody3D, N as Area3D, P as CharacterBody3D, R as Node3D, z as validateCollider3D } from "./gameplay-C0MUMSak.js";
5
5
  import { n as registerDebugSource } from "./debug-draw-BM3DsvtT.js";
6
- import { A as Terrain3D, F as InstancedMesh3D, L as buildMeshGeometry, P as Joint3D } from "./environment-presets-TAGvmM3z.js";
6
+ import { A as Terrain3D, F as InstancedMesh3D, L as buildMeshGeometry, P as Joint3D } from "./environment-presets-fK9oyrrR.js";
7
7
  import { Euler, Matrix4, Quaternion, Vector3 } from "three";
8
8
  //#region src/3d/physics/collider-lines.ts
9
9
  /**
package/dist/react.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { N as Scene, b as Engine, n as BehaviorCtor } from "./behavior-CGSCWOHB.js";
2
- import { c as JsonValue } from "./schema-3ywbdlrv.js";
1
+ import { N as Scene, b as Engine, n as BehaviorCtor } from "./behavior-DibCwrW7.js";
2
+ import { c as JsonValue } from "./schema-CFeioQRE.js";
3
3
  import { CSSProperties, ReactNode } from "react";
4
4
 
5
5
  //#region src/react/index.d.ts
package/dist/react.js CHANGED
@@ -156,7 +156,7 @@ function IncantoCanvas(props) {
156
156
  pointer: latest.pointer,
157
157
  ...keyboard !== void 0 ? { keyboard } : {}
158
158
  };
159
- const next = await (_gameFactory ?? (mode === "3d" ? async (o) => (await import("./create-game-BUD89Kqh.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-B0Wfhi2-.js").then((n) => n.n)).createGame2D(o)))(opts);
159
+ const next = await (_gameFactory ?? (mode === "3d" ? async (o) => (await import("./create-game-BBD3iUFZ.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-WmNFluFz.js").then((n) => n.n)).createGame2D(o)))(opts);
160
160
  if (disposed) {
161
161
  next.dispose();
162
162
  return;
@@ -1,7 +1,7 @@
1
- import { C as Signal, _ as behaviorSchema, f as Node, h as diagnose, m as InputMap } from "./loader-Mig5fY4n.js";
1
+ import { E as Signal, _ as InputMap, b as behaviorSchema, f as Node, g as resolveOrderGroups, m as ORDER_GROUP_BASE, v as diagnose } from "./loader-DAZlgqeC.js";
2
2
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
3
3
  import { t as Rng } from "./rng-DP-SR7eg.js";
4
- import { l as registerNode } from "./registry-CJdGpT2V.js";
4
+ import { l as registerNode } from "./registry-IyWCGe4q.js";
5
5
  //#region src/core/audio/buses.ts
6
6
  /**
7
7
  * Global volume state — `master` × `sfx`/`music` gain (0..1) plus a `muted`
@@ -1608,6 +1608,11 @@ var Engine = class {
1608
1608
  * anything a locale does not declare falls back to it silently.
1609
1609
  */
1610
1610
  locale = new Localization();
1611
+ /**
1612
+ * Draw-order bands in force: the six built in, plus whatever the current
1613
+ * scene declares. Read by `Node2D`/`Node3D.effectiveRenderOrder`.
1614
+ */
1615
+ orderGroups = ORDER_GROUP_BASE;
1611
1616
  /** Low-latency procedural-SFX player (WebAudio, headless-safe). AudioPlayer
1612
1617
  * presets play through it; games may call `engine.sfx.play(...)` directly. */
1613
1618
  sfx = new SfxEngine();
@@ -1682,6 +1687,7 @@ var Engine = class {
1682
1687
  this._unscaledTime = 0;
1683
1688
  if (scene.input) this.input.declare(scene.input);
1684
1689
  if (scene.strings) this.locale.load(scene.strings);
1690
+ this.orderGroups = resolveOrderGroups(scene.orderGroups);
1685
1691
  this.sceneChanged.emit(scene);
1686
1692
  }
1687
1693
  start() {
@@ -1,9 +1,8 @@
1
- import { f as Node } from "./loader-Mig5fY4n.js";
2
- import { t as registerCoreNodes } from "./register-BFLg0-_i.js";
1
+ import { f as Node, h as effectiveOrder } from "./loader-DAZlgqeC.js";
2
+ import { t as registerCoreNodes } from "./register-BHAwM4bK.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
4
  import { t as Rng } from "./rng-DP-SR7eg.js";
5
- import { i as getNodeSchema, l as registerNode } from "./registry-CJdGpT2V.js";
6
- import { r as effectiveOrder } from "./duplicate-C716f-97.js";
5
+ import { i as getNodeSchema, l as registerNode } from "./registry-IyWCGe4q.js";
7
6
  import { i as applyParticlePreset, r as PARTICLE_PRESET_NAMES, t as ParticleSim } from "./particle-sim-Bw7hB93B.js";
8
7
  import { AdditiveBlending, BufferAttribute, BufferGeometry, CanvasTexture, Color, DynamicDrawUsage, Group, InstancedMesh, MathUtils, Matrix4, Mesh, MeshBasicMaterial, NearestFilter, NormalBlending, Object3D, PlaneGeometry } from "three";
9
8
  //#region src/2d/physics/collider-validate.ts
@@ -77,7 +76,7 @@ var Node2D = class extends Node {
77
76
  orderGroup = "default";
78
77
  /** What three actually sorts by: band base + renderOrder. */
79
78
  get effectiveRenderOrder() {
80
- return effectiveOrder(this.orderGroup, this.renderOrder);
79
+ return effectiveOrder(this.orderGroup, this.renderOrder, this.tree?.engine?.orderGroups);
81
80
  }
82
81
  visible = true;
83
82
  _object2D = null;
@@ -1,8 +1,8 @@
1
- import { C as Signal, f as Node, t as buildNodeJson } from "./loader-Mig5fY4n.js";
2
- import { t as registerCoreNodes } from "./register-BFLg0-_i.js";
1
+ import { E as Signal, f as Node, t as buildNodeJson } from "./loader-DAZlgqeC.js";
2
+ import { t as registerCoreNodes } from "./register-BHAwM4bK.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
4
  import { n as jsonEquals, t as jsonClone } from "./json-BLk7H2Qa.js";
5
- import { l as registerNode } from "./registry-CJdGpT2V.js";
5
+ import { l as registerNode } from "./registry-IyWCGe4q.js";
6
6
  //#region src/net/network-manager.ts
7
7
  const managers = /* @__PURE__ */ new WeakMap();
8
8
  /**
@@ -104,7 +104,7 @@ function mergeStaticAliases(ctor) {
104
104
  * hard-validating every key and JSON kind. Shared by nodes and behaviors.
105
105
  * `aliases` maps legacy keys onto current ones (back-compat for renamed props).
106
106
  */
107
- function applySchemaProps(target, schema, props, label, aliases = {}) {
107
+ function applySchemaProps(target, schema, props, label, aliases = {}, extraOptions = {}) {
108
108
  for (const [key, def] of Object.entries(schema)) target[key] = jsonClone(def.default);
109
109
  if (!props) return;
110
110
  for (const [rawKey, value] of Object.entries(props)) {
@@ -118,7 +118,9 @@ function applySchemaProps(target, schema, props, label, aliases = {}) {
118
118
  validOptions: valid
119
119
  });
120
120
  }
121
- validatePropValue(value, def.default, `${label}.${key}`, def.options);
121
+ const extra = extraOptions[key];
122
+ const options = def.options && extra && extra.length > 0 ? [...def.options, ...extra] : def.options;
123
+ validatePropValue(value, def.default, `${label}.${key}`, options);
122
124
  target[key] = jsonClone(value);
123
125
  }
124
126
  }
@@ -126,10 +128,10 @@ function applySchemaProps(target, schema, props, label, aliases = {}) {
126
128
  * Instantiate a registered type, assign schema defaults (cloned), then the
127
129
  * given props — validating every key and its JSON kind against the default.
128
130
  */
129
- function createNode(typeName, props) {
131
+ function createNode(typeName, props, extraOptions) {
130
132
  const ctor = getNodeType(typeName);
131
133
  const node = new ctor();
132
- applySchemaProps(node, getNodeSchema(typeName), props, typeName, mergeStaticAliases(ctor));
134
+ applySchemaProps(node, getNodeSchema(typeName), props, typeName, mergeStaticAliases(ctor), extraOptions);
133
135
  return node;
134
136
  }
135
137
  //#endregion
@@ -60,6 +60,16 @@ interface SceneJson {
60
60
  * translation would not fit (see core/localization.ts).
61
61
  */
62
62
  strings?: Record<string, Record<string, string>>;
63
+ /**
64
+ * Extra draw-order bands, as `name → base offset`, layered over the six built
65
+ * in (`background -2000` … `overlay 3000`). A node's effective order is
66
+ * `base(orderGroup) + renderOrder`, so a band is a NUMBER — declaring a bare
67
+ * name would sort exactly like `default` and mean nothing.
68
+ *
69
+ * `{"orderGroups": {"ui-back": 2500}}` then `"orderGroup": "ui-back"`.
70
+ * Re-declaring a built-in name re-bases it for this scene.
71
+ */
72
+ orderGroups?: Record<string, number>;
63
73
  /** Declarative input action map (loaded into Engine.input). */
64
74
  input?: JsonObject;
65
75
  /** Physics config — `{gravity: [x,y]}` (2D px/s²) or `{gravity: [x,y,z]}` (3D m/s²). */
@@ -1,12 +1,12 @@
1
- import { n as loadScene, x as registerBehavior } from "./loader-Mig5fY4n.js";
2
- import { h as Engine } from "./register-BFLg0-_i.js";
1
+ import { n as loadScene, w as registerBehavior } from "./loader-DAZlgqeC.js";
2
+ import { h as Engine } from "./register-BHAwM4bK.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
4
  import { n as jsonEquals, t as jsonClone } from "./json-BLk7H2Qa.js";
5
- import { i as getNodeSchema, s as mergeStaticProps } from "./registry-CJdGpT2V.js";
6
- import { n as registerGameplayBehaviors } from "./gameplay-BvhcQbfJ.js";
7
- import { t as registerNodes2D } from "./register-DSmIRAf7.js";
8
- import { n as registerNodes3D, t as resolveEnvironmentHdri } from "./environment-presets-TAGvmM3z.js";
9
- import { t as registerNodesNet } from "./register-BjbPMA5B.js";
5
+ import { i as getNodeSchema, s as mergeStaticProps } from "./registry-IyWCGe4q.js";
6
+ import { n as registerGameplayBehaviors } from "./gameplay-C0MUMSak.js";
7
+ import { t as registerNodes2D } from "./register-COGCNitr.js";
8
+ import { n as registerNodes3D, t as resolveEnvironmentHdri } from "./environment-presets-fK9oyrrR.js";
9
+ import { t as registerNodesNet } from "./register-DXwtIVqP.js";
10
10
  import { Box3, Euler, Matrix4, PerspectiveCamera, Quaternion, Vector3 } from "three";
11
11
  //#region src/test/framing.ts
12
12
  /**
@@ -482,10 +482,10 @@ async function runScript(json, opts) {
482
482
  engine.setScene(scene);
483
483
  const physics = opts.physics ?? "auto";
484
484
  if (physics === "2d" || physics === "auto" && scene.dimension === "2d") {
485
- const { enablePhysics2D } = await import("./physics-2d-DqAclql-.js").then((n) => n.r);
485
+ const { enablePhysics2D } = await import("./physics-2d-B4v39hca.js").then((n) => n.r);
486
486
  await enablePhysics2D(engine);
487
487
  } else if (physics === "3d" || physics === "auto" && scene.dimension === "3d") {
488
- const { enablePhysics3D } = await import("./physics-3d-DxBH4sIF.js").then((n) => n.r);
488
+ const { enablePhysics3D } = await import("./physics-3d-DFJVMYET.js").then((n) => n.r);
489
489
  await enablePhysics3D(engine);
490
490
  }
491
491
  const failures = [];
@@ -598,10 +598,10 @@ async function createPlaySession(json, opts = {}) {
598
598
  engine.setScene(scene);
599
599
  const physics = opts.physics ?? "auto";
600
600
  if (physics === "2d" || physics === "auto" && scene.dimension === "2d") {
601
- const { enablePhysics2D } = await import("./physics-2d-DqAclql-.js").then((n) => n.r);
601
+ const { enablePhysics2D } = await import("./physics-2d-B4v39hca.js").then((n) => n.r);
602
602
  await enablePhysics2D(engine);
603
603
  } else if (physics === "3d" || physics === "auto" && scene.dimension === "3d") {
604
- const { enablePhysics3D } = await import("./physics-3d-DxBH4sIF.js").then((n) => n.r);
604
+ const { enablePhysics3D } = await import("./physics-3d-DFJVMYET.js").then((n) => n.r);
605
605
  await enablePhysics3D(engine);
606
606
  }
607
607
  const stepMs = 1e3 / (opts.fixedHz ?? 60);
package/dist/test.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { Ct as LogEntry, N as Scene, b as Engine, bt as Node, n as BehaviorCtor } from "./behavior-CGSCWOHB.js";
2
- import { c as JsonValue, i as SceneJson } from "./schema-3ywbdlrv.js";
3
- import { t as LoadSceneOptions } from "./loader-CUcj00M8.js";
4
- import { i as auditScene, t as IncantoError } from "./errors-BY2kL0hv.js";
1
+ import { N as Scene, Ot as LogEntry, Tt as Node, b as Engine, n as BehaviorCtor } from "./behavior-DibCwrW7.js";
2
+ import { c as JsonValue, i as SceneJson } from "./schema-CFeioQRE.js";
3
+ import { t as LoadSceneOptions } from "./loader-BqigZsfF.js";
4
+ import { i as auditScene, t as IncantoError } from "./errors-DGRtWlSx.js";
5
5
 
6
6
  //#region src/test/framing.d.ts
7
7
  /** Where a node's origin sits relative to the current camera. */
package/dist/test.js CHANGED
@@ -1,3 +1,3 @@
1
- import { t as auditScene } from "./audit-C5oZGAru.js";
2
- import { a as registerAllNodes, c as describeFraming, i as findFloatingProps, l as framingText, n as createPlaySession, o as runScript, r as describeCapture, s as validateScene, t as captureScene } from "./test-9EokzbRd.js";
1
+ import { t as auditScene } from "./audit-D7F3n3Nt.js";
2
+ import { a as registerAllNodes, c as describeFraming, i as findFloatingProps, l as framingText, n as createPlaySession, o as runScript, r as describeCapture, s as validateScene, t as captureScene } from "./test-X_xE6Yay.js";
3
3
  export { auditScene, captureScene, createPlaySession, describeCapture, describeFraming, findFloatingProps, framingText, registerAllNodes, runScript, validateScene };
package/dist/vite.js CHANGED
@@ -1,4 +1,4 @@
1
- import { s as validateScene } from "./test-9EokzbRd.js";
1
+ import { s as validateScene } from "./test-X_xE6Yay.js";
2
2
  import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
3
3
  import { basename, dirname, join, normalize, relative, resolve, sep } from "node:path";
4
4
  //#region src/vite/index.ts
@@ -1 +1 @@
1
- import{n as e}from"./index-CMlKFT0C.js";async function t(t){return new n((await e(()=>import(`./GameServer-C56iOUgF.js`),[],import.meta.url)).GameServer,t)}var n=class{raw;active=new Map;reconnecting=!1;disposed=!1;constructor(e,t){this.raw=new e({...t})}get account(){return this.raw.account}get connected(){return this.raw.connected}connect(){return this.raw.connected?Promise.resolve(!0):(this.disposed=!1,this.rawConnect())}rawConnect(){return this.raw.connect({onDisconnect:()=>void this.reconnect()})}disconnect(){this.disposed=!0;for(let e of this.active.values())e.off();return this.active.clear(),this.raw.disconnect()}remoteFunction(e,t,n){return this.raw.remoteFunction(e,t,n)}track(e){let t=Symbol(`sub`),n={make:e,off:e()};return this.active.set(t,n),()=>{n.off(),this.active.delete(t)}}async reconnect(){if(!this.disposed&&!this.reconnecting){this.reconnecting=!0;try{await this.rawConnect();for(let e of this.active.values())e.off(),e.off=e.make()}finally{this.reconnecting=!1}}}subscribeRoomState(e,t){return this.track(()=>this.raw.subscribeRoomState(e,t))}subscribeRoomMyState(e,t){return this.track(()=>this.raw.subscribeRoomMyState(e,t))}subscribeRoomAllUserStates(e,t){return this.track(()=>this.raw.subscribeRoomAllUserStates(e,e=>{let n={};for(let t of e??[]){if(!t||typeof t.account!=`string`||t.__leaved)continue;let{account:e,__updated:r,__leaved:i,...a}=t;n[e]=a}t(n)}))}subscribeRoomCollection(e,t,n){return this.track(()=>this.raw.subscribeRoomCollection(e,t,({items:e})=>{let t={};for(let n of e??[])n&&typeof n.__id==`string`&&(t[n.__id]=n);n(t)}))}onRoomMessage(e,t,n){return this.track(()=>this.raw.onRoomMessage(e,t,n))}onRoomUserJoin(e,t){return this.track(()=>this.raw.onRoomUserJoin(e,t))}onRoomUserLeave(e,t){return this.track(()=>this.raw.onRoomUserLeave(e,t))}subscribeGlobalState(e){return this.track(()=>this.raw.subscribeGlobalState(e))}subscribeGlobalMyState(e){return this.track(()=>this.raw.subscribeGlobalMyState(e))}subscribeGlobalUserState(e,t){return this.track(()=>this.raw.subscribeGlobalUserState(e,t))}subscribeGlobalCollection(e,t){return this.track(()=>this.raw.subscribeGlobalCollection(e,({items:e})=>{let n={};for(let t of e??[])t&&typeof t.__id==`string`&&(n[t.__id]=t);t(n)}))}subscribeAsset(e,t){return this.track(()=>this.raw.subscribeAsset(e,t))}onGlobalMessage(e,t){return this.track(()=>this.raw.onGlobalMessage(e,t))}};export{t as createAgent8Server};
1
+ import{n as e}from"./index-BkIuXIjp.js";async function t(t){return new n((await e(()=>import(`./GameServer-C56iOUgF.js`),[],import.meta.url)).GameServer,t)}var n=class{raw;active=new Map;reconnecting=!1;disposed=!1;constructor(e,t){this.raw=new e({...t})}get account(){return this.raw.account}get connected(){return this.raw.connected}connect(){return this.raw.connected?Promise.resolve(!0):(this.disposed=!1,this.rawConnect())}rawConnect(){return this.raw.connect({onDisconnect:()=>void this.reconnect()})}disconnect(){this.disposed=!0;for(let e of this.active.values())e.off();return this.active.clear(),this.raw.disconnect()}remoteFunction(e,t,n){return this.raw.remoteFunction(e,t,n)}track(e){let t=Symbol(`sub`),n={make:e,off:e()};return this.active.set(t,n),()=>{n.off(),this.active.delete(t)}}async reconnect(){if(!this.disposed&&!this.reconnecting){this.reconnecting=!0;try{await this.rawConnect();for(let e of this.active.values())e.off(),e.off=e.make()}finally{this.reconnecting=!1}}}subscribeRoomState(e,t){return this.track(()=>this.raw.subscribeRoomState(e,t))}subscribeRoomMyState(e,t){return this.track(()=>this.raw.subscribeRoomMyState(e,t))}subscribeRoomAllUserStates(e,t){return this.track(()=>this.raw.subscribeRoomAllUserStates(e,e=>{let n={};for(let t of e??[]){if(!t||typeof t.account!=`string`||t.__leaved)continue;let{account:e,__updated:r,__leaved:i,...a}=t;n[e]=a}t(n)}))}subscribeRoomCollection(e,t,n){return this.track(()=>this.raw.subscribeRoomCollection(e,t,({items:e})=>{let t={};for(let n of e??[])n&&typeof n.__id==`string`&&(t[n.__id]=n);n(t)}))}onRoomMessage(e,t,n){return this.track(()=>this.raw.onRoomMessage(e,t,n))}onRoomUserJoin(e,t){return this.track(()=>this.raw.onRoomUserJoin(e,t))}onRoomUserLeave(e,t){return this.track(()=>this.raw.onRoomUserLeave(e,t))}subscribeGlobalState(e){return this.track(()=>this.raw.subscribeGlobalState(e))}subscribeGlobalMyState(e){return this.track(()=>this.raw.subscribeGlobalMyState(e))}subscribeGlobalUserState(e,t){return this.track(()=>this.raw.subscribeGlobalUserState(e,t))}subscribeGlobalCollection(e,t){return this.track(()=>this.raw.subscribeGlobalCollection(e,({items:e})=>{let n={};for(let t of e??[])t&&typeof t.__id==`string`&&(n[t.__id]=t);t(n)}))}subscribeAsset(e,t){return this.track(()=>this.raw.subscribeAsset(e,t))}onGlobalMessage(e,t){return this.track(()=>this.raw.onGlobalMessage(e,t))}};export{t as createAgent8Server};