incanto 0.71.0 → 0.72.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 (62) hide show
  1. package/bin/incanto-editor.mjs +15 -9
  2. package/bin/incanto-feel.mjs +11 -1
  3. package/bin/incanto-play.mjs +11 -1
  4. package/bin/incanto-playtest.mjs +11 -1
  5. package/dist/2d.d.ts +3 -3
  6. package/dist/2d.js +3 -3
  7. package/dist/3d.d.ts +3 -3
  8. package/dist/3d.js +5 -5
  9. package/dist/{agent8-Cfmd3ar_.js → agent8-BqZ0_O1u.js} +1 -1
  10. package/dist/{audio-player-L8yccdMP.d.ts → audio-player-ioZ7VKC6.d.ts} +1 -1
  11. package/dist/{behavior-Dcz0fr1S.d.ts → behavior-Bf9P9oB2.d.ts} +1 -1
  12. package/dist/{create-game-CH4kt78v.js → create-game-C9rWqqAC.js} +36 -12
  13. package/dist/{create-game-LCHBLfA4.js → create-game-CmFAtLZp.js} +7 -6
  14. package/dist/debug.d.ts +1 -1
  15. package/dist/editor.js +1069 -1035
  16. package/dist/{environment-presets-99BzP_L-.js → environment-presets-BeHoaGhy.js} +3 -3
  17. package/dist/{gameplay-CNULJvwh.js → gameplay-BlQe-M07.js} +1 -1
  18. package/dist/gameplay.d.ts +1 -1
  19. package/dist/gameplay.js +1 -1
  20. package/dist/index.d.ts +4 -4
  21. package/dist/index.js +4 -4
  22. package/dist/{loader-8-IHvbKD.d.ts → loader-CBfQzB6S.d.ts} +10 -3
  23. package/dist/net.d.ts +2 -2
  24. package/dist/net.js +2 -2
  25. package/dist/{physics-2d-FhrXUc6B.js → physics-2d-DrIgTlLk.js} +2 -2
  26. package/dist/{physics-3d-CFEGxBXZ.js → physics-3d-BzOCw1VS.js} +3 -3
  27. package/dist/{picking-DVo7fI13.js → picking-C9McVJrO.js} +2 -2
  28. package/dist/react.d.ts +1 -1
  29. package/dist/react.js +1 -1
  30. package/dist/{register-DuVdzxbq.js → register-5IYfooAN.js} +1 -1
  31. package/dist/{register-BYQCBySi.js → register-C8HuRkOf.js} +3 -3
  32. package/dist/{replay-F7IZHdFR.d.ts → replay-CBEChqXq.d.ts} +2 -2
  33. package/dist/{replay-DEvp3kyV.js → replay-datiAE-b.js} +15 -8
  34. package/dist/{save-slots-Bvuh2p_r.js → save-slots-CEuJPUle.js} +46 -1
  35. package/dist/{split-screen-eULetcg-.js → split-screen-Bm5DTElG.js} +3 -3
  36. package/dist/{split-screen-CIYf1zSf.d.ts → split-screen-DkqLng6q.d.ts} +2 -2
  37. package/dist/{src-_jk0qLsS.js → src-DRSsRleD.js} +1 -1
  38. package/dist/{test-CmN54kWv.js → test-Djuq3Vhq.js} +13 -13
  39. package/dist/test.d.ts +4 -4
  40. package/dist/test.js +2 -2
  41. package/dist/vite.d.ts +8 -1
  42. package/dist/vite.js +22 -5
  43. package/editor/assets/{agent8-yLIEYHbd.js → agent8-CMKz2cax.js} +1 -1
  44. package/editor/assets/{debug-u31w_yhq.js → debug-DLrQm-az.js} +1 -1
  45. package/editor/assets/{index-DK9xMGpW.js → index-BEKuxYcE.js} +92 -92
  46. package/editor/index.html +1 -1
  47. package/package.json +1 -1
  48. package/skills/incanto-building-2d-games.md +6 -0
  49. package/skills/incanto-editor.md +4 -0
  50. package/skills/incanto-scene-json-authoring.md +30 -0
  51. package/templates-app/beacon-isle-3d/package.json +1 -1
  52. package/templates-app/beacon-isle-3d/src/game.scene.json +377 -185
  53. package/templates-app/molehill-2d/package.json +1 -1
  54. package/templates-app/platformer-2d/package.json +1 -1
  55. package/templates-app/platformer-2d/src/game.scene.json +193 -93
  56. package/templates-app/star-survivor/package.json +1 -1
  57. package/templates-app/star-survivor/src/game.scene.json +18 -9
  58. package/templates-app/tps-3d/package.json +1 -1
  59. package/templates-app/tps-3d/src/game.scene.json +82 -39
  60. package/templates-app/village-quest-3d/package.json +1 -1
  61. package/templates-app/village-quest-3d/src/grove.scene.json +98 -46
  62. package/templates-app/village-quest-3d/src/village.scene.json +449 -223
@@ -1,11 +1,11 @@
1
- import { Y as diagnose } from "./save-slots-Bvuh2p_r.js";
2
- import { M as translateOn, t as registerCoreNodes } from "./register-DuVdzxbq.js";
1
+ import { Y as diagnose } from "./save-slots-CEuJPUle.js";
2
+ import { M as translateOn, t as registerCoreNodes } from "./register-5IYfooAN.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
4
  import { t as Rng } from "./rng-CDOMybym.js";
5
5
  import { c as getNodeSchema, h as didYouMean, p as registerNode } from "./touch-BnCyPA0G.js";
6
6
  import { t as createNoise2D } from "./noise-D3nPpmFg.js";
7
7
  import { i as ParticleSim, n as resolveFrames, o as PARTICLE_PRESET_NAMES, r as validateAnimations, s as applyParticlePreset, t as resolveAnimation } from "./sprite-animation-CqR2o3SA.js";
8
- import { B as rejectScale, D as effectRng, G as StaticBody3D, H as CharacterBody3D, K as Node3D, L as Water3D, Q as worldPosition, T as tolerateUnknownAction, U as PhysicsBody3D, V as Area3D, W as RigidBody3D, X as colliderFootDrop, z as WaterCutout3D } from "./gameplay-CNULJvwh.js";
8
+ import { B as rejectScale, D as effectRng, G as StaticBody3D, H as CharacterBody3D, K as Node3D, L as Water3D, Q as worldPosition, T as tolerateUnknownAction, U as PhysicsBody3D, V as Area3D, W as RigidBody3D, X as colliderFootDrop, z as WaterCutout3D } from "./gameplay-BlQe-M07.js";
9
9
  import { t as checkSheetGrid } from "./sheet-grid-Cea343VO.js";
10
10
  import { n as splatWeights, t as buildHeightmap } from "./heightmap-BYgD5Edk.js";
11
11
  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";
@@ -1,5 +1,5 @@
1
1
  import { t as jsonClone } from "./json-CfTjpvW8.js";
2
- import { B as HudLayer, J as Node, K as requireNumber, P as effectiveOrder, Y as diagnose, d as rebuildOptions, et as Behavior, f as rememberAuthoredPath, h as loadScene, n as SaveSlots, ot as registerBehavior, s as duplicateNode } from "./save-slots-Bvuh2p_r.js";
2
+ import { B as HudLayer, J as Node, K as requireNumber, P as effectiveOrder, Y as diagnose, d as rebuildOptions, et as Behavior, f as rememberAuthoredPath, h as loadScene, n as SaveSlots, ot as registerBehavior, s as duplicateNode } from "./save-slots-CEuJPUle.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
4
  import { t as Rng } from "./rng-CDOMybym.js";
5
5
  import { h as didYouMean } from "./touch-BnCyPA0G.js";
@@ -1,4 +1,4 @@
1
- import { b as Engine, d as PropSchema, jt as Node, n as BehaviorCtor, t as Behavior } from "./behavior-Dcz0fr1S.js";
1
+ import { b as Engine, d as PropSchema, jt as Node, n as BehaviorCtor, t as Behavior } from "./behavior-Bf9P9oB2.js";
2
2
  import { c as JsonValue, s as JsonObject } from "./rng-Bb-IutXB.js";
3
3
 
4
4
  //#region src/gameplay/chase.d.ts
