incanto 0.70.0 → 0.71.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 (67) hide show
  1. package/bin/incanto-verify.mjs +36 -98
  2. package/dist/2d.d.ts +18 -3
  3. package/dist/2d.js +3 -3
  4. package/dist/3d.d.ts +3 -3
  5. package/dist/3d.js +6 -6
  6. package/dist/{agent8-CmNF01gA.js → agent8-Cfmd3ar_.js} +1 -1
  7. package/dist/{audio-player-DaMxqfNE.d.ts → audio-player-L8yccdMP.d.ts} +1 -1
  8. package/dist/{behavior-DZExDn9o.d.ts → behavior-Dcz0fr1S.d.ts} +11 -0
  9. package/dist/{create-game-Bwvh6q8A.js → create-game-CH4kt78v.js} +7 -7
  10. package/dist/{create-game-C7ffQWW7.js → create-game-LCHBLfA4.js} +7 -7
  11. package/dist/debug.d.ts +1 -1
  12. package/dist/editor.js +29 -25
  13. package/dist/{environment-presets-D6Q5BxeE.js → environment-presets-99BzP_L-.js} +3 -3
  14. package/dist/{frame-report-Dlq13Gyj.js → frame-report-D-_7YF2G.js} +1 -1
  15. package/dist/{gameplay-BfHkuzVb.js → gameplay-CNULJvwh.js} +108 -6
  16. package/dist/gameplay.d.ts +68 -4
  17. package/dist/gameplay.js +2 -2
  18. package/dist/index.d.ts +27 -4
  19. package/dist/index.js +4 -4
  20. package/dist/{loader-Cff09LMm.d.ts → loader-8-IHvbKD.d.ts} +1 -1
  21. package/dist/net.d.ts +2 -2
  22. package/dist/net.js +2 -2
  23. package/dist/{physics-2d-CE0Qvy3V.js → physics-2d-FhrXUc6B.js} +2 -2
  24. package/dist/{physics-3d-CpH-2gn5.js → physics-3d-CFEGxBXZ.js} +3 -3
  25. package/dist/{picking-CQJ_PJKh.js → picking-DVo7fI13.js} +3 -3
  26. package/dist/react.d.ts +1 -1
  27. package/dist/react.js +1 -1
  28. package/dist/{register-Bkk0wSDB.js → register-BYQCBySi.js} +100 -8
  29. package/dist/{register-6DYnKZcy.js → register-DuVdzxbq.js} +49 -15
  30. package/dist/{replay-DjAkAzMq.js → replay-DEvp3kyV.js} +2 -2
  31. package/dist/{replay-Dmw-PKQu.d.ts → replay-F7IZHdFR.d.ts} +1 -1
  32. package/dist/{save-slots-BXVg148r.js → save-slots-Bvuh2p_r.js} +56 -3
  33. package/dist/{split-screen--k-XpBjr.d.ts → split-screen-CIYf1zSf.d.ts} +2 -2
  34. package/dist/{split-screen-PL78oVXP.js → split-screen-eULetcg-.js} +3 -3
  35. package/dist/{src-Cxfiv1Hg.js → src-_jk0qLsS.js} +1 -1
  36. package/dist/{test-iHYVUcDK.js → test-CmN54kWv.js} +252 -24
  37. package/dist/test.d.ts +113 -5
  38. package/dist/test.js +3 -3
  39. package/dist/vite.js +3 -3
  40. package/editor/assets/{agent8-D0MS174y.js → agent8-yLIEYHbd.js} +1 -1
  41. package/editor/assets/{debug-BnXkKuYu.js → debug-u31w_yhq.js} +1 -1
  42. package/editor/assets/{index-CIu3uc3l.js → index-DK9xMGpW.js} +94 -94
  43. package/editor/index.html +1 -1
  44. package/package.json +1 -1
  45. package/schemas/scene.schema.json +4 -0
  46. package/skills/incanto-behaviors-and-scripts.md +30 -9
  47. package/skills/incanto-building-2d-games.md +20 -2
  48. package/skills/incanto-gameplay-behaviors.md +63 -1
  49. package/skills/incanto-hud.md +14 -0
  50. package/skills/incanto-node-reference.md +18 -2
  51. package/skills/incanto-playtesting.md +34 -0
  52. package/skills/incanto-save-slots.md +56 -1
  53. package/skills/incanto-verifying-your-game.md +11 -0
  54. package/templates-app/beacon-isle-3d/package.json +1 -1
  55. package/templates-app/beacon-isle-3d/src/game.scene.json +44 -226
  56. package/templates-app/molehill-2d/package.json +1 -1
  57. package/templates-app/molehill-2d/src/game.scene.json +10 -60
  58. package/templates-app/platformer-2d/package.json +1 -1
  59. package/templates-app/platformer-2d/src/game.scene.json +80 -416
  60. package/templates-app/star-survivor/package.json +1 -1
  61. package/templates-app/star-survivor/src/game.scene.json +5 -24
  62. package/templates-app/tps-3d/package.json +1 -1
  63. package/templates-app/tps-3d/src/game.scene.json +13 -71
  64. package/templates-app/village-quest-3d/package.json +1 -1
  65. package/templates-app/village-quest-3d/src/behaviors.ts +21 -4
  66. package/templates-app/village-quest-3d/src/grove.scene.json +16 -87
  67. package/templates-app/village-quest-3d/src/village.scene.json +5 -27
