incanto 0.56.0 → 0.57.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 (60) hide show
  1. package/bin/incanto-verify.mjs +9 -2
  2. package/dist/2d.d.ts +59 -7
  3. package/dist/2d.js +3 -3
  4. package/dist/3d.d.ts +34 -4
  5. package/dist/3d.js +5 -5
  6. package/dist/{behavior-CyQoSu4n.d.ts → behavior-l08AEbq9.d.ts} +5 -0
  7. package/dist/{create-game-CqJkfMzm.js → create-game-C5jQYPah.js} +28 -71
  8. package/dist/{create-game-YvaNWhe6.js → create-game-DpbUrMOQ.js} +146 -7
  9. package/dist/debug.d.ts +1 -1
  10. package/dist/{duplicate-MNLMAcbz.js → duplicate-BPLZDZpd.js} +1 -1
  11. package/dist/{environment-presets-DLHqgNAF.js → environment-presets-CvvQr_bJ.js} +106 -24
  12. package/dist/{frame-report-njybhZon.js → frame-report-BSMny7oe.js} +1 -1
  13. package/dist/{frame-report-DZ70IY26.d.ts → frame-report-DCnHFmto.d.ts} +1 -1
  14. package/dist/{gameplay-C_SPzmUe.js → gameplay-BVphcxmE.js} +89 -13
  15. package/dist/gameplay.d.ts +26 -1
  16. package/dist/gameplay.js +1 -1
  17. package/dist/index.d.ts +45 -5
  18. package/dist/index.js +8 -9
  19. package/dist/{loader-DhI1jFW_.d.ts → loader-BbEMTuWg.d.ts} +1 -1
  20. package/dist/{loader-BTkHYrQn.js → loader-BcrRSjxB.js} +682 -682
  21. package/dist/net.d.ts +2 -2
  22. package/dist/net.js +1 -1
  23. package/dist/{pathfinding-CXGCpRQe.d.ts → pathfinding-mEN4V1CU.d.ts} +1 -1
  24. package/dist/{physics-2d-CfWAggJ1.js → physics-2d-BLcvEFDR.js} +2 -2
  25. package/dist/{physics-3d-NzDwWPrF.js → physics-3d-QBrfIT2Y.js} +3 -3
  26. package/dist/react.d.ts +1 -1
  27. package/dist/react.js +1 -1
  28. package/dist/{register-en63AEZO.js → register-C6ZBFRjd.js} +63 -60
  29. package/dist/{register-p48lHE2o.js → register-Ch70uByv.js} +1615 -1502
  30. package/dist/{replay-ePMz26jw.d.ts → replay-Dw6gMlYA.d.ts} +1 -1
  31. package/dist/{replay-t1pP0gQg.js → replay-s7I2GstT.js} +31 -11
  32. package/dist/sheet-grid-BT6N_Bjs.js +59 -0
  33. package/dist/{split-screen-BsdOHbzP.d.ts → split-screen-B0baBwxI.d.ts} +5 -1
  34. package/dist/{split-screen-CSb_uZ6W.js → split-screen-DLsUrleX.js} +14 -3
  35. package/dist/{sprite-animation-7qvUxF6Z.js → sprite-animation-C0wXLBZJ.js} +8 -4
  36. package/dist/{src-51GA-9m-.js → src-CGjmPw65.js} +55 -2
  37. package/dist/{teardown-C7uVSJvx.js → teardown-Cs113S9F.js} +74 -2
  38. package/dist/{test-Bu6SPNsV.js → test-it1VekWs.js} +28 -19
  39. package/dist/test.d.ts +4 -4
  40. package/dist/test.js +2 -2
  41. package/dist/{touch-BnMyy9tr.js → touch-DESwnpOc.js} +173 -1
  42. package/dist/vite.d.ts +1 -1
  43. package/dist/vite.js +3 -3
  44. package/editor/assets/{agent8-X0Nesj-k.js → agent8-CGT7r3Mb.js} +1 -1
  45. package/editor/assets/{debug-TXqu-ftX.js → debug-BxWSIHG3.js} +1 -1
  46. package/editor/assets/{index-DTdwKKIv.js → index-CV1m-aX5.js} +62 -62
  47. package/editor/index.html +1 -1
  48. package/package.json +1 -1
  49. package/skills/incanto-assets.md +5 -1
  50. package/skills/incanto-audio.md +7 -1
  51. package/skills/incanto-gameplay-behaviors.md +2 -1
  52. package/skills/incanto-hud.md +6 -0
  53. package/skills/incanto-performance.md +5 -0
  54. package/skills/incanto-physics-and-input.md +14 -0
  55. package/skills/incanto-save-slots.md +2 -1
  56. package/skills/incanto-verifying-your-game.md +4 -0
  57. package/templates-app/beacon-isle-3d/package.json +1 -1
  58. package/templates-app/tps-3d/package.json +1 -1
  59. package/templates-app/village-quest-3d/package.json +1 -1
  60. package/dist/log-report-CPFm4OXf.js +0 -173
@@ -1,10 +1,12 @@
1
- import { t as registerCoreNodes } from "./register-p48lHE2o.js";
1
+ import { C as diagnose } from "./loader-BcrRSjxB.js";
2
+ import { t as registerCoreNodes } from "./register-Ch70uByv.js";
2
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
3
4
  import { t as Rng } from "./rng-DP-SR7eg.js";
4
5
  import { i as getNodeSchema, l as registerNode } from "./registry-C7u42TID.js";
5
6
  import { t as createNoise2D } from "./noise-CGUMx44x.js";
6
- import { i as ParticleSim, n as resolveFrames, o as PARTICLE_PRESET_NAMES, r as validateAnimationAliases, s as applyParticlePreset, t as resolveAnimation } from "./sprite-animation-7qvUxF6Z.js";
7
- import { B as Node3D, F as Area3D, I as CharacterBody3D, L as PhysicsBody3D, M as Water3D, P as WaterCutout3D, R as RigidBody3D, W as colliderFootDrop, z as StaticBody3D } from "./gameplay-C_SPzmUe.js";
7
+ import { i as ParticleSim, n as resolveFrames, o as PARTICLE_PRESET_NAMES, r as validateAnimationAliases, s as applyParticlePreset, t as resolveAnimation } from "./sprite-animation-C0wXLBZJ.js";
8
+ import { B as StaticBody3D, F as WaterCutout3D, G as colliderFootDrop, I as Area3D, L as CharacterBody3D, N as Water3D, R as PhysicsBody3D, V as Node3D, w as tolerateUnknownAction, z as RigidBody3D } from "./gameplay-BVphcxmE.js";
9
+ import { t as checkSheetGrid } from "./sheet-grid-BT6N_Bjs.js";
8
10
  import { n as splatWeights, t as buildHeightmap } from "./heightmap-CRK0M4jT.js";
