incanto 0.67.0 → 0.69.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 (87) hide show
  1. package/assets/catalog.json +9 -5
  2. package/bin/_pick-server.mjs +48 -0
  3. package/bin/incanto-assets.mjs +14 -1
  4. package/bin/incanto-check.mjs +69 -5
  5. package/bin/incanto-frame.mjs +10 -25
  6. package/bin/incanto-logs.mjs +8 -18
  7. package/bin/incanto-new.mjs +29 -1
  8. package/bin/incanto-serve.mjs +160 -0
  9. package/bin/incanto-verify.mjs +40 -0
  10. package/bin/incanto.mjs +1 -0
  11. package/dist/2d.d.ts +10 -8
  12. package/dist/2d.js +6 -4
  13. package/dist/3d.d.ts +31 -7
  14. package/dist/3d.js +9 -7
  15. package/dist/{audio-player-BNUHo0JF.d.ts → audio-player-C0j2k-yB.d.ts} +80 -3
  16. package/dist/{behavior-ZnfzKDo3.d.ts → behavior-rm8vVzu_.d.ts} +145 -1
  17. package/dist/boot-failure-CKYrEcGF.js +47 -0
  18. package/dist/{create-game-FAXdHta3.js → create-game-CvJ1wSRP.js} +27 -27
  19. package/dist/{create-game-DMetd3vR.js → create-game-CwxEDlCm.js} +15 -11
  20. package/dist/debug.d.ts +1 -1
  21. package/dist/{duplicate-B8QnX2-r.js → duplicate-Dj4L-5AA.js} +1 -1
  22. package/dist/{editor-switch-DAvWQeld.d.ts → editor-switch-CnIOiyNJ.d.ts} +1 -1
  23. package/dist/editor.js +12 -6
  24. package/dist/env.d.ts +1 -1
  25. package/dist/{environment-presets-C-5g2pMh.js → environment-presets-BO-7XoFV.js} +58 -9
  26. package/dist/{frame-report-DCnHFmto.d.ts → frame-report-DNxDAb1w.d.ts} +8 -0
  27. package/dist/{frame-report-BSMny7oe.js → frame-report-Dlq13Gyj.js} +1 -0
  28. package/dist/{gameplay-CGSv-9XR.js → gameplay-D1KixWK8.js} +175 -151
  29. package/dist/gameplay.d.ts +51 -3
  30. package/dist/gameplay.js +2 -2
  31. package/dist/index.d.ts +6 -6
  32. package/dist/index.js +8 -7
  33. package/dist/{loader-KZESOZmE.js → loader-DZE7B07H.js} +48 -7
  34. package/dist/{loader-DyT30ArB.d.ts → loader-DadV2QCT.d.ts} +2 -2
  35. package/dist/net.d.ts +2 -2
  36. package/dist/net.js +1 -1
  37. package/dist/{physics-2d-_B6zj3zU.js → physics-2d-CF5yyjbj.js} +2 -2
  38. package/dist/{physics-3d-i1IeAY0F.js → physics-3d-DbYaEcZy.js} +3 -3
  39. package/dist/react.d.ts +2 -2
  40. package/dist/react.js +1 -1
  41. package/dist/{register-vIxU3Xbv.js → register-DbVArsns.js} +19 -10
  42. package/dist/{register-Cs53CY7s.js → register-mmfugpaQ.js} +159 -6
  43. package/dist/{replay-BkpDV51O.js → replay-BEHLDcQV.js} +28 -5
  44. package/dist/{replay-D0GcEHYU.d.ts → replay-BQfkX4x7.d.ts} +38 -4
  45. package/dist/{schema-CFeioQRE.d.ts → schema-B6ugCV1Q.d.ts} +11 -0
  46. package/dist/{sheet-grid-BT6N_Bjs.js → sheet-grid-Cea343VO.js} +6 -2
  47. package/dist/{split-screen-DS8RaUV_.js → split-screen-CauMwu6y.js} +2 -2
  48. package/dist/{split-screen-DD5eYIgW.d.ts → split-screen-Cg76MCV5.d.ts} +3 -3
  49. package/dist/{src-BLlsGJW9.js → src-CYEu-_S9.js} +1 -1
  50. package/dist/{teardown-LB9cTnXJ.js → teardown-CMqFVxO9.js} +5 -4
  51. package/dist/{test-81uZ967a.js → test-D6ISmuFE.js} +73 -25
  52. package/dist/test.d.ts +17 -6
  53. package/dist/test.js +3 -3
  54. package/dist/vite.d.ts +70 -2
  55. package/dist/vite.js +176 -14
  56. package/dist/{rendering-options-ByAdi8PF.js → webgl-unavailable-Z5_g8x9H.js} +57 -2
  57. package/editor/assets/{agent8-C2jtNKbx.js → agent8-BDvaZMQJ.js} +1 -1
  58. package/editor/assets/{debug-DoU3KeqS.js → debug-CMULinBW.js} +1 -1
  59. package/editor/assets/{index-CNqHojcC.js → index-CZIRr5EL.js} +92 -92
  60. package/editor/index.html +1 -1
  61. package/package.json +4 -3
  62. package/schemas/scene.schema.json +4 -0
  63. package/skills/incanto-3d-character.md +1 -0
  64. package/skills/incanto-assets.md +16 -2
  65. package/skills/incanto-audio.md +65 -0
  66. package/skills/incanto-building-2d-games.md +66 -0
  67. package/skills/incanto-building-3d-games.md +97 -2
  68. package/skills/incanto-gameplay-behaviors.md +46 -2
  69. package/skills/incanto-node-reference.md +1 -0
  70. package/skills/incanto-physics-and-input.md +23 -0
  71. package/skills/incanto-save-slots.md +27 -0
  72. package/skills/incanto-scene-json-authoring.md +12 -1
  73. package/skills/incanto-verifying-your-game.md +96 -2
  74. package/skills/incanto-your-first-game.md +2 -1
  75. package/templates-app/beacon-isle-3d/package.json +1 -1
  76. package/templates-app/beacon-isle-3d/src/main.ts +21 -4
  77. package/templates-app/platformer-2d/index.html +0 -23
  78. package/templates-app/platformer-2d/package.json +1 -1
  79. package/templates-app/platformer-2d/src/behaviors.ts +26 -16
  80. package/templates-app/platformer-2d/src/game.scene.json +17 -27
  81. package/templates-app/platformer-2d/src/main.ts +32 -13
  82. package/templates-app/star-survivor/package.json +1 -1
  83. package/templates-app/star-survivor/src/main.ts +25 -7
  84. package/templates-app/tps-3d/package.json +1 -1
  85. package/templates-app/tps-3d/src/main.ts +34 -16
  86. package/templates-app/village-quest-3d/package.json +1 -1
  87. package/templates-app/village-quest-3d/src/main.ts +21 -4
