incanto 0.69.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 (147) hide show
  1. package/bin/_behaviors-loader.mjs +22 -0
  2. package/bin/_read-json.mjs +28 -0
  3. package/bin/incanto-assets.mjs +5 -4
  4. package/bin/incanto-check.mjs +58 -31
  5. package/bin/incanto-editor.mjs +128 -5
  6. package/bin/incanto-env.mjs +3 -2
  7. package/bin/incanto-feel.mjs +24 -13
  8. package/bin/incanto-frame.mjs +8 -1
  9. package/bin/incanto-multiplay.mjs +11 -9
  10. package/bin/incanto-new.mjs +105 -10
  11. package/bin/incanto-play.mjs +158 -16
  12. package/bin/incanto-playtest.mjs +66 -23
  13. package/bin/incanto-skills.mjs +14 -2
  14. package/bin/incanto-verify.mjs +121 -102
  15. package/bin/incanto.mjs +3 -2
  16. package/dist/2d.d.ts +296 -34
  17. package/dist/2d.js +4 -4
  18. package/dist/3d.d.ts +157 -9
  19. package/dist/3d.js +8 -8
  20. package/dist/{agent8-CvsfVskX.js → agent8-Cfmd3ar_.js} +61 -8
  21. package/dist/{audio-player-C0j2k-yB.d.ts → audio-player-L8yccdMP.d.ts} +2 -2
  22. package/dist/{behavior-rm8vVzu_.d.ts → behavior-Dcz0fr1S.d.ts} +755 -46
  23. package/dist/{create-game-CwxEDlCm.js → create-game-CH4kt78v.js} +143 -60
  24. package/dist/{create-game-CvJ1wSRP.js → create-game-LCHBLfA4.js} +98 -48
  25. package/dist/debug.d.ts +1 -1
  26. package/dist/debug.js +2 -3
  27. package/dist/diagnostics-Cu85N3tL.d.ts +12 -0
  28. package/dist/{editor-switch-CnIOiyNJ.d.ts → editor-switch-CFU9mCec.d.ts} +22 -13
  29. package/dist/editor.js +1088 -882
  30. package/dist/env.d.ts +1 -1
  31. package/dist/env.js +5 -3
  32. package/dist/{environment-presets-BO-7XoFV.js → environment-presets-99BzP_L-.js} +298 -45
  33. package/dist/{frame-report-Dlq13Gyj.js → frame-report-D-_7YF2G.js} +1 -1
  34. package/dist/{gameplay-D1KixWK8.js → gameplay-CNULJvwh.js} +914 -214
  35. package/dist/gameplay.d.ts +254 -10
  36. package/dist/gameplay.js +2 -2
  37. package/dist/{heightmap-CRK0M4jT.js → heightmap-BYgD5Edk.js} +1 -1
  38. package/dist/index.d.ts +179 -13
  39. package/dist/index.js +10 -12
  40. package/dist/json-CfTjpvW8.js +67 -0
  41. package/dist/{loader-DadV2QCT.d.ts → loader-8-IHvbKD.d.ts} +2 -2
  42. package/dist/net.d.ts +27 -3
  43. package/dist/net.js +2 -2
  44. package/dist/{noise-CGUMx44x.js → noise-D3nPpmFg.js} +1 -1
  45. package/dist/{physics-2d-CF5yyjbj.js → physics-2d-FhrXUc6B.js} +136 -11
  46. package/dist/{physics-3d-DbYaEcZy.js → physics-3d-CFEGxBXZ.js} +104 -23
  47. package/dist/{teardown-CMqFVxO9.js → picking-DVo7fI13.js} +104 -13
  48. package/dist/react.d.ts +2 -2
  49. package/dist/react.js +2 -2
  50. package/dist/{register-DbVArsns.js → register-BYQCBySi.js} +429 -28
  51. package/dist/{register-mmfugpaQ.js → register-DuVdzxbq.js} +594 -831
  52. package/dist/{replay-BEHLDcQV.js → replay-DEvp3kyV.js} +224 -14
  53. package/dist/{replay-BQfkX4x7.d.ts → replay-F7IZHdFR.d.ts} +20 -3
  54. package/dist/{schema-B6ugCV1Q.d.ts → rng-Bb-IutXB.d.ts} +38 -21
  55. package/dist/{rng-DP-SR7eg.js → rng-CDOMybym.js} +22 -0
  56. package/dist/{loader-DZE7B07H.js → save-slots-Bvuh2p_r.js} +4619 -2318
  57. package/dist/{split-screen-Cg76MCV5.d.ts → split-screen-CIYf1zSf.d.ts} +36 -4
  58. package/dist/{split-screen-CauMwu6y.js → split-screen-eULetcg-.js} +159 -26
  59. package/dist/{sprite-animation-CY-mrr1L.js → sprite-animation-CqR2o3SA.js} +39 -8
  60. package/dist/{src-CYEu-_S9.js → src-_jk0qLsS.js} +2 -17
  61. package/dist/test-CmN54kWv.js +4264 -0
  62. package/dist/test.d.ts +639 -30
  63. package/dist/test.js +3 -3
  64. package/dist/touch-BnCyPA0G.js +519 -0
  65. package/dist/vite.d.ts +20 -37
  66. package/dist/vite.js +177 -7
  67. package/dist/{webgl-unavailable-Z5_g8x9H.js → webgl-unavailable-C8aDbGmR.js} +44 -0
  68. package/editor/assets/agent8-yLIEYHbd.js +1 -0
  69. package/editor/assets/{debug-CMULinBW.js → debug-u31w_yhq.js} +2 -2
  70. package/editor/assets/index-DK9xMGpW.js +11046 -0
  71. package/editor/index.html +1 -1
  72. package/package.json +4 -14
  73. package/schemas/scene.schema.json +34 -3
  74. package/skills/incanto-3d-character.md +14 -1
  75. package/skills/incanto-3d-models.md +12 -0
  76. package/skills/incanto-assets.md +9 -1
  77. package/skills/incanto-audio.md +8 -2
  78. package/skills/incanto-behaviors-and-scripts.md +105 -7
  79. package/skills/incanto-building-2d-games.md +97 -10
  80. package/skills/incanto-building-3d-games.md +58 -4
  81. package/skills/incanto-editor.md +46 -7
  82. package/skills/incanto-environment.md +19 -1
  83. package/skills/incanto-game-feel.md +70 -0
  84. package/skills/incanto-gameplay-behaviors.md +172 -20
  85. package/skills/incanto-hud.md +142 -7
  86. package/skills/incanto-localization.md +13 -5
  87. package/skills/incanto-multiplayer.md +83 -3
  88. package/skills/incanto-node-reference.md +239 -59
  89. package/skills/incanto-performance.md +52 -0
  90. package/skills/incanto-physics-and-input.md +123 -24
  91. package/skills/incanto-playtesting.md +112 -2
  92. package/skills/incanto-save-slots.md +217 -7
  93. package/skills/incanto-scene-json-authoring.md +69 -12
  94. package/skills/incanto-verifying-your-game.md +207 -10
  95. package/skills/incanto-web-integration.md +28 -0
  96. package/skills/incanto-your-first-game.md +3 -1
  97. package/templates-app/beacon-isle-3d/generate-world.ts +77 -9
  98. package/templates-app/beacon-isle-3d/package.json +2 -2
  99. package/templates-app/beacon-isle-3d/src/behaviors.ts +22 -0
  100. package/templates-app/beacon-isle-3d/src/game.scene.json +143 -600
  101. package/templates-app/beacon-isle-3d/src/main.ts +11 -1
  102. package/templates-app/beacon-isle-3d/tsconfig.json +1 -1
  103. package/templates-app/beacon-isle-3d/verify.ts +3 -1
  104. package/templates-app/molehill-2d/.incanto/playtest/lost-seed1.json +4277 -0
  105. package/templates-app/molehill-2d/PROJECT/Context.md +58 -0
  106. package/templates-app/molehill-2d/PROJECT/Requirements.md +39 -0
  107. package/templates-app/molehill-2d/PROJECT/Status.md +27 -0
  108. package/templates-app/molehill-2d/PROJECT/Structure.md +48 -0
  109. package/templates-app/molehill-2d/docs/project-2d-rules.md +44 -0
  110. package/templates-app/molehill-2d/index.html +73 -0
  111. package/templates-app/molehill-2d/package.json +23 -0
  112. package/templates-app/molehill-2d/src/behaviors.ts +198 -0
  113. package/templates-app/molehill-2d/src/game.scene.json +1205 -0
  114. package/templates-app/molehill-2d/src/main.ts +41 -0
  115. package/templates-app/molehill-2d/tsconfig.json +13 -0
  116. package/templates-app/molehill-2d/verify.ts +247 -0
  117. package/templates-app/molehill-2d/vite.config.ts +12 -0
  118. package/templates-app/platformer-2d/package.json +2 -2
  119. package/templates-app/platformer-2d/src/game.scene.json +178 -986
  120. package/templates-app/platformer-2d/src/main.ts +11 -1
  121. package/templates-app/platformer-2d/tsconfig.json +1 -1
  122. package/templates-app/star-survivor/package.json +2 -2
  123. package/templates-app/star-survivor/src/game.scene.json +43 -216
  124. package/templates-app/star-survivor/src/main.ts +11 -1
  125. package/templates-app/star-survivor/tsconfig.json +1 -1
  126. package/templates-app/tps-3d/PROJECT/Context.md +1 -1
  127. package/templates-app/tps-3d/package.json +2 -2
  128. package/templates-app/tps-3d/src/behaviors.ts +19 -1
  129. package/templates-app/tps-3d/src/game.scene.json +66 -263
  130. package/templates-app/tps-3d/src/main.ts +13 -2
  131. package/templates-app/tps-3d/tsconfig.json +1 -1
  132. package/templates-app/village-quest-3d/.incanto/playtest/swapped-seed1.json +1735 -0
  133. package/templates-app/village-quest-3d/package.json +2 -2
  134. package/templates-app/village-quest-3d/src/behaviors.ts +42 -4
  135. package/templates-app/village-quest-3d/src/grove.scene.json +68 -306
  136. package/templates-app/village-quest-3d/src/main.ts +11 -1
  137. package/templates-app/village-quest-3d/src/village.scene.json +202 -863
  138. package/templates-app/village-quest-3d/tsconfig.json +1 -1
  139. package/templates-app/village-quest-3d/verify.ts +14 -1
  140. package/dist/duplicate-Dj4L-5AA.js +0 -22
  141. package/dist/json-CwwhxQgb.js +0 -36
  142. package/dist/registry-CF70EArN.js +0 -212
  143. package/dist/rolldown-runtime-D7D4PA-g.js +0 -13
  144. package/dist/test-D6ISmuFE.js +0 -2383
  145. package/dist/touch-DEAmqGdf.js +0 -225
  146. package/editor/assets/agent8-BDvaZMQJ.js +0 -1
  147. package/editor/assets/index-CZIRr5EL.js +0 -10958
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { a as ParticleSimConfig, c as showBootFailure, i as ParticleSim, n as AudioPlayer, o as ParticleView, s as isWebGLAvailable, t as AudioElementLike } from "./audio-player-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";
1
+ import { a as ParticleSimConfig, c as showBootFailure, i as ParticleSim, n as AudioPlayer, o as ParticleView, s as isWebGLAvailable, t as AudioElementLike } from "./audio-player-L8yccdMP.js";
2
+ import { $ as T_PREFIX, A as SettingsValues, At as BusName, B as captureBehaviors, C as EngineStats, Ct as sfxDuration, Dt as MusicTrack, E as DeviceHints, Et as MusicManager, F as BehaviorState, Ft as LogLevel, G as ORDER_GROUP_BASE, H as savesWithoutUid, I as RestoreReport, It as LogManager, J as effectiveOrder, K as OrderGroup, L as SaveSlot, Lt as Signal, M as readDeviceHints, Mt as NodeLifecycle, N as suggestQuality, Nt as SceneTree, O as QualityTier, Ot as PlayMusicOptions, P as Scene, Pt as LogEntry, Q as Localization, R as SaveSlots, Rt as SignalListener, S as Scheduler, St as SynthOptions, T as RendererStats, Tt as MusicBackend, U as SaveStore, V as restoreBehaviors, W as createSaveStore, X as BASE_LOCALE, Y as resolveOrderGroups, Z as LocaleTables, _ as mergeStaticSignals, _t as spatialPan, a as clearBehaviors, at as EffectLog, b as Engine, bt as SfxParams, c as registeredBehaviors, ct as isAudioContextAvailable, d as PropSchema, dt as Listener, et as suggestLocale, f as clearRegistry, ft as ROLLOFF_MODELS, g as getNodeType, gt as spatialGain, h as getNodeSignals, ht as Vec3, i as behaviorSignals, it as EffectKind, j as qualityEnvironment, jt as Node, k as Settings, kt as AudioBuses, l as NodeCtor, lt as Voice, m as getNodeSchema, mt as SpatialParams, n as BehaviorCtor, nt as InputMap, o as getBehavior, ot as SfxEngine, p as createNode, pt as RolloffModel, q as OrderGroupTable, r as behaviorSchema, rt as EffectEvent, s as registerBehavior, st as SfxPlayOptions, t as Behavior, tt as translationKey, u as PropDef, ut as VoicePreset, v as registerNode, vt as SFX_PRESETS, w as GameStats, wt as synthSfx, x as EngineOptions, xt as SfxWave, y as registeredTypes, yt as SFX_PRESET_NAMES, z as behaviorsWithoutSave } from "./behavior-Dcz0fr1S.js";
3
+ import { a as SceneJson, c as JsonValue, d as jsonKind, i as SCENE_FORMAT, l as jsonClone, n as ConnectionJson, o as JsonKind, r as NodeJson, s as JsonObject, t as Rng, u as jsonEquals } from "./rng-Bb-IutXB.js";
4
+ import { n as loadScene, t as LoadSceneOptions } from "./loader-8-IHvbKD.js";
5
5
  import { i as resolveFrames, n as AnimationEntry, r as resolveAnimation, t as AnimationDef } from "./sprite-animation-CMr6f1K2.js";