9
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";
10
12
  import { clone } from "three/addons/utils/SkeletonUtils.js";
@@ -2175,8 +2177,41 @@ var AnimatedSprite3D = class extends Sprite3D {
2175
2177
  }
2176
2178
  this.currentFrame = this.frameList[this.frameIndex] ?? 0;
2177
2179
  }
2180
+ /**
2181
+ * Does the grid fit the image, and does any animation run off the end?
2182
+ *
2183
+ * The same floor-division as the 2D twin, and for a long time the same
2184
+ * division with none of its checking — the checker sat one directory away in
2185
+ * 2d/ where this node could not see it.
2186
+ */
2187
+ checkGrid(width, height) {
2188
+ if (this.gridChecked === this.sheet) return;
2189
+ this.gridChecked = this.sheet;
2190
+ let highest = 0;
2191
+ for (const [name, entry] of Object.entries(this.animations)) {
2192
+ if (typeof entry === "string") continue;
2193
+ try {
2194
+ for (const frame of resolveFrames(entry.frames, name)) if (frame > highest) highest = frame;
2195
+ } catch {
2196
+ return;
2197
+ }
2198
+ }
2199
+ const problem = checkSheetGrid(this.sheet, this.frameWidth, this.frameHeight, width, height, highest);
2200
+ if (problem) diagnose(this.tree?.engine ?? null, "error", problem);
2201
+ }
2202
+ /** Reported once per sheet, so a bad grid says so on the first draw only. */
2203
+ gridChecked = "";
2204
+ /** Reported once, so a sheet with no frame size does not shout every frame. */
2205
+ sizeReported = false;
2178
2206
  resolveTexture(assets) {
2179
- if (!this.sheet || this.frameWidth <= 0 || this.frameHeight <= 0) return null;
2207
+ if (!this.sheet) return null;
2208
+ if (this.frameWidth <= 0 || this.frameHeight <= 0) {
2209
+ if (!this.sizeReported) {
2210
+ this.sizeReported = true;
2211
+ diagnose(this.tree?.engine ?? null, "error", `[incanto] AnimatedSprite3D '${this.name}' has a sheet ('${this.sheet}') but frameWidth/frameHeight are 0 — it draws nothing. Set both to one frame's pixel size (bunx incanto-assets info <name> prints it for a built-in).`);
2212
+ }
2213
+ return null;
2214
+ }
2180
2215
  if (this.loadedSheetRef !== this.sheet) {
2181
2216
  this.sheetTexture?.dispose();
2182
2217
  this.loadedSheetRef = this.sheet;
@@ -2186,6 +2221,7 @@ var AnimatedSprite3D = class extends Sprite3D {
2186
2221
  if (!tex) return null;
2187
2222
  const image = tex.image;
2188
2223
  if (!image?.width || !image.height) return tex;
2224
+ this.checkGrid(image.width, image.height);
2189
2225
  const cols = Math.max(1, Math.floor(image.width / this.frameWidth));
2190
2226
  const col = this.currentFrame % cols;
2191
2227
  const row = Math.floor(this.currentFrame / cols);
@@ -2319,10 +2355,14 @@ var BoneAttachment3D = class extends Node3D {
2319
2355
  this.lookedUpFor = key;
2320
2356
  this.boneObj = null;
2321
2357
  const source = this.getNodeOrNull(this.target);
2358
+ this.source = source;
2322
2359
  if (source && typeof source.findBone === "function") this.boneObj = source.findBone(this.bone);
2323
2360
  }
2324
2361
  const boneObj = this.boneObj;
2325
- if (!boneObj) return;
2362
+ if (!boneObj) {
2363
+ this.reportMissingBone();
2364
+ return;
2365
+ }
2326
2366
  const obj = this._ensureObject3D();
2327
2367
  const parent = obj.parent;
2328
2368
  if (!parent) return;
@@ -2339,6 +2379,28 @@ var BoneAttachment3D = class extends Node3D {
2339
2379
  this.boneObj = null;
2340
2380
  super.free();
2341
2381
  }
2382
+ /** The model this attachment last looked in. */
2383
+ source = null;
2384
+ reportedBone = "";
2385
+ /**
2386
+ * Say when the bone NAME is wrong, without accusing a model that is still
2387
+ * loading.
2388
+ *
2389
+ * The lookup retries every frame on purpose — a GLB mounts async — so the
2390
+ * node can never conclude on its own that the name is bad. But once the model
2391
+ * HAS bones and this one is not among them, it is a typo, and the list that
2392
+ * would fix it is sitting in `boneNames()` right next to `findBone`. Until
2393
+ * now a misspelled bone left the sword at the mount node's authored position
2394
+ * while the character animated away from it, forever, in silence.
2395
+ */
2396
+ reportMissingBone() {
2397
+ if (this.reportedBone === this.bone) return;
2398
+ const names = this.source?.boneNames?.() ?? [];
2399
+ if (names.length === 0) return;
2400
+ this.reportedBone = this.bone;
2401
+ const shown = names.slice(0, 8).join(", ");
2402
+ diagnose(this.tree?.engine ?? null, "error", `[incanto] ${this.getPath()}: '${this.target}' has no bone '${this.bone}'. It has ${names.length}: [${shown}${names.length > 8 ? ", …" : ""}].`);
2403
+ }
2342
2404
  };
2343
2405
  const offsetScratch = new Matrix4();
2344
2406
  const boneScratch = new Matrix4();
@@ -2506,6 +2568,11 @@ const DRAG_DAMPING = .15;
2506
2568
  const SPRING_K = 1.2;
2507
2569
  const SPRING_DAMPING = .08;
2508
2570
  const FALLING_MAX_VEL = -20;
2571
+ /** The schema's own default for an action prop — never a second copy of it. */
2572
+ function defaultActionOf(prop) {
2573
+ const schema = CharacterController3D.props[prop];
2574
+ return typeof schema?.default === "string" ? schema.default : "";
2575
+ }
2509
2576
  const LOOK_SPEED = .002;
2510
2577
  const RAD2DEG = 180 / Math.PI;
2511
2578
  /** Spring-arm camera collision: keep the camera this far in front of an obstacle. */
@@ -2706,8 +2773,10 @@ var CharacterController3D = class extends Node3D {
2706
2773
  const len = Math.hypot(dir[0], dir[2]) || 1;
2707
2774
  mx = dir[0] / len;
2708
2775
  mz = dir[2] / len;
2709
- } catch {}
2710
- const sprinting = safePressed(input, this.sprintAction);
2776
+ } catch (error) {
2777
+ this.reportMissingAction("moveAction", error, "The character will not move.");
2778
+ }
2779
+ const sprinting = this.readAction("sprintAction", () => input.isPressed(this.sprintAction), false, "Sprint will never engage.");
2711
2780
  const intensity = keyboardIntensity(moving, sprinting);
2712
2781
  const speedMultiplier = 1 + (this.sprintMultiplier - 1) * intensity;
2713
2782
  const targetSpeed = moving ? this.maxSpeed * speedMultiplier : 0;
@@ -2741,7 +2810,7 @@ var CharacterController3D = class extends Node3D {
2741
2810
  this.coyoteLeft = Math.max(0, this.coyoteLeft - dt);
2742
2811
  if (!this.grounded && this.coyoteLeft <= 0 && this.jumpsUsed === 0) this.jumpsUsed = 1;
2743
2812
  }
2744
- const pressedJump = safeJustPressed(input, this.jumpAction);
2813
+ const pressedJump = this.readAction("jumpAction", () => input.justPressed(this.jumpAction), false, "The character will never jump.");
2745
2814
  if (pressedJump) this.bufferLeft = Math.max(this.jumpBufferSeconds, 0);
2746
2815
  else this.bufferLeft = Math.max(0, this.bufferLeft - dt);
2747
2816
  if ((this.bufferLeft > 0 || pressedJump) && (footed || this.coyoteLeft > 0 || this.jumpsUsed < this.maxJumps)) {
@@ -2761,7 +2830,7 @@ var CharacterController3D = class extends Node3D {
2761
2830
  }
2762
2831
  if (this.rising) {
2763
2832
  if ((vel[1] ?? 0) <= 0) this.rising = false;
2764
- else if (this.jumpCutMultiplier < 1 && !safePressed(input, this.jumpAction)) {
2833
+ else if (this.jumpCutMultiplier < 1 && !this.readAction("jumpAction", () => input.isPressed(this.jumpAction), false, "The character will never jump.")) {
2765
2834
  const cut = (vel[1] ?? 0) * this.jumpCutMultiplier;
2766
2835
  body.linearVelocity = [
2767
2836
  vel[0],
@@ -2806,6 +2875,31 @@ var CharacterController3D = class extends Node3D {
2806
2875
  }
2807
2876
  }
2808
2877
  }
2878
+ /** Actions already reported missing, so a per-frame read says it once. */
2879
+ reportedActions = /* @__PURE__ */ new Set();
2880
+ /**
2881
+ * Read an input action this controller is allowed to be missing.
2882
+ *
2883
+ * Tolerated because a game may declare no sprint key and no jump; reported
2884
+ * because otherwise a TYPO looks exactly like a deliberate omission, and the
2885
+ * engine has already thrown the sentence that fixes it.
2886
+ */
2887
+ readAction(prop, read, fallback, consequence) {
2888
+ const action = this[prop];
2889
+ return tolerateUnknownAction({
2890
+ engine: this.tree?.engine,
2891
+ who: this.getPath(),
2892
+ reported: this.reportedActions,
2893
+ consequence,
2894
+ authored: action !== defaultActionOf(prop)
2895
+ }, action, read, fallback);
2896
+ }
2897
+ /** Report a throw the caller already caught (the move read has its own try). */
2898
+ reportMissingAction(prop, error, consequence) {
2899
+ this.readAction(prop, () => {
2900
+ throw error;
2901
+ }, void 0, consequence);
2902
+ }
2809
2903
  update(dt) {
2810
2904
  const input = this.tree?.engine?.input;
2811
2905
  if (!input) return;
@@ -2921,28 +3015,14 @@ function worldOf(node) {
2921
3015
  z
2922
3016
  ];
2923
3017
  }
2924
- function safePressed(input, action) {
2925
- try {
2926
- return input.isPressed(action);
2927
- } catch {
2928
- return false;
2929
- }
2930
- }
2931
3018
  /**
2932
3019
  * The EDGE, not the level.
2933
3020
  *
2934
3021
  * Jump used to read `isPressed`, so holding the button re-jumped on every frame
2935
3022
  * the raycast found ground — an auto-hop nobody asked for, and one that makes
2936
3023
  * coyote time incoherent (a held button would re-fire through the whole
2937
- * window). Same undeclared-action tolerance as `safePressed`.
3024
+ * window). Undeclared actions are tolerated, and reported once.
2938
3025
  */
2939
- function safeJustPressed(input, action) {
2940
- try {
2941
- return input.justPressed(action);
2942
- } catch {
2943
- return false;
2944
- }
2945
- }
2946
3026
  //#endregion
2947
3027
  //#region src/3d/vegetation/grass-placement.ts
2948
3028
  const NOISE_SCALE = .15;
@@ -3668,6 +3748,7 @@ var Flowers3D = class extends Node3D {
3668
3748
  this.height,
3669
3749
  this.clustering,
3670
3750
  this.drape,
3751
+ this.avoidWater,
3671
3752
  this.terrain
3672
3753
  ]);
3673
3754
  if (key === this.fieldKey) return;
@@ -5222,6 +5303,7 @@ var Foliage3D = class Foliage3D extends Node3D {
5222
5303
  this.colorA,
5223
5304
  this.colorB,
5224
5305
  this.coverage,
5306
+ this.avoidWater,
5225
5307
  this.flowers,
5226
5308
  this.seed,
5227
5309
  this.drape,
@@ -1,4 +1,4 @@
1
- //#region src/3d/frame-report.ts
1
+ //#region src/core/frame-report.ts
2
2
  /** Rec. 709 relative luminance of an 8-bit triple, 0..1. */
3
3
  function luma(r, g, b) {
4
4
  return (.2126 * r + .7152 * g + .0722 * b) / 255;
@@ -1,4 +1,4 @@
1
- //#region src/3d/frame-report.d.ts
1
+ //#region src/core/frame-report.d.ts
2
2
  /**
3
3
  * What the frame looks like, as something worth saying.
4
4
  *
@@ -1,7 +1,7 @@
1
- import { A as registerBehavior, T as Behavior, b as effectiveOrder, f as Node, n as loadScene, p as SaveSlots } from "./loader-BTkHYrQn.js";
1
+ import { A as registerBehavior, C as diagnose, S as Node, T as Behavior, f as SaveSlots, n as loadScene, y as effectiveOrder } from "./loader-BcrRSjxB.js";
2
2
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
3
3
  import { t as jsonClone } from "./json-BLk7H2Qa.js";
4
- import { t as duplicateNode } from "./duplicate-MNLMAcbz.js";
4
+ import { t as duplicateNode } from "./duplicate-BPLZDZpd.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();
@@ -4172,12 +4172,20 @@ var Buoyancy = class extends Behavior {
4172
4172
  size = [1, 1];
4173
4173
  surface = null;
4174
4174
  wet = false;
4175
+ /** Said once: a body that cannot be pushed will never start being able to. */
4176
+ reportedNoImpulse = false;
4175
4177
  update(dt) {
4176
4178
  if (dt <= 0) return;
4177
4179
  const water = this.resolveWater();
4178
4180
  if (!water) return;
4179
4181
  const node = this.node;
4180
- if (!node.applyImpulse) return;
4182
+ if (!node.applyImpulse) {
4183
+ if (!this.reportedNoImpulse) {
4184
+ this.reportedNoImpulse = true;
4185
+ diagnose(this.node.tree?.engine ?? null, "error", `[incanto] ${this.node.getPath()}: Buoyancy needs a body it can push — this node has no applyImpulse, so it will never float. Put it on a RigidBody3D.`);
4186
+ }
4187
+ return;
4188
+ }
4181
4189
  const [x, y, z] = [
4182
4190
  node.position[0] ?? 0,
4183
4191
  node.position[1] ?? 0,
@@ -5036,6 +5044,35 @@ var FollowCamera = class extends Behavior {
5036
5044
  }
5037
5045
  };
5038
5046
  //#endregion
5047
+ //#region src/core/optional-action.ts
5048
+ /**
5049
+ * Read an input action that a game is ALLOWED not to declare — and say so once
5050
+ * when it is missing.
5051
+ *
5052
+ * `CharacterController3D` and `GameFlow` wrap every input read in a bare
5053
+ * `catch {}`. The tolerance is right: a game with no sprint key should not
5054
+ * crash, and `pause()` stays an API even with no pause action. What was wrong is
5055
+ * that the tolerance is indistinguishable from a TYPO. Write
5056
+ * `"moveAction": "movement"` and the character stands still, forever, while
5057
+ * `InputMap` has already thrown the exact sentence that would fix it —
5058
+ * `Unknown input action 'movement'. Declared actions: [move, jump].` — and the
5059
+ * catch discards it.
5060
+ *
5061
+ * Reported once per node and action, so a per-frame read does not shout.
5062
+ */
5063
+ function tolerateUnknownAction(ctx, action, read, fallback) {
5064
+ try {
5065
+ return read();
5066
+ } catch (error) {
5067
+ if (ctx.authored && !ctx.reported.has(action)) {
5068
+ ctx.reported.add(action);
5069
+ const detail = error instanceof Error ? error.message : String(error);
5070
+ diagnose(ctx.engine ?? null, "error", `[incanto] ${ctx.who}: ${detail} ${ctx.consequence}`);
5071
+ }
5072
+ return fallback;
5073
+ }
5074
+ }
5075
+ //#endregion
5039
5076
  //#region src/gameplay/game-flow.ts
5040
5077
  /**
5041
5078
  * Reload the CURRENT scene from its source JSON — fresh nodes, reset physics,
@@ -5095,7 +5132,7 @@ function goToScene(engine, sceneJson, opts) {
5095
5132
  * through a `%Banner` UiBanner when one exists; otherwise states are silent
5096
5133
  * (drive your own UI off the `flowChanged` signal).
5097
5134
  */
5098
- var GameFlow = class extends Behavior {
5135
+ var GameFlow = class GameFlow extends Behavior {
5099
5136
  static signals = ["flowChanged"];
5100
5137
  static props = {
5101
5138
  restartAction: { default: "restart" },
@@ -5121,6 +5158,28 @@ var GameFlow = class extends Behavior {
5121
5158
  * fine and means pause is API-only).
5122
5159
  */
5123
5160
  pauseAction = "pause";
5161
+ /** Actions already reported missing, so a per-frame poll says it once. */
5162
+ reportedActions = /* @__PURE__ */ new Set();
5163
+ /**
5164
+ * Poll an action this flow is allowed to be missing, and say so once when the
5165
+ * author named one that does not exist.
5166
+ *
5167
+ * Tolerated because `pause()` and `restart()` stay API-only in a game with no
5168
+ * such key. Reported because a typed-out `"restartAction": "retry"` that is
5169
+ * never declared leaves a frozen game-over screen that answers nothing, and
5170
+ * the engine has already thrown the sentence that fixes it.
5171
+ */
5172
+ readAction(prop, consequence) {
5173
+ const action = this[prop];
5174
+ const schema = GameFlow.props[prop];
5175
+ return tolerateUnknownAction({
5176
+ engine: this.engine,
5177
+ who: this.node.getPath(),
5178
+ reported: this.reportedActions,
5179
+ consequence,
5180
+ authored: action !== (typeof schema?.default === "string" ? schema.default : "")
5181
+ }, action, () => this.engine.input.justPressed(action), false);
5182
+ }
5124
5183
  /**
5125
5184
  * A node shown while paused and hidden otherwise — a `UiPanel` of buttons in
5126
5185
  * practice. '' turns the whole thing off.
@@ -5192,16 +5251,12 @@ var GameFlow = class extends Behavior {
5192
5251
  }
5193
5252
  update() {
5194
5253
  if (this.state === "playing" || this.state === "paused") {
5195
- try {
5196
- if (this.engine.input.justPressed(this.pauseAction)) if (this.state === "playing") this.pause();
5197
- else this.resume();
5198
- } catch {}
5254
+ if (this.readAction("pauseAction", "The pause key will do nothing.")) if (this.state === "playing") this.pause();
5255
+ else this.resume();
5199
5256
  return;
5200
5257
  }
5201
5258
  if (this.state !== "gameover" && this.state !== "won") return;
5202
- try {
5203
- if (this.engine.input.justPressed(this.restartAction)) this.restart();
5204
- } catch {}
5259
+ if (this.readAction("restartAction", "The restart key will do nothing.")) this.restart();
5205
5260
  }
5206
5261
  };
5207
5262
  //#endregion
@@ -5770,7 +5825,10 @@ var Patrol = class extends Behavior {
5770
5825
  }
5771
5826
  const node = this.node;
5772
5827
  const target = this.pointAt(this.index);
5773
- if (!target) return;
5828
+ if (!target) {
5829
+ this.reportDeadWaypoint(this.index);
5830
+ return;
5831
+ }
5774
5832
  const { position, reached } = moveToward(node.position, target, this.speed * dt);
5775
5833
  moveBody(node, position, dt);
5776
5834
  if (reached) {
@@ -5779,6 +5837,24 @@ var Patrol = class extends Behavior {
5779
5837
  if (this.pauseAt > 0) this.pauseTimer = this.pauseAt;
5780
5838
  }
5781
5839
  }
5840
+ /** Waypoints already reported dead, so a per-frame stall says it once. */
5841
+ reportedDead = /* @__PURE__ */ new Set();
5842
+ /**
5843
+ * Say which waypoint the route died on.
5844
+ *
5845
+ * A `points` entry can be a node path, and a misspelled one stops the
5846
+ * patroller the moment the index reaches it — `advance()` is never called, so
5847
+ * it never moves again — with nothing printed. `points` is an ARRAY, so it
5848
+ * cannot carry `nodePath: true`, and `nodeRefWarnings` only inspects string
5849
+ * props: every other node-path prop in the engine is covered by that lint and
5850
+ * this one is invisible to it.
5851
+ */
5852
+ reportDeadWaypoint(i) {
5853
+ if (this.reportedDead.has(i)) return;
5854
+ this.reportedDead.add(i);
5855
+ const raw = this.points[i];
5856
+ diagnose(this.node.tree?.engine ?? null, "error", `[incanto] ${this.node.getPath()}: waypoint ${i} (${JSON.stringify(raw)}) resolves to nothing — the patrol stops here and never moves again.`);
5857
+ }
5782
5858
  /** Resolve waypoint `i` to a position, reading node paths live. */
5783
5859
  pointAt(i) {
5784
5860
  const raw = this.points[i];
@@ -6721,4 +6797,4 @@ function registerGameplayBehaviors(opts) {
6721
6797
  for (const [name, ctor] of Object.entries(GAMEPLAY_BEHAVIORS)) registerBehavior(name, ctor, { replace });
6722
6798
  }
6723
6799
  //#endregion
6724
- export { Collector as A, Node3D as B, restartScene as C, phaseOf as D, DayNight as E, Area3D as F, createCausticsQuad as H, CharacterBody3D as I, PhysicsBody3D as L, Water3D as M, WATER_CUTOUT_MAX as N, DamageOnContact as O, WaterCutout3D as P, RigidBody3D as R, goToScene as S, FloatAway as T, WATER_MAX_RIPPLES as U, validateCollider3D as V, colliderFootDrop as W, Cooldown as _, Wander as a, Interactable as b, SavePoint as c, Patrol as d, PathFollow as f, CameraShake as g, Lifetime as h, WaveSpawner as i, Chase as j, Health as k, Projectile as l, MoveTo as m, registerGameplayBehaviors as n, Spawner as o, Oscillate as p, ZombieAI as r, ScoreKeeper as s, GAMEPLAY_BEHAVIORS as t, Pickup as u, hitStop as v, FollowCamera as w, GameFlow as x, screenFlash as y, StaticBody3D as z };
6800
+ export { Health as A, StaticBody3D as B, restartScene as C, DayNight as D, FloatAway as E, WaterCutout3D as F, colliderFootDrop as G, validateCollider3D as H, Area3D as I, CharacterBody3D as L, Chase as M, Water3D as N, phaseOf as O, WATER_CUTOUT_MAX as P, PhysicsBody3D as R, goToScene as S, FollowCamera as T, createCausticsQuad as U, Node3D as V, WATER_MAX_RIPPLES as W, Cooldown as _, Wander as a, Interactable as b, SavePoint as c, Patrol as d, PathFollow as f, CameraShake as g, Lifetime as h, WaveSpawner as i, Collector as j, DamageOnContact as k, Projectile as l, MoveTo as m, registerGameplayBehaviors as n, Spawner as o, Oscillate as p, ZombieAI as r, ScoreKeeper as s, GAMEPLAY_BEHAVIORS as t, Pickup as u, hitStop as v, tolerateUnknownAction as w, GameFlow as x, screenFlash as y, RigidBody3D as z };
@@ -1,4 +1,4 @@
1
- import { At as Node, b as Engine, d as PropSchema, n as BehaviorCtor, t as Behavior } from "./behavior-CyQoSu4n.js";
1
+ import { At as Node, b as Engine, d as PropSchema, n as BehaviorCtor, t as Behavior } from "./behavior-l08AEbq9.js";
2
2
  import { c as JsonValue, s as JsonObject } from "./schema-CFeioQRE.js";
3
3
 
4
4
  //#region src/gameplay/chase.d.ts
@@ -318,6 +318,19 @@ declare class Patrol extends Behavior {
318
318
  private pauseTimer;
319
319
  override onReady(): void;
320
320
  override update(dt: number): void;
321
+ /** Waypoints already reported dead, so a per-frame stall says it once. */
322
+ private readonly reportedDead;
323
+ /**
324
+ * Say which waypoint the route died on.
325
+ *
326
+ * A `points` entry can be a node path, and a misspelled one stops the
327
+ * patroller the moment the index reaches it — `advance()` is never called, so
328
+ * it never moves again — with nothing printed. `points` is an ARRAY, so it
329
+ * cannot carry `nodePath: true`, and `nodeRefWarnings` only inspects string
330
+ * props: every other node-path prop in the engine is covered by that lint and
331
+ * this one is invisible to it.
332
+ */
333
+ private reportDeadWaypoint;
321
334
  /** Resolve waypoint `i` to a position, reading node paths live. */
322
335
  private pointAt;
323
336
  private advance;
@@ -775,6 +788,18 @@ declare class GameFlow extends Behavior {
775
788
  * fine and means pause is API-only).
776
789
  */
777
790
  pauseAction: string;
791
+ /** Actions already reported missing, so a per-frame poll says it once. */
792
+ private readonly reportedActions;
793
+ /**
794
+ * Poll an action this flow is allowed to be missing, and say so once when the
795
+ * author named one that does not exist.
796
+ *
797
+ * Tolerated because `pause()` and `restart()` stay API-only in a game with no
798
+ * such key. Reported because a typed-out `"restartAction": "retry"` that is
799
+ * never declared leaves a frozen game-over screen that answers nothing, and
800
+ * the engine has already thrown the sentence that fixes it.
801
+ */
802
+ private readAction;
778
803
  /**
779
804
  * A node shown while paused and hidden otherwise — a `UiPanel` of buttons in
780
805
  * practice. '' turns the whole thing off.
package/dist/gameplay.js CHANGED
@@ -1,2 +1,2 @@
1
- import { A as Collector, C as restartScene, D as phaseOf, E as DayNight, O as DamageOnContact, S as goToScene, T as FloatAway, _ as Cooldown, a as Wander, b as Interactable, c as SavePoint, d as Patrol, f as PathFollow, g as CameraShake, h as Lifetime, i as WaveSpawner, j as Chase, k as Health, l as Projectile, m as MoveTo, n as registerGameplayBehaviors, o as Spawner, p as Oscillate, r as ZombieAI, s as ScoreKeeper, t as GAMEPLAY_BEHAVIORS, u as Pickup, v as hitStop, w as FollowCamera, x as GameFlow, y as screenFlash } from "./gameplay-C_SPzmUe.js";
1
+ import { A as Health, C as restartScene, D as DayNight, E as FloatAway, M as Chase, O as phaseOf, S as goToScene, T as FollowCamera, _ as Cooldown, a as Wander, b as Interactable, c as SavePoint, d as Patrol, f as PathFollow, g as CameraShake, h as Lifetime, i as WaveSpawner, j as Collector, k as DamageOnContact, l as Projectile, m as MoveTo, n as registerGameplayBehaviors, o as Spawner, p as Oscillate, r as ZombieAI, s as ScoreKeeper, t as GAMEPLAY_BEHAVIORS, u as Pickup, v as hitStop, x as GameFlow, y as screenFlash } from "./gameplay-BVphcxmE.js";
2
2
  export { CameraShake, Chase, Collector, Cooldown, DamageOnContact, DayNight, FloatAway, FollowCamera, GAMEPLAY_BEHAVIORS, GameFlow, Health, Interactable, Lifetime, MoveTo, Oscillate, PathFollow, Patrol, Pickup, Projectile, SavePoint, ScoreKeeper, Spawner, Wander, WaveSpawner, ZombieAI, goToScene, hitStop, phaseOf, registerGameplayBehaviors, restartScene, screenFlash };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { $ as T_PREFIX, A as SettingsValues, At as Node, B as captureBehaviors, C as EngineStats, Ct as synthSfx, Dt as PlayMusicOptions, E as DeviceHints, Et as MusicTrack, F as BehaviorState, Ft as LogManager, G as ORDER_GROUP_BASE, H as savesWithoutUid, I as RestoreReport, It as Signal, J as effectiveOrder, K as OrderGroup, L as SaveSlot, Lt as SignalListener, M as readDeviceHints, Mt as SceneTree, N as suggestQuality, Nt as LogEntry, O as QualityTier, Ot as AudioBuses, P as Scene, Pt as LogLevel, Q as Localization, R as SaveSlots, S as Scheduler, St as SynthOptions, T as RendererStats, Tt as MusicManager, 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 NodeLifecycle, k as Settings, kt as BusName, 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 MusicBackend, x as EngineOptions, xt as SfxWave, y as registeredTypes, yt as SFX_PRESET_NAMES, z as behaviorsWithoutSave } from "./behavior-CyQoSu4n.js";
1
+ import { $ as T_PREFIX, A as SettingsValues, At as Node, B as captureBehaviors, C as EngineStats, Ct as synthSfx, Dt as PlayMusicOptions, E as DeviceHints, Et as MusicTrack, F as BehaviorState, Ft as LogManager, G as ORDER_GROUP_BASE, H as savesWithoutUid, I as RestoreReport, It as Signal, J as effectiveOrder, K as OrderGroup, L as SaveSlot, Lt as SignalListener, M as readDeviceHints, Mt as SceneTree, N as suggestQuality, Nt as LogEntry, O as QualityTier, Ot as AudioBuses, P as Scene, Pt as LogLevel, Q as Localization, R as SaveSlots, S as Scheduler, St as SynthOptions, T as RendererStats, Tt as MusicManager, 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 NodeLifecycle, k as Settings, kt as BusName, 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 MusicBackend, x as EngineOptions, xt as SfxWave, y as registeredTypes, yt as SFX_PRESET_NAMES, z as behaviorsWithoutSave } from "./behavior-l08AEbq9.js";
2
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-DhI1jFW_.js";
3
+ import { n as loadScene, t as LoadSceneOptions } from "./loader-BbEMTuWg.js";
4
4
  import { i as resolveFrames, n as AnimationEntry, r as resolveAnimation, t as AnimationDef } from "./sprite-animation-CMr6f1K2.js";
5
5
  import { n as ParticleSimConfig, r as ParticleView, t as ParticleSim } from "./particle-sim-C5OfBbmU.js";
6
- import { a as AudioElementLike, i as gridFromRows, n as PathGrid, o as AudioPlayer, r as findPath, t as FindPathOptions } from "./pathfinding-CXGCpRQe.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-ePMz26jw.js";
6
+ import { a as AudioElementLike, i as gridFromRows, n as PathGrid, o as AudioPlayer, r as findPath, t as FindPathOptions } from "./pathfinding-mEN4V1CU.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-Dw6gMlYA.js";
8
8
 
9
9
  //#region src/core/audio/crossfade.d.ts
10
10
  /**
@@ -36,6 +36,9 @@ declare class WebAudioMusicBackend implements MusicBackend {
36
36
  /** True once a backend is present (lazily created on first use). */
37
37
  get available(): boolean;
38
38
  private ensure;
39
+ /** Told when a track will never play. Set by the manager, which knows the
40
+ * engine that owns the log. */
41
+ onTrackError: ((src: string, reason: string) => void) | null;
39
42
  createTrack(src: string): MusicTrack;
40
43
  unlock(): void;
41
44
  dispose(): void;
@@ -374,6 +377,17 @@ declare abstract class HudWidgetBase extends Node {
374
377
  private host;
375
378
  override onExitTree(): void;
376
379
  override update(_dt: number): void;
380
+ /** Which anchor slot this widget was mounted into. */
381
+ private mountedAnchor;
382
+ /**
383
+ * Move to the slot the anchor now names.
384
+ *
385
+ * `_mountWidget` read `anchor` once and `_element` is nulled only on
386
+ * `onExitTree`, so moving a widget from topLeft to bottomRight — from a
387
+ * behavior or from the editor's inspector, which live-patches string props —
388
+ * did nothing at all, forever.
389
+ */
390
+ private _followAnchor;
377
391
  protected _sync(): void;
378
392
  /**
379
393
  * Resolve a text prop through the engine's locale.
@@ -422,6 +436,9 @@ declare class UiText extends HudWidgetBase {
422
436
  */
423
437
  get shown(): string;
424
438
  protected _build(): HTMLElement;
439
+ /** The whole appearance as one string, so re-applying is one comparison. */
440
+ private look;
441
+ private lastLook;
425
442
  protected override _sync(): void;
426
443
  }
427
444
  /** A labeled progress bar (health, stamina, reload, boss HP). */
@@ -454,6 +471,11 @@ declare class UiBar extends HudWidgetBase {
454
471
  /** Move the ceiling on its own, leaving the fill where it is. */
455
472
  setMax(max: number): void;
456
473
  protected _build(): HTMLElement;
474
+ private track;
475
+ private lastTrackLook;
476
+ private lastFillColor;
477
+ /** The track's whole appearance, so re-applying is one comparison. */
478
+ private trackLook;
457
479
  protected override _sync(): void;
458
480
  }
459
481
  /**
@@ -481,6 +503,10 @@ declare class UiBanner extends HudWidgetBase {
481
503
  /** Drop everything (scene transitions). */
482
504
  clear(): void;
483
505
  protected _build(): HTMLElement;
506
+ /** The whole look, so re-applying is one comparison. `size` was baked in at
507
+ * build, and a banner could never be resized. */
508
+ private look;
509
+ private lastLook;
484
510
  override update(dt: number): void;
485
511
  }
486
512
  //#endregion
@@ -508,6 +534,10 @@ declare class UiButton extends HudWidgetBase {
508
534
  /** Programmatic press — same path as a click (tests, gamepad menus). */
509
535
  press(): void;
510
536
  protected _build(): HTMLElement;
537
+ /** The whole look, so re-applying is one comparison. `size`/`color` were baked
538
+ * in at build, and a button could never be restyled afterwards. */
539
+ private look;
540
+ private lastLook;
511
541
  protected override _sync(): void;
512
542
  }
513
543
  /**
@@ -674,6 +704,8 @@ declare class UiToggle extends HudWidgetBase {
674
704
  private input;
675
705
  private last;
676
706
  protected _build(): HTMLElement;
707
+ private tag;
708
+ private lastLabel;
677
709
  protected override _sync(): void;
678
710
  }
679
711
  /** One of several — quality, resolution, language. Emits `changed(value)`. */
@@ -928,6 +960,14 @@ declare function preloadUrls(urls: string[], onProgress?: (loaded: number, total
928
960
  declare function assetUrls(assets: Record<string, {
929
961
  url?: string;
930
962
  }> | undefined): string[];
963
+ /**
964
+ * Preload every scene-asset URL behind the standard overlay, then remove it:
965
+ *
966
+ * await preloadSceneAssets(sceneJson.assets);
967
+ */
968
+ declare function preloadSceneAssets(assets: Record<string, {
969
+ url?: string;
970
+ }> | undefined, title?: string): Promise<void>;
931
971
  //#endregion
932
972
  //#region src/core/register.d.ts
933
973
  /**
@@ -1089,4 +1129,4 @@ declare function computeViewport(canvasW: number, canvasH: number, viewport: {
1089
1129
  /** Engine version. Kept in sync with package.json by the release pipeline. */
1090
1130
  declare const VERSION: string;
1091
1131
  //#endregion
1092
- export { type AnimationDef, type AnimationEntry, type AssetFailure, 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, type DriveScript, type DriveStep, type EffectEvent, type EffectKind, EffectLog, Engine, type EngineOptions, type EngineStats, type FindPathOptions, type GameStats, type GroupedLog, type HudAnchor, HudLayer, IncantoError, type IncantoErrorCode, type IncantoErrorDetails, InputMap, type JsonKind, type JsonObject, type JsonValue, type Listener, type LiveInput, type LiveReport, 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 RefNode, type RefProblem, type RefResult, 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, UiFrameCapSelect, UiImage, UiLanguageSelect, UiMuteToggle, UiPanel, UiQualitySelect, UiRenderScaleSelect, UiSelect, UiSlider, UiText, UiToggle, UiVolumeSlider, 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, describeRefProblem, duplicateNode, effectiveOrder, fadeGain, findPath, getBehavior, getNodeSchema, getNodeSignals, getNodeType, gridFromRows, isAudioContextAvailable, isConstRef, joystickVector, jsonClone, jsonEquals, jsonKind, loadScene, logReport, logText, mergeStaticSignals, newUid, nodeRefWarnings, parseDrive, parseNodePath, preloadUrls, qualityEnvironment, readDeviceHints, registerBehavior, registerCoreNodes, registerNode, registeredBehaviors, registeredTypes, replay, resolveAnimation, resolveConstants, resolveFrames, resolveOrderGroups, resolveRefInJson, resolveRendering, resolveViewport, restoreBehaviors, savesWithoutUid, serializeNode, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
1132
+ export { type AnimationDef, type AnimationEntry, type AssetFailure, 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, type DriveScript, type DriveStep, type EffectEvent, type EffectKind, EffectLog, Engine, type EngineOptions, type EngineStats, type FindPathOptions, type GameStats, type GroupedLog, type HudAnchor, HudLayer, IncantoError, type IncantoErrorCode, type IncantoErrorDetails, InputMap, type JsonKind, type JsonObject, type JsonValue, type Listener, type LiveInput, type LiveReport, 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 RefNode, type RefProblem, type RefResult, 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, UiFrameCapSelect, UiImage, UiLanguageSelect, UiMuteToggle, UiPanel, UiQualitySelect, UiRenderScaleSelect, UiSelect, UiSlider, UiText, UiToggle, UiVolumeSlider, 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, describeRefProblem, duplicateNode, effectiveOrder, fadeGain, findPath, getBehavior, getNodeSchema, getNodeSignals, getNodeType, gridFromRows, isAudioContextAvailable, isConstRef, 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, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
package/dist/index.js CHANGED
@@ -1,14 +1,13 @@
1
- import { A as registerBehavior, D as behaviorSignals, E as behaviorSchema, M as Signal, O as clearBehaviors, S as InputMap, T as Behavior, _ as savesWithoutUid, a as SCENE_FORMAT, b as effectiveOrder, c as SceneTree, d as resolveConstants, f as Node, g as restoreBehaviors, h as captureBehaviors, i as serializeNode, j as registeredBehaviors, k as getBehavior, l as CONST_REF_KEY, m as behaviorsWithoutSave, n as loadScene, o as computeViewport, p as SaveSlots, r as Scene, s as resolveViewport, u as isConstRef, v as createSaveStore, w as parseNodePath, x as resolveOrderGroups, y as ORDER_GROUP_BASE } from "./loader-BTkHYrQn.js";
2
- import { A as BASE_LOCALE, B as SFX_PRESETS, D as suggestQuality, E as readDeviceHints, F as SfxEngine, G as crossfadeGains, H as synthSfx, I as isAudioContextAvailable, K as fadeGain, L as ROLLOFF_MODELS, M as T_PREFIX, N as suggestLocale, O as LogManager, P as translationKey, R as spatialGain, S as Settings, U as MusicManager, V as SFX_PRESET_NAMES, W as WebAudioMusicBackend, _ as UiBanner, a as UiMuteToggle, b as AudioPlayer, c as UiRenderScaleSelect, d as UiToggle, f as UiVolumeSlider, g as HudLayer, h as UiDialogue, i as UiLanguageSelect, j as Localization, k as EffectLog, l as UiSelect, m as UiButton, 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 UiBar, w as qualityEnvironment, x as Engine, y as UiText, z as spatialPan } from "./register-p48lHE2o.js";
1
+ import { A as registerBehavior, D as behaviorSignals, E as behaviorSchema, M as Signal, O as clearBehaviors, S as Node, T as Behavior, _ as createSaveStore, a as SCENE_FORMAT, b as resolveOrderGroups, c as SceneTree, d as resolveConstants, f as SaveSlots, g as savesWithoutUid, h as restoreBehaviors, i as serializeNode, j as registeredBehaviors, k as getBehavior, l as CONST_REF_KEY, m as captureBehaviors, n as loadScene, o as computeViewport, p as behaviorsWithoutSave, r as Scene, s as resolveViewport, u as isConstRef, v as ORDER_GROUP_BASE, w as parseNodePath, x as InputMap, y as effectiveOrder } from "./loader-BcrRSjxB.js";
2
+ import { A as UiText, B as spatialPan, C as suggestQuality, E as HudLayer, F as translationKey, G as WebAudioMusicBackend, H as SFX_PRESET_NAMES, I as SfxEngine, J as AudioBuses, K as crossfadeGains, L as isAudioContextAvailable, M as Localization, N as T_PREFIX, O as UiBanner, P as suggestLocale, R as ROLLOFF_MODELS, S as readDeviceHints, T as EffectLog, U as synthSfx, V as SFX_PRESETS, W as MusicManager, _ as Engine, a as UiMuteToggle, b as qualityEnvironment, c as UiRenderScaleSelect, d as UiToggle, f as UiVolumeSlider, g as AudioPlayer, h as UiDialogue, i as UiLanguageSelect, j as BASE_LOCALE, k as UiBar, l as UiSelect, m as UiButton, n as UiFrameCapSelect, o as UiPanel, p as Timer, q as fadeGain, r as UiImage, s as UiQualitySelect, t as registerCoreNodes, u as UiSlider, v as Settings, w as LogManager, z as spatialGain } from "./register-Ch70uByv.js";
3
3
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
4
  import { t as Rng } from "./rng-DP-SR7eg.js";
5
5
  import { n as jsonEquals, r as jsonKind, t as jsonClone } from "./json-BLk7H2Qa.js";
6
6
  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-C7u42TID.js";
7
- import { a as nodeRefWarnings, i as describeRefProblem, n as startRecording, o as resolveRefInJson, r as auditScene, t as replay } from "./replay-t1pP0gQg.js";
8
- import { n as logText, r as parseDrive, t as logReport } from "./log-report-CPFm4OXf.js";
7
+ import { a as nodeRefWarnings, i as describeRefProblem, n as startRecording, o as resolveRefInJson, r as auditScene, t as replay } from "./replay-s7I2GstT.js";
8
+ import { a as logReport, i as resolveRendering, n as attachTouchControls, o as logText, r as joystickVector, s as parseDrive, t as TouchControls } from "./touch-DESwnpOc.js";
9
9
  import { t as createNoise2D } from "./noise-CGUMx44x.js";
10
- 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-7qvUxF6Z.js";
11
- import { a as findPath, i as preloadUrls, n as newUid, o as gridFromRows, r as assetUrls, t as VERSION } from "./src-51GA-9m-.js";
12
- import { i as resolveRendering, n as attachTouchControls, r as joystickVector, t as TouchControls } from "./touch-BnMyy9tr.js";
13
- import { t as duplicateNode } from "./duplicate-MNLMAcbz.js";
14
- 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, 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, joystickVector, jsonClone, jsonEquals, jsonKind, loadScene, logReport, logText, mergeStaticSignals, newUid, nodeRefWarnings, parseDrive, parseNodePath, preloadUrls, qualityEnvironment, readDeviceHints, registerBehavior, registerCoreNodes, registerNode, registeredBehaviors, registeredTypes, replay, resolveAnimation, resolveConstants, resolveFrames, resolveOrderGroups, resolveRefInJson, resolveRendering, resolveViewport, restoreBehaviors, savesWithoutUid, serializeNode, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
10
+ 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-C0wXLBZJ.js";
11
+ import { a as preloadUrls, i as preloadSceneAssets, n as newUid, o as findPath, r as assetUrls, s as gridFromRows, t as VERSION } from "./src-CGjmPw65.js";
12
+ import { t as duplicateNode } from "./duplicate-BPLZDZpd.js";
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, 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, 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, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
@@ -1,4 +1,4 @@
1
- import { P as Scene, b as Engine } from "./behavior-CyQoSu4n.js";
1
+ import { P as Scene, b as Engine } from "./behavior-l08AEbq9.js";
2
2
  import { i as SceneJson } from "./schema-CFeioQRE.js";
3
3
 
4
4
  //#region src/core/scene/loader.d.ts