@@ -1,7 +1,7 @@
1
- import { O as Node, P as Behavior, _ as SaveSlots, k as diagnose, n as loadScene, w as effectiveOrder, z as registerBehavior } from "./loader-KZESOZmE.js";
1
+ import { O as Node, P as Behavior, _ as SaveSlots, k as diagnose, n as loadScene, w as effectiveOrder, z as registerBehavior } from "./loader-DZE7B07H.js";
2
2
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
3
3
  import { t as jsonClone } from "./json-CwwhxQgb.js";
4
- import { t as duplicateNode } from "./duplicate-B8QnX2-r.js";
4
+ import { t as duplicateNode } from "./duplicate-Dj4L-5AA.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();
@@ -4255,6 +4255,143 @@ const cutoutMaskMaterial = new ShaderMaterial({
4255
4255
  side: DoubleSide
4256
4256
  });
4257
4257
  //#endregion
4258
+ //#region src/gameplay/spatial.ts
4259
+ /** Duck-type test: every spatial node (Node2D/Node3D) exposes `position: number[]`. */
4260
+ function hasPosition$1(node) {
4261
+ return Array.isArray(node.position);
4262
+ }
4263
+ /**
4264
+ * Movement behaviors are dimension-agnostic — they read/write `this.node.position`
4265
+ * directly. Attaching one to a non-spatial node (no `position` array) would be a
4266
+ * silent no-op, so assert it at ready (engine philosophy: hard load-time errors).
4267
+ */
4268
+ function requirePosition(behavior) {
4269
+ const node = behavior.node;
4270
+ if (!hasPosition$1(node)) {
4271
+ const behaviorName = behavior.constructor.name;
4272
+ throw new IncantoError("PROP_TYPE_MISMATCH", `${behaviorName} on '${node.getPath()}' needs a spatial node with a numeric 'position' array (a Node2D/Node3D subtype). '${node.name}' has none.`, { path: node.getPath() });
4273
+ }
4274
+ return node;
4275
+ }
4276
+ /** Euclidean distance between two position arrays (works for 2D and 3D). */
4277
+ function distance$1(a, b) {
4278
+ let sum = 0;
4279
+ const n = Math.max(a.length, b.length);
4280
+ for (let i = 0; i < n; i++) {
4281
+ const d = (a[i] ?? 0) - (b[i] ?? 0);
4282
+ sum += d * d;
4283
+ }
4284
+ return Math.sqrt(sum);
4285
+ }
4286
+ /** Component-wise `a + b` (dimension = max of the two; missing components are 0). */
4287
+ function add(a, b) {
4288
+ const n = Math.max(a.length, b.length);
4289
+ const out = new Array(n);
4290
+ for (let i = 0; i < n; i++) out[i] = (a[i] ?? 0) + (b[i] ?? 0);
4291
+ return out;
4292
+ }
4293
+ /** Vector length. */
4294
+ function length(v) {
4295
+ let sum = 0;
4296
+ for (const c of v) sum += c * c;
4297
+ return Math.sqrt(sum);
4298
+ }
4299
+ /** Unit vector (zero-length stays zero). */
4300
+ function normalize(v) {
4301
+ const len = length(v);
4302
+ if (len === 0) return v.map(() => 0);
4303
+ return v.map((c) => c / len);
4304
+ }
4305
+ /**
4306
+ * Step `from` toward `to` by at most `maxStep`. Returns the new position and
4307
+ * whether the destination was reached this step (clamped — no overshoot).
4308
+ */
4309
+ function moveToward(from, to, maxStep) {
4310
+ const n = Math.max(from.length, to.length);
4311
+ let sum = 0;
4312
+ for (let i = 0; i < n; i++) {
4313
+ const d = (to[i] ?? 0) - (from[i] ?? 0);
4314
+ sum += d * d;
4315
+ }
4316
+ const dist = Math.sqrt(sum);
4317
+ const position = new Array(n);
4318
+ if (dist <= maxStep || dist === 0) {
4319
+ for (let i = 0; i < n; i++) position[i] = to[i] ?? 0;
4320
+ return {
4321
+ position,
4322
+ reached: true
4323
+ };
4324
+ }
4325
+ const f = maxStep / dist;
4326
+ for (let i = 0; i < n; i++) {
4327
+ const c = from[i] ?? 0;
4328
+ position[i] = c + ((to[i] ?? 0) - c) * f;
4329
+ }
4330
+ return {
4331
+ position,
4332
+ reached: false
4333
+ };
4334
+ }
4335
+ /**
4336
+ * Frame-rate-independent lerp factor for an exponential chase. `smoothing` is a
4337
+ * 0..1 retention factor: 0 snaps instantly; higher values chase more slowly.
4338
+ * (60fps reference, matching Camera2D's `follow`.)
4339
+ */
4340
+ function smoothingFactor(smoothing, dt) {
4341
+ const s = Math.min(Math.max(smoothing, 0), .99);
4342
+ return s <= 0 ? 1 : 1 - s ** (dt * 60);
4343
+ }
4344
+ /**
4345
+ * A node's position with every spatial ancestor's added in.
4346
+ *
4347
+ * The tree composes transforms for DRAWING — three does it for free — and every
4348
+ * piece of engine logic that reads `node.position` gets the LOCAL number
4349
+ * instead. Physics already knew (`worldPosition2D`/`worldPosition3D` in the
4350
+ * adapters); the camera did not, and neither did anything that chases a target.
4351
+ *
4352
+ * A camera parented to the player is the Godot and Phaser idiom, and the
4353
+ * authoring skill explicitly permits it — *"EVERY node type can hold children …
4354
+ * any node works as a grouping container"*. Measured on exactly that scene:
4355
+ *
4356
+ * ```
4357
+ * player world position : [1400, 900]
4358
+ * renderer view centre : {"x":0,"y":0}
4359
+ * framing : camera /Level/Player/Cam centred [1400, 900]
4360
+ * 1 in view, 0 outside it
4361
+ * ```
4362
+ *
4363
+ * The renderer drew empty world 1600 px from the player while `framing` — the
4364
+ * instrument the skills tell you to trust before handing a game back —
4365
+ * certified the player on screen.
4366
+ *
4367
+ * Arity comes from the node itself: a 2D node has two components, a 3D node
4368
+ * three, and an ancestor that is neither contributes nothing.
4369
+ */
4370
+ function worldPosition(node) {
4371
+ const own = node.position;
4372
+ if (!Array.isArray(own)) return [];
4373
+ const out = own.slice();
4374
+ for (let at = node.parent; at; at = at.parent) {
4375
+ const p = at.position;
4376
+ if (!Array.isArray(p)) continue;
4377
+ for (let i = 0; i < out.length; i++) out[i] = (out[i] ?? 0) + (p[i] ?? 0);
4378
+ }
4379
+ return out;
4380
+ }
4381
+ /**
4382
+ * Turn a world position into the local one `node.position` has to hold for the
4383
+ * node to END UP there — the inverse of `worldPosition` for its parent chain.
4384
+ */
4385
+ function localFromWorld(node, world) {
4386
+ const out = world.slice();
4387
+ for (let at = node.parent; at; at = at.parent) {
4388
+ const p = at.position;
4389
+ if (!Array.isArray(p)) continue;
4390
+ for (let i = 0; i < out.length; i++) out[i] = (out[i] ?? 0) - (p[i] ?? 0);
4391
+ }
4392
+ return out;
4393
+ }
4394
+ //#endregion
4258
4395
  //#region src/gameplay/buoyancy.ts