package/dist/gameplay.js CHANGED
@@ -1,2 +1,2 @@
1
- import { A as DayNight, C as goToScene, E as FollowCamera, F as Collector, I as Chase, M as DamageOnContact, N as Health, O as FloatAway, P as Currency, Q as worldPosition, S as GameFlow, Z as localFromWorld, _ as CameraShake, a as Wander, b as screenFlash, c as SavePoint, d as Pickup, f as Patrol, g as Lifetime, h as MoveTo, i as WaveSpawner, j as phaseOf, k as FaceTarget, l as Projectile, m as Oscillate, n as registerGameplayBehaviors, o as Spawner, p as PathFollow, r as ZombieAI, s as ScoreKeeper, t as GAMEPLAY_BEHAVIORS, u as PrefabShelf, v as Cooldown, w as restartScene, x as Interactable, y as hitStop } from "./gameplay-CNULJvwh.js";
1
+ import { A as DayNight, C as goToScene, E as FollowCamera, F as Collector, I as Chase, M as DamageOnContact, N as Health, O as FloatAway, P as Currency, Q as worldPosition, S as GameFlow, Z as localFromWorld, _ as CameraShake, a as Wander, b as screenFlash, c as SavePoint, d as Pickup, f as Patrol, g as Lifetime, h as MoveTo, i as WaveSpawner, j as phaseOf, k as FaceTarget, l as Projectile, m as Oscillate, n as registerGameplayBehaviors, o as Spawner, p as PathFollow, r as ZombieAI, s as ScoreKeeper, t as GAMEPLAY_BEHAVIORS, u as PrefabShelf, v as Cooldown, w as restartScene, x as Interactable, y as hitStop } from "./gameplay-BlQe-M07.js";
2
2
  export { CameraShake, Chase, Collector, Cooldown, Currency, DamageOnContact, DayNight, FaceTarget, FloatAway, FollowCamera, GAMEPLAY_BEHAVIORS, GameFlow, Health, Interactable, Lifetime, MoveTo, Oscillate, PathFollow, Patrol, Pickup, PrefabShelf, Projectile, SavePoint, ScoreKeeper, Spawner, Wander, WaveSpawner, ZombieAI, goToScene, hitStop, localFromWorld, phaseOf, registerGameplayBehaviors, restartScene, screenFlash, worldPosition };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { a as ParticleSimConfig, c as showBootFailure, i as ParticleSim, n as AudioPlayer, o as ParticleView, s as isWebGLAvailable, t as AudioElementLike } from "./audio-player-L8yccdMP.js";
2
- import { $ as T_PREFIX, A as SettingsValues, At as BusName, B as captureBehaviors, C as EngineStats, Ct as sfxDuration, Dt as MusicTrack, E as DeviceHints, Et as MusicManager, F as BehaviorState, Ft as LogLevel, G as ORDER_GROUP_BASE, H as savesWithoutUid, I as RestoreReport, It as LogManager, J as effectiveOrder, K as OrderGroup, L as SaveSlot, Lt as Signal, M as readDeviceHints, Mt as NodeLifecycle, N as suggestQuality, Nt as SceneTree, O as QualityTier, Ot as PlayMusicOptions, P as Scene, Pt as LogEntry, Q as Localization, R as SaveSlots, Rt as SignalListener, S as Scheduler, St as SynthOptions, T as RendererStats, Tt as MusicBackend, U as SaveStore, V as restoreBehaviors, W as createSaveStore, X as BASE_LOCALE, Y as resolveOrderGroups, Z as LocaleTables, _ as mergeStaticSignals, _t as spatialPan, a as clearBehaviors, at as EffectLog, b as Engine, bt as SfxParams, c as registeredBehaviors, ct as isAudioContextAvailable, d as PropSchema, dt as Listener, et as suggestLocale, f as clearRegistry, ft as ROLLOFF_MODELS, g as getNodeType, gt as spatialGain, h as getNodeSignals, ht as Vec3, i as behaviorSignals, it as EffectKind, j as qualityEnvironment, jt as Node, k as Settings, kt as AudioBuses, l as NodeCtor, lt as Voice, m as getNodeSchema, mt as SpatialParams, n as BehaviorCtor, nt as InputMap, o as getBehavior, ot as SfxEngine, p as createNode, pt as RolloffModel, q as OrderGroupTable, r as behaviorSchema, rt as EffectEvent, s as registerBehavior, st as SfxPlayOptions, t as Behavior, tt as translationKey, u as PropDef, ut as VoicePreset, v as registerNode, vt as SFX_PRESETS, w as GameStats, wt as synthSfx, x as EngineOptions, xt as SfxWave, y as registeredTypes, yt as SFX_PRESET_NAMES, z as behaviorsWithoutSave } from "./behavior-Dcz0fr1S.js";
1
+ import { a as ParticleSimConfig, c as showBootFailure, i as ParticleSim, n as AudioPlayer, o as ParticleView, s as isWebGLAvailable, t as AudioElementLike } from "./audio-player-ioZ7VKC6.js";
2
+ import { $ as T_PREFIX, A as SettingsValues, At as BusName, B as captureBehaviors, C as EngineStats, Ct as sfxDuration, Dt as MusicTrack, E as DeviceHints, Et as MusicManager, F as BehaviorState, Ft as LogLevel, G as ORDER_GROUP_BASE, H as savesWithoutUid, I as RestoreReport, It as LogManager, J as effectiveOrder, K as OrderGroup, L as SaveSlot, Lt as Signal, M as readDeviceHints, Mt as NodeLifecycle, N as suggestQuality, Nt as SceneTree, O as QualityTier, Ot as PlayMusicOptions, P as Scene, Pt as LogEntry, Q as Localization, R as SaveSlots, Rt as SignalListener, S as Scheduler, St as SynthOptions, T as RendererStats, Tt as MusicBackend, U as SaveStore, V as restoreBehaviors, W as createSaveStore, X as BASE_LOCALE, Y as resolveOrderGroups, Z as LocaleTables, _ as mergeStaticSignals, _t as spatialPan, a as clearBehaviors, at as EffectLog, b as Engine, bt as SfxParams, c as registeredBehaviors, ct as isAudioContextAvailable, d as PropSchema, dt as Listener, et as suggestLocale, f as clearRegistry, ft as ROLLOFF_MODELS, g as getNodeType, gt as spatialGain, h as getNodeSignals, ht as Vec3, i as behaviorSignals, it as EffectKind, j as qualityEnvironment, jt as Node, k as Settings, kt as AudioBuses, l as NodeCtor, lt as Voice, m as getNodeSchema, mt as SpatialParams, n as BehaviorCtor, nt as InputMap, o as getBehavior, ot as SfxEngine, p as createNode, pt as RolloffModel, q as OrderGroupTable, r as behaviorSchema, rt as EffectEvent, s as registerBehavior, st as SfxPlayOptions, t as Behavior, tt as translationKey, u as PropDef, ut as VoicePreset, v as registerNode, vt as SFX_PRESETS, w as GameStats, wt as synthSfx, x as EngineOptions, xt as SfxWave, y as registeredTypes, yt as SFX_PRESET_NAMES, z as behaviorsWithoutSave } from "./behavior-Bf9P9oB2.js";
3
3
  import { a as SceneJson, c as JsonValue, d as jsonKind, i as SCENE_FORMAT, l as jsonClone, n as ConnectionJson, o as JsonKind, r as NodeJson, s as JsonObject, t as Rng, u as jsonEquals } from "./rng-Bb-IutXB.js";
4
- import { n as loadScene, t as LoadSceneOptions } from "./loader-8-IHvbKD.js";
4
+ import { n as loadScene, t as LoadSceneOptions } from "./loader-CBfQzB6S.js";
5
5
  import { i as resolveFrames, n as AnimationEntry, r as resolveAnimation, t as AnimationDef } from "./sprite-animation-CMr6f1K2.js";
6
6
  import { i as gridFromRows, n as PathGrid, r as findPath, t as FindPathOptions } from "./pathfinding-_fGrCFmH.js";
7
- import { a as startRecording, c as IncantoErrorDetails, i as replay, l as auditScene, n as ReplayEvent, o as IncantoError, r as ReplayJson, s as IncantoErrorCode, t as Recorder } from "./replay-F7IZHdFR.js";
7
+ import { a as startRecording, c as IncantoErrorDetails, i as replay, l as auditScene, n as ReplayEvent, o as IncantoError, r as ReplayJson, s as IncantoErrorCode, t as Recorder } from "./replay-CBEChqXq.js";
8
8
 
9
9
  //#region src/core/audio/crossfade.d.ts