6
6
  import { i as gridFromRows, n as PathGrid, r as findPath, t as FindPathOptions } from "./pathfinding-_fGrCFmH.js";
7
- import { a as startRecording, c as IncantoErrorDetails, i as replay, l as auditScene, n as ReplayEvent, o as IncantoError, r as ReplayJson, s as IncantoErrorCode, t as Recorder } from "./replay-BQfkX4x7.js";
7
+ import { a as startRecording, c as IncantoErrorDetails, i as replay, l as auditScene, n as ReplayEvent, o as IncantoError, r as ReplayJson, s as IncantoErrorCode, t as Recorder } from "./replay-F7IZHdFR.js";
8
8
 
9
9
  //#region src/core/audio/crossfade.d.ts
10
10
  /**
@@ -109,6 +109,20 @@ type DriveStep = {
109
109
  kind: "pointer";
110
110
  dx: number;
111
111
  dy: number;
112
+ } | {
113
+ kind: "at";
114
+ x: number;
115
+ y: number;
116
+ } | {
117
+ kind: "atNode";
118
+ path: string;
119
+ } | {
120
+ kind: "click";
121
+ button: number;
122
+ } | {
123
+ kind: "mouse";
124
+ button: number;
125
+ down: boolean;
112
126
  } | {
113
127
  kind: "step";
114
128
  ms: number;
@@ -245,13 +259,26 @@ type RefResult = {
245
259
  declare function resolveRefInJson(root: RefNode | undefined, owner: readonly number[], value: string): RefResult;
246
260
  /** The problem in English, for `incanto-check` and as the editor's base text. */