4259
4396
  /** Gravity the float is sized against (m/s²) — the cap is expressed in g. */
4260
4397
  const G = 9.81;
@@ -4333,11 +4470,14 @@ var Buoyancy = class extends Behavior {
4333
4470
  }
4334
4471
  return;
4335
4472
  }
4336
- const [x, y, z] = [
4337
- node.position[0] ?? 0,
4338
- node.position[1] ?? 0,
4339
- node.position[2] ?? 0
4340
- ];
4473
+ const [x, y, z] = (() => {
4474
+ const w = worldPosition(node);
4475
+ return [
4476
+ w[0] ?? 0,
4477
+ w[1] ?? 0,
4478
+ w[2] ?? 0
4479
+ ];
4480
+ })();
4341
4481
  const half = [(this.size[0] ?? 1) / 2, (this.size[1] ?? 1) / 2];
4342
4482
  const points = this.samplePoints(x, z, half[0], half[1]);
4343
4483
  const mass = node.mass ?? 1;
@@ -4480,143 +4620,6 @@ function moveBody(node, to, dt) {
4480
4620
  body.moveAndSlide();
4481
4621
  }
4482
4622
  //#endregion
4483
- //#region src/gameplay/spatial.ts
4484
- /** Duck-type test: every spatial node (Node2D/Node3D) exposes `position: number[]`. */
4485
- function hasPosition$1(node) {
4486
- return Array.isArray(node.position);
4487
- }
4488
- /**
4489
- * Movement behaviors are dimension-agnostic — they read/write `this.node.position`
4490
- * directly. Attaching one to a non-spatial node (no `position` array) would be a
4491
- * silent no-op, so assert it at ready (engine philosophy: hard load-time errors).
4492
- */
4493
- function requirePosition(behavior) {
4494
- const node = behavior.node;
4495
- if (!hasPosition$1(node)) {
4496
- const behaviorName = behavior.constructor.name;
4497
- throw new IncantoError("PROP_TYPE_MISMATCH", `${behaviorName} on '${node.getPath()}' needs a spatial node with a numeric 'position' array (a Node2D/Node3D subtype). '${node.name}' has none.`, { path: node.getPath() });
4498
- }
4499
- return node;
4500
- }
4501
- /** Euclidean distance between two position arrays (works for 2D and 3D). */
4502
- function distance$1(a, b) {
4503
- let sum = 0;
4504
- const n = Math.max(a.length, b.length);
4505
- for (let i = 0; i < n; i++) {
4506
- const d = (a[i] ?? 0) - (b[i] ?? 0);
4507
- sum += d * d;
4508
- }
4509
- return Math.sqrt(sum);
4510
- }
4511
- /** Component-wise `a + b` (dimension = max of the two; missing components are 0). */
4512
- function add(a, b) {
4513
- const n = Math.max(a.length, b.length);
4514
- const out = new Array(n);
4515
- for (let i = 0; i < n; i++) out[i] = (a[i] ?? 0) + (b[i] ?? 0);
4516
- return out;
4517
- }
4518
- /** Vector length. */
4519
- function length(v) {
4520
- let sum = 0;
4521
- for (const c of v) sum += c * c;
4522
- return Math.sqrt(sum);
4523
- }
4524
- /** Unit vector (zero-length stays zero). */
4525
- function normalize(v) {
4526
- const len = length(v);
4527
- if (len === 0) return v.map(() => 0);
4528
- return v.map((c) => c / len);
4529
- }
4530
- /**
4531
- * Step `from` toward `to` by at most `maxStep`. Returns the new position and
4532
- * whether the destination was reached this step (clamped — no overshoot).
4533
- */
4534
- function moveToward(from, to, maxStep) {
4535
- const n = Math.max(from.length, to.length);
4536
- let sum = 0;
4537
- for (let i = 0; i < n; i++) {
4538
- const d = (to[i] ?? 0) - (from[i] ?? 0);
4539
- sum += d * d;
4540
- }
4541
- const dist = Math.sqrt(sum);
4542
- const position = new Array(n);
4543
- if (dist <= maxStep || dist === 0) {
4544
- for (let i = 0; i < n; i++) position[i] = to[i] ?? 0;
4545
- return {
4546
- position,
4547
- reached: true
4548
- };
4549
- }
4550
- const f = maxStep / dist;
4551
- for (let i = 0; i < n; i++) {
4552
- const c = from[i] ?? 0;
4553
- position[i] = c + ((to[i] ?? 0) - c) * f;
4554
- }
4555
- return {
4556
- position,
4557
- reached: false
4558
- };
4559
- }
4560
- /**
4561
- * Frame-rate-independent lerp factor for an exponential chase. `smoothing` is a
4562
- * 0..1 retention factor: 0 snaps instantly; higher values chase more slowly.
4563
- * (60fps reference, matching Camera2D's `follow`.)
4564
- */
4565
- function smoothingFactor(smoothing, dt) {
4566
- const s = Math.min(Math.max(smoothing, 0), .99);
4567
- return s <= 0 ? 1 : 1 - s ** (dt * 60);
4568
- }
4569
- /**
4570
- * A node's position with every spatial ancestor's added in.
4571
- *
4572
- * The tree composes transforms for DRAWING — three does it for free — and every
4573
- * piece of engine logic that reads `node.position` gets the LOCAL number
4574
- * instead. Physics already knew (`worldPosition2D`/`worldPosition3D` in the
4575
- * adapters); the camera did not, and neither did anything that chases a target.
4576
- *
4577
- * A camera parented to the player is the Godot and Phaser idiom, and the
4578
- * authoring skill explicitly permits it — *"EVERY node type can hold children …
4579
- * any node works as a grouping container"*. Measured on exactly that scene:
4580
- *
4581
- * ```
4582
- * player world position : [1400, 900]
4583
- * renderer view centre : {"x":0,"y":0}
4584
- * framing : camera /Level/Player/Cam centred [1400, 900]
4585
- * 1 in view, 0 outside it
4586
- * ```
4587
- *
4588
- * The renderer drew empty world 1600 px from the player while `framing` — the
4589
- * instrument the skills tell you to trust before handing a game back —
4590
- * certified the player on screen.
4591
- *
4592
- * Arity comes from the node itself: a 2D node has two components, a 3D node
4593
- * three, and an ancestor that is neither contributes nothing.
4594
- */
4595
- function worldPosition(node) {
4596
- const own = node.position;
4597
- if (!Array.isArray(own)) return [];
4598
- const out = own.slice();
4599
- for (let at = node.parent; at; at = at.parent) {
4600
- const p = at.position;
4601
- if (!Array.isArray(p)) continue;
4602
- for (let i = 0; i < out.length; i++) out[i] = (out[i] ?? 0) + (p[i] ?? 0);
4603
- }
4604
- return out;
4605
- }
4606
- /**
4607
- * Turn a world position into the local one `node.position` has to hold for the
4608
- * node to END UP there — the inverse of `worldPosition` for its parent chain.
4609
- */
4610
- function localFromWorld(node, world) {
4611
- const out = world.slice();
4612
- for (let at = node.parent; at; at = at.parent) {
4613
- const p = at.position;
4614
- if (!Array.isArray(p)) continue;
4615
- for (let i = 0; i < out.length; i++) out[i] = (out[i] ?? 0) - (p[i] ?? 0);
4616
- }
4617
- return out;
4618
- }
4619
- //#endregion
4620
4623
  //#region src/gameplay/chase.ts