10
10
  /**
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import { n as jsonEquals, r as jsonKind, t as jsonClone } from "./json-CfTjpvW8.js";
2
- import { $ as parseNodePath, A as SceneTree, B as HudLayer, D as computeViewport, E as resolveConstants, F as resolveOrderGroups, G as UiText, I as InputMap, J as Node, N as ORDER_GROUP_BASE, O as resolveViewport, P as effectiveOrder, Q as resolveRefInJson, T as isConstRef, U as UiBanner, W as UiBar, X as describeRefProblem, Z as nodeRefWarnings, _ as Scene, a as restoreBehaviors, at as getBehavior, ct as Signal, et as Behavior, h as loadScene, i as captureBehaviors, it as clearBehaviors, j as createSaveStore, k as newUid, n as SaveSlots, nt as behaviorSchema, o as savesWithoutUid, ot as registerBehavior, r as behaviorsWithoutSave, rt as behaviorSignals, s as duplicateNode, st as registeredBehaviors, v as serializeNode, w as CONST_REF_KEY, y as SCENE_FORMAT } from "./save-slots-Bvuh2p_r.js";
3
- import { A as T_PREFIX, B as SFX_PRESET_NAMES, D as EffectLog, E as LogManager, F as isAudioContextAvailable, G as crossfadeGains, H as synthSfx, I as ROLLOFF_MODELS, K as fadeGain, L as spatialGain, N as translationKey, O as BASE_LOCALE, P as SfxEngine, R as spatialPan, S as qualityEnvironment, T as suggestQuality, U as MusicManager, V as sfxDuration, W as WebAudioMusicBackend, _ as AudioPlayer, a as UiMuteToggle, b as Settings, c as UiRenderScaleSelect, d as UiToggle, f as UiVolumeSlider, g as UiDialogue, h as UiButton, i as UiLanguageSelect, j as suggestLocale, k as Localization, l as UiSelect, m as Respawn, n as UiFrameCapSelect, o as UiPanel, p as Timer, q as AudioBuses, r as UiImage, s as UiQualitySelect, t as registerCoreNodes, u as UiSlider, v as Engine, w as readDeviceHints, z as SFX_PRESETS } from "./register-DuVdzxbq.js";
2
+ import { $ as parseNodePath, A as SceneTree, B as HudLayer, D as computeViewport, E as resolveConstants, F as resolveOrderGroups, G as UiText, I as InputMap, J as Node, N as ORDER_GROUP_BASE, O as resolveViewport, P as effectiveOrder, Q as resolveRefInJson, T as isConstRef, U as UiBanner, W as UiBar, X as describeRefProblem, Z as nodeRefWarnings, _ as Scene, a as restoreBehaviors, at as getBehavior, ct as Signal, et as Behavior, h as loadScene, i as captureBehaviors, it as clearBehaviors, j as createSaveStore, k as newUid, n as SaveSlots, nt as behaviorSchema, o as savesWithoutUid, ot as registerBehavior, r as behaviorsWithoutSave, rt as behaviorSignals, s as duplicateNode, st as registeredBehaviors, v as serializeNode, w as CONST_REF_KEY, y as SCENE_FORMAT } from "./save-slots-CEuJPUle.js";
3
+ import { A as T_PREFIX, B as SFX_PRESET_NAMES, D as EffectLog, E as LogManager, F as isAudioContextAvailable, G as crossfadeGains, H as synthSfx, I as ROLLOFF_MODELS, K as fadeGain, L as spatialGain, N as translationKey, O as BASE_LOCALE, P as SfxEngine, R as spatialPan, S as qualityEnvironment, T as suggestQuality, U as MusicManager, V as sfxDuration, W as WebAudioMusicBackend, _ as AudioPlayer, a as UiMuteToggle, b as Settings, c as UiRenderScaleSelect, d as UiToggle, f as UiVolumeSlider, g as UiDialogue, h as UiButton, i as UiLanguageSelect, j as suggestLocale, k as Localization, l as UiSelect, m as Respawn, n as UiFrameCapSelect, o as UiPanel, p as Timer, q as AudioBuses, r as UiImage, s as UiQualitySelect, t as registerCoreNodes, u as UiSlider, v as Engine, w as readDeviceHints, z as SFX_PRESETS } from "./register-5IYfooAN.js";
4
4
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
5
5
  import { t as Rng } from "./rng-CDOMybym.js";
6
6
  import { c as getNodeSchema, f as mergeStaticSignals, i as joystickVector, l as getNodeSignals, m as registeredTypes, n as attachTouchControls, o as clearRegistry, p as registerNode, s as createNode, t as TouchControls, u as getNodeType } from "./touch-BnCyPA0G.js";
7
- import { n as startRecording, r as auditScene, t as replay } from "./replay-DEvp3kyV.js";
7
+ import { n as startRecording, r as auditScene, t as replay } from "./replay-datiAE-b.js";
8
8
  import { t as showBootFailure } from "./boot-failure-CKYrEcGF.js";
9
9
  import { a as logText, i as logReport, o as parseDrive, r as resolveRendering, t as isWebGLAvailable } from "./webgl-unavailable-C8aDbGmR.js";
10
10
  import { t as createNoise2D } from "./noise-D3nPpmFg.js";
11
11
  import { a as PARTICLE_PRESETS, i as ParticleSim, n as resolveFrames, o as PARTICLE_PRESET_NAMES, s as applyParticlePreset, t as resolveAnimation } from "./sprite-animation-CqR2o3SA.js";
12
- import { a as findPath, i as preloadUrls, n as assetUrls, o as gridFromRows, r as preloadSceneAssets, t as VERSION } from "./src-_jk0qLsS.js";
12
+ import { a as findPath, i as preloadUrls, n as assetUrls, o as gridFromRows, r as preloadSceneAssets, t as VERSION } from "./src-DRSsRleD.js";
13
13
  export { AudioBuses, AudioPlayer, BASE_LOCALE, Behavior, CONST_REF_KEY, EffectLog, Engine, HudLayer, IncantoError, InputMap, Localization, LogManager, MusicManager, Node, ORDER_GROUP_BASE, PARTICLE_PRESETS, PARTICLE_PRESET_NAMES, ParticleSim, ROLLOFF_MODELS, Respawn, Rng, SCENE_FORMAT, SFX_PRESETS, SFX_PRESET_NAMES, SaveSlots, Scene, SceneTree, Settings, SfxEngine, Signal, T_PREFIX, Timer, TouchControls, UiBanner, UiBar, UiButton, UiDialogue, UiFrameCapSelect, UiImage, UiLanguageSelect, UiMuteToggle, UiPanel, UiQualitySelect, UiRenderScaleSelect, UiSelect, UiSlider, UiText, UiToggle, UiVolumeSlider, VERSION, WebAudioMusicBackend, applyParticlePreset, assetUrls, attachTouchControls, auditScene, behaviorSchema, behaviorSignals, behaviorsWithoutSave, captureBehaviors, clearBehaviors, clearRegistry, computeViewport, createNode, createNoise2D, createSaveStore, crossfadeGains, describeRefProblem, duplicateNode, effectiveOrder, fadeGain, findPath, getBehavior, getNodeSchema, getNodeSignals, getNodeType, gridFromRows, isAudioContextAvailable, isConstRef, isWebGLAvailable, joystickVector, jsonClone, jsonEquals, jsonKind, loadScene, logReport, logText, mergeStaticSignals, newUid, nodeRefWarnings, parseDrive, parseNodePath, preloadSceneAssets, preloadUrls, qualityEnvironment, readDeviceHints, registerBehavior, registerCoreNodes, registerNode, registeredBehaviors, registeredTypes, replay, resolveAnimation, resolveConstants, resolveFrames, resolveOrderGroups, resolveRefInJson, resolveRendering, resolveViewport, restoreBehaviors, savesWithoutUid, serializeNode, sfxDuration, showBootFailure, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
@@ -1,10 +1,17 @@
1
- import { P as Scene, b as Engine } from "./behavior-Dcz0fr1S.js";
1
+ import { P as Scene, b as Engine } from "./behavior-Bf9P9oB2.js";
2
2
  import { a as SceneJson } from "./rng-Bb-IutXB.js";
3
3
 
4
4
  //#region src/core/scene/loader.d.ts
5
5
  interface LoadSceneOptions {
6
- /** Resolve a sub-scene path referenced by `{instance: '<path>'}`. */
7
- resolveScene?: (path: string) => SceneJson;
6
+ /**
7
+ * Resolve a sub-scene path referenced by `{instance: '<path>'}`.
8
+ *
9
+ * Returning nothing is a real answer — "I do not have that one" — and the
10
+ * loader turns it into `UNRESOLVED_INSTANCE` naming the node and the path.
11
+ * The type said `=> SceneJson`, so the one recipe a game actually writes
12
+ * (`prefabs[path] ?? null` over a bundler's eager glob) did not typecheck.
13
+ */
14
+ resolveScene?: (path: string) => SceneJson | null | undefined;
8
15
  /**
9
16
  * Assets declared ELSEWHERE in the project, for `$ref` validation.
10
17
  *
package/dist/net.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { d as PropSchema, jt as Node } from "./behavior-Dcz0fr1S.js";
1
+ import { d as PropSchema, jt as Node } from "./behavior-Bf9P9oB2.js";
2
2
  import { t as DiagnosticSink } from "./diagnostics-Cu85N3tL.js";
3
- import { a as NetworkManagerOptions, c as LocalGameServer, d as ServerClass, f as createLocalGameServer, g as Unsubscribe, h as NetworkTransport, i as NetworkManager, l as LocalGameServerOptions, m as LoopbackTransport, n as SplitScreenPlayer, o as applySyncPatch, p as LoopbackHub, r as createSplitScreen, s as CollectionOptions, t as SplitScreenOptions, u as LocalGameServerTransport } from "./split-screen-CIYf1zSf.js";
3
+ import { a as NetworkManagerOptions, c as LocalGameServer, d as ServerClass, f as createLocalGameServer, g as Unsubscribe, h as NetworkTransport, i as NetworkManager, l as LocalGameServerOptions, m as LoopbackTransport, n as SplitScreenPlayer, o as applySyncPatch, p as LoopbackHub, r as createSplitScreen, s as CollectionOptions, t as SplitScreenOptions, u as LocalGameServerTransport } from "./split-screen-DkqLng6q.js";
4
4
 
5
5
  //#region src/net/agent8.d.ts
6
6
  /**
package/dist/net.js CHANGED
@@ -1,3 +1,3 @@
1
- import { n as createAgent8Server } from "./agent8-Cfmd3ar_.js";
2
- import { a as NetworkManager, d as createLocalGameServer, f as LoopbackHub, l as LocalGameServer, n as registerNodesNet, o as applySyncPatch, p as LoopbackTransport, r as NetworkSpawner, t as createSplitScreen, u as LocalGameServerTransport } from "./split-screen-eULetcg-.js";
1
+ import { n as createAgent8Server } from "./agent8-BqZ0_O1u.js";
2
+ import { a as NetworkManager, d as createLocalGameServer, f as LoopbackHub, l as LocalGameServer, n as registerNodesNet, o as applySyncPatch, p as LoopbackTransport, r as NetworkSpawner, t as createSplitScreen, u as LocalGameServerTransport } from "./split-screen-Bm5DTElG.js";
3
3
  export { LocalGameServer, LocalGameServerTransport, LoopbackHub, LoopbackTransport, NetworkManager, NetworkSpawner, applySyncPatch, createAgent8Server, createLocalGameServer, createSplitScreen, registerNodesNet };
@@ -1,7 +1,7 @@
1
1
  import { o as __exportAll } from "./json-CfTjpvW8.js";
2
- import { Y as diagnose } from "./save-slots-Bvuh2p_r.js";
2
+ import { Y as diagnose } from "./save-slots-CEuJPUle.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-BYQCBySi.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-C8HuRkOf.js";
5
5
  import { n as registerDebugSource } from "./debug-draw-BM3DsvtT.js";
6
6
  import { n as jointContacts, t as withoutRapierInitNoise } from "./quiet-rapier-C6fW4zcW.js";
7
7
  //#region src/2d/physics/physics-2d.ts
@@ -1,10 +1,10 @@
1
1
  import { o as __exportAll } from "./json-CfTjpvW8.js";
2
- import { Y as diagnose } from "./save-slots-Bvuh2p_r.js";
2
+ import { Y as diagnose } from "./save-slots-CEuJPUle.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
- import { H as CharacterBody3D, K as Node3D, U as PhysicsBody3D, V as Area3D, W as RigidBody3D, q as validateCollider3D } from "./gameplay-CNULJvwh.js";
4
+ import { H as CharacterBody3D, K as Node3D, U as PhysicsBody3D, V as Area3D, W as RigidBody3D, q as validateCollider3D } from "./gameplay-BlQe-M07.js";
5
5
  import { n as registerDebugSource } from "./debug-draw-BM3DsvtT.js";
6
6
  import { n as jointContacts, t as withoutRapierInitNoise } from "./quiet-rapier-C6fW4zcW.js";
7
- import { A as Terrain3D, F as InstancedMesh3D, L as buildMeshGeometry, P as Joint3D } from "./environment-presets-99BzP_L-.js";
7
+ import { A as Terrain3D, F as InstancedMesh3D, L as buildMeshGeometry, P as Joint3D } from "./environment-presets-BeHoaGhy.js";
8
8
  import { Euler, Matrix4, Quaternion, Vector3 } from "three";
9
9
  //#region src/3d/physics/collider-lines.ts
10
10
  /**
@@ -1,7 +1,7 @@
1
- import { _ as AudioPlayer } from "./register-DuVdzxbq.js";
1
+ import { _ as AudioPlayer } from "./register-5IYfooAN.js";
2
2
  import { i as logReport, o as parseDrive } from "./webgl-unavailable-C8aDbGmR.js";
3
3
  import { a as frameSignature, i as frameImage, o as frameStats } from "./frame-report-D-_7YF2G.js";
4
- import { Q as worldPosition } from "./gameplay-CNULJvwh.js";
4
+ import { Q as worldPosition } from "./gameplay-BlQe-M07.js";
5
5
  //#region src/core/audio-errors.ts
6
6
  /** Every AudioPlayer under `root` whose source could not be played. */