247
261
  declare function describeRefProblem(problem: RefProblem, value: string): string;
262
+ interface RefWarningOptions {
263
+ /**
264
+ * This file is a PREFAB another scene drops in, so a path may legitimately
265
+ * leave it.
266
+ *
267
+ * `/root/Bolts` is the fragment's own root only while the fragment is alone;
268
+ * attached, it resolves. Four such warnings stood forever on four of five
269
+ * files of a real project whose main scene audited clean. The verdict is
270
+ * reworded rather than suppressed: a typo'd path is MOST likely in a file
271
+ * written away from the scene that gives it meaning, so it still gets named.
272
+ */
273
+ fragment?: boolean;
274
+ }
248
275
  /**
249
276
  * Scene lints for node-path props that point at nothing.
250
277
  *
251
278
  * An EMPTY value is not reported: `''` is the default of most of these props and
252
279
  * means "not set", which is a choice rather than a typo.
253
280
  */
254
- declare function nodeRefWarnings(scene: JsonObject): string[];
281
+ declare function nodeRefWarnings(scene: JsonObject, opts?: RefWarningOptions): string[];
255
282
  //#endregion
256
283
  //#region src/core/nodes/hud.d.ts
257
284
  /**
@@ -305,6 +332,22 @@ declare class HudLayer extends Node {
305
332
  override onExitTree(): void;
306
333
  override update(): void;
307
334
  /**
335
+ * Is this the layer the keyboard is talking to?
336
+ *
337
+ * Keyboard focus is singular by nature — a browser has ONE focused element —
338
+ * and `focusNavigation` is per LAYER, so a game with a HUD and a modal that
339
+ * armed both had a single Enter activate the focused widget in EACH: the
340
+ * pause menu's RESUME and whatever the screen underneath happened to have
341
+ * focused, which is "the modal does not block the screen behind it" arriving
342
+ * through the keyboard.
343
+ *
344
+ * The TOPMOST armed layer wins — last in document order, which is the one
345
+ * drawn on top, and the one a modal is. A hidden layer is not armed at all: a
346
+ * closed menu must not eat the key from the HUD it covers. With one layer,
347
+ * which is the usual case, this is always true.
348
+ */
349
+ private ownsFocus;
350
+ /**
308
351
  * Arrow keys / d-pad move the focus, Enter / A activates it.
309
352
  *
310
353
  * Off by default: a game whose HUD has a button must not lose its arrow keys
@@ -361,6 +404,19 @@ declare abstract class HudWidgetBase extends Node {
361
404
  * A or an arrow ON this widget means. Default: nothing.
362
405
  */