4621
4624
  /**
4622
4625
  * Home in on a target node — the workhorse enemy AI. Each frame moves toward
@@ -4678,7 +4681,8 @@ var Chase = class extends Behavior {
4678
4681
  if (!mover || !hasPosition$1(mover)) return;
4679
4682
  const target = this.node.getNodeOrNull(this.target);
4680
4683
  if (!target || !hasPosition$1(target)) return;
4681
- const d = distance$1(mover.position, target.position);
4684
+ const targetPos = localFromWorld(mover, worldPosition(target));
4685
+ const d = distance$1(mover.position, targetPos);
4682
4686
  if (this.loseRange > 0 && d > this.loseRange) {
4683
4687
  if (!this.lost) {
4684
4688
  this.lost = true;
@@ -4698,7 +4702,7 @@ var Chase = class extends Behavior {
4698
4702
  this.inRange = false;
4699
4703
  const step = Math.min(this.speed * dt, this.stopRange > 0 ? d - this.stopRange : d);
4700
4704
  const from = [...mover.position];
4701
- const { position } = moveToward(mover.position, target.position, Math.max(0, step));
4705
+ const { position } = moveToward(mover.position, targetPos, Math.max(0, step));
4702
4706
  moveBody(mover, position, dt);
4703
4707
  if (this.facePath !== "") {
4704
4708
  const skin = this.node.getNodeOrNull(this.facePath);
@@ -5614,7 +5618,8 @@ function tolerateUnknownAction(ctx, action, read, fallback) {
5614
5618
  function restartScene(engine) {
5615
5619
  const source = engine.scene?.source;
5616
5620
  if (!source) return;
5617
- engine.setScene(loadScene(jsonClone(source)));
5621
+ engine.setScene(loadScene(jsonClone(source), { engine }));
5622
+ engine.ensurePhysics();
5618
5623
  }
5619
5624
  /**
5620
5625
  * Swap to another scene behind a black fade (title→game→next level).
@@ -5623,7 +5628,8 @@ function restartScene(engine) {
5623
5628
  function goToScene(engine, sceneJson, opts) {
5624
5629
  const fade = opts?.fadeSeconds ?? .4;
5625
5630
  const swap = () => {
5626
- engine.setScene(loadScene(jsonClone(sceneJson)));
5631
+ engine.setScene(loadScene(jsonClone(sceneJson), { engine }));
5632
+ engine.ensurePhysics();
5627
5633
  };
5628
5634
  if (typeof document === "undefined" || fade <= 0) {
5629
5635
  swap();
@@ -5831,13 +5837,13 @@ var Interactable = class extends Behavior {
5831
5837
  if (!engine?.scene) return;
5832
5838
  if (!engine.input.justPressed(this.action)) return;
5833
5839
  if (!hasPosition(this.node)) return;
5834
- const self = this.node.position;
5840
+ const self = worldPosition(this.node);
5835
5841
  let nearest = null;
5836
5842
  let nearestDist = Number.POSITIVE_INFINITY;
5837
5843
  const actors = this.node.tree?.getNodesInGroup(this.actorGroup) ?? collectGroup(this.node.getRoot(), this.actorGroup);
5838
5844
  for (const actor of actors) {
5839
5845
  if (!hasPosition(actor)) continue;
5840
- const d = distance(self, actor.position);
5846
+ const d = distance(self, worldPosition(actor));
5841
5847
  if (d <= this.range && d < nearestDist) {
5842
5848
  nearest = actor;
5843
5849
  nearestDist = d;
@@ -6675,6 +6681,20 @@ var SavePoint = class extends Behavior {
6675
6681
  this.slots ??= new SaveSlots(this.game);
6676
6682
  return this.slots;
6677
6683
  }
6684
+ /**
6685
+ * Has this run already said the saves are going nowhere?
6686
+ *
6687
+ * `saved(slot)` is the engine's own instrument for "it saved", and it fired
6688
+ * identically in a private window where the write landed in a Map that dies
6689
+ * with the tab. In-session everything looked healthy — the slot read back,
6690
+ * `slotScene()` answered — and across the reload the score went 5 to 0 and
6691
+ * `list()` went `["1"]` to `[]`, with `engine.log.entries().length = 0` and
6692
+ * `stats().errors = 0` in every phase. Byte-identical to a healthy control.
6693
+ *
6694
+ * So it goes through `engine.log`, not just the console: that is what
6695
+ * `incanto-logs` reads and what the `says` rung reports.
6696
+ */
6697
+ warnedVolatile = false;
6678
6698
  pendingRestore = false;