7
7
  function audioErrors(root) {
package/dist/react.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { P as Scene, b as Engine, n as BehaviorCtor } from "./behavior-Dcz0fr1S.js";
1
+ import { P as Scene, b as Engine, n as BehaviorCtor } from "./behavior-Bf9P9oB2.js";
2
2
  import { c as JsonValue } from "./rng-Bb-IutXB.js";
3
3
  import { CSSProperties, ReactNode } from "react";
4
4
 
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-LCHBLfA4.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-CH4kt78v.js").then((n) => n.n)).createGame2D(o)))(opts);
159
+ const next = await (_gameFactory ?? (mode === "3d" ? async (o) => (await import("./create-game-CmFAtLZp.js").then((n) => n.n)).createGame3D(o) : async (o) => (await import("./create-game-C9rWqqAC.js").then((n) => n.n)).createGame2D(o)))(opts);
160
160
  if (disposed) {
161
161
  next.dispose();
162
162
  return;
@@ -1,5 +1,5 @@
1
1
  import { o as __exportAll } from "./json-CfTjpvW8.js";
2
- import { B as HudLayer, F as resolveOrderGroups, G as UiText, H as TAPPABLE, I as InputMap, J as Node, N as ORDER_GROUP_BASE, U as UiBanner, V as HudWidgetBase, W as UiBar, Y as diagnose, a as restoreBehaviors, ct as Signal, i as captureBehaviors, j as createSaveStore, q as requireText, t as ENGINE_STATE_KEY, z as FITS } from "./save-slots-Bvuh2p_r.js";
2
+ import { B as HudLayer, F as resolveOrderGroups, G as UiText, H as TAPPABLE, I as InputMap, J as Node, N as ORDER_GROUP_BASE, U as UiBanner, V as HudWidgetBase, W as UiBar, Y as diagnose, a as restoreBehaviors, ct as Signal, i as captureBehaviors, j as createSaveStore, q as requireText, t as ENGINE_STATE_KEY, z as FITS } from "./save-slots-CEuJPUle.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
4
  import { t as Rng } from "./rng-CDOMybym.js";
5
5
  import { p as registerNode } from "./touch-BnCyPA0G.js";
@@ -1,9 +1,9 @@
1
- import { J as Node, P as effectiveOrder, Y as diagnose } from "./save-slots-Bvuh2p_r.js";
2
- import { M as translateOn, t as registerCoreNodes } from "./register-DuVdzxbq.js";
1
+ import { J as Node, P as effectiveOrder, Y as diagnose } from "./save-slots-CEuJPUle.js";
2
+ import { M as translateOn, t as registerCoreNodes } from "./register-5IYfooAN.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
4
  import { c as getNodeSchema, h as didYouMean, p as registerNode } from "./touch-BnCyPA0G.js";
5
5
  import { i as ParticleSim, n as resolveFrames, o as PARTICLE_PRESET_NAMES, r as validateAnimations, s as applyParticlePreset, t as resolveAnimation } from "./sprite-animation-CqR2o3SA.js";
6
- import { D as effectRng, Q as worldPosition, T as tolerateUnknownAction, Z as localFromWorld } from "./gameplay-CNULJvwh.js";
6
+ import { D as effectRng, Q as worldPosition, T as tolerateUnknownAction, Z as localFromWorld } from "./gameplay-BlQe-M07.js";
7
7
  import { t as checkSheetGrid } from "./sheet-grid-Cea343VO.js";
8
8
  import { AdditiveBlending, BufferAttribute, BufferGeometry, CanvasTexture, Color, DynamicDrawUsage, Group, InstancedMesh, MathUtils, Matrix4, Mesh, MeshBasicMaterial, NearestFilter, NormalBlending, Object3D, PlaneGeometry, SRGBColorSpace } from "three";
9
9
  //#region src/2d/physics/collider-validate.ts
@@ -1,4 +1,4 @@
1
- import { b as Engine } from "./behavior-Dcz0fr1S.js";
1
+ import { b as Engine } from "./behavior-Bf9P9oB2.js";
2
2
  import { s as JsonObject } from "./rng-Bb-IutXB.js";
3
3
 
4
4
  //#region src/core/audit.d.ts
@@ -59,7 +59,7 @@ declare function auditScene(scene: JsonObject, opts?: AuditOptions): string[];
59
59
  * Incanto fails loudly with machine-readable codes and messages that list valid
60
60
  * alternatives — AI agents self-correct on hard failures, not warnings.
61
61
  */
62
- type IncantoErrorCode = "AMBIGUOUS_HANDLER" | "BAD_FORMAT" | "BAD_NODE_PATH" | "DANGLING_CONNECTION" | "DUPLICATE_BEHAVIOR" | "DUPLICATE_NODE_TYPE" | "DUPLICATE_UNIQUE_NAME" | "DUPLICATE_UID" | "NETWORK_UNAVAILABLE" | "NODE_NOT_FOUND" | "PROP_TYPE_MISMATCH" | "TREE_VIOLATION" | "UNKNOWN_ANIMATION" | "UNKNOWN_ASSET" | "UNKNOWN_CONSTANT" | "UNKNOWN_BEHAVIOR" | "UNKNOWN_HANDLER" | "UNKNOWN_NODE_TYPE" | "UNKNOWN_PROP" | "UNKNOWN_SIGNAL" | "UNRESOLVED_INSTANCE" | "WEBGL_UNAVAILABLE";
62
+ type IncantoErrorCode = "AMBIGUOUS_HANDLER" | "BAD_FORMAT" | "BAD_NODE_PATH" | "DANGLING_CONNECTION" | "DUPLICATE_BEHAVIOR" | "DUPLICATE_NODE_TYPE" | "DUPLICATE_UNIQUE_NAME" | "DUPLICATE_UID" | "NETWORK_UNAVAILABLE" | "NODE_NOT_FOUND" | "PROP_TYPE_MISMATCH" | "TREE_VIOLATION" | "UNKNOWN_ANIMATION" | "UNKNOWN_ASSET" | "UNKNOWN_CONSTANT" | "UNKNOWN_BEHAVIOR" | "UNKNOWN_HANDLER" | "UNKNOWN_NODE_TYPE" | "UNKNOWN_PROP" | "UNKNOWN_SIGNAL" | "UNRESOLVED_INSTANCE" | "WRONG_DIMENSION" | "WEBGL_UNAVAILABLE";
63
63
  /**
64
64
  * Structured context mirrored from the prose message — tools and agents parse
65
65
  * THESE instead of regexing the message (which is for humans and may reword).
@@ -1,5 +1,5 @@
1
- import { L as handlerShadowWarnings, R as sceneDimension, V as HudWidgetBase, Z as nodeRefWarnings } from "./save-slots-Bvuh2p_r.js";
2
- import { N as translationKey } from "./register-DuVdzxbq.js";
1
+ import { L as handlerShadowWarnings, R as sceneDimension, V as HudWidgetBase, Z as nodeRefWarnings } from "./save-slots-CEuJPUle.js";
2
+ import { N as translationKey } from "./register-5IYfooAN.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
4
  import { u as getNodeType } from "./touch-BnCyPA0G.js";
5
5
  //#region src/core/audit.ts
@@ -174,7 +174,7 @@ function auditScene(scene, opts = {}) {
174
174
  /** Nodes whose script produces NOTHING but signals — see `SIGNAL_ONLY`. */
175
175
  const silentSignals = [];
176
176
  const groupRefs = [];
177
- const walk = (node, path, insideHud, staticRoot, transformed) => {
177
+ const walk = (node, path, insideHud, staticRoot, transformed, onShelf) => {
178
178
  const type = node.type ?? "";
179
179
  const props = node.props ?? {};
180
180
  const script = node.script?.name;
@@ -189,6 +189,11 @@ function auditScene(scene, opts = {}) {
189
189
  if (props.current === true) currentCameras += 1;
190
190
  if (script === "FollowCamera") followedCameras.push(path);
191
191
  }
192
+ if (type === "TileMap2D") {
193
+ const cells = Array.isArray(props.cells) ? props.cells : [];
194
+ const colours = props.colors ?? {};
195
+ if (cells.length > 0 && (props.texture ?? "") === "" && Object.keys(colours).length === 0) warnings.push(`${path}: TileMap2D has ${cells.length} row(s) and neither "texture" nor "colors", so nothing of it is drawn. Give it a "colors" entry per legend char to see the level before the art arrives. (If it is meant to be an invisible collision map over scenery you drew yourself, this warning is the price of saying so.)`);
196
+ }
192
197
  if (type === "CharacterController3D") cameraDrivers.push(path);
193
198
  if (type === "Terrain3D") terrains.push(path);
194
199
  if (DRAPERS.has(type) && (props.terrain ?? "") === "") autoDrapers.push(path);
@@ -219,7 +224,7 @@ function auditScene(scene, opts = {}) {
219
224
  const collider = props.collider;
220
225
  if (!collider || collider.shape === void 0) warnings.push(`${path}: ${type} has no collider — physics will skip it (add "collider": { "shape": ... }).`);
221
226
  }
222
- if (isHudWidget(type) && !insideHud) warnings.push(`${path}: ${type} works only as a descendant of a HudLayer — it will not render.`);
227
+ if (isHudWidget(type) && !insideHud && !onShelf) warnings.push(`${path}: ${type} works only as a descendant of a HudLayer — it will not render.`);
223
228
  if (staticRoot && ANIMATED_TYPES.has(type)) warnings.push(`${path}: ${type} is frozen inside static subtree '${staticRoot}' — it will not animate/update on screen.`);
224
229
  const nextStatic = staticRoot ?? (props.static === true ? node.name ?? path : null);
225
230
  const nextHud = insideHud || type === "HudLayer";
@@ -228,12 +233,14 @@ function auditScene(scene, opts = {}) {
228
233
  path,
229
234
  what: own
230
235
  } : transformed;
231
- for (const child of node.children ?? []) walk(child, `${path}/${child.name ?? "?"}`, nextHud, nextStatic, nextTransformed);
236
+ const nextShelf = onShelf || script === "PrefabShelf";
237
+ for (const child of node.children ?? []) walk(child, `${path}/${child.name ?? "?"}`, nextHud, nextStatic, nextTransformed, nextShelf);
232
238
  };
233
- walk(root, root.name ?? "root", false, root.props?.static === true ? root.name ?? "root" : null, transformOf(root.props ?? {}) ? {
239
+ const rootTransform = transformOf(root.props ?? {});
240
+ walk(root, root.name ?? "root", false, root.props?.static === true ? root.name ?? "root" : null, rootTransform ? {
234
241
  path: root.name ?? "root",
235
- what: transformOf(root.props ?? {})
236
- } : null);
242
+ what: rootTransform
243
+ } : null, root.script?.name === "PrefabShelf");
237
244
  if (needUid.length > 0) warnings.push(`these carry state a save keeps and have no uid to key it under, so the save comes back EMPTY and the load reports no problem: ${needUid.join(", ")}. Give each one a "uid" from newUid().`);
238
245
  if (terrains.length > 1 && autoDrapers.length > 0) warnings.push(`${autoDrapers.join(", ")}: this scene has ${terrains.length} Terrain3Ds (${terrains.join(", ")}) and these do not say which one they grow on — with no \`terrain\` path they take the FIRST one in the tree, so the rest drape to the wrong height with nothing reported. Name it: "terrain": "%Name".`);
239
246
  if (cameraDrivers.length > 1) warnings.push(`${cameraDrivers.join(", ")}: ${cameraDrivers.length} CharacterController3Ds drive the SAME camera (each one finds the first \`current\` camera in the tree), so the last of them wins every frame and the others have no view. For local co-op give each player a panel with \`createSplitScreen\` (one engine each); otherwise only one node may carry a controller.`);
@@ -2085,6 +2085,36 @@ function inferSceneDimension(root) {
2085
2085
  function sceneDimension(json) {
2086
2086
  return json.dimension ?? inferSceneDimension(json.root);
2087
2087
  }
2088
+ /**
2089
+ * Every node whose type name belongs to the OTHER world, with its path.
2090
+ *
2091
+ * The two halves of the engine are strangers by design: `Renderer2D` walks
2092
+ * `Node2D`s and `Physics2D` tracks 2D bodies; the 3D pair do the same for
2093
+ * theirs, and neither knows the other's nodes exist. So a `MeshInstance3D`
2094
+ * dropped into a 2D scene loads, validates, appears in the tree, opens a full
2095
+ * inspector — and is never drawn and never simulated. The editor's add-node
2096
+ * list offers all of them, because the LOADER is what says no, and the loader
2097
+ * did not.
2098
+ *
2099
+ * The suffix is the authority here, as it already is for
2100
+ * {@link inferSceneDimension} and for the registry's missing-registrar hint.
2101
+ */
2102
+ function foreignDimensionNodes(root, dimension) {
2103
+ const wrong = dimension === "2d" ? "3D" : "2D";
2104
+ const out = [];
2105
+ const visit = (n, parent) => {
2106
+ if (typeof n !== "object" || n === null) return;
2107
+ const node = n;
2108
+ const path = `${parent}/${typeof node.name === "string" ? node.name : "?"}`;
2109
+ if (typeof node.type === "string" && node.type.endsWith(wrong)) out.push({
2110
+ path,
2111
+ type: node.type
2112
+ });
2113
+ if (Array.isArray(node.children)) for (const child of node.children) visit(child, path);
2114
+ };
2115
+ visit(root, "");
2116
+ return out;
2117
+ }
2088
2118
  //#endregion
2089
2119
  //#region src/core/scene/handler-collision.ts
2090
2120
  /**
@@ -4436,6 +4466,18 @@ function loadScene(json, opts) {
4436
4466
  validateHeader(sceneJson);
4437
4467
  validateStrings(sceneJson.strings);
4438
4468
  const dimension = sceneDimension(sceneJson);
4469
+ if (dimension) {
4470
+ const foreign = foreignDimensionNodes(sceneJson.root, dimension);
4471
+ if (foreign.length > 0) {
4472
+ const first = foreign[0];
4473
+ const others = foreign.length > 1 ? ` (and ${foreign.length - 1} more)` : "";
4474
+ const declared = sceneJson.dimension ? `declared "dimension": "${dimension}"` : `no "dimension" key, and its other nodes make it ${dimension}`;
4475
+ throw new IncantoError("WRONG_DIMENSION", `${first.type} '${first.path}'${others} is a ${dimension === "2d" ? "3D" : "2D"} node in a scene with ${declared}. The ${dimension} renderer never draws it and the ${dimension} physics never simulates it. Use the matching node type, or move it to its own scene.`, {
4476
+ path: first.path,
4477
+ nodeType: first.type
4478
+ });
4479
+ }
4480
+ }
4439
4481
  validateEnvironment(sceneJson.environment, dimension);
4440
4482
  inheritedStrings = {};
4441
4483
  inheritedAssets = {};
@@ -4858,7 +4900,10 @@ function buildNode(nj, opts, stack, parentPath, constants, bands = []) {
4858
4900
  rejectUnknownKeys(nj, NODE_KEYS, "node", nj.name ?? "");
4859
4901
  rejectWrongKinds(nj, nj.name ?? "");
4860
4902
  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.`);
4861
- if (nj.instance !== void 0) return buildInstance(nj, opts, stack, path, constants, bands);
4903
+ if (nj.instance !== void 0) {
4904
+ if (nj.props !== void 0) throw new IncantoError("BAD_FORMAT", `Node '${nj.name}' places an instance and declares "props" — a placement's props go in "overrides", which deep-merge onto the sub-scene root. "props" here is read by nothing.`, { prop: "props" });
4905
+ return buildInstance(nj, opts, stack, path, constants, bands);
4906
+ }
4862
4907
  if (nj.type === void 0) throw new IncantoError("BAD_FORMAT", `Node '${nj.name}' must declare either "type" or "instance".`);
4863
4908
  const node = createNode(nj.type, resolveConstants(nj.props, constants), { orderGroup: bands });
4864
4909
  applyCommon(node, nj, opts, constants);
@@ -1,6 +1,6 @@
1
1
  import { n as jsonEquals, t as jsonClone } from "./json-CfTjpvW8.js";
2
- import { J as Node, Y as diagnose, ct as Signal, d as rebuildOptions, h as loadScene, l as markCloned, m as buildSceneSubtree, p as stripUids, u as markTemplateName } from "./save-slots-Bvuh2p_r.js";
3
- import { t as registerCoreNodes, v as Engine } from "./register-DuVdzxbq.js";
2
+ import { J as Node, Y as diagnose, ct as Signal, d as rebuildOptions, h as loadScene, l as markCloned, m as buildSceneSubtree, p as stripUids, u as markTemplateName } from "./save-slots-CEuJPUle.js";
3
+ import { t as registerCoreNodes, v as Engine } from "./register-5IYfooAN.js";
4
4
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
5
5
  import { p as registerNode } from "./touch-BnCyPA0G.js";
6
6
  //#region src/net/loopback.ts
@@ -1150,7 +1150,7 @@ function applySyncPatch(root, patch, setProp, onMissingNode) {
1150
1150
  }
1151
1151
  }
1152
1152
  async function createDefaultTransport(config, diagnostics) {
1153
- const { createAgent8Server } = await import("./agent8-Cfmd3ar_.js").then((n) => n.t);
1153
+ const { createAgent8Server } = await import("./agent8-BqZ0_O1u.js").then((n) => n.t);
1154
1154
  return createAgent8Server(config, diagnostics);
1155
1155
  }
1156
1156
  //#endregion
@@ -1,7 +1,7 @@
1
- import { Lt as Signal, b as Engine, jt as Node } from "./behavior-Dcz0fr1S.js";
1
+ import { Lt as Signal, b as Engine, jt as Node } from "./behavior-Bf9P9oB2.js";
2
2
  import { t as DiagnosticSink } from "./diagnostics-Cu85N3tL.js";
3
3
  import { a as SceneJson, c as JsonValue, s as JsonObject } from "./rng-Bb-IutXB.js";
4
- import { t as LoadSceneOptions } from "./loader-8-IHvbKD.js";
4
+ import { t as LoadSceneOptions } from "./loader-CBfQzB6S.js";
5
5
 
6
6
  //#region src/net/types.d.ts
7
7
  type Unsubscribe = () => void;
@@ -199,6 +199,6 @@ async function preloadSceneAssets(assets, title) {
199
199
  //#endregion
200
200
  //#region src/index.ts
201
201
  /** Engine version. Kept in sync with package.json by the release pipeline. */
202
- const VERSION = "0.71.0";
202
+ const VERSION = "0.72.0";
203
203
  //#endregion
204
204
  export { findPath as a, preloadUrls as i, assetUrls as n, gridFromRows as o, preloadSceneAssets as r, VERSION as t };
@@ -1,14 +1,14 @@
1
1
  import { n as jsonEquals, t as jsonClone } from "./json-CfTjpvW8.js";
2
- import { B as HudLayer, M as resetMemorySaves, O as resolveViewport, V as HudWidgetBase, c as isCloned, h as loadScene, ot as registerBehavior, tt as StubBehavior } from "./save-slots-Bvuh2p_r.js";
3
- import { v as Engine } from "./register-DuVdzxbq.js";
2
+ import { B as HudLayer, M as resetMemorySaves, O as resolveViewport, V as HudWidgetBase, c as isCloned, h as loadScene, ot as registerBehavior, tt as StubBehavior } from "./save-slots-CEuJPUle.js";
3
+ import { v as Engine } from "./register-5IYfooAN.js";
4
4
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
5
5
  import { t as Rng } from "./rng-CDOMybym.js";
6
6
  import { c as getNodeSchema, d as mergeStaticProps, u as getNodeType } from "./touch-BnCyPA0G.js";
7
- import { n as startRecording } from "./replay-DEvp3kyV.js";
8
- import { Q as worldPosition, n as registerGameplayBehaviors } from "./gameplay-CNULJvwh.js";
9
- import { t as registerNodes2D } from "./register-BYQCBySi.js";
10
- import { n as registerNodes3D, t as resolveEnvironmentHdri } from "./environment-presets-99BzP_L-.js";
11
- import { a as NetworkManager, c as readSyncKey, i as sanitizeName, n as registerNodesNet, r as NetworkSpawner, s as findOwnerNode, t as createSplitScreen } from "./split-screen-eULetcg-.js";
7
+ import { n as startRecording } from "./replay-datiAE-b.js";
8
+ import { Q as worldPosition, n as registerGameplayBehaviors } from "./gameplay-BlQe-M07.js";
9
+ import { t as registerNodes2D } from "./register-C8HuRkOf.js";
10
+ import { n as registerNodes3D, t as resolveEnvironmentHdri } from "./environment-presets-BeHoaGhy.js";
11
+ import { a as NetworkManager, c as readSyncKey, i as sanitizeName, n as registerNodesNet, r as NetworkSpawner, s as findOwnerNode, t as createSplitScreen } from "./split-screen-Bm5DTElG.js";
12
12
  import { Box3, Euler, Frustum, Matrix4, PerspectiveCamera, Quaternion, Ray, Vector3 } from "three";
13
13
  //#region src/core/asset-urls.ts
14
14
  /** Keys inside a `material` object that hold a texture URL. */
@@ -3389,8 +3389,8 @@ async function playMultiplayer(opts) {
3389
3389
  */
3390
3390
  async function joinLate(server, first, opts) {
3391
3391
  try {
3392
- const { Engine } = await import("./register-DuVdzxbq.js").then((n) => n.y);
3393
- const { loadScene } = await import("./save-slots-Bvuh2p_r.js").then((n) => n.g);
3392
+ const { Engine } = await import("./register-5IYfooAN.js").then((n) => n.y);
3393
+ const { loadScene } = await import("./save-slots-CEuJPUle.js").then((n) => n.g);
3394
3394
  const { jsonClone } = await import("./json-CfTjpvW8.js").then((n) => n.i);
3395
3395
  const engine = new Engine(opts.seed !== void 0 ? { seed: opts.seed + 999 } : {});
3396
3396
  engine.setScene(loadScene(jsonClone(opts.scene), opts.load));
@@ -3988,10 +3988,10 @@ async function runScript(json, opts) {
3988
3988
  if (opts.locale) engine.locale.locale = opts.locale;
3989
3989
  const physics = opts.physics ?? "auto";
3990
3990
  if (physics === "2d" || physics === "auto" && scene.dimension === "2d") {
3991
- const { enablePhysics2D } = await import("./physics-2d-FhrXUc6B.js").then((n) => n.r);
3991
+ const { enablePhysics2D } = await import("./physics-2d-DrIgTlLk.js").then((n) => n.r);
3992
3992
  await enablePhysics2D(engine);
3993
3993
  } else if (physics === "3d" || physics === "auto" && scene.dimension === "3d") {
3994
- const { enablePhysics3D } = await import("./physics-3d-CFEGxBXZ.js").then((n) => n.r);
3994
+ const { enablePhysics3D } = await import("./physics-3d-BzOCw1VS.js").then((n) => n.r);
3995
3995
  await enablePhysics3D(engine);
3996
3996
  }
3997
3997
  const failures = [];
@@ -4218,10 +4218,10 @@ async function createPlaySession(json, opts = {}) {
4218
4218
  engine.setScene(scene);
4219
4219
  const physics = opts.physics ?? "auto";
4220
4220
  if (physics === "2d" || physics === "auto" && scene.dimension === "2d") {
4221
- const { enablePhysics2D } = await import("./physics-2d-FhrXUc6B.js").then((n) => n.r);
4221
+ const { enablePhysics2D } = await import("./physics-2d-DrIgTlLk.js").then((n) => n.r);
4222
4222
  await enablePhysics2D(engine);
4223
4223
  } else if (physics === "3d" || physics === "auto" && scene.dimension === "3d") {
4224
- const { enablePhysics3D } = await import("./physics-3d-CFEGxBXZ.js").then((n) => n.r);
4224
+ const { enablePhysics3D } = await import("./physics-3d-BzOCw1VS.js").then((n) => n.r);
4225
4225
  await enablePhysics3D(engine);
4226
4226
  }
4227
4227
  const stepMs = 1e3 / (opts.fixedHz ?? 60);
package/dist/test.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { P as Scene$1, Pt as LogEntry, b as Engine, jt as Node, n as BehaviorCtor } from "./behavior-Dcz0fr1S.js";
1
+ import { P as Scene$1, Pt as LogEntry, b as Engine, jt as Node, n as BehaviorCtor } from "./behavior-Bf9P9oB2.js";
2
2
  import { a as SceneJson, c as JsonValue, s as JsonObject } from "./rng-Bb-IutXB.js";
3
- import { t as LoadSceneOptions } from "./loader-8-IHvbKD.js";
4
- import { l as auditScene, o as IncantoError, r as ReplayJson, u as instancedScenes } from "./replay-F7IZHdFR.js";
5
- import { l as LocalGameServerOptions, n as SplitScreenPlayer } from "./split-screen-CIYf1zSf.js";
3
+ import { t as LoadSceneOptions } from "./loader-CBfQzB6S.js";
4
+ import { l as auditScene, o as IncantoError, r as ReplayJson, u as instancedScenes } from "./replay-CBEChqXq.js";
5
+ import { l as LocalGameServerOptions, n as SplitScreenPlayer } from "./split-screen-DkqLng6q.js";
6
6
  import { Matrix4, Vector3 } from "three";
7
7
 
8
8
  //#region src/core/asset-urls.d.ts
package/dist/test.js CHANGED
@@ -1,3 +1,3 @@
1
- import { i as instancedScenes, r as auditScene } from "./replay-DEvp3kyV.js";
2
- import { A as geometricPicker, C as facingReport, D as playtest, E as findPlayer, F as sceneAssetUrls, M as pointAtNode, N as describeFraming, O as playtestFailed, P as framingText, S as collectionProblems, T as failingReplays, _ as feelReport, a as registerAllNodes, b as takeCollectionSnapshots, c as feelsRung, d as ladderVerdict, f as saysRung, g as playMultiplayer, h as multiplayText, i as findFloatingProps, j as geometricView, k as playtestText, l as firstLine, m as multiplayProblems, n as createPlaySession, o as runScript, p as unmeasuredPlays, r as describeCapture, s as validateScene, t as captureScene, u as ladderText, v as feelText, w as facingText, x as agreementProblems, y as takeAgreementSnapshots } from "./test-CmN54kWv.js";
1
+ import { i as instancedScenes, r as auditScene } from "./replay-datiAE-b.js";
2
+ import { A as geometricPicker, C as facingReport, D as playtest, E as findPlayer, F as sceneAssetUrls, M as pointAtNode, N as describeFraming, O as playtestFailed, P as framingText, S as collectionProblems, T as failingReplays, _ as feelReport, a as registerAllNodes, b as takeCollectionSnapshots, c as feelsRung, d as ladderVerdict, f as saysRung, g as playMultiplayer, h as multiplayText, i as findFloatingProps, j as geometricView, k as playtestText, l as firstLine, m as multiplayProblems, n as createPlaySession, o as runScript, p as unmeasuredPlays, r as describeCapture, s as validateScene, t as captureScene, u as ladderText, v as feelText, w as facingText, x as agreementProblems, y as takeAgreementSnapshots } from "./test-Djuq3Vhq.js";
3
3
  export { agreementProblems, auditScene, captureScene, collectionProblems, createPlaySession, describeCapture, describeFraming, facingReport, facingText, failingReplays, feelReport, feelText, feelsRung, findFloatingProps, findPlayer, firstLine, framingText, geometricPicker, geometricView, instancedScenes, ladderText, ladderVerdict, multiplayProblems, multiplayText, playMultiplayer, playtest, playtestFailed, playtestText, pointAtNode, registerAllNodes, runScript, saysRung, sceneAssetUrls, takeAgreementSnapshots, takeCollectionSnapshots, unmeasuredPlays, validateScene };
package/dist/vite.d.ts CHANGED
@@ -222,6 +222,13 @@ declare function sceneFacts(json: unknown): {
222
222
  ok: false;
223
223
  why: string;
224
224
  };
225
+ /**
226
+ * The dimension the NEXT scene should be, counted from the ones already here.
227
+ *
228
+ * Whatever the sibling scenes are is overwhelmingly what the next one should
229
+ * be; `null` when the project has no scenes yet and the caller decides.
230
+ */
231
+ declare function projectDimension(root: string): "2d" | "3d" | null;
225
232
  /** @internal Exported for tests. Root-bounded walk, deepest 6 levels. */
226
233
  declare function discoverScenes(root: string): ProjectFileEntry[];
227
234
  /**
@@ -310,4 +317,4 @@ declare function serveDeviceAuth(req: LibraryReq, res: LibraryRes, opts?: Incant
310
317
  /** @internal Exported for tests — the whole request/response behaviour. */
311
318
  declare function serveLibrary(req: LibraryReq, res: LibraryRes, opts?: IncantoLibraryOptions, doFetch?: typeof fetch): Promise<void>;
312
319
  //#endregion
313
- export { type FrameHost, type FrameReq, type FrameRes, IncantoLibraryOptions, IncantoScenesOptions, type IncantoTrimOptions, ProjectFileEntry, type StaticInspectHost, createStaticInspectHost, discoverScenes, incantoLibrary, incantoScenes, incantoTrim, listeningPorts, maskToken, onlyKnownOptions, parseProcNetTcp, resolveSceneFile, sceneFacts, serveDeviceAuth, serveFrameEndpoints, serveLibrary, serveSceneFile, serveSceneList, serveTokenStatus };
320
+ export { type FrameHost, type FrameReq, type FrameRes, IncantoLibraryOptions, IncantoScenesOptions, type IncantoTrimOptions, ProjectFileEntry, type StaticInspectHost, createStaticInspectHost, discoverScenes, incantoLibrary, incantoScenes, incantoTrim, listeningPorts, maskToken, onlyKnownOptions, parseProcNetTcp, projectDimension, resolveSceneFile, sceneFacts, serveDeviceAuth, serveFrameEndpoints, serveLibrary, serveSceneFile, serveSceneList, serveTokenStatus };
package/dist/vite.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import { a as parseJsonText } from "./json-CfTjpvW8.js";
2
+ import { k as newUid } from "./save-slots-CEuJPUle.js";
2
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
3
- import { t as VERSION } from "./src-_jk0qLsS.js";
4
+ import { t as VERSION } from "./src-DRSsRleD.js";
4
5
  import { n as diffSignatures } from "./frame-report-D-_7YF2G.js";
5
- import { s as validateScene } from "./test-CmN54kWv.js";
6
+ import { s as validateScene } from "./test-Djuq3Vhq.js";
6
7
  import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
7
8
  import { basename, dirname, extname, join, normalize, relative, resolve, sep } from "node:path";
8
9
  import { fileURLToPath } from "node:url";
@@ -708,6 +709,20 @@ function inspect(abs, size) {
708
709
  nodes: facts.nodes
709
710
  } } : { notScene: facts.why };
710
711
  }
712
+ /**
713
+ * The dimension the NEXT scene should be, counted from the ones already here.
714
+ *
715
+ * Whatever the sibling scenes are is overwhelmingly what the next one should
716
+ * be; `null` when the project has no scenes yet and the caller decides.
717
+ */
718
+ function projectDimension(root) {
719
+ let d2 = 0;
720
+ let d3 = 0;
721
+ for (const entry of discoverScenes(root)) if (entry.scene?.dimension === "3d") d3 += 1;
722
+ else if (entry.scene?.dimension === "2d") d2 += 1;
723
+ if (d3 === 0 && d2 === 0) return null;
724
+ return d3 > d2 ? "3d" : "2d";
725
+ }
711
726
  /** @internal Exported for tests. Root-bounded walk, deepest 6 levels. */
712
727
  function discoverScenes(root) {
713
728
  const found = [];
@@ -812,16 +827,18 @@ async function serveSceneList(req, res, root) {
812
827
  if (!abs) return json(res, 400, { error: "path must be a .json file inside the project" });
813
828
  if (existsSync(abs)) return json(res, 409, { error: `already exists: ${String(wanted)}` });
814
829
  const name = basename(abs).replace(/\.scene\.json$|\.json$/, "") || "Scene";
830
+ const dimension = (body.dimension === "3d" || body.dimension === "2d" ? body.dimension : null) ?? projectDimension(base) ?? "2d";
815
831
  try {
816
832
  mkdirSync(dirname(abs), { recursive: true });
817
833
  writeFileSync(abs, `${JSON.stringify({
818
834
  format: 1,
819
835
  type: "scene",
820
- dimension: "3d",
836
+ dimension,
821
837
  name,
822
838
  root: {
823
839
  name,
824
- type: "Node3D"
840
+ type: dimension === "3d" ? "Node3D" : "Node2D",
841
+ uid: newUid()
825
842
  }
826
843
  }, null, 2)}\n`);
827
844
  } catch (error) {
@@ -1066,4 +1083,4 @@ function libraryItem(row) {
1066
1083
  };
1067
1084
  }
1068
1085
  //#endregion
1069
- export { createStaticInspectHost, discoverScenes, incantoLibrary, incantoScenes, incantoTrim, listeningPorts, maskToken, onlyKnownOptions, parseProcNetTcp, resolveSceneFile, sceneFacts, serveDeviceAuth, serveFrameEndpoints, serveLibrary, serveSceneFile, serveSceneList, serveTokenStatus };
1086
+ export { createStaticInspectHost, discoverScenes, incantoLibrary, incantoScenes, incantoTrim, listeningPorts, maskToken, onlyKnownOptions, parseProcNetTcp, projectDimension, resolveSceneFile, sceneFacts, serveDeviceAuth, serveFrameEndpoints, serveLibrary, serveSceneFile, serveSceneList, serveTokenStatus };
@@ -1 +1 @@
1
- import{i as e,n as t}from"./index-DK9xMGpW.js";async function n(e,n){return new a((await t(()=>import(`./GameServer-C56iOUgF.js`),[],import.meta.url)).GameServer,e,{diagnostics:n})}var r=[500,1e3,2e3,4e3,8e3],i=8,a=class{raw;active=new Map;reconnecting=!1;disposed=!1;diagnostics;wait;constructor(e,t,n){this.diagnostics=n?.diagnostics??null,this.wait=n?.wait??(e=>new Promise(t=>{setTimeout(t,e)})),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{for(let t=0;t<i;t++){let n=!1,i=null;try{n=await this.rawConnect()!==!1}catch(e){i=e}if(this.disposed)return;if(n){for(let e of this.active.values())e.off(),e.off=e.make();t>0&&e(this.diagnostics,`info`,`[incanto] multiplayer reconnected after ${t+1} attempts.`);return}t===0&&e(this.diagnostics,`warn`,`[incanto] the multiplayer connection dropped and the server would not take it back${i?` (${i instanceof Error?i.message:String(i)})`:``}. Retrying — other players cannot see this one until it comes back.`);let a=r[Math.min(t,r.length-1)]??8e3;if(await this.wait(a),this.disposed)return}e(this.diagnostics,`error`,`[incanto] multiplayer gave up after ${i} reconnect attempts — this client is offline and the others cannot see it. Call connect() again to retry.`)}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{n as createAgent8Server};
1
+ import{i as e,n as t}from"./index-BEKuxYcE.js";async function n(e,n){return new a((await t(()=>import(`./GameServer-C56iOUgF.js`),[],import.meta.url)).GameServer,e,{diagnostics:n})}var r=[500,1e3,2e3,4e3,8e3],i=8,a=class{raw;active=new Map;reconnecting=!1;disposed=!1;diagnostics;wait;constructor(e,t,n){this.diagnostics=n?.diagnostics??null,this.wait=n?.wait??(e=>new Promise(t=>{setTimeout(t,e)})),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{for(let t=0;t<i;t++){let n=!1,i=null;try{n=await this.rawConnect()!==!1}catch(e){i=e}if(this.disposed)return;if(n){for(let e of this.active.values())e.off(),e.off=e.make();t>0&&e(this.diagnostics,`info`,`[incanto] multiplayer reconnected after ${t+1} attempts.`);return}t===0&&e(this.diagnostics,`warn`,`[incanto] the multiplayer connection dropped and the server would not take it back${i?` (${i instanceof Error?i.message:String(i)})`:``}. Retrying — other players cannot see this one until it comes back.`);let a=r[Math.min(t,r.length-1)]??8e3;if(await this.wait(a),this.disposed)return}e(this.diagnostics,`error`,`[incanto] multiplayer gave up after ${i} reconnect attempts — this client is offline and the others cannot see it. Call connect() again to retry.`)}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{n as createAgent8Server};