363
406
  _activate(_dir: number): void;
407
+ /**
408
+ * @internal What a MOUSE CLICK on this widget does. Defaults to `_activate`.
409
+ *
410
+ * For a button, a toggle and a select the two are the same thing, which is
411
+ * why one entry point served both for a while. For `UiDialogue` they are
412
+ * not: Enter on a waiting choice ANSWERS it, and a click on the box does
413
+ * not — `advance()` returns early while `current.choices` is set, with the
414
+ * comment "must pick — clicks don't skip choices".
415
+ *
416
+ * A harness whose `click:` answered the question would pass a test the real
417
+ * game fails, which is the one thing the ladder must not do.
418
+ */
419
+ _click(): void;
364
420
  /** @internal Draw the focus ring. Overridable if a widget wants its own. */
365
421
  _paintFocus(): void;
366
422
  /** @internal */
@@ -379,6 +435,27 @@ declare abstract class HudWidgetBase extends Node {
379
435
  */
380
436
  _mountWidget(): void;
381
437
  /**
438
+ * The gesture, without a pointer — the `press()` of drag and drop.
439
+ *
440
+ * All four signals lived on `_wireDrag`, which is wired to a DOM element and
441
+ * therefore does not exist headless. So the one screen the HUD skill says
442
+ * needs more than a click — an inventory — was the one screen no harness
443
+ * could drive: `dragStarted`, `droppedOn`, `dropped` and `dragCancelled`
444
+ * were unreachable from `runScript`, `incanto-playtest` and every check in
445
+ * the ladder, and a game that moves items between slots could only be tested
446
+ * by hand in a browser.
447
+ *
448
+ * Same rules as the pointer path, so a test that passes here is a test about
449
+ * the game: a non-`draggable` source does nothing, a target that is not a
450
+ * `dropTarget` CANCELS, and dropping a thing back where it came from — on
451
+ * itself, or on the slot it is already in — is not a move.
452
+ *
453
+ * Returns whether the drop was taken.
454
+ */
455
+ dropOnto(target: HudWidgetBase | null): boolean;
456
+ /** The slot this widget is sitting in, if any — its origin for a drop. */
457
+ private dropTargetAbove;
458
+ /**
382
459
  * Drag and drop, on the DOM the engine already builds.
383
460
  *
384
461
  * An inventory is the one screen where "click it" is not enough, and every
@@ -409,6 +486,12 @@ declare abstract class HudWidgetBase extends Node {
409
486
  * did nothing at all, forever.
410
487
  */
411
488
  private _followAnchor;
489
+ /**
490
+ * Follow the engine, and let a change made HERE reach it — with or without a
491
+ * DOM element. No element access allowed: this is the half that runs
492
+ * headless.
493
+ */
494
+ protected _pull(): void;
412
495
  protected _sync(): void;
413
496
  /**
414
497
  * Resolve a text prop through the engine's locale.
@@ -487,6 +570,20 @@ declare class UiText extends HudWidgetBase {
487
570
  * authored opening line. Filling the slot with nothing instead would put
488
571
  * `"Gems / 8"` on screen for every game's first frame, and a score line
489
572
  * that starts blank looks broken rather than empty.
573
+ *
574
+ * Unless there IS no opening line. `format` alone painted `""`:
575
+ *
576
+ * ```
577
+ * format = 'Gems {} / 8'
578
+ * shown before setText "" <- nothing on screen
579
+ * shown after setText "Gems 3 / 8"
580
+ * ```
581
+ *
582
+ * and the signals a HUD is wired to — `scoreChanged`, `healthChanged` — only
583
+ * fire on CHANGE, so the row stays invisible through the whole opening of the
584
+ * game and forever if the value never moves. An empty slot in a visible
585
+ * template is the lesser of those two: it shows the author what they
586
+ * declared, where they declared it.
490
587
  */
491
588
  get shown(): string;
492
589
  override _paintedText(): string | undefined;
@@ -522,7 +619,7 @@ declare class UiBar extends HudWidgetBase {
522
619
  * already has, so a bar whose ceiling moves (a max-HP upgrade) needs no
523
620
  * second wire.
524
621
  */
525
- setValue(value: number, max?: number): void;
622
+ setValue(value: number, max?: number | undefined): void;
526
623
  /** Move the ceiling on its own, leaving the fill where it is. */
527
624
  setMax(max: number): void;
528
625
  protected _build(): HTMLElement;
@@ -554,7 +651,7 @@ declare class UiBanner extends HudWidgetBase {
554
651
  show(text: string, opts?: {
555
652
  color?: string;
556
653
  seconds?: number;
557
- }): void;
654
+ } | undefined): void;
558
655
  /** Drop everything (scene transitions). */
559
656
  clear(): void;
560
657
  protected _build(): HTMLElement;
@@ -626,7 +723,7 @@ declare class UiDialogue extends HudWidgetBase {
626
723
  /** What the box currently shows (grows while typing) — test-friendly. */
627
724
  get showing(): string;
628
725
  /** Queue a line; optional `choices` renders buttons after the line types out. */
629
- say(speaker: string, text: string, choices?: string[]): void;
726
+ say(speaker: string, text: string, choices?: string[] | undefined): void;
630
727
  /**
631
728
  * A dialogue takes focus while it is up.
632
729
  *
@@ -647,6 +744,14 @@ declare class UiDialogue extends HudWidgetBase {
647
744
  * `dir` is 0 for "activate" and ±1 for a nudge, the same shape `UiSelect`
648
745
  * uses — so one key layout drives a menu, a slider and a conversation.
649
746
  */
747
+ /**
748
+ * A click on the BOX is `advance()`, which refuses to skip a choice.
749
+ *
750
+ * The DOM handler is `box.addEventListener('click', () => this.advance())`
751
+ * and `advance` returns early while `current.choices` is set. Enter is a
752
+ * different verb — it answers — so a harness clicking the box must not.
753
+ */
754
+ override _click(): void;
650
755
  override _activate(dir: number): void;
651
756
  /** Show which option the keyboard is on — a ring nobody can see is not one. */
652
757
  private paintCursor;
@@ -776,6 +881,16 @@ declare class Timer extends Node {
776
881
  private remaining;
777
882
  start(time?: number): void;
778
883
  stop(): void;
884
+ /**
885
+ * Scene-load validation: a period of zero is a timer that never fires.
886
+ *
887
+ * `update` guards it — a non-positive period "would spin forever on any dt",
888
+ * so it calls `stop()` — and the guard is right. Being SILENT about it is
889
+ * what a load error is for: a scene asking for a tick every zero seconds got
890
+ * no ticks and no word said. The runtime guard stays, for code that zeroes
891
+ * the period from a handler.
892
+ */
893
+ static validateJson(node: Node): void;
779
894
  override onReady(): void;
780
895
  override update(dt: number): void;
781
896
  }
@@ -858,6 +973,17 @@ declare class UiSlider extends HudWidgetBase {
858
973
  override focusable: boolean;
859
974
  /** Left/right nudge by one step — the only sane thing a d-pad can mean here. */
860
975
  override _activate(dir: number): void;
976
+ /**
977
+ * Move it as a PERSON would: set the value and say so.
978
+ *
979
+ * `UiButton` has `press()` and the value widgets had nothing, because
980
+ * assigning `.value` deliberately does not emit (restoring a saved setting
981
+ * must not fire the handler that saved it). So a harness — or a game driving
982
+ * its own menu: a preset button, "reset to defaults", a tutorial that moves a
983
+ * slider for you — had one route to "the player changed this", and it was
984
+ * `_activate`, which is internal and takes a direction rather than a value.
985
+ */
986
+ choose(value: number): void;
861
987
  private input;
862
988
  private text;
863
989
  private last;
@@ -874,6 +1000,8 @@ declare class UiToggle extends HudWidgetBase {
874
1000
  override focusable: boolean;
875
1001
  /** Confirm flips it; left/right set it explicitly, which reads better on a pad. */
876
1002
  override _activate(dir: number): void;
1003
+ /** Flip it as a PERSON would: set the value and say so. See `UiSlider.choose`. */
1004
+ choose(value: boolean): void;
877
1005
  private input;
878
1006
  private last;
879
1007
  protected _build(): HTMLElement;
@@ -890,8 +1018,34 @@ declare class UiSelect extends HudWidgetBase {
890
1018
  options: string;
891
1019
  value: string;
892
1020
  override focusable: boolean;
1021
+ /** The options, as the list of values it actually offers. */
1022
+ private choices;
1023
+ /**
1024
+ * A value the list cannot show is a setting the game and the screen disagree
1025
+ * about.
1026
+ *
1027
+ * The browser cannot select an option that does not exist, so it shows the
1028
+ * FIRST one — while `node.value` keeps answering with what it was given, and
1029
+ * `changed` only fires when a person moves it, so nothing ever reconciles
1030
+ * them. That is the shape a saved setting has after a patch removes a quality
1031
+ * tier, and it is silent for the rest of the session.
1032
+ *
1033
+ * A hard error at LOAD, like every other enum in this engine. An empty value
1034
+ * is "nothing chosen yet", which is a choice.
1035
+ */
1036
+ static validateJson(node: Node): void;
893
1037
  /** Left/right (and confirm) walk the list — a select has no other gesture. */
894
1038
  override _activate(dir: number): void;
1039
+ /**
1040
+ * Pick an option as a PERSON would: set the value and say so. See
1041
+ * `UiSlider.choose`.
1042
+ *
1043
+ * An option the list does not offer is refused, for the reason
1044
+ * `validateJson` refuses it in the file: the browser would show the first one
1045
+ * while the node kept answering with what it was given, and nothing would
1046
+ * ever reconcile them.
1047
+ */
1048
+ choose(value: string): void;
895
1049
  private select;
896
1050
  private labelEl;
897
1051
  private lastLabel;
@@ -909,7 +1063,18 @@ declare class UiSelect extends HudWidgetBase {
909
1063
  */
910
1064
  protected _optionLabel(value: string): string;
911
1065
  private fillOptions;
1066
+ /** What was already reported, so a stuck value is said once and not per frame. */
1067
+ private complainedAbout;
1068
+ /**
1069
+ * The runtime half of `validateJson`.
1070
+ *
1071
+ * A behaviour may legitimately write the value first and widen `options`
1072
+ * after — so this reports rather than refuses, and goes quiet again when the
1073
+ * list catches up.
1074
+ */
1075
+ private reportMismatch;
912
1076
  protected override _sync(): void;
1077
+ protected override _pull(): void;
913
1078
  }
914
1079
  /**
915
1080
  * The language picker, done — because every game needs the same one.
@@ -935,7 +1100,7 @@ declare class UiLanguageSelect extends UiSelect {
935
1100
  override label: string;
936
1101
  /** Last locale we PUSHED into `value`, to tell an engine change from a player one. */
937
1102
  private lastLocale;
938
- protected override _sync(): void;
1103
+ protected override _pull(): void;
939
1104
  protected override _optionLabel(value: string): string;
940
1105
  }
941
1106
  /**
@@ -967,6 +1132,7 @@ declare abstract class UiSettingSelect extends UiSelect {
967
1132
  * `settings.quality.high` is worse than one reading `High`. English is the
968
1133
  * base language and the fallback, always.
969
1134
  */
1135
+ protected override _pull(): void;
970
1136
  protected override _sync(): void;
971
1137
  }
972
1138
  /**
@@ -1062,7 +1228,7 @@ declare class UiVolumeSlider extends UiSlider {
1062
1228
  /** Last value we PUSHED in, to tell an engine-side change from a player drag. */
1063
1229
  private lastPushed;
1064
1230
  protected override _labelText(): string;
1065
- protected override _sync(): void;
1231
+ protected override _pull(): void;
1066
1232
  }
1067
1233
  /**
1068
1234
  * The mute switch.
@@ -1079,7 +1245,7 @@ declare class UiMuteToggle extends UiToggle {
1079
1245
  static override readonly props: PropSchema;
1080
1246
  private lastPushed;
1081
1247
  protected override _labelText(): string;
1082
- protected override _sync(): void;
1248
+ protected override _pull(): void;
1083
1249
  }
1084
1250
  //#endregion
1085
1251
  //#region src/core/noise.d.ts
@@ -1208,7 +1374,7 @@ declare function resolveConstants<T extends JsonValue | undefined>(value: T, con
1208
1374
  * duplicating a uid'd template can never mint colliding ids. Names ARE
1209
1375
  * kept — rename clones you need to look up individually.
1210
1376
  */
1211
- declare function duplicateNode(node: Node): Node;
1377
+ declare function duplicateNode(node: Node, opts?: LoadSceneOptions): Node;
1212
1378
  //#endregion
1213
1379
  //#region src/core/scene/serializer.d.ts
1214
1380
  /**
package/dist/index.js CHANGED
@@ -1,15 +1,13 @@
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";
1
+ import { n as jsonEquals, r as jsonKind, t as jsonClone } from "./json-CfTjpvW8.js";
2
+ import { $ as parseNodePath, A as SceneTree, B as HudLayer, D as computeViewport, E as resolveConstants, F as resolveOrderGroups, G as UiText, I as InputMap, J as Node, N as ORDER_GROUP_BASE, O as resolveViewport, P as effectiveOrder, Q as resolveRefInJson, T as isConstRef, U as UiBanner, W as UiBar, X as describeRefProblem, Z as nodeRefWarnings, _ as Scene, a as restoreBehaviors, at as getBehavior, ct as Signal, et as Behavior, h as loadScene, i as captureBehaviors, it as clearBehaviors, j as createSaveStore, k as newUid, n as SaveSlots, nt as behaviorSchema, o as savesWithoutUid, ot as registerBehavior, r as behaviorsWithoutSave, rt as behaviorSignals, s as duplicateNode, st as registeredBehaviors, v as serializeNode, w as CONST_REF_KEY, y as SCENE_FORMAT } from "./save-slots-Bvuh2p_r.js";
3
+ import { A as T_PREFIX, B as SFX_PRESET_NAMES, D as EffectLog, E as LogManager, F as isAudioContextAvailable, G as crossfadeGains, H as synthSfx, I as ROLLOFF_MODELS, K as fadeGain, L as spatialGain, N as translationKey, O as BASE_LOCALE, P as SfxEngine, R as spatialPan, S as qualityEnvironment, T as suggestQuality, U as MusicManager, V as sfxDuration, W as WebAudioMusicBackend, _ as AudioPlayer, a as UiMuteToggle, b as Settings, c as UiRenderScaleSelect, d as UiToggle, f as UiVolumeSlider, g as UiDialogue, h as UiButton, i as UiLanguageSelect, j as suggestLocale, k as Localization, l as UiSelect, m as Respawn, n as UiFrameCapSelect, o as UiPanel, p as Timer, q as AudioBuses, r as UiImage, s as UiQualitySelect, t as registerCoreNodes, u as UiSlider, v as Engine, w as readDeviceHints, z as SFX_PRESETS } from "./register-DuVdzxbq.js";
3
4
  import { t as IncantoError } from "./errors-BpWbnbb_.js";
4
- import { t as Rng } from "./rng-DP-SR7eg.js";
5
- import { n as jsonEquals, r as jsonKind, t as jsonClone } from "./json-CwwhxQgb.js";
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
- 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-BEHLDcQV.js";
5
+ import { t as Rng } from "./rng-CDOMybym.js";
6
+ import { c as getNodeSchema, f as mergeStaticSignals, i as joystickVector, l as getNodeSignals, m as registeredTypes, n as attachTouchControls, o as clearRegistry, p as registerNode, s as createNode, t as TouchControls, u as getNodeType } from "./touch-BnCyPA0G.js";
7
+ import { n as startRecording, r as auditScene, t as replay } from "./replay-DEvp3kyV.js";
9
8
  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";
11
- import { t as createNoise2D } from "./noise-CGUMx44x.js";
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";
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";
9
+ import { a as logText, i as logReport, o as parseDrive, r as resolveRendering, t as isWebGLAvailable } from "./webgl-unavailable-C8aDbGmR.js";
10
+ import { t as createNoise2D } from "./noise-D3nPpmFg.js";
11
+ import { a as PARTICLE_PRESETS, i as ParticleSim, n as resolveFrames, o as PARTICLE_PRESET_NAMES, s as applyParticlePreset, t as resolveAnimation } from "./sprite-animation-CqR2o3SA.js";
12
+ import { a as findPath, i as preloadUrls, n as assetUrls, o as gridFromRows, r as preloadSceneAssets, t as VERSION } from "./src-_jk0qLsS.js";
15
13
  export { AudioBuses, AudioPlayer, BASE_LOCALE, Behavior, CONST_REF_KEY, EffectLog, Engine, HudLayer, IncantoError, InputMap, Localization, LogManager, MusicManager, Node, ORDER_GROUP_BASE, PARTICLE_PRESETS, PARTICLE_PRESET_NAMES, ParticleSim, ROLLOFF_MODELS, Respawn, Rng, SCENE_FORMAT, SFX_PRESETS, SFX_PRESET_NAMES, SaveSlots, Scene, SceneTree, Settings, SfxEngine, Signal, T_PREFIX, Timer, TouchControls, UiBanner, UiBar, UiButton, UiDialogue, UiFrameCapSelect, UiImage, UiLanguageSelect, UiMuteToggle, UiPanel, UiQualitySelect, UiRenderScaleSelect, UiSelect, UiSlider, UiText, UiToggle, UiVolumeSlider, VERSION, WebAudioMusicBackend, applyParticlePreset, assetUrls, attachTouchControls, auditScene, behaviorSchema, behaviorSignals, behaviorsWithoutSave, captureBehaviors, clearBehaviors, clearRegistry, computeViewport, createNode, createNoise2D, createSaveStore, crossfadeGains, describeRefProblem, duplicateNode, effectiveOrder, fadeGain, findPath, getBehavior, getNodeSchema, getNodeSignals, getNodeType, gridFromRows, isAudioContextAvailable, isConstRef, isWebGLAvailable, joystickVector, jsonClone, jsonEquals, jsonKind, loadScene, logReport, logText, mergeStaticSignals, newUid, nodeRefWarnings, parseDrive, parseNodePath, preloadSceneAssets, preloadUrls, qualityEnvironment, readDeviceHints, registerBehavior, registerCoreNodes, registerNode, registeredBehaviors, registeredTypes, replay, resolveAnimation, resolveConstants, resolveFrames, resolveOrderGroups, resolveRefInJson, resolveRendering, resolveViewport, restoreBehaviors, savesWithoutUid, serializeNode, sfxDuration, showBootFailure, spatialGain, spatialPan, startRecording, suggestLocale, suggestQuality, synthSfx, translationKey };
@@ -0,0 +1,67 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, no_symbols) => {
4
+ let target = {};
5
+ for (var name in all) __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true
8
+ });
9
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
10
+ return target;
11
+ };
12
+ //#endregion
13
+ //#region src/core/json.ts
14
+ var json_exports = /* @__PURE__ */ __exportAll({
15
+ jsonClone: () => jsonClone,
16
+ jsonEquals: () => jsonEquals,
17
+ jsonKind: () => jsonKind,
18
+ parseJsonText: () => parseJsonText
19
+ });
20
+ /**
21
+ * `JSON.parse`, minus the byte nobody can see.
22
+ *
23
+ * A UTF-8 byte order mark is legal in a UTF-8 file and meaningless in it, and
24
+ * `JSON.parse` refuses it. Windows PowerShell 5.1's `Set-Content` writes one by
25
+ * default and several editors add it on "save as UTF-8", so a scene written by
26
+ * an ordinary tool came back as
27
+ *
28
+ * ```
29
+ * [BAD_JSON] Unexpected token '\uFEFF', "\uFEFF{ "format"... is not valid JSON
30
+ * ```
31
+ *
32
+ * about a character that is ZERO WIDTH: the author sees valid JSON, an error
33
+ * pointing at nothing, and no way forward. Node's own `require()` of a .json
34
+ * file has stripped it for a decade; `JSON.parse` is the one door that does not.
35
+ */
36
+ function parseJsonText(text) {
37
+ return JSON.parse(text.charCodeAt(0) === 65279 ? text.slice(1) : text);
38
+ }
39
+ function jsonKind(value) {
40
+ if (value === null) return "null";
41
+ if (Array.isArray(value)) return "array";
42
+ const t = typeof value;
43
+ if (t === "string" || t === "number" || t === "boolean") return t;
44
+ return "object";
45
+ }
46
+ /** Deep structural equality over JSON values (used for delta-only serialization). */
47
+ function jsonEquals(a, b) {
48
+ if (a === b) return true;
49
+ if (Array.isArray(a) && Array.isArray(b)) return a.length === b.length && a.every((v, i) => jsonEquals(v, b[i]));
50
+ if (a !== null && b !== null && typeof a === "object" && typeof b === "object") {
51
+ if (Array.isArray(a) || Array.isArray(b)) return false;
52
+ const ka = Object.keys(a);
53
+ const kb = Object.keys(b);
54
+ return ka.length === kb.length && ka.every((k) => k in b && jsonEquals(a[k], b[k]));
55
+ }
56
+ return false;
57
+ }
58
+ /**
59
+ * Deep clone of JSON-safe data (defaults must never be shared between
60
+ * instances). The value must contain only JSON types.
61
+ */
62
+ function jsonClone(value) {
63
+ if (value === null || typeof value !== "object") return value;
64
+ return JSON.parse(JSON.stringify(value));
65
+ }
66
+ //#endregion
67
+ export { parseJsonText as a, json_exports as i, jsonEquals as n, __exportAll as o, jsonKind as r, jsonClone as t };
@@ -1,5 +1,5 @@
1
- import { P as Scene, b as Engine } from "./behavior-rm8vVzu_.js";
2
- import { i as SceneJson } from "./schema-B6ugCV1Q.js";
1
+ import { P as Scene, b as Engine } from "./behavior-Dcz0fr1S.js";
2
+ import { a as SceneJson } from "./rng-Bb-IutXB.js";
3
3
 
4
4
  //#region src/core/scene/loader.d.ts
5
5
  interface LoadSceneOptions {
package/dist/net.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { d as PropSchema, jt as Node } from "./behavior-rm8vVzu_.js";
2
- import { a as NetworkManagerOptions, c as LocalGameServer, d as ServerClass, f as createLocalGameServer, g as Unsubscribe, h as NetworkTransport, i as NetworkManager, l as LocalGameServerOptions, m as LoopbackTransport, n as SplitScreenPlayer, o as applySyncPatch, p as LoopbackHub, r as createSplitScreen, s as CollectionOptions, t as SplitScreenOptions, u as LocalGameServerTransport } from "./split-screen-Cg76MCV5.js";
1
+ import { d as PropSchema, jt as Node } from "./behavior-Dcz0fr1S.js";
2
+ import { t as DiagnosticSink } from "./diagnostics-Cu85N3tL.js";
3
+ import { a as NetworkManagerOptions, c as LocalGameServer, d as ServerClass, f as createLocalGameServer, g as Unsubscribe, h as NetworkTransport, i as NetworkManager, l as LocalGameServerOptions, m as LoopbackTransport, n as SplitScreenPlayer, o as applySyncPatch, p as LoopbackHub, r as createSplitScreen, s as CollectionOptions, t as SplitScreenOptions, u as LocalGameServerTransport } from "./split-screen-CIYf1zSf.js";
3
4
 
4
5
  //#region src/net/agent8.d.ts
5
6
  /**
@@ -22,7 +23,7 @@ declare function createAgent8Server(config?: {
22
23
  verse?: string;
23
24
  account?: string;
24
25
  auth?: string;
25
- }): Promise<NetworkTransport>;
26
+ }, diagnostics?: DiagnosticSink | null): Promise<NetworkTransport>;
26
27
  //#endregion
27
28
  //#region src/net/nodes/network-spawner.d.ts
28
29
  /**
@@ -48,6 +49,8 @@ declare class NetworkSpawner extends Node {
48
49
  private readonly positionTargets;
49
50
  private readonly failedKeys;
50
51
  private readonly reported;
52
+ /** Seconds spent looking for a NetworkManager — see the report in `update`. */
53
+ private waited;
51
54
  override update(dt: number): void;
52
55
  private currentEntries;
53
56
  /**
@@ -63,6 +66,27 @@ declare class NetworkSpawner extends Node {
63
66
  /** Say it ONCE per message — a per-frame repeat would drown the log. */
64
67
  private report;
65
68
  private setProp;
69
+ /**
70
+ * What the NETWORK last said this node's position is — not where it is drawn.
71
+ *
72
+ * A remote copy renders slightly in the past, chasing its target at
73
+ * ~12.5%/frame. That is the right way to draw one and the wrong way to
74
+ * COMPARE one: `incanto-multiplay`'s `agrees` rung read the rendered
75
+ * position, so a late joiner whose interpolation had not converged was
76
+ * reported as disagreeing with the owner —
77
+ *
78
+ * ✗ late has p1's `position` as [-3.3465…], not [-3.3989…]
79
+ *
80
+ * — on both SHIPPED 2D multiplayer examples, which exit 1 today on the plain
81
+ * documented command. The size of the "disagreement" is the player's speed
82
+ * times the chase lag, so a faster game fails harder while replicating
83
+ * perfectly.
84
+ *
85
+ * `undefined` when this spawner has no target for that node: it is not one of
86
+ * ours, or `interpolate` is off, in which case the drawn value IS the
87
+ * received one.
88
+ */
89
+ replicatedPosition(node: Node): number[] | undefined;
66
90
  private stepInterpolation;
67
91
  }
68
92
  //#endregion
package/dist/net.js CHANGED
@@ -1,3 +1,3 @@
1
- import { n as createAgent8Server } from "./agent8-CvsfVskX.js";
2
- import { a as NetworkManager, d as createLocalGameServer, f as LoopbackHub, l as LocalGameServer, n as registerNodesNet, o as applySyncPatch, p as LoopbackTransport, r as NetworkSpawner, t as createSplitScreen, u as LocalGameServerTransport } from "./split-screen-CauMwu6y.js";
1
+ import { n as createAgent8Server } from "./agent8-Cfmd3ar_.js";
2
+ import { a as NetworkManager, d as createLocalGameServer, f as LoopbackHub, l as LocalGameServer, n as registerNodesNet, o as applySyncPatch, p as LoopbackTransport, r as NetworkSpawner, t as createSplitScreen, u as LocalGameServerTransport } from "./split-screen-eULetcg-.js";
3
3
  export { LocalGameServer, LocalGameServerTransport, LoopbackHub, LoopbackTransport, NetworkManager, NetworkSpawner, applySyncPatch, createAgent8Server, createLocalGameServer, createSplitScreen, registerNodesNet };
@@ -1,4 +1,4 @@
1
- import { t as Rng } from "./rng-DP-SR7eg.js";
1
+ import { t as Rng } from "./rng-CDOMybym.js";
2
2
  //#region src/core/noise.ts
3
3
  /** Skewing factors for 2D simplex: F2 = (√3−1)/2, G2 = (3−√3)/6. */
4
4
  const F2 = .5 * (Math.sqrt(3) - 1);