6679
6699
  pendingProbe = false;
6680
6700
  onReady() {
@@ -6734,6 +6754,10 @@ var SavePoint = class extends Behavior {
6734
6754
  savedAt: Date.now(),
6735
6755
  playtime: Math.round(this.elapsed)
6736
6756
  });
6757
+ if (!this.store().persistent && !this.warnedVolatile) {
6758
+ this.warnedVolatile = true;
6759
+ engine.log.warn(`SavePoint wrote slot '${this.slot}' to memory, not to disk — this browser refused localStorage (private window, storage disabled, or quota exhausted), so the run is lost when the page closes. \`SaveSlots.persistent\` is how a game asks before promising the player anything.`);
6760
+ }
6737
6761
  this.emit("saved", this.slot);
6738
6762
  }
6739
6763
  /**
@@ -7294,7 +7318,7 @@ var ZombieAI = class extends Behavior {
7294
7318
  this.pickGoal();
7295
7319
  }
7296
7320
  const target = this.aggroTarget ? this.node.getNodeOrNull(this.aggroTarget) : null;
7297
- const targetPos = target && hasPosition$1(target) ? target.position : null;
7321
+ const targetPos = target && hasPosition$1(target) ? localFromWorld(mover, worldPosition(target)) : null;
7298
7322
  const aggroDist = targetPos ? this.groundDistance(mover.position, targetPos) : Number.POSITIVE_INFINITY;
7299
7323
  if (!this.aggro && aggroDist <= this.aggroRange) {
7300
7324
  this.aggro = true;
@@ -1,5 +1,5 @@
1
- import { b as Engine, d as PropSchema, jt as Node, n as BehaviorCtor, t as Behavior } from "./behavior-ZnfzKDo3.js";
2
- import { c as JsonValue, s as JsonObject } from "./schema-CFeioQRE.js";
1
+ import { b as Engine, d as PropSchema, jt as Node, n as BehaviorCtor, t as Behavior } from "./behavior-rm8vVzu_.js";
2
+ import { c as JsonValue, s as JsonObject } from "./schema-B6ugCV1Q.js";
3
3
 
4
4
  //#region src/gameplay/chase.d.ts
5
5
  /**
@@ -558,6 +558,20 @@ declare class SavePoint extends Behavior {
558
558
  private elapsed;
559
559
  private slots;
560
560
  private store;
561
+ /**
562
+ * Has this run already said the saves are going nowhere?
563
+ *
564
+ * `saved(slot)` is the engine's own instrument for "it saved", and it fired
565
+ * identically in a private window where the write landed in a Map that dies
566
+ * with the tab. In-session everything looked healthy — the slot read back,
567
+ * `slotScene()` answered — and across the reload the score went 5 to 0 and
568
+ * `list()` went `["1"]` to `[]`, with `engine.log.entries().length = 0` and
569
+ * `stats().errors = 0` in every phase. Byte-identical to a healthy control.
570
+ *
571
+ * So it goes through `engine.log`, not just the console: that is what
572
+ * `incanto-logs` reads and what the `says` rung reports.
573
+ */
574
+ private warnedVolatile;
561
575
  private pendingRestore;