@@ -11,7 +11,7 @@
11
11
  },
12
12
  "dependencies": {
13
13
  "@dimforge/rapier2d-compat": "0.19.3",
14
- "incanto": "^0.70.0",
14
+ "incanto": "^0.71.0",
15
15
  "three": "^0.184.0"
16
16
  },
17
17
  "devDependencies": {
@@ -83,10 +83,7 @@
83
83
  {
84
84
  "name": "Vitals",
85
85
  "type": "Node2D",
86
- "script": {
87
- "name": "Health",
88
- "props": { "max": 100, "invulnerableFor": 0.6 }
89
- },
86
+ "script": { "name": "Health", "props": { "max": 100, "invulnerableFor": 0.6 } },
90
87
  "uid": "n_bk99wi475y8y1c1g"
91
88
  }
92
89
  ],
@@ -159,10 +156,7 @@
159
156
  {
160
157
  "name": "Drop",
161
158
  "type": "Node2D",
162
- "script": {
163
- "name": "EnemyDrop",
164
- "props": { "xp": 1, "color": "#ff8a5b" }
165
- },
159
+ "script": { "name": "EnemyDrop", "props": { "xp": 1, "color": "#ff8a5b" } },
166
160
  "uid": "n_ik9ixyv3h463m3bj"
167
161
  }
168
162
  ],
@@ -239,10 +233,7 @@
239
233
  {
240
234
  "name": "Drop",
241
235
  "type": "Node2D",
242
- "script": {
243
- "name": "EnemyDrop",
244
- "props": { "xp": 2, "color": "#8fd0ff" }
245
- },
236
+ "script": { "name": "EnemyDrop", "props": { "xp": 2, "color": "#8fd0ff" } },
246
237
  "uid": "n_ldwl2f8oqqnmv0uc"
247
238
  }
248
239
  ],
@@ -308,18 +299,8 @@
308
299
  "uid": "n_tlqu945vs98khzn8"
309
300
  },
310
301
  "connections": [
311
- {
312
- "signal": "died",
313
- "from": "Player/Vitals",
314
- "to": "/root",
315
- "handler": "loseLife"
316
- },
317
- {
318
- "signal": "damaged",
319
- "from": "Player/Vitals",
320
- "to": "SfxHurt",
321
- "handler": "play"
322
- },
302
+ { "signal": "died", "from": "Player/Vitals", "to": "/root", "handler": "loseLife" },
303
+ { "signal": "damaged", "from": "Player/Vitals", "to": "SfxHurt", "handler": "play" },
323
304
  { "signal": "won", "from": "/root", "to": "SfxWin", "handler": "play" },
324
305
  { "signal": "lost", "from": "/root", "to": "SfxLose", "handler": "play" }
325
306
  ]
@@ -13,7 +13,7 @@
13
13
  "@dimforge/rapier2d-compat": "0.19.3",
14
14
  "@dimforge/rapier3d-compat": "0.19.3",
15
15
  "@pixiv/three-vrm": "^3.5.3",
16
- "incanto": "^0.70.0",
16
+ "incanto": "^0.71.0",
17
17
  "three": "^0.184.0"
18
18
  },
19
19
  "devDependencies": {
@@ -385,11 +385,7 @@
385
385
  "type": "Camera3D",
386
386
  "props": { "position": [0, 2.6, 23], "fov": 70, "current": true, "far": 400 }
387
387
  },