562
576
  private pendingProbe;
563
577
  override onReady(): void;
@@ -1071,6 +1085,40 @@ declare class PathFollow extends Behavior {
1071
1085
  override update(dt: number): void;
1072
1086
  }
1073
1087
  //#endregion
1088
+ //#region src/gameplay/spatial.d.ts
1089
+ /**
1090
+ * A node's position with every spatial ancestor's added in.
1091
+ *
1092
+ * The tree composes transforms for DRAWING — three does it for free — and every
1093
+ * piece of engine logic that reads `node.position` gets the LOCAL number
1094
+ * instead. Physics already knew (`worldPosition2D`/`worldPosition3D` in the
1095
+ * adapters); the camera did not, and neither did anything that chases a target.
1096
+ *
1097
+ * A camera parented to the player is the Godot and Phaser idiom, and the
1098
+ * authoring skill explicitly permits it — *"EVERY node type can hold children …
1099
+ * any node works as a grouping container"*. Measured on exactly that scene:
1100
+ *
1101
+ * ```
1102
+ * player world position : [1400, 900]
1103
+ * renderer view centre : {"x":0,"y":0}
1104
+ * framing : camera /Level/Player/Cam centred [1400, 900]
1105
+ * 1 in view, 0 outside it
1106
+ * ```
1107
+ *
1108
+ * The renderer drew empty world 1600 px from the player while `framing` — the
1109
+ * instrument the skills tell you to trust before handing a game back —
1110
+ * certified the player on screen.
1111
+ *
1112
+ * Arity comes from the node itself: a 2D node has two components, a 3D node
1113
+ * three, and an ancestor that is neither contributes nothing.
1114
+ */
1115
+ declare function worldPosition(node: Node): number[];
1116
+ /**
1117
+ * Turn a world position into the local one `node.position` has to hold for the
1118
+ * node to END UP there — the inverse of `worldPosition` for its parent chain.
1119
+ */
1120
+ declare function localFromWorld(node: Node, world: readonly number[]): number[];
1121
+ //#endregion
1074
1122
  //#region src/gameplay/index.d.ts