388
- {
389
- "name": "HurtSfx",
390
- "type": "AudioPlayer",
391
- "props": { "preset": "hurt", "volume": 0.6 }
392
- },
388
+ { "name": "HurtSfx", "type": "AudioPlayer", "props": { "preset": "hurt", "volume": 0.6 } },
393
389
  {
394
390
  "name": "Spawner",
395
391
  "type": "Node3D",
@@ -398,24 +394,9 @@
398
394
  "name": "WaveSpawner",
399
395
  "props": {
400
396
  "waves": [
401
- {
402
- "prefab": "EnemyTemplate",
403
- "count": 4,
404
- "interval": 1.1,
405
- "delayBefore": 2
406
- },
407
- {
408
- "prefab": "EnemyTemplate",
409
- "count": 6,
410
- "interval": 0.9,
411
- "delayBefore": 3
412
- },
413
- {
414
- "prefab": "EnemyTemplate",
415
- "count": 8,
416
- "interval": 0.7,
417
- "delayBefore": 3
418
- }
397
+ { "prefab": "EnemyTemplate", "count": 4, "interval": 1.1, "delayBefore": 2 },
398
+ { "prefab": "EnemyTemplate", "count": 6, "interval": 0.9, "delayBefore": 3 },
399
+ { "prefab": "EnemyTemplate", "count": 8, "interval": 0.7, "delayBefore": 3 }
419
400
  ]
420
401
  }
421
402
  },
@@ -453,11 +434,7 @@
453
434
  "mesh": "sphere",
454
435
  "size": [0.12, 0.12, 0.12],
455
436
  "position": [0, 0.55, 0.32],
456
- "material": {
457
- "color": "#ffec5c",
458
- "emissive": "#ffd000",
459
- "emissiveIntensity": 2
460
- }
437
+ "material": { "color": "#ffec5c", "emissive": "#ffd000", "emissiveIntensity": 2 }
461
438
  }
462
439
  },
463
440
  {
@@ -551,31 +528,11 @@
551
528
  "color": "#c9d2dd"
552
529
  }
553
530
  },
554
- {
555
- "name": "Volume",
556
- "type": "UiVolumeSlider",
557
- "uid": "n_5p4124fbnjxx8s0c"
558
- },
559
- {
560
- "name": "Mute",
561
- "type": "UiMuteToggle",
562
- "uid": "n_e1lyn3mvsy3vj2qr"
563
- },
564
- {
565
- "name": "Quality",
566
- "type": "UiQualitySelect",
567
- "uid": "n_35r1h71i75yft3ex"
568
- },
569
- {
570
- "name": "RenderScale",
571
- "type": "UiRenderScaleSelect",
572
- "uid": "n_emg840df89fqsriw"
573
- },
574
- {
575
- "name": "FrameCap",
576
- "type": "UiFrameCapSelect",
577
- "uid": "n_mgqwgghn0bx900ip"
578
- }
531
+ { "name": "Volume", "type": "UiVolumeSlider", "uid": "n_5p4124fbnjxx8s0c" },
532
+ { "name": "Mute", "type": "UiMuteToggle", "uid": "n_e1lyn3mvsy3vj2qr" },
533
+ { "name": "Quality", "type": "UiQualitySelect", "uid": "n_35r1h71i75yft3ex" },
534
+ { "name": "RenderScale", "type": "UiRenderScaleSelect", "uid": "n_emg840df89fqsriw" },
535
+ { "name": "FrameCap", "type": "UiFrameCapSelect", "uid": "n_mgqwgghn0bx900ip" }
579
536
  ]
580
537
  }
581
538
  ]
@@ -585,23 +542,8 @@
585
542
  },
586
543
  "connections": [
587
544
  { "signal": "died", "from": "Player", "to": "/root", "handler": "loseLife" },
588
- {
589
- "signal": "lifeLost",
590
- "from": "/root",
591
- "to": "Player",
592
- "handler": "reviveFull"
593
- },
594
- {
595
- "signal": "damaged",
596
- "from": "Player",
597
- "to": "HurtSfx",
598
- "handler": "play"
599
- },
600
- {
601
- "signal": "allCleared",
602
- "from": "Spawner",
603
- "to": "Hud",
604
- "handler": "onAllCleared"
605
- }
545
+ { "signal": "lifeLost", "from": "/root", "to": "Player", "handler": "reviveFull" },
546
+ { "signal": "damaged", "from": "Player", "to": "HurtSfx", "handler": "play" },
547
+ { "signal": "allCleared", "from": "Spawner", "to": "Hud", "handler": "onAllCleared" }
606
548
  ]
607
549
  }
@@ -13,7 +13,7 @@
13
13
  "@dimforge/rapier2d-compat": "0.19.3",
14
14
  "@dimforge/rapier3d-compat": "0.19.3",
15
15
  "@pixiv/three-vrm": "^3.5.3",
16
- "incanto": "^0.70.0",
16
+ "incanto": "^0.71.0",
17
17
  "three": "^0.184.0"
18
18
  },
19
19
  "devDependencies": {
@@ -23,7 +23,7 @@ import type {
23
23
  UiText,
24
24
  Voice,
25
25
  } from 'incanto';
26
- import { Behavior, findPath, gridFromRows } from 'incanto';
26
+ import { Behavior, findPath, gridFromRows, Timer } from 'incanto';
27
27
  import { mergeSolidRects, parseCells } from 'incanto/2d';
28
28
  import type { Camera3D, CharacterController3D, Node3D, Trail3D } from 'incanto/3d';
29
29
  import { MeshInstance3D, Particles3D, StaticBody3D } from 'incanto/3d';
@@ -594,7 +594,18 @@ export class SwordStrike extends Behavior {
594
594
  /** Strike bookkeeping: hits per wolf (module-scope — survives behavior instances). */
595
595
  const wolfHits = new WeakMap<Node, number>();
596
596
 
597
- /** Red hurt-flash on every mesh of the wolf, reverted a beat later. */
597
+ /**
598
+ * Red hurt-flash on every mesh of the wolf, reverted a beat later.
599
+ *
600
+ * The beat is a `Timer`, not a `setTimeout` — which is what this was, and what
601
+ * `incanto-behaviors-and-scripts.md` calls "the canonical serializable game
602
+ * clock — NEVER setTimeout in game logic". Three things a wall-clock timeout
603
+ * gets wrong here: it keeps running while the game is paused (`timeScale: 0`),
604
+ * it ignores `timeScale` entirely, and in a headless run — where a minute of
605
+ * play takes a second — it fires long after the frame that asked for it, so a
606
+ * seeded playtest stops being reproducible. The node is a child of the wolf,
607
+ * so a wolf that dies mid-flash takes its timer with it.
608
+ */
598
609
  function flashWolf(wolf: Node): void {
599
610
  const meshes: { material: Record<string, unknown> }[] = [];
600
611
  const walk = (n: Node): void => {
@@ -606,11 +617,17 @@ function flashWolf(wolf: Node): void {
606
617
  walk(wolf);
607
618
  const originals = meshes.map((m) => m.material);
608
619
  for (const m of meshes) m.material = { ...m.material, color: '#ff5544' };
609
- setTimeout(() => {
620
+ const beat = new Timer('Unflash');
621
+ beat.waitTime = 0.13;
622
+ beat.oneShot = true;
623
+ beat.autostart = true;
624
+ beat.on('timeout', () => {
610
625
  meshes.forEach((m, i) => {
611
626
  if (wolf.tree) m.material = originals[i] as Record<string, unknown>;
612
627
  });
613
- }, 130);
628
+ beat.queueFree();
629
+ });
630
+ wolf.addChild(beat);
614
631
  }
615
632
 
616
633
  export const BEHAVIORS = { VillageDirector, GroveDirector, SwordStrike };
@@ -108,42 +108,22 @@
108
108
  {
109
109
  "name": "Pine1",
110
110
  "type": "Tree3D",
111
- "props": {
112
- "position": [-18, 0, -13],
113
- "type": "conifer",
114
- "seed": 7,
115
- "height": 9
116
- }
111
+ "props": { "position": [-18, 0, -13], "type": "conifer", "seed": 7, "height": 9 }
117
112
  },
118
113
  {
119
114
  "name": "Pine2",
120
115
  "type": "Tree3D",
121
- "props": {
122
- "position": [18, 0, -12],
123
- "type": "conifer",
124
- "seed": 13,
125
- "height": 8
126
- }
116
+ "props": { "position": [18, 0, -12], "type": "conifer", "seed": 13, "height": 8 }
127
117
  },
128
118
  {
129
119
  "name": "Pine3",
130
120
  "type": "Tree3D",
131
- "props": {
132
- "position": [-17, 0, 12],
133
- "type": "dead",
134
- "seed": 29,
135
- "height": 7
136
- }
121
+ "props": { "position": [-17, 0, 12], "type": "dead", "seed": 29, "height": 7 }
137
122
  },
138
123
  {
139
124
  "name": "Pine4",
140
125
  "type": "Tree3D",
141
- "props": {
142
- "position": [17, 0, 13],
143
- "type": "conifer",
144
- "seed": 41,
145
- "height": 10
146
- }
126
+ "props": { "position": [17, 0, 13], "type": "conifer", "seed": 41, "height": 10 }
147
127
  },
148
128
  {
149
129
  "name": "Moon",
@@ -197,11 +177,7 @@
197
177
  "mesh": "sphere",
198
178
  "size": [0.07, 0.07, 0.07],
199
179
  "position": [-0.1, 0.24, 1],
200
- "material": {
201
- "color": "#ff3030",
202
- "emissive": "#ff3030",
203
- "emissiveIntensity": 2
204
- }
180
+ "material": { "color": "#ff3030", "emissive": "#ff3030", "emissiveIntensity": 2 }
205
181
  }
206
182
  },
207
183
  {
@@ -211,11 +187,7 @@
211
187
  "mesh": "sphere",
212
188
  "size": [0.07, 0.07, 0.07],
213
189
  "position": [0.1, 0.24, 1],
214
- "material": {
215
- "color": "#ff3030",
216
- "emissive": "#ff3030",
217
- "emissiveIntensity": 2
218
- }
190
+ "material": { "color": "#ff3030", "emissive": "#ff3030", "emissiveIntensity": 2 }
219
191
  }
220
192
  },
221
193
  {
@@ -298,11 +270,7 @@
298
270
  "mesh": "sphere",
299
271
  "size": [0.07, 0.07, 0.07],
300
272
  "position": [-0.1, 0.24, 1],
301
- "material": {
302
- "color": "#ff3030",
303
- "emissive": "#ff3030",
304
- "emissiveIntensity": 2
305
- }
273
+ "material": { "color": "#ff3030", "emissive": "#ff3030", "emissiveIntensity": 2 }
306
274
  }
307
275
  },
308
276
  {
@@ -312,11 +280,7 @@
312
280
  "mesh": "sphere",
313
281
  "size": [0.07, 0.07, 0.07],
314
282
  "position": [0.1, 0.24, 1],
315
- "material": {
316
- "color": "#ff3030",
317
- "emissive": "#ff3030",
318
- "emissiveIntensity": 2
319
- }
283
+ "material": { "color": "#ff3030", "emissive": "#ff3030", "emissiveIntensity": 2 }
320
284
  }
321
285
  },