1075
1123
  /** Every built-in gameplay behavior, keyed by its registration name. */
1076
1124
  declare const GAMEPLAY_BEHAVIORS: Readonly<Record<string, BehaviorCtor>>;
@@ -1083,4 +1131,4 @@ declare function registerGameplayBehaviors(opts?: {
1083
1131
  replace?: boolean;
1084
1132
  }): void;
1085
1133
  //#endregion
1086
- export { CameraShake, Chase, Collector, Cooldown, Currency, DamageOnContact, DayNight, type DayPhase, FaceTarget, FloatAway, FollowCamera, GAMEPLAY_BEHAVIORS, GameFlow, type GameFlowState, Health, Interactable, Lifetime, MoveTo, Oscillate, PathFollow, Patrol, Pickup, Projectile, SavePoint, ScoreKeeper, Spawner, Wander, WaveSpawner, ZombieAI, goToScene, hitStop, phaseOf, registerGameplayBehaviors, restartScene, screenFlash };
1134
+ export { CameraShake, Chase, Collector, Cooldown, Currency, DamageOnContact, DayNight, type DayPhase, FaceTarget, FloatAway, FollowCamera, GAMEPLAY_BEHAVIORS, GameFlow, type GameFlowState, Health, Interactable, Lifetime, MoveTo, Oscillate, PathFollow, Patrol, Pickup, Projectile, SavePoint, ScoreKeeper, Spawner, Wander, WaveSpawner, ZombieAI, goToScene, hitStop, localFromWorld, phaseOf, registerGameplayBehaviors, restartScene, screenFlash, worldPosition };
package/dist/gameplay.js CHANGED
@@ -1,2 +1,2 @@
1
- import { A as DamageOnContact, C as restartScene, D as FaceTarget, E as FloatAway, M as Currency, N as Collector, O as DayNight, P as Chase, 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 Health, k as phaseOf, 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-CGSv-9XR.js";
2
- export { CameraShake, Chase, Collector, Cooldown, Currency, DamageOnContact, DayNight, FaceTarget, 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 };
1
+ import { A as DamageOnContact, C as restartScene, D as FaceTarget, E as FloatAway, F as localFromWorld, I as worldPosition, M as Currency, N as Collector, O as DayNight, P as Chase, 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 Health, k as phaseOf, 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-D1KixWK8.js";
2
+ export { CameraShake, Chase, Collector, Cooldown, Currency, DamageOnContact, DayNight, FaceTarget, FloatAway, FollowCamera, GAMEPLAY_BEHAVIORS, GameFlow, Health, Interactable, Lifetime, MoveTo, Oscillate, PathFollow, Patrol, Pickup, 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 { $ 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-ZnfzKDo3.js";
2
- import { a as Rng, c as JsonValue, d as jsonKind, i as SceneJson, l as jsonClone, n as NodeJson, o as JsonKind, r as SCENE_FORMAT, s as JsonObject, t as ConnectionJson, u as jsonEquals } from "./schema-CFeioQRE.js";
3
- import { n as loadScene, t as LoadSceneOptions } from "./loader-DyT30ArB.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-C0j2k-yB.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-rm8vVzu_.js";
3
+ 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-B6ugCV1Q.js";
4
+ import { n as loadScene, t as LoadSceneOptions } from "./loader-DadV2QCT.js";
4
5
  import { i as resolveFrames, n as AnimationEntry, r as resolveAnimation, t as AnimationDef } from "./sprite-animation-CMr6f1K2.js";
5
- import { a as ParticleSimConfig, i as ParticleSim, n as AudioPlayer, o as ParticleView, t as AudioElementLike } from "./audio-player-BNUHo0JF.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-D0GcEHYU.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-BQfkX4x7.js";
8
8
 
9
9
  //#region src/core/audio/crossfade.d.ts
10
10
  /**
@@ -1309,4 +1309,4 @@ declare function computeViewport(canvasW: number, canvasH: number, viewport: {
1309
1309
  /** Engine version. Kept in sync with package.json by the release pipeline. */
1310
1310
  declare const VERSION: string;
1311
1311
  //#endregion
1312
- 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, Respawn, 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, sfxDuration, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
1312
+ 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, Respawn, 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, 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 };
package/dist/index.js CHANGED
@@ -1,14 +1,15 @@
1
- import { A as describeRefProblem, B as registeredBehaviors, C as ORDER_GROUP_BASE, E as InputMap, F as behaviorSchema, I as behaviorSignals, L as clearBehaviors, M as resolveRefInJson, N as parseNodePath, O as Node, P as Behavior, R as getBehavior, S as createSaveStore, T as resolveOrderGroups, V as Signal, _ as SaveSlots, a as serializeNode, b as restoreBehaviors, d as computeViewport, f as resolveViewport, g as resolveConstants, h as isConstRef, i as Scene, j as nodeRefWarnings, m as CONST_REF_KEY, n as loadScene, o as SCENE_FORMAT, p as SceneTree, v as behaviorsWithoutSave, w as effectiveOrder, x as savesWithoutUid, y as captureBehaviors, z as registerBehavior } from "./loader-KZESOZmE.js";
2
- import { A as UiBanner, B as isAudioContextAvailable, D as EffectLog, E as LogManager, F as T_PREFIX, G as SFX_PRESET_NAMES, H as spatialGain, I as suggestLocale, J as MusicManager, K as sfxDuration, M as UiText, N as BASE_LOCALE, O as HudLayer, P as Localization, Q as AudioBuses, R as translationKey, S as qualityEnvironment, T as suggestQuality, U as spatialPan, V as ROLLOFF_MODELS, W as SFX_PRESETS, X as crossfadeGains, Y as WebAudioMusicBackend, Z as fadeGain, _ 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 UiBar, l as UiSelect, m as Respawn, n as UiFrameCapSelect, o as UiPanel, p as Timer, q as synthSfx, r as UiImage, s as UiQualitySelect, t as registerCoreNodes, u as UiSlider, v as Engine, w as readDeviceHints, z as SfxEngine } from "./register-Cs53CY7s.js";
1
+ import { A as describeRefProblem, B as registeredBehaviors, C as ORDER_GROUP_BASE, E as InputMap, F as behaviorSchema, I as behaviorSignals, L as clearBehaviors, M as resolveRefInJson, N as parseNodePath, O as Node, P as Behavior, R as getBehavior, S as createSaveStore, T as resolveOrderGroups, V as Signal, _ as SaveSlots, a as serializeNode, b as restoreBehaviors, d as computeViewport, f as resolveViewport, g as resolveConstants, h as isConstRef, i as Scene, j as nodeRefWarnings, m as CONST_REF_KEY, n as loadScene, o as SCENE_FORMAT, p as SceneTree, v as behaviorsWithoutSave, w as effectiveOrder, x as savesWithoutUid, y as captureBehaviors, z as registerBehavior } from "./loader-DZE7B07H.js";
2
+ import { A as UiBanner, B as isAudioContextAvailable, D as EffectLog, E as LogManager, F as T_PREFIX, G as SFX_PRESET_NAMES, H as spatialGain, I as suggestLocale, J as MusicManager, K as sfxDuration, M as UiText, N as BASE_LOCALE, O as HudLayer, P as Localization, Q as AudioBuses, R as translationKey, S as qualityEnvironment, T as suggestQuality, U as spatialPan, V as ROLLOFF_MODELS, W as SFX_PRESETS, X as crossfadeGains, Y as WebAudioMusicBackend, Z as fadeGain, _ 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 UiBar, l as UiSelect, m as Respawn, n as UiFrameCapSelect, o as UiPanel, p as Timer, q as synthSfx, r as UiImage, s as UiQualitySelect, t as registerCoreNodes, u as UiSlider, v as Engine, w as readDeviceHints, z as SfxEngine } from "./register-mmfugpaQ.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-CwwhxQgb.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-CF70EArN.js";
7
7
  import { i as joystickVector, n as attachTouchControls, t as TouchControls } from "./touch-DEAmqGdf.js";
8
- import { n as startRecording, r as auditScene, t as replay } from "./replay-BkpDV51O.js";
9
- import { i as parseDrive, n as logReport, r as logText, t as resolveRendering } from "./rendering-options-ByAdi8PF.js";
8
+ import { n as startRecording, r as auditScene, t as replay } from "./replay-BEHLDcQV.js";
9
+ import { t as showBootFailure } from "./boot-failure-CKYrEcGF.js";
10
+ import { a as logText, i as logReport, o as parseDrive, r as resolveRendering, t as isWebGLAvailable } from "./webgl-unavailable-Z5_g8x9H.js";
10
11
  import { t as createNoise2D } from "./noise-CGUMx44x.js";
11
12
  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-CY-mrr1L.js";
12
- import { a as preloadUrls, i as preloadSceneAssets, n as newUid, o as findPath, r as assetUrls, s as gridFromRows, t as VERSION } from "./src-BLlsGJW9.js";
13
- import { t as duplicateNode } from "./duplicate-B8QnX2-r.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, 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, 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, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
13
+ import { a as preloadUrls, i as preloadSceneAssets, n as newUid, o as findPath, r as assetUrls, s as gridFromRows, t as VERSION } from "./src-CYEu-_S9.js";
14
+ import { t as duplicateNode } from "./duplicate-Dj4L-5AA.js";
15
+ 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 };