322
286
  {
@@ -399,11 +363,7 @@
399
363
  "mesh": "sphere",
400
364
  "size": [0.07, 0.07, 0.07],
401
365
  "position": [-0.1, 0.24, 1],
402
- "material": {
403
- "color": "#ff3030",
404
- "emissive": "#ff3030",
405
- "emissiveIntensity": 2
406
- }
366
+ "material": { "color": "#ff3030", "emissive": "#ff3030", "emissiveIntensity": 2 }
407
367
  }
408
368
  },
409
369
  {
@@ -413,11 +373,7 @@
413
373
  "mesh": "sphere",
414
374
  "size": [0.07, 0.07, 0.07],
415
375
  "position": [0.1, 0.24, 1],
416
- "material": {
417
- "color": "#ff3030",
418
- "emissive": "#ff3030",
419
- "emissiveIntensity": 2
420
- }
376
+ "material": { "color": "#ff3030", "emissive": "#ff3030", "emissiveIntensity": 2 }
421
377
  }
422
378
  },
423
379
  {
@@ -602,11 +558,7 @@
602
558
  "type": "AudioPlayer",
603
559
  "props": { "preset": "shoot", "volume": 0.35, "pitch": 0.55 }
604
560
  },
605
- {
606
- "name": "HitSfx",
607
- "type": "AudioPlayer",
608
- "props": { "preset": "hit", "volume": 0.6 }
609
- },
561
+ { "name": "HitSfx", "type": "AudioPlayer", "props": { "preset": "hit", "volume": 0.6 } },
610
562
  { "name": "Catch", "type": "Respawn" }
611
563
  ],
612
564
  "script": { "name": "Health", "props": { "max": 100, "invulnerableFor": 0.8 } },
@@ -617,11 +569,7 @@
617
569
  "type": "Camera3D",
618
570
  "props": { "current": true, "position": [0, 4, 19] }
619
571
  },
620
- {
621
- "name": "WinSfx",
622
- "type": "AudioPlayer",
623
- "props": { "preset": "win", "volume": 0.6 }
624
- },
572
+ { "name": "WinSfx", "type": "AudioPlayer", "props": { "preset": "win", "volume": 0.6 } },
625
573
  {
626
574
  "name": "HUD",
627
575
  "type": "HudLayer",
@@ -630,12 +578,7 @@
630
578
  "name": "Quest",
631
579
  "type": "UiText",
632
580
  "uid": "n_nmkf915b9r8d37nf",
633
- "props": {
634
- "text": "Wolves left: 3",
635
- "size": 16,
636
- "anchor": "topLeft",
637
- "shadow": true
638
- }
581
+ "props": { "text": "Wolves left: 3", "size": 16, "anchor": "topLeft", "shadow": true }
639
582
  },
640
583
  {
641
584
  "name": "HP",
@@ -674,11 +617,7 @@
674
617
  {
675
618
  "name": "ResumeHint",
676
619
  "type": "UiText",
677
- "props": {
678
- "text": "Esc to resume · R to restart",
679
- "size": 13,
680
- "color": "#c9d2dd"
681
- }
620
+ "props": { "text": "Esc to resume · R to restart", "size": 13, "color": "#c9d2dd" }
682
621
  }
683
622
  ]
684
623
  }
@@ -688,17 +627,7 @@
688
627
  "uid": "n_tq2dy6amirvyfhlg"
689
628
  },
690
629
  "connections": [
691
- {
692
- "signal": "triggerEnter",
693
- "from": "ReturnPortal",
694
- "to": "/root",
695
- "handler": "onPortalEnter"
696
- },
697
- {
698
- "signal": "died",
699
- "from": "Player",
700
- "to": "/root",
701
- "handler": "onPlayerDown"
702
- }
630
+ { "signal": "triggerEnter", "from": "ReturnPortal", "to": "/root", "handler": "onPortalEnter" },
631
+ { "signal": "died", "from": "Player", "to": "/root", "handler": "onPlayerDown" }
703
632
  ]
704
633
  }
@@ -2654,10 +2654,7 @@
2654
2654
  "name": "Elder",
2655
2655
  "type": "Node3D",
2656
2656
  "props": { "position": [3, 0, -2] },
2657
- "script": {
2658
- "name": "Interactable",
2659
- "props": { "action": "interact", "range": 2.8 }
2660
- },
2657
+ "script": { "name": "Interactable", "props": { "action": "interact", "range": 2.8 } },
2661
2658
  "children": [
2662
2659
  {
2663
2660
  "name": "Body",
@@ -2811,11 +2808,7 @@
2811
2808
  "type": "AudioPlayer",
2812
2809
  "props": { "preset": "shoot", "volume": 0.35, "pitch": 0.55 }
2813
2810
  },
2814
- {
2815
- "name": "HitSfx",
2816
- "type": "AudioPlayer",
2817
- "props": { "preset": "hit", "volume": 0.6 }
2818
- },
2811
+ { "name": "HitSfx", "type": "AudioPlayer", "props": { "preset": "hit", "volume": 0.6 } },
2819
2812
  { "name": "Catch", "type": "Respawn" }
2820
2813
  ]
2821
2814
  },
@@ -2881,23 +2874,8 @@
2881
2874
  "uid": "n_2a2pghqmq92ko29c"
2882
2875
  },
2883
2876
  "connections": [
2884
- {
2885
- "signal": "interacted",
2886
- "from": "Elder",
2887
- "to": "/root",
2888
- "handler": "onTalk"
2889
- },
2890
- {
2891
- "signal": "triggerEnter",
2892
- "from": "GroveGate",
2893
- "to": "/root",
2894
- "handler": "onGateEnter"
2895
- },
2896
- {
2897
- "signal": "pressed",
2898
- "from": "HUD/RestartBtn",
2899
- "to": "/root",
2900
- "handler": "onRestart"
2901
- }
2877
+ { "signal": "interacted", "from": "Elder", "to": "/root", "handler": "onTalk" },
2878
+ { "signal": "triggerEnter", "from": "GroveGate", "to": "/root", "handler": "onGateEnter" },
2879
+ { "signal": "pressed", "from": "HUD/RestartBtn", "to": "/root", "handler": "onRestart" }
2902
2880
  ]
2903
2881
  }