@skewedaspect/sage 0.9.6 → 0.10.0-beta.2

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 (74) hide show
  1. package/dist/behaviors/sound.d.ts +12 -127
  2. package/dist/classes/debugConsole.d.ts +1 -0
  3. package/dist/classes/gameEngine.d.ts +31 -46
  4. package/dist/classes/gameLevel.d.ts +21 -12
  5. package/dist/classes/level.d.ts +24 -29
  6. package/dist/entities/constants.d.ts +1 -0
  7. package/dist/entities/defineEntity.d.ts +17 -0
  8. package/dist/entities/entityPicking.d.ts +15 -0
  9. package/dist/entities/meshConfig.d.ts +14 -0
  10. package/dist/entities/nodeEntity.d.ts +43 -0
  11. package/dist/entities/nodePool.d.ts +8 -0
  12. package/dist/entities/nodeSimulation.d.ts +30 -0
  13. package/dist/entities/nodeSimulationContext.d.ts +17 -0
  14. package/dist/entities/standardMeshSource.d.ts +8 -0
  15. package/dist/events/payloads.d.ts +0 -42
  16. package/dist/events/types.d.ts +2 -23
  17. package/dist/input/actionContext.d.ts +13 -0
  18. package/dist/input/actionRegistry.d.ts +7 -0
  19. package/dist/input/binding.d.ts +33 -0
  20. package/dist/input/bindings/delta.d.ts +23 -0
  21. package/dist/input/bindings/toggle.d.ts +25 -0
  22. package/dist/input/bindings/trigger.d.ts +23 -0
  23. package/dist/input/bindings/value.d.ts +26 -0
  24. package/dist/input/configuration.d.ts +15 -0
  25. package/dist/input/deliverAction.d.ts +4 -0
  26. package/dist/input/deviceReader.d.ts +5 -0
  27. package/dist/input/deviceReaders/gamepad.d.ts +9 -0
  28. package/dist/input/deviceReaders/keyboard.d.ts +8 -0
  29. package/dist/input/deviceReaders/mouse.d.ts +9 -0
  30. package/dist/input/deviceState.d.ts +24 -0
  31. package/dist/input/inputCapture.d.ts +21 -0
  32. package/dist/input/resolveBinding.d.ts +4 -0
  33. package/dist/interfaces/game.d.ts +21 -5
  34. package/dist/interfaces/level.d.ts +21 -3
  35. package/dist/managers/asset.d.ts +17 -3
  36. package/dist/managers/game.d.ts +15 -5
  37. package/dist/managers/input.d.ts +31 -51
  38. package/dist/managers/level.d.ts +20 -4
  39. package/dist/managers/outline.d.ts +4 -4
  40. package/dist/managers/simulationSave.d.ts +38 -0
  41. package/dist/{postProcessingFrameGraph-CaMgQzR-.js → postProcessingFrameGraph-C3Og4kaS.js} +34 -26
  42. package/dist/postProcessingFrameGraph-C3Og4kaS.js.map +1 -0
  43. package/dist/sage.d.ts +54 -16
  44. package/dist/sage.es.js +1868 -2424
  45. package/dist/sage.es.js.map +1 -1
  46. package/dist/sage.umd.js +1 -1
  47. package/dist/sage.umd.js.map +1 -1
  48. package/dist/utils/bounds.d.ts +11 -0
  49. package/dist/utils/physics.d.ts +4 -1
  50. package/package.json +29 -66
  51. package/LICENSE +0 -21
  52. package/Readme.md +0 -73
  53. package/dist/behaviors/index.d.ts +0 -2
  54. package/dist/behaviors/stateMachine.d.ts +0 -76
  55. package/dist/classes/bindings/toggle.d.ts +0 -116
  56. package/dist/classes/bindings/trigger.d.ts +0 -81
  57. package/dist/classes/bindings/value.d.ts +0 -104
  58. package/dist/classes/entity.d.ts +0 -332
  59. package/dist/classes/input/gamepad.d.ts +0 -94
  60. package/dist/classes/input/keyboard.d.ts +0 -66
  61. package/dist/classes/input/mouse.d.ts +0 -91
  62. package/dist/classes/input/readers/gamepad.d.ts +0 -73
  63. package/dist/classes/input/readers/keyboard.d.ts +0 -56
  64. package/dist/classes/input/readers/mouse.d.ts +0 -41
  65. package/dist/interfaces/action.d.ts +0 -22
  66. package/dist/interfaces/binding.d.ts +0 -123
  67. package/dist/interfaces/entity.d.ts +0 -97
  68. package/dist/interfaces/input.d.ts +0 -180
  69. package/dist/managers/binding.d.ts +0 -233
  70. package/dist/managers/entity.d.ts +0 -264
  71. package/dist/managers/save.d.ts +0 -75
  72. package/dist/postProcessingFrameGraph-CaMgQzR-.js.map +0 -1
  73. package/dist/utils/entityProxy.d.ts +0 -2
  74. package/dist/utils/raycast.d.ts +0 -26
package/dist/sage.es.js CHANGED
@@ -1,4 +1,4 @@
1
- import { AbstractMesh as e, ActionManager as t, ArcRotateCamera as n, Color3 as r, Color4 as i, CreateAudioEngineAsync as a, CubeTexture as o, DefaultRenderingPipeline as s, DirectionalLight as c, Engine as l, ExecuteCodeAction as u, FreeCamera as d, HDRCubeTexture as f, HavokPlugin as p, HemisphericLight as m, ImageProcessingConfiguration as h, ImportMeshAsync as g, LoadAssetContainerAsync as _, Matrix as v, Mesh as y, MeshBuilder as b, NullEngine as x, PBRMaterial as S, PhysicsAggregate as C, PhysicsShapeType as w, PointLight as ee, Quaternion as T, RectAreaLight as te, SSAO2RenderingPipeline as ne, Scene as re, SelectionOutlineLayer as ie, SoundState as ae, SpotLight as oe, StandardMaterial as E, Texture as se, TransformNode as D, UniversalCamera as ce, Vector3 as O, WebGPUEngine as le } from "@babylonjs/core";
1
+ import { AbstractMesh as e, ActionManager as t, ArcRotateCamera as n, Color3 as r, Color4 as i, CreateAudioEngineAsync as a, CubeTexture as o, DefaultRenderingPipeline as s, DirectionalLight as c, Engine as l, ExecuteCodeAction as u, FreeCamera as d, HDRCubeTexture as f, HavokPlugin as p, HemisphericLight as m, ImageProcessingConfiguration as h, ImportMeshAsync as g, LoadAssetContainerAsync as ee, Matrix as _, Mesh as v, MeshBuilder as y, NullEngine as b, PBRMaterial as x, PhysicsAggregate as S, PhysicsShapeType as C, PointLight as te, Quaternion as w, RectAreaLight as ne, SSAO2RenderingPipeline as re, Scene as ie, SelectionOutlineLayer as ae, SoundState as oe, SpotLight as T, StandardMaterial as E, Texture as se, TransformNode as D, UniversalCamera as ce, Vector3 as O, WebGPUEngine as le } from "@babylonjs/core";
2
2
  import { registerBuiltInLoaders as ue } from "@babylonjs/loaders/dynamic";
3
3
  import { GeospatialCamera as de } from "@babylonjs/core/Cameras/geospatialCamera";
4
4
  import { ClusteredLightContainer as fe } from "@babylonjs/core/Lights/Clustered/clusteredLightContainer";
@@ -17,7 +17,7 @@ var he = class {
17
17
  }
18
18
  setNamespace(e) {
19
19
  if (!(this._disposed || e === this._namespaceName)) {
20
- this._removeNamespace(), this._namespaceName = e, this._installNamespace();
20
+ this._assertNamespaceFree(e), this._removeNamespace(), this._namespaceName = e, this._installNamespace();
21
21
  for (let [e, t] of this._entries) t.getter ? this._defineGetter(e, t.getter) : this._defineValue(e, t.value);
22
22
  }
23
23
  }
@@ -36,8 +36,11 @@ var he = class {
36
36
  _getNamespace() {
37
37
  return Reflect.get(window, this._namespaceName);
38
38
  }
39
+ _assertNamespaceFree(e) {
40
+ if (!(typeof window > "u") && Reflect.has(window, e)) throw Error(`window.${e} is already occupied, and the debug console will not overwrite it. Pick a different namespace with the debug.namespace option.`);
41
+ }
39
42
  _installNamespace() {
40
- typeof window > "u" || Reflect.set(window, this._namespaceName, {});
43
+ typeof window > "u" || (this._assertNamespaceFree(this._namespaceName), Reflect.set(window, this._namespaceName, {}));
41
44
  }
42
45
  _removeNamespace() {
43
46
  typeof window > "u" || Reflect.deleteProperty(window, this._namespaceName);
@@ -59,7 +62,7 @@ var he = class {
59
62
  configurable: !0
60
63
  });
61
64
  }
62
- }, k = "0.9.6", A = class {
65
+ }, k = "0.10.0-beta.2", ge = class {
63
66
  canvas;
64
67
  renderEngine;
65
68
  physics;
@@ -67,22 +70,27 @@ var he = class {
67
70
  engines;
68
71
  eventBus;
69
72
  logger;
70
- raycast;
73
+ simulation = null;
71
74
  timer;
72
75
  debug;
73
76
  largeWorldRendering;
74
77
  started = !1;
78
+ _stopped = !1;
75
79
  _log;
80
+ _buildSimulation;
76
81
  _beforeStartHook = null;
77
82
  _onStartHook = null;
78
83
  _onTeardownHook = null;
79
84
  constructor(e, t, n, r, i, a, o, s, c, l = !1, u) {
80
- this.canvas = e, this.renderEngine = t, this.physics = n, this.eventBus = r, this.logger = i, this.raycast = a, this.timer = o, this.engines = s, this.managers = c, this.debug = u ?? {
85
+ this.canvas = e, this.renderEngine = t, this.physics = n, this.eventBus = r, this.logger = i, this.timer = a, this._buildSimulation = o, this.engines = s, this.managers = c, this.debug = u ?? {
81
86
  colliders: void 0,
82
87
  console: null,
83
88
  expose: () => {}
84
89
  }, this.largeWorldRendering = l, this._log = i.getLogger("GameEngine");
85
90
  }
91
+ rebuildSimulation(e, t) {
92
+ return this.simulation = this._buildSimulation(e, t), this.simulation;
93
+ }
86
94
  onBeforeStart(e) {
87
95
  if (this._beforeStartHook !== null) throw Error("A beforeStart hook is already registered. Only one hook is allowed per lifecycle event.");
88
96
  this._beforeStartHook = e;
@@ -98,15 +106,13 @@ var he = class {
98
106
  subscribe(e, t) {
99
107
  return this.eventBus.subscribe(e, t);
100
108
  }
101
- subscribeAction(e, t) {
102
- return this.eventBus.subscribe(`action:${e}`, t);
103
- }
104
109
  async start() {
105
110
  this.started ? this._log.warn("Game engine is already started. Skipping start.") : (this._log.info(`Starting SkewedAspect Game Engine (Version: ${k})...`), this._beforeStartHook && (this._log.debug("Executing beforeStart hook..."), await this._beforeStartHook(this)), await this.managers.gameManager.start(), this._log.info("Game engine started successfully"), this._onStartHook && (this._log.debug("Executing onStart hook..."), await this._onStartHook(this)), this.started = !0);
106
111
  }
107
112
  async stop() {
108
- if (this.started) {
109
- this._log.info(`Stopping SkewedAspect Game Engine (Version: ${k})...`);
113
+ if (this._stopped) this._log.warn("Game engine is already stopped. Skipping stop.");
114
+ else {
115
+ this._stopped = !0, this._log.info(`Stopping SkewedAspect Game Engine (Version: ${k})...`);
110
116
  let e = null;
111
117
  if (this._onTeardownHook) try {
112
118
  this._log.debug("Executing onTeardown hook..."), await this._onTeardownHook(this);
@@ -131,9 +137,9 @@ var he = class {
131
137
  }
132
138
  }
133
139
  if (this.started = !1, this._log.info("Game engine stopped successfully"), e) throw e;
134
- } else this._log.warn("Game engine is not started. Skipping stop.");
140
+ }
135
141
  }
136
- }, j = class {
142
+ }, _e = class {
137
143
  timers;
138
144
  constructor() {
139
145
  this.timers = /* @__PURE__ */ new Map();
@@ -192,7 +198,7 @@ var he = class {
192
198
  console.info(`${a} Timer '${t}' completed in ${i.toFixed(2)}ms`, o, s, c);
193
199
  } else console.warn(`[${e}]: Timer '${t}' does not exist`);
194
200
  }
195
- }, M = class {
201
+ }, A = class {
196
202
  trace(e, t, ...n) {}
197
203
  debug(e, t, ...n) {}
198
204
  info(e, t, ...n) {}
@@ -200,11 +206,11 @@ var he = class {
200
206
  error(e, t, ...n) {}
201
207
  time(e, t) {}
202
208
  timeEnd(e, t) {}
203
- }, N = class {
209
+ }, j = class {
204
210
  category;
205
211
  backend;
206
212
  minLevel;
207
- constructor(e, t = "none", n = new M()) {
213
+ constructor(e, t = "none", n = new A()) {
208
214
  this.category = e, this.backend = n, this.minLevel = t;
209
215
  }
210
216
  updateSettings(e, t) {
@@ -242,21 +248,21 @@ var he = class {
242
248
  default: return !1;
243
249
  }
244
250
  }
245
- }, P = class {
251
+ }, M = class {
246
252
  backend;
247
253
  level;
248
254
  loggers;
249
- constructor(e = "debug", t = new j()) {
255
+ constructor(e = "debug", t = new _e()) {
250
256
  this.backend = t, this.level = e, this.loggers = /* @__PURE__ */ new Map();
251
257
  }
252
258
  setBackend(e) {
253
259
  this.backend = e, this.loggers.forEach((e) => {
254
- e instanceof N && e.updateSettings(this.backend, this.level);
260
+ e instanceof j && e.updateSettings(this.backend, this.level);
255
261
  });
256
262
  }
257
263
  setLevel(e) {
258
264
  this.level = e, this.loggers.forEach((e) => {
259
- e instanceof N && e.updateSettings(this.backend, this.level);
265
+ e instanceof j && e.updateSettings(this.backend, this.level);
260
266
  });
261
267
  }
262
268
  getLevel() {
@@ -264,14 +270,14 @@ var he = class {
264
270
  }
265
271
  getLogger(e) {
266
272
  let t = this.loggers.get(e);
267
- return t || (t = new N(e, this.level, this.backend), this.loggers.set(e, t)), t;
273
+ return t || (t = new j(e, this.level, this.backend), this.loggers.set(e, t)), t;
268
274
  }
269
- }, F = class {
275
+ }, N = class {
270
276
  directMap = /* @__PURE__ */ new Map();
271
277
  patternSubs = /* @__PURE__ */ new Set();
272
278
  _log;
273
279
  constructor(e) {
274
- this._log = e?.getLogger("EventBus") || new N("EventBus");
280
+ this._log = e?.getLogger("EventBus") || new j("EventBus");
275
281
  }
276
282
  subscribe(e, t) {
277
283
  return this._log.trace(`Subscribe request for: ${e.toString()}`), e instanceof RegExp || typeof e == "string" && e.includes("*") ? this.subscribePattern(e, t) : this.subscribeExact(e, t);
@@ -316,7 +322,605 @@ var he = class {
316
322
  async $teardown() {
317
323
  this._log.debug("Tearing down EventBus"), this.directMap.clear(), this.patternSubs.clear();
318
324
  }
319
- }, I = class {
325
+ }, P = class {}, F = class extends P {
326
+ defaults = { displayName: "" };
327
+ };
328
+ function ve(e, t) {
329
+ return t;
330
+ }
331
+ var ye = class extends P {
332
+ static ops = ["transitionTo"];
333
+ onUpdate(e) {
334
+ let t = this.state.currentState;
335
+ this.states[t].update?.call(this, e);
336
+ }
337
+ transitionTo(e) {
338
+ if (!(e in this.states)) throw Error(`StateMachineBehavior: no state named "${e}" is declared.`);
339
+ if (e === this.state.currentState) return;
340
+ let t = this.state.currentState;
341
+ this.states[t].exit?.call(this, e), this.state.currentState = e, this.states[e].enter?.call(this, t);
342
+ }
343
+ }, be = 32, xe = 64, Se = 5;
344
+ function I(e) {
345
+ let t = e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace(/\\\*/g, ".*");
346
+ return RegExp(`^${t}$`);
347
+ }
348
+ var L = class e {
349
+ #e = [];
350
+ #t = [];
351
+ #n = /* @__PURE__ */ new Map();
352
+ #r = /* @__PURE__ */ new Map();
353
+ register(e, t) {
354
+ if (this.#n.has(e.id)) throw Error(`A subscriber is already registered under the ID "${e.id}".`);
355
+ this.#n.set(e.id, e);
356
+ let n = [], r = [];
357
+ for (let i of t) {
358
+ let t = i;
359
+ if (t.endsWith(":*")) {
360
+ let n = {
361
+ pattern: I(t),
362
+ subscriber: e
363
+ };
364
+ r.push(n), this.#t.push(n);
365
+ } else n.includes(t) || (n.push(t), this.#i(t, e));
366
+ }
367
+ return this.#o(e, n, r);
368
+ }
369
+ emit(e) {
370
+ this.#e.push(e);
371
+ }
372
+ drain() {
373
+ let e = [], t = 0;
374
+ for (; this.#e.length > 0;) {
375
+ if (t += 1, t > 64) {
376
+ this.#e = [], e.push(/* @__PURE__ */ Error("The drain exceeded 64 passes."));
377
+ break;
378
+ }
379
+ let n = this.#e;
380
+ this.#e = [];
381
+ for (let t of n) this.#s(t, e);
382
+ }
383
+ if (e.length > 0) throw AggregateError(e, "The drain raised.");
384
+ }
385
+ #i(e, t) {
386
+ let n = this.#r.get(e) ?? [];
387
+ n.push(t), this.#r.set(e, n);
388
+ }
389
+ #a(e, t) {
390
+ let n = this.#r.get(e);
391
+ if (n === void 0) return;
392
+ let r = n.indexOf(t);
393
+ r >= 0 && n.splice(r, 1), n.length === 0 && this.#r.delete(e);
394
+ }
395
+ #o(e, t, n) {
396
+ let r = !0;
397
+ return () => {
398
+ if (!r) return;
399
+ r = !1, this.#n.get(e.id) === e && this.#n.delete(e.id);
400
+ for (let n of t) this.#a(n, e);
401
+ let i = [];
402
+ for (let e of this.#t) n.includes(e) || i.push(e);
403
+ this.#t = i;
404
+ };
405
+ }
406
+ #s(t, n) {
407
+ if (t.targetID !== void 0) {
408
+ let r = this.#n.get(t.targetID);
409
+ r !== void 0 && e.#l(r, t, n);
410
+ return;
411
+ }
412
+ let r = /* @__PURE__ */ new Set();
413
+ for (let i of [...this.#r.get(t.type) ?? []]) e.#c(i, t, r, n);
414
+ for (let i of [...this.#t]) i.pattern.test(t.type) && e.#c(i.subscriber, t, r, n);
415
+ }
416
+ static #c(t, n, r, i) {
417
+ r.has(t) || (r.add(t), e.#l(t, n, i));
418
+ }
419
+ static #l(e, t, n) {
420
+ try {
421
+ e.receive(t);
422
+ } catch (e) {
423
+ n.push(e);
424
+ }
425
+ }
426
+ };
427
+ function R(e, t) {
428
+ throw TypeError(`Entity "${e}" state holds a value that is not finite JSON-compatible data at "${t}".`);
429
+ }
430
+ function z(e, t, n, r) {
431
+ if (e === null || typeof e == "string" || typeof e == "boolean") return e;
432
+ if (typeof e == "number") return Number.isFinite(e) || R(t, n), e;
433
+ if (Array.isArray(e)) {
434
+ r.has(e) && R(t, n), r.add(e);
435
+ let i = [];
436
+ for (let [a, o] of e.entries()) i.push(z(o, t, `${n}[${a}]`, r));
437
+ return r.delete(e), i;
438
+ }
439
+ if (typeof e == "object") {
440
+ let i = Object.getPrototypeOf(e);
441
+ (i !== Object.prototype && i !== null || r.has(e)) && R(t, n), r.add(e);
442
+ let a = Object.create(null);
443
+ for (let [i, o] of Object.entries(e)) a[i] = z(o, t, n === "" ? i : `${n}.${i}`, r);
444
+ return r.delete(e), a;
445
+ }
446
+ return R(t, n);
447
+ }
448
+ function B(e, t) {
449
+ return z(e, t, "", /* @__PURE__ */ new Set());
450
+ }
451
+ var Ce = class e {
452
+ id;
453
+ name;
454
+ context;
455
+ state;
456
+ ops;
457
+ eventSubscriptions;
458
+ static behaviors = [];
459
+ #e = [];
460
+ #t = [];
461
+ #n;
462
+ #r = 0;
463
+ #i;
464
+ static create(t, n, r, i) {
465
+ return e.#a(this, t, n, r ?? {}, !0, i);
466
+ }
467
+ static restore(t, n, r, i) {
468
+ return e.#a(this, t, n, r, !1, i);
469
+ }
470
+ static #a(e, t, n, r, i, a) {
471
+ return new e(t, n, r, i, a);
472
+ }
473
+ constructor(t, n, r, i, a) {
474
+ this.id = t, this.name = a ?? new.target.name, this.context = n;
475
+ let o = new.target.behaviors;
476
+ for (let e of o) this.#e.push(new e());
477
+ this.state = e.#u(this.#e, r, t);
478
+ let s = Object.create(null);
479
+ this.ops = s;
480
+ let c = [];
481
+ for (let [e, t] of o.entries()) {
482
+ let n = this.#e[e];
483
+ n !== void 0 && (Object.assign(n, {
484
+ state: this.state,
485
+ ops: s,
486
+ entity: this
487
+ }), this.#o(n, t, s), this.#s(n, t, c));
488
+ }
489
+ this.eventSubscriptions = c, this.#n = n.bus.register(this, c), i && this.#l();
490
+ }
491
+ hasBehavior(e) {
492
+ for (let t of this.#e) if (t instanceof e) return !0;
493
+ return !1;
494
+ }
495
+ getEntity(e) {
496
+ return this.context.getEntity(e);
497
+ }
498
+ emit(e, t, n) {
499
+ let r = {
500
+ type: e,
501
+ senderID: this.id,
502
+ targetID: n,
503
+ payload: t
504
+ };
505
+ if (this.#i !== void 0) {
506
+ this.#i.push(r);
507
+ return;
508
+ }
509
+ this.context.bus.emit(r);
510
+ }
511
+ update(e) {
512
+ for (let t of this.#e) t.onUpdate?.(e);
513
+ }
514
+ receive(t) {
515
+ let n = t;
516
+ for (let r of this.#t) if (e.#f(r, n.type) && r.instance.onEvent?.(t) === !0) return !0;
517
+ return !1;
518
+ }
519
+ destroy() {
520
+ this.#n();
521
+ }
522
+ attachedBehaviors() {
523
+ return [...this.#e];
524
+ }
525
+ #o(e, t, n) {
526
+ for (let r of t.ops ?? []) {
527
+ if (Object.hasOwn(n, r)) throw Error(`Two behaviors on entity "${this.id}" expose the operation "${String(r)}".`);
528
+ let i = e[r];
529
+ if (typeof i != "function") throw Error(`Behavior "${t.name}" declares the operation "${String(r)}" with no method behind it.`);
530
+ n[r] = this.#c(r, i, e);
531
+ }
532
+ }
533
+ #s(e, t, n) {
534
+ let r = [], i = [];
535
+ for (let e of t.events ?? []) {
536
+ let t = e;
537
+ t.endsWith(":*") ? i.push(I(t)) : r.push(t), n.includes(e) || n.push(e);
538
+ }
539
+ (r.length > 0 || i.length > 0) && this.#t.push({
540
+ instance: e,
541
+ exact: r,
542
+ patterns: i
543
+ });
544
+ }
545
+ #c(e, t, n) {
546
+ return (...r) => {
547
+ this.#r += 1;
548
+ try {
549
+ if (this.#r > 32) throw RangeError(`Operation "${String(e)}" on entity "${this.id}" ran deeper than the operation call depth limit of 32.`);
550
+ return t.apply(n, r);
551
+ } finally {
552
+ --this.#r;
553
+ }
554
+ };
555
+ }
556
+ #l() {
557
+ this.#i = [];
558
+ try {
559
+ for (let e of this.#e) e.onCreate?.();
560
+ } catch (e) {
561
+ throw this.#i = void 0, this.#n(), e;
562
+ }
563
+ let e = this.#i;
564
+ this.#i = void 0;
565
+ for (let t of e) this.context.bus.emit(t);
566
+ }
567
+ static #u(t, n, r) {
568
+ let i = Object.create(null);
569
+ i.tags = [];
570
+ for (let e of t) Object.assign(i, B(e.defaults, r));
571
+ return Object.assign(i, B(n, r)), e.#d(i, r), i;
572
+ }
573
+ static #d(e, t) {
574
+ let n = e.tags;
575
+ if (!Array.isArray(n)) throw TypeError(`Entity "${t}" tags must be a list of strings.`);
576
+ let r = [];
577
+ for (let e of n) {
578
+ if (typeof e != "string") throw TypeError(`Entity "${t}" tags must be a list of strings.`);
579
+ if (r.includes(e)) throw Error(`Entity "${t}" carries the tag "${e}" more than once.`);
580
+ r.push(e);
581
+ }
582
+ }
583
+ static #f(e, t) {
584
+ if (e.exact.includes(t)) return !0;
585
+ for (let n of e.patterns) if (n.test(t)) return !0;
586
+ return !1;
587
+ }
588
+ }, we = class e {
589
+ #e = new L();
590
+ #t;
591
+ #n;
592
+ #r;
593
+ #i = 0;
594
+ #a = 0;
595
+ #o = 0;
596
+ #s = [];
597
+ constructor(e) {
598
+ if (this.#t = e.fixedStepDuration, this.#n = e.entityClasses, this.#r = e.allocator, !Number.isFinite(this.#t) || this.#t <= 0) throw RangeError("A fixed step duration must be a finite number greater than zero.");
599
+ }
600
+ get bus() {
601
+ return this.#e;
602
+ }
603
+ get tick() {
604
+ return this.#i;
605
+ }
606
+ get entities() {
607
+ return [...this.#s];
608
+ }
609
+ spawn(e, t, n) {
610
+ let r = this.#f(e), i = t;
611
+ if (i === void 0 && (i = this.#d()), this.getEntity(i) !== void 0) throw Error(`The simulation already holds an entity under the ID "${i}".`);
612
+ let a = r.create(i, this, n ?? {}, e);
613
+ return this.#s.push(a), a;
614
+ }
615
+ despawn(e) {
616
+ let t = this.#s.findIndex((t) => t.id === e);
617
+ if (t < 0) return;
618
+ let n = this.#s[t];
619
+ n !== void 0 && (n.destroy(), this.#s.splice(t, 1));
620
+ }
621
+ getEntity(e) {
622
+ return this.#s.find((t) => t.id === e);
623
+ }
624
+ getEntitiesByTag(t) {
625
+ let n = [];
626
+ for (let r of this.#s) e.#p(r).tags.includes(t) && n.push(r);
627
+ return n;
628
+ }
629
+ runStepsForElapsedTime(e) {
630
+ if (!Number.isFinite(e) || e < 0) throw RangeError("Elapsed time must be a finite number of zero or more.");
631
+ this.#o += e;
632
+ let t = 0;
633
+ for (; this.#l() && t < 5;) this.#u(), t += 1;
634
+ t === 5 && this.#l() && (this.#o %= this.#t);
635
+ }
636
+ snapshot() {
637
+ let e = [];
638
+ for (let t of this.#s) e.push({
639
+ id: t.id,
640
+ name: t.name,
641
+ state: B(t.state, t.id)
642
+ });
643
+ return {
644
+ tick: this.#i,
645
+ idCounter: this.#a,
646
+ entities: e
647
+ };
648
+ }
649
+ fromSnapshot(e) {
650
+ let t = this.buildReplacementSimulation({
651
+ fixedStepDuration: this.#t,
652
+ entityClasses: this.#n,
653
+ allocator: this.#r
654
+ });
655
+ return t.#c(e), t;
656
+ }
657
+ buildReplacementSimulation(t) {
658
+ return new e(t);
659
+ }
660
+ #c(e) {
661
+ let t = [];
662
+ try {
663
+ for (let n of e.entities) {
664
+ let e = this.#f(n.name).restore(n.id, this, n.state, n.name);
665
+ t.push(e);
666
+ }
667
+ } catch (e) {
668
+ for (let e of t) e.destroy();
669
+ throw e;
670
+ }
671
+ this.#s = t, this.#i = e.tick, this.#a = e.idCounter;
672
+ }
673
+ #l() {
674
+ return this.#o + 2 ** -52 >= this.#t;
675
+ }
676
+ #u() {
677
+ for (let e of [...this.#s]) e.update(this.#t);
678
+ try {
679
+ this.#e.drain();
680
+ } finally {
681
+ this.#o -= this.#t, Math.abs(this.#o) <= 2 ** -52 && (this.#o = 0), this.#i += 1;
682
+ }
683
+ }
684
+ #d() {
685
+ return this.#r === void 0 ? (this.#a += 1, `entity-${this.#a}`) : this.#r();
686
+ }
687
+ #f(e) {
688
+ let t = this.#n[e];
689
+ if (t === void 0) throw Error(`The entity class table holds no class named "${e}".`);
690
+ return t;
691
+ }
692
+ static #p(e) {
693
+ return e.state;
694
+ }
695
+ }, V = /* @__PURE__ */ new WeakMap(), H = class e extends Ce {
696
+ static poolable = !1;
697
+ static poolSize;
698
+ static meshConfig;
699
+ static actions;
700
+ #e;
701
+ get node() {
702
+ return this.#e.node;
703
+ }
704
+ get mesh() {
705
+ return this.#e.mesh;
706
+ }
707
+ set mesh(e) {
708
+ this.#e.mesh = e;
709
+ }
710
+ get audio() {
711
+ return this.context.audio;
712
+ }
713
+ showCollider(e, t) {
714
+ let n = this.context.colliders, r = this.#t();
715
+ if (e === void 0 || e === !0) {
716
+ for (let e of r) n.showColliderForNode(e);
717
+ return;
718
+ }
719
+ if (e !== !1) {
720
+ if (typeof e == "string") {
721
+ if (e.startsWith("#")) {
722
+ for (let t of r) n.showColliderForNode(t, e);
723
+ return;
724
+ }
725
+ let i = r.find((t) => t.name === e);
726
+ i && n.showColliderForNode(i, t);
727
+ return;
728
+ }
729
+ for (let t of r) {
730
+ let r = e[t.name];
731
+ r && n.showColliderForNode(t, r);
732
+ }
733
+ }
734
+ }
735
+ hideCollider(e) {
736
+ let t = this.context.colliders, n = this.#t();
737
+ if (e === void 0) {
738
+ for (let e of n) t.hideColliderForNode(e);
739
+ return;
740
+ }
741
+ let r = n.find((t) => t.name === e);
742
+ r && t.hideColliderForNode(r);
743
+ }
744
+ #t() {
745
+ let e = [];
746
+ this.node.physicsBody && e.push(this.node);
747
+ for (let t of this.node.getChildTransformNodes(!1)) t.physicsBody && e.push(t);
748
+ return e;
749
+ }
750
+ constructor(t, n, r, i, a) {
751
+ super(t, n, r, i, a);
752
+ let o = n, s = new.target, c = this.state;
753
+ if (c.position === void 0 && (c.position = {
754
+ x: 0,
755
+ y: 0,
756
+ z: 0
757
+ }), c.rotation === void 0 && (c.rotation = {
758
+ x: 0,
759
+ y: 0,
760
+ z: 0,
761
+ w: 1
762
+ }), c.nodeName !== void 0) this.#e = {
763
+ node: e.#o(o, c.nodeName),
764
+ mesh: void 0
765
+ }, this.#n();
766
+ else {
767
+ let e = s.poolable ? o.pool.take(this.name) : void 0;
768
+ if (e !== void 0) this.#e = e, this.#e.node.setEnabled(!0), this.#a(), V.has(e) ? V.set(e, () => {
769
+ this.#r();
770
+ }) : this.#n();
771
+ else {
772
+ this.#e = {
773
+ node: new D(t, o.scene),
774
+ mesh: void 0
775
+ }, this.#a();
776
+ let e = this.#e;
777
+ V.set(e, () => {
778
+ this.#r();
779
+ }), o.loadMesh(this.name, this.state).then((t) => {
780
+ t !== void 0 && (t.parent = e.node), e.mesh = t;
781
+ let n = V.get(e);
782
+ V.delete(e), n?.();
783
+ });
784
+ }
785
+ }
786
+ if (c.parentID !== void 0) {
787
+ let t = o.getEntity(c.parentID);
788
+ t instanceof e && (this.node.parent = t.node);
789
+ }
790
+ }
791
+ #n() {
792
+ try {
793
+ this.#r();
794
+ } catch (e) {
795
+ throw super.destroy(), e;
796
+ }
797
+ }
798
+ #r() {
799
+ let e = this.state;
800
+ e.debugCollider !== void 0 && this.showCollider(e.debugCollider);
801
+ for (let e of this.attachedBehaviors()) e.onMeshLoaded?.();
802
+ }
803
+ #i() {
804
+ for (let e of this.attachedBehaviors()) e.onDestroy?.();
805
+ }
806
+ update(e) {
807
+ super.update(e), this.state.nodeName === void 0 && this.#a();
808
+ }
809
+ #a() {
810
+ let e = this.state;
811
+ this.node.position = new O(e.position.x, e.position.y, e.position.z), this.node.rotationQuaternion = new w(e.rotation.x, e.rotation.y, e.rotation.z, e.rotation.w);
812
+ }
813
+ destroy() {
814
+ if (this.hideCollider(), this.#i(), super.destroy(), V.has(this.#e) && V.set(this.#e, () => {}), this.state.nodeName !== void 0) return;
815
+ let e = this.constructor;
816
+ e.poolable ? this.context.pool.give(this.name, this.#e, e.poolSize) : this.node.dispose();
817
+ }
818
+ static #o(e, t) {
819
+ let n = e.scene.getNodeByName(t);
820
+ if (!(n instanceof D)) throw Error(`NodeEntity: no authored node named "${t}" exists in the scene.`);
821
+ return n;
822
+ }
823
+ };
824
+ //#endregion
825
+ //#region src/entities/entityPicking.ts
826
+ function Te(e, t) {
827
+ let n = [];
828
+ for (let t of e) t instanceof H && n.push(t);
829
+ let r = t;
830
+ for (; r !== null;) {
831
+ for (let e of n) if (e.node === r) return e;
832
+ r = r.parent;
833
+ }
834
+ }
835
+ function Ee(e, t) {
836
+ if (t?.tags === void 0) return !0;
837
+ let n = e.state.tags;
838
+ for (let e of t.tags) if (!n.includes(e)) return !1;
839
+ return !0;
840
+ }
841
+ function De(e, t, n) {
842
+ if (t === null || !t.hit || t.pickedMesh === null || t.pickedPoint === null) return;
843
+ let r = Te(e, t.pickedMesh);
844
+ if (r === void 0 || !Ee(r, n)) return;
845
+ let i = t.getNormal(!0, !0);
846
+ return {
847
+ entity: r,
848
+ mesh: t.pickedMesh,
849
+ point: t.pickedPoint,
850
+ distance: t.distance,
851
+ normal: i ?? O.Zero()
852
+ };
853
+ }
854
+ //#endregion
855
+ //#region src/entities/nodeSimulation.ts
856
+ var Oe = class e extends we {
857
+ scene;
858
+ pool;
859
+ loadMesh;
860
+ audio;
861
+ colliders;
862
+ #e;
863
+ constructor(e) {
864
+ super(e), this.scene = e.scene, this.pool = e.pool, this.loadMesh = e.loadMesh, this.audio = e.audio, this.colliders = e.colliders, this.#e = e.entityClasses;
865
+ }
866
+ async prewarm(e, t, n = {}) {
867
+ let r = this.#e[e], i = await Promise.all(Array.from({ length: t }, () => this.loadMesh(e, n)));
868
+ for (let t of i) {
869
+ let n = new D(e, this.scene);
870
+ t !== void 0 && (t.parent = n), this.pool.give(e, {
871
+ node: n,
872
+ mesh: t
873
+ }, r?.poolSize);
874
+ }
875
+ }
876
+ pickEntityWithRay(e, t) {
877
+ return De(this.entities, this.scene.pickWithRay(e), t);
878
+ }
879
+ pickEntity(e, t, n) {
880
+ return De(this.entities, this.scene.pick(e, t), n);
881
+ }
882
+ pickEntityForward(e, t, n) {
883
+ return this.pickEntityWithRay(e.getForwardRay(t), n);
884
+ }
885
+ getEntityForMesh(e) {
886
+ return Te(this.entities, e);
887
+ }
888
+ buildReplacementSimulation(t) {
889
+ return new e({
890
+ ...t,
891
+ scene: this.scene,
892
+ pool: this.pool,
893
+ loadMesh: this.loadMesh,
894
+ audio: this.audio,
895
+ colliders: this.colliders
896
+ });
897
+ }
898
+ }, ke = class {
899
+ #e = /* @__PURE__ */ new Map();
900
+ take(e) {
901
+ let t = this.#e.get(e);
902
+ if (t !== void 0) return t.pop();
903
+ }
904
+ give(e, t, n = 8) {
905
+ t.node.parent = null, t.node.setEnabled(!1);
906
+ let r = this.#e.get(e);
907
+ if (r === void 0 && (r = [], this.#e.set(e, r)), r.length >= n) {
908
+ t.node.dispose();
909
+ return;
910
+ }
911
+ r.push(t);
912
+ }
913
+ clear(e) {
914
+ let t = this.#e.get(e);
915
+ if (t !== void 0) {
916
+ for (let e of t) e.node.dispose();
917
+ this.#e.delete(e);
918
+ }
919
+ }
920
+ clearAll() {
921
+ for (let e of [...this.#e.keys()]) this.clear(e);
922
+ }
923
+ }, Ae = class {
320
924
  _engine = null;
321
925
  _mainBus = null;
322
926
  _buses = /* @__PURE__ */ new Map();
@@ -361,7 +965,7 @@ var he = class {
361
965
  //#endregion
362
966
  //#region src/engines/scene.ts
363
967
  ue();
364
- var L = class {
968
+ var je = class {
365
969
  _canvas;
366
970
  _engine;
367
971
  _havok;
@@ -370,7 +974,7 @@ var L = class {
370
974
  this._canvas = e, this._engine = t, this._havok = n, this._log = r.getLogger("SceneEngine");
371
975
  }
372
976
  createScene() {
373
- return new re(this._engine);
977
+ return new ie(this._engine);
374
978
  }
375
979
  enablePhysics(e, t = new O(0, -9.8, 0), n) {
376
980
  this._log.debug(`Enabling physics with gravity (${t.x}, ${t.y}, ${t.z})...`);
@@ -390,32 +994,32 @@ var L = class {
390
994
  return i.intensity = r, i;
391
995
  }
392
996
  createPointLight(e, t, n, r = 1) {
393
- let i = new ee(e, t, n);
997
+ let i = new te(e, t, n);
394
998
  return i.intensity = r, i;
395
999
  }
396
1000
  createSpotLight(e, t, n, r, i, a, o = 1) {
397
- let s = new oe(e, t, n, r, i, a);
1001
+ let s = new T(e, t, n, r, i, a);
398
1002
  return s.intensity = o, s;
399
1003
  }
400
1004
  createRectAreaLight(e, t, n, r, i, a = 1) {
401
- let o = new te(e, t, n, r, i);
1005
+ let o = new ne(e, t, n, r, i);
402
1006
  return o.intensity = a, o;
403
1007
  }
404
1008
  createSphere(e, t = {}, n) {
405
- return b.CreateSphere(e, {
1009
+ return y.CreateSphere(e, {
406
1010
  diameter: 1,
407
1011
  segments: 32,
408
1012
  ...t
409
1013
  }, n);
410
1014
  }
411
1015
  createBox(e, t = {}, n) {
412
- return b.CreateBox(e, {
1016
+ return y.CreateBox(e, {
413
1017
  size: 1,
414
1018
  ...t
415
1019
  }, n);
416
1020
  }
417
1021
  createGround(e, t = {}, n) {
418
- return b.CreateGround(e, {
1022
+ return y.CreateGround(e, {
419
1023
  width: 6,
420
1024
  height: 6,
421
1025
  subdivisions: 2,
@@ -423,7 +1027,7 @@ var L = class {
423
1027
  }, n);
424
1028
  }
425
1029
  createCylinder(e, t = {}, n) {
426
- return b.CreateCylinder(e, {
1030
+ return y.CreateCylinder(e, {
427
1031
  height: 2,
428
1032
  diameterTop: 1,
429
1033
  diameterBottom: 1,
@@ -431,7 +1035,7 @@ var L = class {
431
1035
  }, n);
432
1036
  }
433
1037
  addPhysics(e, t, n = {}, r) {
434
- return new C(e, t, {
1038
+ return new S(e, t, {
435
1039
  mass: 1,
436
1040
  restitution: .75,
437
1041
  friction: .5,
@@ -441,7 +1045,7 @@ var L = class {
441
1045
  async loadModel(e, t) {
442
1046
  this._log.debug(`Loading model: ${e}`);
443
1047
  try {
444
- let n = await _(`${e}`, t);
1048
+ let n = await ee(`${e}`, t);
445
1049
  return this._log.debug(`Model loaded successfully: ${e}`), n;
446
1050
  } catch (t) {
447
1051
  throw this._log.error(`Failed to load model: ${e}`, t), t;
@@ -459,14 +1063,15 @@ var L = class {
459
1063
  async $teardown() {
460
1064
  this._log.info("Tearing down SceneEngine"), this._log.info("SceneEngine torn down successfully");
461
1065
  }
462
- }, R = class {
1066
+ }, Me = 6, Ne = class {
463
1067
  _eventBus;
464
1068
  _sceneEngine;
465
1069
  _log;
466
1070
  _containers = /* @__PURE__ */ new Map();
467
1071
  _sourceMeshes = /* @__PURE__ */ new Map();
1072
+ _pendingContainers = /* @__PURE__ */ new Map();
468
1073
  constructor(e, t, n) {
469
- this._eventBus = e, this._sceneEngine = t, this._log = n?.getLogger("AssetManager") ?? new N("AssetManager");
1074
+ this._eventBus = e, this._sceneEngine = t, this._log = n?.getLogger("AssetManager") ?? new j("AssetManager");
470
1075
  }
471
1076
  _parsePath(e) {
472
1077
  let t = e.indexOf("#");
@@ -478,16 +1083,22 @@ var L = class {
478
1083
  async _loadContainer(e) {
479
1084
  let t = this._containers.get(e);
480
1085
  if (t) return t.refCount++, t.container;
1086
+ let n = this._pendingContainers.get(e);
1087
+ n || (n = this._fetchContainer(e), this._pendingContainers.set(e, n));
1088
+ let r = await n, i = this._containers.get(e);
1089
+ return i && i.refCount++, r;
1090
+ }
1091
+ async _fetchContainer(e) {
481
1092
  this._log.debug(`Loading asset container: ${e}`);
482
- let n = this._sceneEngine.createScene();
1093
+ let t = this._sceneEngine.createScene();
483
1094
  try {
484
- let t = await this._sceneEngine.loadModel(e, n);
1095
+ let n = await this._sceneEngine.loadModel(e, t);
485
1096
  return this._containers.set(e, {
486
- container: t,
487
- refCount: 1
488
- }), this._log.debug(`Cached asset container: ${e}`), t;
1097
+ container: n,
1098
+ refCount: 0
1099
+ }), this._log.debug(`Cached asset container: ${e}`), n;
489
1100
  } finally {
490
- n.dispose();
1101
+ t.dispose(), this._pendingContainers.delete(e);
491
1102
  }
492
1103
  }
493
1104
  _findMeshInContainer(e, t, n) {
@@ -522,15 +1133,34 @@ var L = class {
522
1133
  return t.clone(`${t.name}-clone`);
523
1134
  }
524
1135
  async preload(e) {
525
- let t = e.length;
526
- for (let n = 0; n < e.length; n++) await this.load(e[n]), this._eventBus.publish({
527
- type: "asset:progress",
528
- payload: {
529
- path: e[n],
530
- loaded: n + 1,
531
- total: t
1136
+ let t = e.length, n = [], r = 0, i = 0, a = async () => {
1137
+ for (; r < e.length;) {
1138
+ let a = e[r];
1139
+ r++;
1140
+ let o = !0;
1141
+ try {
1142
+ await this.load(a);
1143
+ } catch (e) {
1144
+ o = !1, n.push({
1145
+ path: a,
1146
+ error: e
1147
+ });
1148
+ }
1149
+ o && (i++, this._eventBus.publish({
1150
+ type: "asset:progress",
1151
+ payload: {
1152
+ path: a,
1153
+ loaded: i,
1154
+ total: t
1155
+ }
1156
+ }));
532
1157
  }
533
- });
1158
+ }, o = [], s = Math.min(Me, t);
1159
+ for (let e = 0; e < s; e++) o.push(a());
1160
+ if (await Promise.all(o), n.length > 0) {
1161
+ let e = n.map((e) => e.path).join(", ");
1162
+ throw AggregateError(n.map((e) => e.error), `Preload failed for ${n.length} of ${t} assets: ${e}`);
1163
+ }
534
1164
  this._eventBus.publish({
535
1165
  type: "asset:complete",
536
1166
  payload: { paths: e }
@@ -552,685 +1182,77 @@ var L = class {
552
1182
  async $teardown() {
553
1183
  this.disposeAll();
554
1184
  }
555
- }, z = [
556
- "trigger",
557
- "toggle",
558
- "value"
559
- ], ge = [
560
- "keyboard",
561
- "mouse",
562
- "gamepad"
563
- ];
564
- function _e(e) {
565
- return e.type === "keyboard";
566
- }
567
- function B(e) {
568
- return e.type === "mouse";
1185
+ };
1186
+ //#endregion
1187
+ //#region src/utils/capabilities.ts
1188
+ function U() {
1189
+ return typeof window < "u" && window.document !== void 0;
569
1190
  }
570
- function V(e) {
571
- return e.type === "gamepad";
1191
+ function Pe() {
1192
+ return U() && !!window.navigator.gpu;
572
1193
  }
573
1194
  //#endregion
574
- //#region src/classes/bindings/trigger.ts
575
- var ve = class {
576
- type = "trigger";
577
- action;
578
- context;
579
- deviceID;
580
- deviceType;
581
- reader;
582
- _edgeMode;
583
- _threshold;
584
- _lastDigitalState = !1;
585
- get options() {
586
- return {
587
- edgeMode: this._edgeMode,
588
- threshold: this._threshold
589
- };
1195
+ //#region src/managers/game.ts
1196
+ var Fe = class {
1197
+ _engine;
1198
+ _eventBus;
1199
+ _gameEngine = null;
1200
+ _inputManager = null;
1201
+ _levelManager;
1202
+ _log;
1203
+ _boundRenderLoop;
1204
+ _boundResizeHandler;
1205
+ _frameCallbacks = [];
1206
+ _nextCallbackId = 0;
1207
+ _paused = !1;
1208
+ started = !1;
1209
+ constructor(e, t, n, r) {
1210
+ this._engine = e, this._eventBus = t, this._levelManager = n, this._log = r?.getLogger("GameManager") || new j("GameManager"), this._boundRenderLoop = this._renderLoop.bind(this), this._boundResizeHandler = this._resizeHandler.bind(this), U() && window.addEventListener("resize", this._boundResizeHandler);
590
1211
  }
591
- constructor(e, t, n, r, i = {}) {
592
- this.action = e, this.deviceID = t, this.deviceType = n, this.reader = r, this.context = i.context, this._edgeMode = i.edgeMode ?? "rising", this._threshold = i.threshold ?? .5;
1212
+ get currentScene() {
1213
+ return this._levelManager.currentLevel?.scene ?? null;
593
1214
  }
594
- process(e, t) {
595
- let n = this.reader.getValue(e) ?? !1, r = typeof n == "boolean" ? n : n >= this._threshold, i = !1;
596
- switch (this._edgeMode) {
597
- case "rising":
598
- i = r && !this._lastDigitalState;
599
- break;
600
- case "falling":
601
- i = !r && this._lastDigitalState;
602
- break;
603
- case "both":
604
- i = r !== this._lastDigitalState;
605
- break;
606
- }
607
- if (this._lastDigitalState = r, i) {
608
- let e;
609
- if (this.action.type === "analog") {
610
- let t = typeof n == "number" ? n : n ? 1 : 0;
611
- if (this.action.minValue !== void 0 || this.action.maxValue !== void 0) {
612
- let e = this.action.minValue ?? 0, n = this.action.maxValue ?? 1;
613
- t = e + t * (n - e);
614
- }
615
- e = t;
616
- } else e = !0;
617
- let r = {
618
- type: `action:${this.action.name}`,
619
- payload: {
620
- value: e,
621
- deviceId: this.deviceID,
622
- context: this.context
623
- }
624
- };
625
- t.publish(r);
626
- }
1215
+ $setGameEngine(e) {
1216
+ this._gameEngine = e;
627
1217
  }
628
- resetEdgeState(e) {
629
- if (e) {
630
- let t = this.reader.getValue(e) ?? !1;
631
- this._lastDigitalState = typeof t == "boolean" ? t : t >= this._threshold;
632
- } else this._lastDigitalState = !1;
1218
+ setInputManager(e) {
1219
+ this._inputManager = e;
633
1220
  }
634
- toJSON() {
635
- return {
636
- type: this.type,
637
- action: this.action.name,
638
- input: {
639
- deviceID: this.deviceID,
640
- ...this.reader.toJSON()
641
- },
642
- context: this.context,
643
- options: this.options
644
- };
1221
+ get isPaused() {
1222
+ return this._paused;
645
1223
  }
646
- }, ye = class {
647
- type = "toggle";
648
- action;
649
- context;
650
- deviceID;
651
- deviceType;
652
- reader;
653
- _invert;
654
- _threshold;
655
- _initialState;
656
- _onValue;
657
- _offValue;
658
- _lastDigitalState = !1;
659
- _toggleState;
660
- get state() {
661
- return this._toggleState;
662
- }
663
- set state(e) {
664
- this._toggleState = e;
665
- }
666
- get onValue() {
667
- return this._onValue;
668
- }
669
- get offValue() {
670
- return this._offValue;
671
- }
672
- get value() {
673
- return this.action.type === "analog" ? this._toggleState ? this.action.maxValue ?? 1 : this.action.minValue ?? 0 : this._toggleState ? this._onValue : this._offValue;
674
- }
675
- get options() {
676
- return {
677
- invert: this._invert,
678
- threshold: this._threshold,
679
- initialState: this._initialState,
680
- onValue: this._onValue,
681
- offValue: this._offValue
1224
+ registerFrameCallback(e, t) {
1225
+ let n = this._nextCallbackId++;
1226
+ return this._frameCallbacks.push({
1227
+ id: n,
1228
+ callback: e,
1229
+ suspendedByPause: t?.suspendedByPause ?? !0
1230
+ }), this._log.debug(`Registered frame callback (id: ${n})`), () => {
1231
+ let e = this._frameCallbacks.findIndex((e) => e.id === n);
1232
+ e !== -1 && (this._frameCallbacks.splice(e, 1), this._log.debug(`Unregistered frame callback (id: ${n})`));
682
1233
  };
683
1234
  }
684
- constructor(e, t, n, r, i = {}) {
685
- this.action = e, this.deviceID = t, this.deviceType = n, this.reader = r, this.context = i.context, this._invert = i.invert ?? !1, this._threshold = i.threshold ?? .5, this._initialState = i.initialState ?? !1, this._toggleState = this._initialState, this._onValue = i.onValue ?? !0, this._offValue = i.offValue ?? !1;
1235
+ _renderLoop() {
1236
+ let e = this._engine.getDeltaTime() / 1e3;
1237
+ if (!this._paused) {
1238
+ if (this._gameEngine === null) throw Error("GameManager: gameEngine not set. Call $setGameEngine() first.");
1239
+ this._gameEngine.simulation !== null && (this._inputManager !== null && this._inputManager.routeCapturedInput(this._gameEngine.simulation), this._gameEngine.simulation.runStepsForElapsedTime(e));
1240
+ }
1241
+ for (let { callback: t, suspendedByPause: n } of this._frameCallbacks) if (!(this._paused && n)) try {
1242
+ t(e);
1243
+ } catch (e) {
1244
+ this._log.error("Error in frame callback:", e);
1245
+ }
1246
+ this.currentScene && this.currentScene.render();
686
1247
  }
687
- process(e, t) {
688
- let n = this.reader.getValue(e) ?? !1, r = typeof n == "boolean" ? n : n >= this._threshold, i = this._invert ? !r && this._lastDigitalState : r && !this._lastDigitalState;
689
- this._lastDigitalState = r, i && (this._toggleState = !this._toggleState, t.publish({
690
- type: `action:${this.action.name}`,
691
- payload: {
692
- value: this.value,
693
- deviceId: this.deviceID,
694
- context: this.context
695
- }
696
- }));
1248
+ _resizeHandler() {
1249
+ this.started && this._engine.resize();
697
1250
  }
698
- resetEdgeState(e) {
699
- if (e) {
700
- let t = this.reader.getValue(e) ?? !1;
701
- this._lastDigitalState = typeof t == "boolean" ? t : t >= this._threshold;
702
- } else this._lastDigitalState = !1;
1251
+ async start() {
1252
+ this._engine.runRenderLoop(this._boundRenderLoop), this.started = !0, this._log.info("SkewedAspect Game Engine started successfully");
703
1253
  }
704
- reset() {
705
- this._toggleState = this._initialState;
706
- }
707
- toJSON() {
708
- return {
709
- type: this.type,
710
- action: this.action.name,
711
- input: {
712
- deviceID: this.deviceID,
713
- ...this.reader.toJSON()
714
- },
715
- state: this._toggleState,
716
- context: this.context,
717
- options: this.options
718
- };
719
- }
720
- }, be = class {
721
- type = "value";
722
- action;
723
- context;
724
- deviceID;
725
- deviceType;
726
- reader;
727
- _scale;
728
- _offset;
729
- _invert;
730
- _emitOnChange;
731
- _deadzone;
732
- _onValue;
733
- _offValue;
734
- _min;
735
- _max;
736
- _lastValue;
737
- get options() {
738
- return {
739
- scale: this._scale,
740
- offset: this._offset,
741
- invert: this._invert,
742
- emitOnChange: this._emitOnChange,
743
- deadzone: this._deadzone,
744
- onValue: this._onValue,
745
- offValue: this._offValue,
746
- min: this._min,
747
- max: this._max
748
- };
749
- }
750
- constructor(e, t, n, r, i = {}) {
751
- this.action = e, this.deviceID = t, this.deviceType = n, this.reader = r, this.context = i.context, this._scale = i.scale ?? 1, this._offset = i.offset ?? 0, this._invert = i.invert ?? !1, this._emitOnChange = i.emitOnChange ?? !0, this._deadzone = i.deadzone ?? 0, this._onValue = i.onValue ?? !0, this._offValue = i.offValue ?? !1;
752
- let a = this.action.type === "analog" ? this.action.minValue ?? -Infinity : -Infinity;
753
- this._min = i.min ?? a;
754
- let o = this.action.type === "analog" ? this.action.maxValue ?? Infinity : Infinity;
755
- this._max = i.max ?? o;
756
- }
757
- process(e, t) {
758
- let n = this.reader.getValue(e);
759
- if (n === void 0) return;
760
- let r = typeof n == "boolean" ? n ? 1 : 0 : n, i = this._deadzone > 0 && Math.abs(r) < this._deadzone ? 0 : r;
761
- i = (this._invert ? -i : i) * this._scale + this._offset, i = Math.max(this._min, Math.min(this._max, i)), !(this._emitOnChange && this._lastValue === i) && (this._lastValue = i, t.publish({
762
- type: `action:${this.action.name}`,
763
- payload: {
764
- value: i,
765
- deviceId: this.deviceID,
766
- context: this.context
767
- }
768
- }));
769
- }
770
- resetEdgeState(e) {}
771
- toJSON() {
772
- return {
773
- type: this.type,
774
- action: this.action.name,
775
- input: {
776
- deviceID: this.deviceID,
777
- ...this.reader.toJSON()
778
- },
779
- context: this.context,
780
- options: this.options
781
- };
782
- }
783
- }, xe = class e {
784
- sourceType = "key";
785
- sourceKey;
786
- useDelta;
787
- constructor(e, t = {}) {
788
- this.sourceKey = e, this.useDelta = t.useDelta || !1;
789
- }
790
- getValue(e) {
791
- if (e.type !== "keyboard") return;
792
- let t = e;
793
- return this.useDelta ? t.delta[this.sourceKey] : t.keys[this.sourceKey];
794
- }
795
- static fromString(t, n = {}) {
796
- return new e(t, n);
797
- }
798
- toJSON() {
799
- return {
800
- type: "keyboard",
801
- sourceType: this.sourceType,
802
- sourceKey: this.sourceKey,
803
- options: { useDelta: this.useDelta }
804
- };
805
- }
806
- }, Se = class e {
807
- sourceType;
808
- sourceKey;
809
- constructor(e, t) {
810
- this.sourceType = e, this.sourceKey = t;
811
- }
812
- getValue(e) {
813
- if (e.type === "mouse") switch (this.sourceType) {
814
- case "button": {
815
- let t = e.buttons[this.sourceKey];
816
- return t ? t.pressed : void 0;
817
- }
818
- case "position": {
819
- let [t, n] = this.sourceKey.split(":");
820
- return !t || !n || t !== "absolute" && t !== "relative" || n !== "x" && n !== "y" ? void 0 : e.position[t][n];
821
- }
822
- case "wheel": {
823
- let t = this.sourceKey === "deltaX" || this.sourceKey === "deltaY" || this.sourceKey === "deltaZ";
824
- return e.wheel && t ? e.wheel[this.sourceKey] : void 0;
825
- }
826
- default: return;
827
- }
828
- }
829
- static fromString(t) {
830
- let [n, ...r] = t.split(":"), i = r.join(":");
831
- if (!n || !i) throw Error(`Invalid mouse source format: ${t}`);
832
- return new e(n, i);
833
- }
834
- toJSON() {
835
- return {
836
- type: "mouse",
837
- sourceType: this.sourceType,
838
- sourceKey: this.sourceKey
839
- };
840
- }
841
- }, Ce = class e {
842
- sourceType;
843
- sourceKey;
844
- useAnalogValue;
845
- deadzone;
846
- invert;
847
- constructor(e, t, n = {}) {
848
- this.sourceType = e, this.sourceKey = t, this.useAnalogValue = n.useAnalogValue || !1, this.deadzone = n.deadzone || .1, this.invert = n.invert || !1;
849
- }
850
- getValue(e) {
851
- if (e.type === "gamepad") switch (this.sourceType) {
852
- case "button": {
853
- let t = e.buttons[this.sourceKey];
854
- return t ? this.useAnalogValue ? t.value : t.pressed : void 0;
855
- }
856
- case "axis": {
857
- let t = e.axes[this.sourceKey];
858
- return t === void 0 ? void 0 : (Math.abs(t) < this.deadzone && (t = 0), this.invert ? -t : t);
859
- }
860
- default: return;
861
- }
862
- }
863
- static fromString(t, n = {}) {
864
- let [r, i] = t.split(":");
865
- if (!r || !i) throw Error(`Invalid gamepad source format: ${t}`);
866
- return new e(r, i, n);
867
- }
868
- toJSON() {
869
- return {
870
- type: "gamepad",
871
- sourceType: this.sourceType,
872
- sourceKey: this.sourceKey,
873
- options: {
874
- useAnalogValue: this.useAnalogValue,
875
- deadzone: this.deadzone,
876
- invert: this.invert
877
- }
878
- };
879
- }
880
- }, we = .05, Te = .5, Ee = class {
881
- _bindings = /* @__PURE__ */ new Map();
882
- _actions = /* @__PURE__ */ new Map();
883
- _contexts = /* @__PURE__ */ new Map();
884
- _activeContexts = /* @__PURE__ */ new Set();
885
- _lastActiveDeviceType = null;
886
- _lastInputState = /* @__PURE__ */ new Map();
887
- _captureState = null;
888
- _eventBus;
889
- _inputUnsubscribe = null;
890
- _log;
891
- constructor(e, t) {
892
- this._eventBus = e, this._inputUnsubscribe = this._eventBus.subscribe("input:changed", (e) => {
893
- let t = e.payload;
894
- t && this.$handleInput(t.device, t.state);
895
- }), this._log = t?.getLogger("BindingManager") || new N("BindingManager"), this._log.debug("BindingManager initialized");
896
- }
897
- _isBindingContextActive(e) {
898
- return e.context ? this._activeContexts.has(e.context) : !0;
899
- }
900
- _getOrCreateContext(e, t = !0) {
901
- let n = this._contexts.get(e);
902
- return n || (n = {
903
- name: e,
904
- exclusive: t
905
- }, this._contexts.set(e, n), this._log.debug(`Auto-created context "${e}" (exclusive: ${t})`)), n;
906
- }
907
- _deactivateExclusiveContexts(e) {
908
- let t = [];
909
- for (let n of this._activeContexts) n !== e && this._contexts.get(n)?.exclusive && (this._activeContexts.delete(n), t.push(n));
910
- return t;
911
- }
912
- _shouldUpdateActiveDevice(e) {
913
- return B(e) ? Object.values(e.buttons).some((e) => e.pressed) || e.wheel !== void 0 : V(e) ? Object.values(e.buttons).some((e) => e.pressed) || Object.values(e.axes).some((e) => Math.abs(e) > we) : !0;
914
- }
915
- _createBindingFromDefinition(e) {
916
- let t = this._actions.get(e.action);
917
- if (!t) return this._log.warn(`Cannot create binding: Action "${e.action}" not found.`), null;
918
- let { deviceID: n, ...r } = e.input;
919
- switch (e.type) {
920
- case "trigger": return new ve(t, n, e.input.type, this._createInputSourceFromDefinition(r), {
921
- ...e.options || {},
922
- context: e.context
923
- });
924
- case "toggle": return new ye(t, n, e.input.type, this._createInputSourceFromDefinition(r), {
925
- ...e.options || {},
926
- context: e.context
927
- });
928
- case "value": return new be(t, n, e.input.type, this._createInputSourceFromDefinition(r), {
929
- ...e.options || {},
930
- context: e.context
931
- });
932
- default: return this._log.error(`Binding type not implemented: ${e.type}`), null;
933
- }
934
- }
935
- _createInputSourceFromDefinition(e) {
936
- switch (e.type) {
937
- case "keyboard": return new xe(e.sourceKey, e.options);
938
- case "mouse": {
939
- let t = e.sourceType;
940
- if (!(t === "button" || t === "position" || t === "wheel")) throw Error(`Invalid mouse source type: ${t}`);
941
- return new Se(t, e.sourceKey);
942
- }
943
- case "gamepad": {
944
- let t = e.sourceType;
945
- if (!(t === "button" || t === "axis")) throw Error(`Invalid gamepad source type: ${t}`);
946
- return new Ce(t, e.sourceKey, e.options);
947
- }
948
- default: throw Error(`Unsupported input source type: ${e.type}`);
949
- }
950
- }
951
- _processCaptureInput(e, t) {
952
- let n = this._captureState;
953
- if (!n) return;
954
- let { options: r } = n;
955
- if (!r.deviceTypes.includes(e.type)) return;
956
- let i = null;
957
- if (_e(t)) {
958
- if (t.event?.repeat === !0) return;
959
- for (let n of Object.keys(t.delta)) if (t.delta[n] === !0) {
960
- i = {
961
- type: "keyboard",
962
- sourceType: "key",
963
- sourceKey: n,
964
- deviceID: e.id
965
- };
966
- break;
967
- }
968
- } else if (B(t)) {
969
- for (let n of Object.keys(t.buttons)) if (t.buttons[n].pressed) {
970
- i = {
971
- type: "mouse",
972
- sourceType: "button",
973
- sourceKey: n,
974
- deviceID: e.id
975
- };
976
- break;
977
- }
978
- } else if (V(t)) {
979
- for (let n of Object.keys(t.buttons)) if (t.buttons[n].pressed) {
980
- i = {
981
- type: "gamepad",
982
- sourceType: "button",
983
- sourceKey: n,
984
- deviceID: e.id
985
- };
986
- break;
987
- }
988
- if (!i) {
989
- for (let n of Object.keys(t.axes)) if (Math.abs(t.axes[n]) > Te) {
990
- i = {
991
- type: "gamepad",
992
- sourceType: "axis",
993
- sourceKey: n,
994
- deviceID: e.id
995
- };
996
- break;
997
- }
998
- }
999
- }
1000
- if (!i || r.sourceTypes && !r.sourceTypes.includes(i.sourceType)) return;
1001
- let { resolve: a } = n;
1002
- this._cleanupCapture(), a(i);
1003
- }
1004
- _cleanupCapture() {
1005
- let e = this._captureState;
1006
- if (!e) return;
1007
- e.abortCleanup && e.abortCleanup();
1008
- let { snapshot: t } = e;
1009
- this._captureState = null, this.deactivateContext("__sage_capture__"), this._contexts.delete("__sage_capture__");
1010
- for (let e of t) this.activateContext(e);
1011
- }
1012
- $handleInput(e, t) {
1013
- if (this._lastInputState.set(e.id, t), this._shouldUpdateActiveDevice(t) && e.type !== this._lastActiveDeviceType) {
1014
- let t = this._lastActiveDeviceType;
1015
- this._lastActiveDeviceType = e.type, this._eventBus.publish({
1016
- type: "input:device-type:changed",
1017
- payload: {
1018
- deviceType: e.type,
1019
- previousDeviceType: t
1020
- }
1021
- });
1022
- }
1023
- if (this._captureState) {
1024
- this._processCaptureInput(e, t);
1025
- return;
1026
- }
1027
- let n = this._bindings.get(e.id);
1028
- if (!(!n || n.length === 0) && !(this._activeContexts.size === 0 && n.some((e) => e.context))) for (let e of n) this._isBindingContextActive(e) && e.process(t, this._eventBus);
1029
- }
1030
- registerAction(e) {
1031
- if (this._log.debug(`Registering action "${e.name}"`), this._actions.has(e.name)) {
1032
- let t = `Action "${e.name}" already registered.`;
1033
- throw this._log.error(t), Error(t);
1034
- }
1035
- this._actions.set(e.name, e), this._log.debug(`Action "${e.name}" registered successfully`);
1036
- }
1037
- getAction(e) {
1038
- this._log.trace(`Getting action "${e}"`);
1039
- let t = this._actions.get(e) ?? null;
1040
- return t || this._log.debug(`Action "${e}" not found`), t;
1041
- }
1042
- get lastActiveDeviceType() {
1043
- return this._lastActiveDeviceType;
1044
- }
1045
- captureInput(e) {
1046
- if (this._captureState) throw Error("captureInput() already in progress");
1047
- let t = [...this._activeContexts];
1048
- return this.registerContext("__sage_capture__", !0), this.activateContext("__sage_capture__"), new Promise((n, r) => {
1049
- let i = {
1050
- resolve: n,
1051
- reject: r,
1052
- options: e,
1053
- snapshot: t
1054
- };
1055
- if (this._captureState = i, e.signal) {
1056
- if (e.signal.aborted) {
1057
- this._cleanupCapture(), r(e.signal.reason ?? /* @__PURE__ */ Error("captureInput() aborted"));
1058
- return;
1059
- }
1060
- let t = () => {
1061
- let t = e.signal?.reason ?? /* @__PURE__ */ Error("captureInput() aborted");
1062
- this._cleanupCapture(), r(t);
1063
- };
1064
- e.signal.addEventListener("abort", t, { once: !0 }), i.abortCleanup = () => {
1065
- e.signal?.removeEventListener("abort", t);
1066
- };
1067
- }
1068
- });
1069
- }
1070
- registerContext(e, t = !0) {
1071
- let n = this._getOrCreateContext(e, t);
1072
- return n.exclusive !== t && (n.exclusive = t, this._log.info(`Updated context "${e}" exclusivity: ${t}`)), n;
1073
- }
1074
- activateContext(e) {
1075
- let t = this._getOrCreateContext(e).exclusive;
1076
- this._log.debug(`Activating context "${e}" (exclusive: ${t})`);
1077
- let n = this._activeContexts.has(e);
1078
- if (t) {
1079
- let t = this._deactivateExclusiveContexts(e);
1080
- t.length > 0 && this._log.info(`Deactivated exclusive contexts: ${t.join(", ")}`);
1081
- }
1082
- if (!n) {
1083
- this._activeContexts.add(e);
1084
- for (let [t, n] of this._bindings.entries()) {
1085
- let r = this._lastInputState.get(t);
1086
- for (let t of n) t.context === e && t.resetEdgeState(r);
1087
- }
1088
- this._log.info(`Context "${e}" activated${t ? " as exclusive" : ""}`);
1089
- }
1090
- }
1091
- deactivateContext(e) {
1092
- this._log.debug(`Deactivating context "${e}"`), this._activeContexts.has(e) ? (this._activeContexts.delete(e), this._log.info(`Context "${e}" deactivated`)) : this._log.debug(`Context "${e}" was not active`);
1093
- }
1094
- getActiveContexts() {
1095
- return [...this._activeContexts];
1096
- }
1097
- isContextActive(e) {
1098
- return this._activeContexts.has(e);
1099
- }
1100
- getContext(e) {
1101
- return this._contexts.get(e) || null;
1102
- }
1103
- $registerBinding(e) {
1104
- if (!z.includes(e.type)) throw Error(`Invalid binding type: ${e.type}`);
1105
- e.context && !this._contexts.has(e.context) && this.registerContext(e.context), this._bindings.has(e.deviceID) || this._bindings.set(e.deviceID, []), this._bindings.get(e.deviceID)?.push(e), this._log.debug(`Registered ${e.type} binding for "${e.action.name}" in context "${e.context || null}"`);
1106
- }
1107
- registerBinding(e) {
1108
- let t = this._createBindingFromDefinition(e);
1109
- t ? this.$registerBinding(t) : this._log.error(`Failed to create binding for action "${e.action}" with type "${e.type}"`);
1110
- }
1111
- unregisterBindings(e, t = null) {
1112
- this._log.debug(`Unregistering all bindings for action "${e}" in context "${t}"`);
1113
- let n = 0;
1114
- for (let [r, i] of this._bindings.entries()) {
1115
- let a = i.filter((r) => {
1116
- let i = r.context || null, a = r.action.name !== e || i !== t;
1117
- return a || n++, a;
1118
- });
1119
- a.length !== i.length && this._bindings.set(r, a);
1120
- }
1121
- this._log.info(`Removed ${n} bindings for action "${e}" in context "${t}"`);
1122
- }
1123
- getBindingsForAction(e, t, n) {
1124
- let r = [];
1125
- for (let i of this._bindings.values()) for (let a of i) {
1126
- if (a.action.name !== e || t !== void 0 && a.deviceType !== t) continue;
1127
- let i = a.context || null;
1128
- n !== void 0 && i !== n || r.push(a);
1129
- }
1130
- return r;
1131
- }
1132
- exportConfiguration() {
1133
- this._log.debug("Exporting binding configuration");
1134
- let e = [...this._actions.values()].map((e) => e.type === "analog" ? {
1135
- name: e.name,
1136
- type: e.type,
1137
- label: e.label,
1138
- minValue: e.minValue ?? 0,
1139
- maxValue: e.maxValue ?? 1
1140
- } : e), t = [];
1141
- for (let e of this._bindings.values()) for (let n of e) t.push(n.toJSON());
1142
- let n = [...this._contexts.values()].map((e) => ({
1143
- name: e.name,
1144
- exclusive: e.exclusive,
1145
- active: this._activeContexts.has(e.name)
1146
- }));
1147
- return this._log.info(`Configuration exported: ${e.length} actions, ${t.length} bindings, ${n.length} contexts`), {
1148
- actions: e,
1149
- bindings: t,
1150
- contexts: n
1151
- };
1152
- }
1153
- importConfiguration(e) {
1154
- this._log.debug("Importing binding configuration"), this._bindings.clear(), this._actions.clear(), this._contexts.clear(), this._activeContexts.clear();
1155
- for (let t of e.actions) this.registerAction(t);
1156
- for (let t of e.contexts) this.registerContext(t.name, t.exclusive), t.active && this.activateContext(t.name);
1157
- for (let t of e.bindings) try {
1158
- this.registerBinding(t);
1159
- } catch (e) {
1160
- e instanceof Error && this._log.error(`Failed to import binding for action "${t.action}": ${e.message}`);
1161
- }
1162
- this._log.info(`Configuration imported: ${e.actions.length} actions, ${e.bindings.length} bindings, ${e.contexts.length} contexts`);
1163
- }
1164
- async $teardown() {
1165
- if (this._log.info("Tearing down BindingManager"), this._captureState) {
1166
- let { reject: e } = this._captureState;
1167
- this._cleanupCapture(), e(/* @__PURE__ */ Error("BindingManager torn down during captureInput()"));
1168
- }
1169
- this._inputUnsubscribe &&= (this._inputUnsubscribe(), null), this._bindings.clear(), this._lastInputState.clear(), this._actions.clear(), this._contexts.clear(), this._activeContexts.clear(), this._lastActiveDeviceType = null, this._log.info("BindingManager torn down successfully");
1170
- }
1171
- };
1172
- //#endregion
1173
- //#region src/utils/capabilities.ts
1174
- function H() {
1175
- return typeof window < "u" && window.document !== void 0;
1176
- }
1177
- function De() {
1178
- return H() && !!window.navigator.gpu;
1179
- }
1180
- //#endregion
1181
- //#region node_modules/hexoid/dist/index.mjs
1182
- for (var Oe = class {
1183
- _engine;
1184
- _eventBus;
1185
- _entityManager;
1186
- _inputManager;
1187
- _levelManager;
1188
- _log;
1189
- _boundRenderLoop;
1190
- _boundResizeHandler;
1191
- _frameCallbacks = [];
1192
- _nextCallbackId = 0;
1193
- _paused = !1;
1194
- started = !1;
1195
- constructor(e, t, n, r, i, a) {
1196
- this._engine = e, this._eventBus = t, this._entityManager = n, this._inputManager = r, this._levelManager = i, this._log = a?.getLogger("GameManager") || new N("GameManager"), this._boundRenderLoop = this._renderLoop.bind(this), this._boundResizeHandler = this._resizeHandler.bind(this), H() && window.addEventListener("resize", this._boundResizeHandler);
1197
- }
1198
- get currentScene() {
1199
- return this._levelManager.currentLevel?.scene ?? null;
1200
- }
1201
- get isPaused() {
1202
- return this._paused;
1203
- }
1204
- registerFrameCallback(e) {
1205
- let t = this._nextCallbackId++;
1206
- return this._frameCallbacks.push({
1207
- id: t,
1208
- callback: e
1209
- }), this._log.debug(`Registered frame callback (id: ${t})`), () => {
1210
- let e = this._frameCallbacks.findIndex((e) => e.id === t);
1211
- e !== -1 && (this._frameCallbacks.splice(e, 1), this._log.debug(`Unregistered frame callback (id: ${t})`));
1212
- };
1213
- }
1214
- _renderLoop() {
1215
- let e = this._engine.getDeltaTime() / 1e3;
1216
- if (this._inputManager.pollGamepads(), !this._paused) {
1217
- this._entityManager.$frameUpdate(e);
1218
- for (let { callback: t } of this._frameCallbacks) try {
1219
- t(e);
1220
- } catch (e) {
1221
- this._log.error("Error in frame callback:", e);
1222
- }
1223
- }
1224
- this.currentScene && this.currentScene.render();
1225
- }
1226
- _resizeHandler() {
1227
- this.started && this._engine.resize();
1228
- }
1229
- async start() {
1230
- this._engine.runRenderLoop(this._boundRenderLoop), this.started = !0, this._log.info("SkewedAspect Game Engine started successfully");
1231
- }
1232
- async stop() {
1233
- this.started = !1, this._engine.stopRenderLoop(), this._log.info("SkewedAspect Game Engine stopped successfully");
1254
+ async stop() {
1255
+ this.started = !1, this._engine.stopRenderLoop(), this._log.info("SkewedAspect Game Engine stopped successfully");
1234
1256
  }
1235
1257
  pause(e) {
1236
1258
  if (this._paused) {
@@ -1253,599 +1275,322 @@ for (var Oe = class {
1253
1275
  });
1254
1276
  }
1255
1277
  async $teardown() {
1256
- this._log.info("Tearing down GameManager"), this.started && await this.stop(), H() && window.removeEventListener("resize", this._boundResizeHandler), this._frameCallbacks = [], this._log.info("GameManager torn down successfully");
1278
+ this._log.info("Tearing down GameManager"), this.started && await this.stop(), U() && window.removeEventListener("resize", this._boundResizeHandler), this._frameCallbacks = [], this._log.info("GameManager torn down successfully");
1257
1279
  }
1258
- }, U = 256, W = []; U--;) W[U] = (U + 256).toString(16).substring(1);
1259
- function ke(e) {
1260
- e ||= 16;
1261
- var t = "", n = 0;
1262
- return function() {
1263
- if (!t || n === 256) {
1264
- for (t = "", n = (1 + e) / 2 | 0; n--;) t += W[256 * Math.random() | 0];
1265
- t = t.substring(n = 0, e - 2);
1266
- }
1267
- return t + W[n++];
1268
- };
1269
- }
1270
- //#endregion
1271
- //#region src/utils/id.ts
1272
- var Ae = ke(16), G = class {
1273
- entity = null;
1274
- $emit(e) {
1275
- if (!this.entity) throw Error("Entity is not set for this behavior.");
1276
- e.senderID = this.entity.id, this.entity.eventBus.publish(e);
1277
- }
1278
- $emitStateChanged(e, t) {
1279
- if (!this.entity) throw Error("Entity is not set for this behavior.");
1280
- this.$emit({
1281
- type: "entity:state-changed",
1282
- payload: {
1283
- entityId: this.entity.id,
1284
- entityType: this.entity.type,
1285
- state: e ?? this.entity.state,
1286
- changes: t
1287
- }
1280
+ }, Ie = class {
1281
+ #e = /* @__PURE__ */ new Map();
1282
+ #t = [];
1283
+ registerContext(e, t = !0) {
1284
+ this.#e.set(e, {
1285
+ exclusive: t,
1286
+ active: !1
1288
1287
  });
1289
1288
  }
1290
- $setEntity(e) {
1291
- this.entity = e;
1292
- }
1293
- }, je = class {
1294
- id;
1295
- type;
1296
- name;
1297
- node;
1298
- children = [];
1299
- parent = null;
1300
- state;
1301
- behaviors = [];
1302
- eventBus;
1303
- _gameEngine = null;
1304
- _entityManager = null;
1305
- _tags = /* @__PURE__ */ new Set();
1306
- subscriptions = /* @__PURE__ */ new Map();
1307
- constructor(e, t, n, r, i) {
1308
- this.id = Ae(), this.type = e, this.name = i, this.state = n, this.eventBus = t;
1309
- for (let e of r) this.attachBehavior(new e());
1310
- }
1311
- get tags() {
1312
- return this._tags;
1313
- }
1314
- hasTag(e) {
1315
- return this._tags.has(e);
1316
- }
1317
- $addTag(e) {
1318
- this._tags.add(e);
1319
- }
1320
- $removeTag(e) {
1321
- return this._tags.delete(e);
1322
- }
1323
- getChildNode(e) {
1324
- if (this.node) return this.node.getChildren((t) => t.name === e, !1)[0];
1325
- }
1326
- findNode(e) {
1327
- if (!this.node) return;
1328
- let t = this.node;
1329
- for (let n of e.split("/")) t = t?.getChildren((e) => e.name === n, !1)[0];
1330
- return t;
1331
- }
1332
- $attachToNode(e, t) {
1333
- this.node = e, this._gameEngine = t;
1334
- for (let n of this.behaviors) n.onNodeAttached?.(e, t);
1335
- for (let t of this.children) t.node && (t.node.parent = e);
1336
- }
1337
- $detachFromNode() {
1338
- this.unhighlight();
1339
- for (let e of this.children) e.node && (e.node.parent = null);
1340
- for (let e of this.behaviors) e.onNodeDetached?.();
1341
- this.node = void 0, this._gameEngine = null;
1342
- }
1343
- highlight(e) {
1344
- let t = this._gameEngine?.managers?.levelManager?.currentLevel?.outlines;
1345
- t && t.highlightEntity(e, this);
1289
+ activateContext(e, t) {
1290
+ let n = this.#n(e);
1291
+ if (n.exclusive) for (let [t, n] of this.#e) t !== e && n.exclusive && (n.active = !1);
1292
+ n.active = !0;
1293
+ for (let n of this.#t) n.context === e && n.prime(t(n));
1346
1294
  }
1347
- unhighlight(e) {
1348
- let t = this._gameEngine?.managers?.levelManager?.currentLevel?.outlines;
1349
- t && (e ? t.unhighlightEntity(e, this) : t.unhighlightEntityAll(this));
1350
- }
1351
- showCollider(e, t) {
1352
- if (!this.node || !this._gameEngine) return;
1353
- let n = this._gameEngine.debug?.colliders;
1354
- if (!n) return;
1355
- let r = this._getPhysicsNodes();
1356
- if (e === void 0 || e === !0) {
1357
- for (let e of r) n.showColliderForNode(e, void 0);
1358
- return;
1359
- }
1360
- if (typeof e == "string") {
1361
- if (e.startsWith("#")) {
1362
- for (let t of r) n.showColliderForNode(t, e);
1363
- return;
1364
- }
1365
- let i = r.find((t) => t.name === e);
1366
- i && n.showColliderForNode(i, t);
1367
- return;
1368
- }
1369
- if (typeof e == "object") {
1370
- let t = e;
1371
- for (let e of r) {
1372
- let r = t[e.name];
1373
- r && n.showColliderForNode(e, r);
1374
- }
1375
- }
1376
- }
1377
- hideCollider(e) {
1378
- if (!this.node || !this._gameEngine) return;
1379
- let t = this._gameEngine.debug?.colliders;
1380
- if (!t) return;
1381
- let n = this._getPhysicsNodes();
1382
- if (e === void 0) {
1383
- for (let e of n) t.hideColliderForNode(e);
1384
- return;
1385
- }
1386
- let r = n.find((t) => t.name === e);
1387
- r && t.hideColliderForNode(r);
1388
- }
1389
- _getPhysicsNodes() {
1390
- if (!this.node) return [];
1391
- let e = [];
1392
- this.node.physicsBody && e.push(this.node);
1393
- for (let t of this.node.getChildTransformNodes(!1)) t.physicsBody && e.push(t);
1394
- return e;
1395
- }
1396
- $addChild(e) {
1397
- this.children.push(e), e.parent = this, this.node && e.node && (e.node.parent = this.node);
1398
- }
1399
- $removeChild(e) {
1400
- let t = this.children.indexOf(e);
1401
- t !== -1 && (this.children.splice(t, 1), e.parent = null, e.node && (e.node.parent = null));
1402
- }
1403
- $setEntityManager(e) {
1404
- this._entityManager = e;
1405
- }
1406
- async send(e, t, n) {
1407
- if (e === this.id) return this.$send(t, n, this.id);
1408
- if (!this._entityManager) throw Error("Entity is not registered with an EntityManager.");
1409
- return this._entityManager.send(e, t, n, this.id);
1410
- }
1411
- async request(e, t, n) {
1412
- if (e === this.id) return this.$request(t, n, this.id);
1413
- if (!this._entityManager) throw Error("Entity is not registered with an EntityManager.");
1414
- return this._entityManager.request(e, t, n, this.id);
1415
- }
1416
- async $send(e, t, n) {
1417
- await this.$processEvent({
1418
- type: e,
1419
- targetID: this.id,
1420
- senderID: n,
1421
- payload: t
1422
- });
1295
+ deactivateContext(e) {
1296
+ this.#n(e).active = !1;
1423
1297
  }
1424
- async $request(e, t, n) {
1425
- let r = {
1426
- type: e,
1427
- targetID: this.id,
1428
- senderID: n,
1429
- payload: t
1430
- }, i;
1431
- for (let e of this.behaviors) try {
1432
- let t = await e.processRequest?.(r, this.state);
1433
- if (t !== void 0) return {
1434
- success: !0,
1435
- value: t
1436
- };
1437
- } catch (e) {
1438
- i = e instanceof Error ? e.message : String(e);
1439
- }
1440
- return {
1441
- success: !1,
1442
- error: i ?? `No handler for request "${e}" on entity "${this.name ?? this.id}"`
1443
- };
1298
+ isActive(e) {
1299
+ return this.#e.get(e)?.active === !0;
1444
1300
  }
1445
- $reset(e, t) {
1446
- this.state = { ...e }, this._tags.clear();
1447
- for (let e of t) this._tags.add(e);
1448
- this.node && this.$detachFromNode();
1449
- for (let e of this.behaviors) e.onReset?.(this.state);
1450
- for (let e of this.children) e.$reset({}, []);
1451
- this.parent = null;
1301
+ isRegistered(e) {
1302
+ return this.#e.has(e);
1452
1303
  }
1453
- async $processEvent(e) {
1454
- for (let t of this.behaviors) if (await t.processEvent(e, this.state)) break;
1304
+ addBinding(e) {
1305
+ this.#t.push(e);
1455
1306
  }
1456
- $update(e) {
1457
- for (let t of this.behaviors) t.update?.(e, this.state);
1458
- for (let t of this.children) t.$update(e);
1307
+ removeBinding(e) {
1308
+ let t = this.#t.indexOf(e);
1309
+ t !== -1 && this.#t.splice(t, 1);
1459
1310
  }
1460
- async $destroy() {
1461
- for (let e of [...this.children]) await e.$destroy();
1462
- this.children.length = 0;
1463
- for (let e of this.behaviors) await e.destroy?.();
1464
- for (let e of this.subscriptions.values()) e.unsubscribe();
1465
- this.behaviors = [], this.subscriptions.clear();
1311
+ list() {
1312
+ return [...this.#t];
1466
1313
  }
1467
- findBehaviorIndex(e) {
1468
- return this.behaviors.findIndex((t) => t.constructor === e);
1314
+ isLive(e) {
1315
+ return e.context === void 0 || this.isActive(e.context);
1469
1316
  }
1470
- hasBehavior(e) {
1471
- return this.findBehaviorIndex(e) !== -1;
1317
+ #n(e) {
1318
+ let t = this.#e.get(e);
1319
+ if (t === void 0) throw Error(`No context is registered under the name "${e}".`);
1320
+ return t;
1472
1321
  }
1473
- getBehavior(e) {
1474
- return this.behaviors.find((t) => t.constructor === e);
1322
+ }, Le = class {
1323
+ #e = /* @__PURE__ */ new Map();
1324
+ register(e) {
1325
+ if (this.#e.has(e.name)) throw Error(`An action is already registered under the name "${e.name}".`);
1326
+ if (e.type === "analog" && e.minValue !== void 0 && e.maxValue !== void 0 && e.minValue > e.maxValue) throw Error(`Action "${e.name}": minValue (${e.minValue}) is above maxValue (${e.maxValue}).`);
1327
+ this.#e.set(e.name, e);
1475
1328
  }
1476
- attachBehavior(e, t) {
1477
- if (this.hasBehavior(e.constructor)) throw Error(`Behavior ${e.constructor.name} is already attached to this entity.`);
1478
- for (let t of e.eventSubscriptions) {
1479
- let e = this.subscriptions.get(t);
1480
- if (e) e.count++;
1481
- else {
1482
- let e = this.eventBus.subscribe(t, this.$processEvent.bind(this));
1483
- this.subscriptions.set(t, {
1484
- count: 1,
1485
- unsubscribe: e
1486
- });
1487
- }
1488
- }
1489
- if (!t) this.behaviors.push(e);
1490
- else {
1491
- if ([
1492
- t.before,
1493
- t.after,
1494
- t.at
1495
- ].filter((e) => e !== void 0).length > 1) throw Error("attachBehavior: specify only one of before, after, or at");
1496
- if (t.before) {
1497
- let n = this.findBehaviorIndex(t.before);
1498
- if (n === -1) throw Error(`attachBehavior: no behavior of type ${t.before.name} found`);
1499
- this.behaviors.splice(n, 0, e);
1500
- } else if (t.after) {
1501
- let n = this.findBehaviorIndex(t.after);
1502
- if (n === -1) throw Error(`attachBehavior: no behavior of type ${t.after.name} found`);
1503
- this.behaviors.splice(n + 1, 0, e);
1504
- } else if (t.at !== void 0) {
1505
- let n = Math.max(0, Math.min(t.at, this.behaviors.length));
1506
- this.behaviors.splice(n, 0, e);
1507
- } else this.behaviors.push(e);
1508
- }
1509
- e.$setEntity(this), this.node && this._gameEngine && e.onNodeAttached?.(this.node, this._gameEngine);
1510
- }
1511
- detachBehavior(e) {
1512
- let t = this.findBehaviorIndex(e);
1513
- if (t === -1) return !1;
1514
- let n = this.behaviors[t];
1515
- this.node && n.onNodeDetached?.();
1516
- for (let e of n.eventSubscriptions) {
1517
- let t = this.subscriptions.get(e);
1518
- t && (t.count--, t.count <= 0 && (t.unsubscribe(), this.subscriptions.delete(e)));
1519
- }
1520
- return this.behaviors.splice(t, 1), n.$setEntity(null), !0;
1521
- }
1522
- }, Me = class {
1523
- eventBus;
1524
- entities = /* @__PURE__ */ new Map();
1525
- entityDefinitions = /* @__PURE__ */ new Map();
1526
- _gameEngine = null;
1527
- bindingManager;
1528
- _log;
1529
- _entitiesByName = /* @__PURE__ */ new Map();
1530
- _entitiesByType = /* @__PURE__ */ new Map();
1531
- _entitiesByTag = /* @__PURE__ */ new Map();
1532
- _entitiesByNode = /* @__PURE__ */ new Map();
1533
- _pools = /* @__PURE__ */ new Map();
1534
- constructor(e, t, n) {
1535
- this.eventBus = e, this.bindingManager = n, this._log = t?.getLogger("EntityManager") || new N("EntityManager"), this._log.info("EntityManager initialized");
1536
- }
1537
- $setGameEngine(e) {
1538
- this._gameEngine = e;
1329
+ get(e) {
1330
+ return this.#e.get(e);
1539
1331
  }
1540
- get _engine() {
1541
- if (!this._gameEngine) throw Error("EntityManager: gameEngine not set. Call $setGameEngine() first.");
1542
- return this._gameEngine;
1332
+ list() {
1333
+ return [...this.#e.values()];
1543
1334
  }
1544
- _getOrCreateSet(e, t) {
1545
- let n = e.get(t);
1546
- return n || (n = /* @__PURE__ */ new Set(), e.set(t, n)), n;
1335
+ };
1336
+ //#endregion
1337
+ //#region src/input/deliverAction.ts
1338
+ function Re(e, t, n, r) {
1339
+ let i = e.process(t);
1340
+ if (i === void 0) return;
1341
+ let a = {
1342
+ type: `action:${e.action.name}`,
1343
+ senderID: r,
1344
+ payload: i.value
1345
+ };
1346
+ n.bus.emit(a);
1347
+ }
1348
+ function ze(e, t, n, r) {
1349
+ let i = {
1350
+ type: `action:${e.name}`,
1351
+ senderID: r,
1352
+ payload: t
1353
+ };
1354
+ n.bus.emit(i);
1355
+ }
1356
+ //#endregion
1357
+ //#region src/managers/input.ts
1358
+ var W = "sage-input", Be = .2, G = 0;
1359
+ function Ve(e) {
1360
+ return Math.abs(e - G) > Be;
1361
+ }
1362
+ function He(e, t) {
1363
+ return Math.abs(e - G) > 2 || Math.abs(t - G) > 2;
1364
+ }
1365
+ var Ue = class {
1366
+ actions = new Le();
1367
+ contexts = new Ie();
1368
+ #e = {};
1369
+ #t = {};
1370
+ #n = {
1371
+ x: 0,
1372
+ y: 0
1373
+ };
1374
+ #r = {
1375
+ deltaX: 0,
1376
+ deltaY: 0,
1377
+ deltaZ: 0
1378
+ };
1379
+ #i = {
1380
+ x: 0,
1381
+ y: 0
1382
+ };
1383
+ #a = /* @__PURE__ */ new Map();
1384
+ #o = /* @__PURE__ */ new Set();
1385
+ #s = /* @__PURE__ */ new Map();
1386
+ #c;
1387
+ #l;
1388
+ #u;
1389
+ #d;
1390
+ #f;
1391
+ #p;
1392
+ #m;
1393
+ #h;
1394
+ constructor() {
1395
+ this.#u = (e) => {
1396
+ this.#g("keyboard", "key", e.code) && e.preventDefault(), this.#e[e.code] = !0, this.#c = "keyboard", this.#T({
1397
+ device: {
1398
+ type: "keyboard",
1399
+ index: 0
1400
+ },
1401
+ sourceType: "key",
1402
+ sourceKey: e.code,
1403
+ value: !0
1404
+ });
1405
+ }, this.#d = (e) => {
1406
+ this.#e[e.code] = !1;
1407
+ }, this.#f = (e) => {
1408
+ if (e.pointerType !== "mouse") return;
1409
+ let t = String(e.button);
1410
+ this.#g("mouse", "button", t) && e.preventDefault(), this.#t[t] = !0, this.#c = "mouse", this.#T({
1411
+ device: {
1412
+ type: "mouse",
1413
+ index: 0
1414
+ },
1415
+ sourceType: "button",
1416
+ sourceKey: t,
1417
+ value: !0
1418
+ });
1419
+ }, this.#p = (e) => {
1420
+ e.pointerType === "mouse" && (this.#t[String(e.button)] = !1);
1421
+ }, this.#m = (e) => {
1422
+ e.pointerType === "mouse" && (this.#n.x = e.clientX, this.#n.y = e.clientY, this.#i.x += e.movementX, this.#i.y += e.movementY, He(e.movementX, e.movementY) && (this.#c = "mouse"));
1423
+ }, this.#h = (e) => {
1424
+ this.#g("mouse", "wheel") && e.preventDefault(), this.#r.deltaX = e.deltaX, this.#r.deltaY = e.deltaY, this.#r.deltaZ = e.deltaZ, (e.deltaX !== G || e.deltaY !== G || e.deltaZ !== G) && (this.#c = "mouse", this.#w(e));
1425
+ }, U() && (window.addEventListener("keydown", this.#u), window.addEventListener("keyup", this.#d), window.addEventListener("pointerdown", this.#f), window.addEventListener("pointerup", this.#p), window.addEventListener("pointermove", this.#m), window.addEventListener("wheel", this.#h, { passive: !1 }));
1547
1426
  }
1548
- _indexEntity(e) {
1549
- this._getOrCreateSet(this._entitiesByType, e.type).add(e), e.name && this._getOrCreateSet(this._entitiesByName, e.name).add(e);
1550
- for (let t of e.tags) this._getOrCreateSet(this._entitiesByTag, t).add(e);
1551
- e.node && this._entitiesByNode.set(e.node, e);
1427
+ get lastActiveDeviceType() {
1428
+ return this.#c;
1552
1429
  }
1553
- _unindexEntity(e) {
1554
- let t = this._entitiesByType.get(e.type);
1555
- if (t && (t.delete(e), t.size === 0 && this._entitiesByType.delete(e.type)), e.name) {
1556
- let t = this._entitiesByName.get(e.name);
1557
- t && (t.delete(e), t.size === 0 && this._entitiesByName.delete(e.name));
1558
- }
1559
- for (let t of e.tags) {
1560
- let n = this._entitiesByTag.get(t);
1561
- n && (n.delete(e), n.size === 0 && this._entitiesByTag.delete(t));
1562
- }
1563
- e.node && this._entitiesByNode.delete(e.node);
1430
+ deviceState(e, t) {
1431
+ return this.#b(e, t);
1564
1432
  }
1565
- _resolveInheritance(e) {
1566
- let t = e.extends;
1567
- if (!t) return e;
1568
- let n = this.entityDefinitions.get(t);
1569
- if (!n) {
1570
- let e = `Cannot extend "${t}": base entity definition is not registered.`;
1571
- throw this._log.error(e), Error(e);
1572
- }
1573
- let r;
1574
- return (n.tags || e.tags) && (r = [...new Set([...n.tags ?? [], ...e.tags ?? []])]), {
1575
- type: e.type,
1576
- name: e.name ?? n.name,
1577
- mesh: e.mesh ?? n.mesh,
1578
- defaultState: {
1579
- ...n.defaultState,
1580
- ...e.defaultState
1581
- },
1582
- behaviors: e.behaviors ?? n.behaviors,
1583
- actions: e.actions ?? n.actions,
1584
- tags: r,
1585
- poolable: e.poolable ?? n.poolable,
1586
- poolSize: e.poolSize ?? n.poolSize,
1587
- children: e.children ?? n.children,
1588
- onBeforeCreate: e.onBeforeCreate ?? n.onBeforeCreate,
1589
- onCreate: e.onCreate ?? n.onCreate,
1590
- onBeforeDestroy: e.onBeforeDestroy ?? n.onBeforeDestroy,
1591
- onDestroy: e.onDestroy ?? n.onDestroy
1433
+ registerCapture(e) {
1434
+ return this.#o.add(e), () => {
1435
+ this.#o.delete(e);
1592
1436
  };
1593
1437
  }
1594
- _areActionsCompatible(e, t) {
1595
- return !(e.type !== t.type || e.type === "analog" && t.type === "analog" && (t.minValue !== void 0 && e.minValue !== t.minValue || t.maxValue !== void 0 && e.maxValue !== t.maxValue));
1596
- }
1597
- _registerEntityActions(e) {
1598
- if (e.actions) for (let t of e.actions) try {
1599
- let n = this.bindingManager.getAction(t.name);
1600
- n ? this._areActionsCompatible(n, t) ? this._log.trace(`Action "${t.name}" already registered with compatible options, skipping registration`) : this._log.warn(`Action "${t.name}" already registered with different options. Entity "${e.type}" requires: ${JSON.stringify(t)}, but found: ${JSON.stringify(n)}`) : (this._log.debug(`Registering action "${t.name}" from entity type "${e.type}"`), this.bindingManager.registerAction(t));
1601
- } catch (e) {
1602
- this._log.debug(`Failed to register action "${t.name}": ${e instanceof Error ? e.message : String(e)}`);
1438
+ getBindingsForAction(e, t, n) {
1439
+ let r = [];
1440
+ for (let i of this.contexts.list()) {
1441
+ let a = i.action.name === e, o = t === void 0 || i.device.type === t, s = n === void 0 || i.context === n;
1442
+ a && o && s && r.push(i);
1603
1443
  }
1444
+ return r;
1604
1445
  }
1605
- $frameUpdate(e) {
1606
- this._log.trace(`Updating ${this.entities.size} entities with dt=${e}`);
1607
- for (let t of this.entities.values()) t.parent || t.$update(e);
1608
- }
1609
- _cloneDefaultState(e) {
1610
- try {
1611
- return structuredClone(e.defaultState);
1612
- } catch (t) {
1613
- throw Error(`Entity type '${e.type}' has a defaultState that cannot be structured-cloned. defaultState must be plain data (no functions, class instances, or DOM references).`, { cause: t });
1446
+ routeCapturedInput(e) {
1447
+ this.#x();
1448
+ let t = /* @__PURE__ */ new Map();
1449
+ for (let n of this.contexts.list()) if (this.contexts.isLive(n)) {
1450
+ let r = this.#b(n.device.type, n.device.index);
1451
+ n.kind === "value" ? this.#_(t, n, r) : Re(n, r, e, W);
1614
1452
  }
1453
+ this.#v(t, e), this.#C(e), this.#i.x = G, this.#i.y = G, this.#r.deltaX = G, this.#r.deltaY = G, this.#r.deltaZ = G;
1615
1454
  }
1616
- async _buildDefinitionMesh(e, t) {
1617
- if (!t.mesh) return;
1618
- if (t.node) {
1619
- this._log.warn(`Ignoring 'mesh' option for entity ${e.id}: 'node' was supplied, and the two are exclusive.`);
1620
- return;
1621
- }
1622
- let { levelManager: n } = this._engine.managers, r = n.loadingLevel ?? n.currentLevel;
1623
- if (!r?.isLoaded) {
1624
- this._log.warn(`Cannot build a mesh for entity ${e.id}: no level is loaded.`);
1625
- return;
1455
+ #g(e, t, n) {
1456
+ for (let r of this.contexts.list()) if (r.preventDefault && this.contexts.isLive(r)) {
1457
+ let { device: i, sourceType: a, sourceKey: o } = r.input;
1458
+ if (i.type === e && a === t && (n === void 0 || o === n)) return !0;
1626
1459
  }
1627
- await r.createEntityMesh(e, { enabled: t.mesh === "enabled" });
1460
+ return !1;
1628
1461
  }
1629
- registerEntityDefinition(e) {
1630
- this._log.debug(`Registering entity definition: ${e.type}`);
1631
- let t = e.extends ? this._resolveInheritance(e) : e;
1632
- this._registerEntityActions(t), this.entityDefinitions.set(t.type, t), t.poolSize && t.poolSize > 0 && this.prewarm(t.type, t.poolSize);
1462
+ async $teardown() {
1463
+ U() && (window.removeEventListener("keydown", this.#u), window.removeEventListener("keyup", this.#d), window.removeEventListener("pointerdown", this.#f), window.removeEventListener("pointerup", this.#p), window.removeEventListener("pointermove", this.#m), window.removeEventListener("wheel", this.#h));
1464
+ }
1465
+ #_(e, t, n) {
1466
+ let r = t.process(n);
1467
+ if (r === void 0) return;
1468
+ let i = Number(r.value), a = e.get(t.action.name);
1469
+ a === void 0 ? e.set(t.action.name, {
1470
+ action: t.action,
1471
+ value: i
1472
+ }) : a.value += i;
1473
+ }
1474
+ #v(e, t) {
1475
+ for (let [t, n] of this.#s) e.has(t) || e.set(t, {
1476
+ action: n,
1477
+ value: 0
1478
+ });
1479
+ for (let [n, r] of e) {
1480
+ let e = this.#y(r.action, r.value), i = e !== this.#y(r.action, G), a = this.#s.has(n);
1481
+ i ? this.#s.set(n, r.action) : this.#s.delete(n), (i || a) && ze(r.action, e, t, W);
1482
+ }
1633
1483
  }
1634
- getDefinition(e) {
1635
- return this.entityDefinitions.get(e);
1484
+ #y(e, t) {
1485
+ return e.type === "analog" ? e.minValue !== void 0 && t < e.minValue ? e.minValue : e.maxValue !== void 0 && t > e.maxValue ? e.maxValue : t : t;
1636
1486
  }
1637
- async createEntity(e, t = {}) {
1638
- this._log.debug(`Creating entity of type: ${e}`);
1639
- let n = this.entityDefinitions.get(e);
1640
- if (!n) {
1641
- let t = `Entity type ${e} is not registered.`;
1642
- throw this._log.error(t), Error(t);
1643
- }
1644
- if (n.poolable) {
1645
- let r = this._pools.get(e);
1646
- if (r && r.length > 0) {
1647
- this._log.trace(`Recycling entity from pool for type: ${e}`);
1648
- let i = r.pop();
1649
- if (i.$reset(this._cloneDefaultState(n), n.tags ?? []), i.$setEntityManager(this), t.initialState && (i.state = {
1650
- ...i.state,
1651
- ...t.initialState
1652
- }), t.tags) for (let e of t.tags) i.$addTag(e);
1653
- return t.node && i.$attachToNode(t.node, this._engine), this.entities.set(i.id, i), this._indexEntity(i), await this._buildDefinitionMesh(i, t), this._log.debug(`Recycled entity ${i.id} from pool`), i;
1654
- }
1655
- }
1656
- this._log.trace(`Using entity definition with ${n.behaviors?.length || 0} behaviors`);
1657
- let r = {
1658
- ...this._cloneDefaultState(n),
1659
- ...t.initialState
1487
+ #b(e, t) {
1488
+ if (e === "keyboard") return { keys: this.#e };
1489
+ if (e === "mouse") return {
1490
+ buttons: this.#t,
1491
+ position: this.#n,
1492
+ wheel: this.#r,
1493
+ movement: this.#i
1660
1494
  };
1661
- if (n.onBeforeCreate) {
1662
- this._log.trace(`Calling onBeforeCreate hook for entity type: ${e}`);
1663
- let t = await n.onBeforeCreate(r);
1664
- t !== void 0 && (r = t);
1665
- }
1666
- let i = t.name ?? n.name, a = new je(n.type, this.eventBus, r, n.behaviors, i);
1667
- if (a.$setEntityManager(this), t.node && a.$attachToNode(t.node, this._engine), n.tags) for (let e of n.tags) a.$addTag(e);
1668
- if (t.tags) for (let e of t.tags) a.$addTag(e);
1669
- if (this.entities.set(a.id, a), this._indexEntity(a), this._log.debug(`Entity created with ID: ${a.id}${i ? ` (name: ${i})` : ""}`), n.onCreate) {
1670
- this._log.trace(`Calling onCreate hook for entity type: ${e}`);
1671
- let t = await n.onCreate(a.state);
1672
- t !== void 0 && (a.state = t);
1673
- }
1674
- if (n.children) for (let e of n.children) {
1675
- let t = { ...e.initialState };
1676
- e.position && (t._position = e.position), e.rotation && (t._rotation = e.rotation);
1677
- let n = await this.createEntity(e.type, {
1678
- name: e.name,
1679
- initialState: t
1680
- });
1681
- a.$addChild(n);
1495
+ let n = this.#a.get(t);
1496
+ return n === void 0 ? {
1497
+ buttons: {},
1498
+ axes: {}
1499
+ } : n;
1500
+ }
1501
+ #x() {
1502
+ if (typeof navigator > "u" || typeof navigator.getGamepads != "function") return;
1503
+ let e = navigator.getGamepads();
1504
+ for (let t = 0; t < e.length; t++) {
1505
+ let n = e[t];
1506
+ n !== null && this.#S(t, n);
1682
1507
  }
1683
- return await this._buildDefinitionMesh(a, t), a;
1684
1508
  }
1685
- async destroyEntity(e) {
1686
- this._log.debug(`Destroying entity: ${e}`);
1687
- let t = this.entities.get(e);
1688
- if (t) {
1689
- let n = this.entityDefinitions.get(t.type);
1690
- if (n?.poolable) {
1691
- this._log.trace(`Pooling entity ${e} instead of destroying`);
1692
- for (let e of [...t.children]) await this.destroyEntity(e.id);
1693
- t.parent && t.parent.$removeChild(t), this._unindexEntity(t), t.$reset(this._cloneDefaultState(n), n.tags ?? []);
1694
- let r = this._pools.get(t.type);
1695
- r || (r = [], this._pools.set(t.type, r)), r.push(t), this.entities.delete(e), this._log.debug(`Entity ${e} pooled`);
1696
- return;
1697
- }
1698
- for (let e of [...t.children]) await this.destroyEntity(e.id);
1699
- if (t.parent && t.parent.$removeChild(t), n?.onBeforeDestroy) {
1700
- this._log.trace(`Calling onBeforeDestroy hook for entity: ${e}`);
1701
- let r = await n.onBeforeDestroy(t.state);
1702
- r !== void 0 && (t.state = r);
1509
+ #S(e, t) {
1510
+ let n = {}, r = !1;
1511
+ for (let i = 0; i < t.buttons.length; i++) {
1512
+ let a = t.buttons[i].value, o = String(i);
1513
+ n[o] = a, Ve(a) && (r = !0, this.#T({
1514
+ device: {
1515
+ type: "gamepad",
1516
+ index: e
1517
+ },
1518
+ sourceType: "button",
1519
+ sourceKey: o,
1520
+ value: a
1521
+ }));
1522
+ }
1523
+ let i = {};
1524
+ for (let n = 0; n < t.axes.length; n++) {
1525
+ let a = t.axes[n], o = String(n);
1526
+ i[o] = a, Ve(a) && (r = !0, this.#T({
1527
+ device: {
1528
+ type: "gamepad",
1529
+ index: e
1530
+ },
1531
+ sourceType: "axis",
1532
+ sourceKey: o,
1533
+ value: a
1534
+ }));
1535
+ }
1536
+ this.#a.set(e, {
1537
+ buttons: n,
1538
+ axes: i
1539
+ }), r && (this.#c = "gamepad");
1540
+ }
1541
+ #C(e) {
1542
+ if (this.#c === this.#l) return;
1543
+ let t = this.#l;
1544
+ this.#l = this.#c, this.#c !== void 0 && e.bus.emit({
1545
+ type: "input:deviceChanged",
1546
+ senderID: W,
1547
+ payload: {
1548
+ deviceType: this.#c,
1549
+ previousDeviceType: t
1703
1550
  }
1704
- this._unindexEntity(t), await t.$destroy(), n?.onDestroy && (this._log.trace(`Calling onDestroy hook for entity: ${e}`), await n.onDestroy(t.state)), this.entities.delete(e), this._log.debug(`Entity ${e} destroyed`);
1705
- } else this._log.warn(`Attempted to destroy non-existent entity: ${e}`);
1551
+ });
1706
1552
  }
1707
- getEntity(e) {
1708
- return this._log.trace(`Getting entity: ${e}`), this.entities.get(e) ?? null;
1709
- }
1710
- addEntity(e) {
1711
- this._log.debug(`Adding existing entity: ${e.id} (type: ${e.type})`), e.$setEntityManager(this), this.entities.set(e.id, e), this._indexEntity(e);
1712
- }
1713
- removeEntity(e) {
1714
- this._log.debug(`Removing entity: ${e}`);
1715
- let t = this.entities.get(e);
1716
- t ? (this._unindexEntity(t), this.entities.delete(e), this._log.debug(`Entity ${e} removed`)) : this._log.warn(`Attempted to remove non-existent entity: ${e}`);
1717
- }
1718
- addChild(e, t) {
1719
- let n = this.entities.get(e), r = this.entities.get(t);
1720
- return n ? r ? (n.$addChild(r), this._log.trace(`Added child ${t} to parent ${e}`), !0) : (this._log.warn(`addChild: child entity "${t}" not found`), !1) : (this._log.warn(`addChild: parent entity "${e}" not found`), !1);
1721
- }
1722
- removeChild(e, t) {
1723
- let n = this.entities.get(e), r = this.entities.get(t);
1724
- return n ? r ? (n.$removeChild(r), this._log.trace(`Removed child ${t} from parent ${e}`), !0) : (this._log.warn(`removeChild: child entity "${t}" not found`), !1) : (this._log.warn(`removeChild: parent entity "${e}" not found`), !1);
1725
- }
1726
- getByName(e) {
1727
- let t = this._entitiesByName.get(e);
1728
- if (t && t.size > 0) return t.values().next().value;
1729
- }
1730
- getEntitiesByName(e) {
1731
- let t = this._entitiesByName.get(e);
1732
- return t ? Array.from(t) : [];
1733
- }
1734
- getByType(e) {
1735
- let t = this._entitiesByType.get(e);
1736
- return t ? Array.from(t) : [];
1737
- }
1738
- getByTag(e) {
1739
- let t = this._entitiesByTag.get(e);
1740
- return t ? Array.from(t) : [];
1741
- }
1742
- getByTags(e, t = "all") {
1743
- if (e.length === 0) return [];
1744
- if (t === "any") {
1745
- let t = /* @__PURE__ */ new Set();
1746
- for (let n of e) {
1747
- let e = this._entitiesByTag.get(n);
1748
- if (e) for (let n of e) t.add(n);
1553
+ #w(e) {
1554
+ let t = [
1555
+ {
1556
+ sourceKey: "deltaY",
1557
+ value: e.deltaY
1558
+ },
1559
+ {
1560
+ sourceKey: "deltaX",
1561
+ value: e.deltaX
1562
+ },
1563
+ {
1564
+ sourceKey: "deltaZ",
1565
+ value: e.deltaZ
1749
1566
  }
1750
- return Array.from(t);
1751
- } else {
1752
- let t = e.map((e) => this._entitiesByTag.get(e)).filter((e) => e !== void 0);
1753
- if (t.length !== e.length) return [];
1754
- t.sort((e, t) => e.size - t.size);
1755
- let [n, ...r] = t;
1756
- return Array.from(n).filter((e) => r.every((t) => t.has(e)));
1757
- }
1758
- }
1759
- getAllEntities() {
1760
- return this.entities.values();
1761
- }
1762
- get entityCount() {
1763
- return this.entities.size;
1764
- }
1765
- async send(e, t, n, r) {
1766
- let i = this.entities.get(e) ?? this.getByName(e);
1767
- if (!i) {
1768
- this._log.warn(`send: entity "${e}" not found`);
1769
- return;
1770
- }
1771
- await i.$send(t, n, r);
1772
- }
1773
- async request(e, t, n, r) {
1774
- let i = this.entities.get(e) ?? this.getByName(e);
1775
- return i ? i.$request(t, n, r) : {
1776
- success: !1,
1777
- error: `Entity "${e}" not found`
1778
- };
1779
- }
1780
- addTag(e, t) {
1781
- let n = typeof e == "string" ? this.entities.get(e) : e;
1782
- return n ? n.hasTag(t) ? !1 : (n.$addTag(t), this._getOrCreateSet(this._entitiesByTag, t).add(n), this._log.trace(`Added tag "${t}" to entity ${n.id}`), !0) : (this._log.warn("addTag: entity not found"), !1);
1783
- }
1784
- removeTag(e, t) {
1785
- let n = typeof e == "string" ? this.entities.get(e) : e;
1786
- if (!n) return this._log.warn("removeTag: entity not found"), !1;
1787
- if (!n.$removeTag(t)) return !1;
1788
- let r = this._entitiesByTag.get(t);
1789
- return r && (r.delete(n), r.size === 0 && this._entitiesByTag.delete(t)), this._log.trace(`Removed tag "${t}" from entity ${n.id}`), !0;
1790
- }
1791
- getByNode(e) {
1792
- return this._entitiesByNode.get(e);
1793
- }
1794
- attachToNode(e, t) {
1795
- let n = typeof e == "string" ? this.entities.get(e) : e;
1796
- return n ? this._entitiesByNode.has(t) ? (this._log.warn("attachToNode: node already has an attached entity"), !1) : (n.node && this._entitiesByNode.delete(n.node), n.$attachToNode(t, this._engine), this._entitiesByNode.set(t, n), this._log.trace(`Attached entity ${n.id} to node "${t.name}"`), !0) : (this._log.warn("attachToNode: entity not found"), !1);
1797
- }
1798
- detachFromNode(e) {
1799
- let t = typeof e == "string" ? this.entities.get(e) : e;
1800
- if (!t) return this._log.warn("detachFromNode: entity not found"), !1;
1801
- if (!t.node) return !1;
1802
- this._entitiesByNode.delete(t.node);
1803
- let n = t.node.name;
1804
- return t.$detachFromNode(), this._log.trace(`Detached entity ${t.id} from node "${n}"`), !0;
1805
- }
1806
- async prewarm(e, t) {
1807
- this._log.debug(`Prewarming pool for "${e}" with ${t} entities`);
1808
- for (let n = 0; n < t; n++) {
1809
- let t = await this.createEntity(e);
1810
- await this.destroyEntity(t.id);
1811
- }
1812
- }
1813
- async drainPool(e) {
1814
- let t = this._pools.get(e);
1815
- if (t) {
1816
- this._log.debug(`Draining pool for "${e}" (${t.length} entities)`);
1817
- for (let e of t) await e.$destroy();
1818
- t.length = 0, this._pools.delete(e);
1819
- }
1567
+ ];
1568
+ for (let e of t) e.value !== G && this.#T({
1569
+ device: {
1570
+ type: "mouse",
1571
+ index: 0
1572
+ },
1573
+ sourceType: "wheel",
1574
+ sourceKey: e.sourceKey,
1575
+ value: e.value
1576
+ });
1820
1577
  }
1821
- async $teardown() {
1822
- this._log.info(`Tearing down EntityManager with ${this.entities.size} entities`);
1823
- let e = [...this.entities.keys()];
1824
- for (let t of e) try {
1825
- await this.destroyEntity(t);
1826
- } catch (e) {
1827
- this._log.error(`Error destroying entity ${t}: ${e}`);
1828
- }
1829
- for (let e of [...this._pools.keys()]) try {
1830
- await this.drainPool(e);
1831
- } catch (t) {
1832
- this._log.error(`Error draining pool for "${e}": ${t}`);
1833
- }
1834
- this.entityDefinitions.clear(), this._entitiesByName.clear(), this._entitiesByType.clear(), this._entitiesByTag.clear(), this._entitiesByNode.clear(), this._log.info("EntityManager torn down successfully");
1578
+ #T(e) {
1579
+ for (let t of this.#o) t.feed(e);
1835
1580
  }
1836
- }, Ne = {
1581
+ }, We = {
1837
1582
  hable: h.TONEMAPPING_STANDARD,
1838
1583
  reinhard: h.TONEMAPPING_STANDARD,
1839
1584
  hejidawson: h.TONEMAPPING_STANDARD,
1840
1585
  photographic: h.TONEMAPPING_STANDARD,
1841
1586
  aces: h.TONEMAPPING_ACES
1842
1587
  };
1843
- function Pe(e, t) {
1588
+ function Ge(e, t) {
1844
1589
  if (!e.activeCamera) return;
1845
1590
  t.volumetric && console.warn("[SAGE] Volumetric lighting requires renderer: \"frameGraph\". Ignored in pipeline mode.");
1846
1591
  let n = new s("sage-default", !0, e, e.cameras);
1847
- if (t.bloom && (n.bloomEnabled = !0, t.bloom.weight !== void 0 && (n.bloomWeight = t.bloom.weight), t.bloom.threshold !== void 0 && (n.bloomThreshold = t.bloom.threshold), t.bloom.scale !== void 0 && (n.bloomScale = t.bloom.scale), t.bloom.kernel !== void 0 && (n.bloomKernel = t.bloom.kernel)), t.tonemap && (n.imageProcessingEnabled = !0, n.imageProcessing.toneMappingEnabled = !0, t.tonemap.operator && (n.imageProcessing.toneMappingType = Ne[t.tonemap.operator] ?? h.TONEMAPPING_STANDARD)), t.grain && (n.grainEnabled = !0, t.grain.intensity !== void 0 && (n.grain.intensity = t.grain.intensity), t.grain.animated !== void 0 && (n.grain.animated = t.grain.animated)), t.vignette && (n.imageProcessingEnabled = !0, n.imageProcessing.vignetteEnabled = !0, t.vignette.weight !== void 0 && (n.imageProcessing.vignetteWeight = t.vignette.weight), t.vignette.stretch !== void 0 && (n.imageProcessing.vignetteStretch = t.vignette.stretch), t.vignette.color && (n.imageProcessing.vignetteColor = new i(t.vignette.color.r, t.vignette.color.g, t.vignette.color.b, 1))), t.sharpen && (n.sharpenEnabled = !0, t.sharpen.edge !== void 0 && (n.sharpen.edgeAmount = t.sharpen.edge), t.sharpen.color !== void 0 && (n.sharpen.colorAmount = t.sharpen.color)), t.chromaticAberration && (n.chromaticAberrationEnabled = !0, t.chromaticAberration.amount !== void 0 && (n.chromaticAberration.aberrationAmount = t.chromaticAberration.amount)), t.ssao) {
1848
- let n = new ne("sage-ssao", e, {
1592
+ if (t.bloom && (n.bloomEnabled = !0, t.bloom.weight !== void 0 && (n.bloomWeight = t.bloom.weight), t.bloom.threshold !== void 0 && (n.bloomThreshold = t.bloom.threshold), t.bloom.scale !== void 0 && (n.bloomScale = t.bloom.scale), t.bloom.kernel !== void 0 && (n.bloomKernel = t.bloom.kernel)), t.tonemap && (n.imageProcessingEnabled = !0, n.imageProcessing.toneMappingEnabled = !0, t.tonemap.operator && (n.imageProcessing.toneMappingType = We[t.tonemap.operator] ?? h.TONEMAPPING_STANDARD)), t.grain && (n.grainEnabled = !0, t.grain.intensity !== void 0 && (n.grain.intensity = t.grain.intensity), t.grain.animated !== void 0 && (n.grain.animated = t.grain.animated)), t.vignette && (n.imageProcessingEnabled = !0, n.imageProcessing.vignetteEnabled = !0, t.vignette.weight !== void 0 && (n.imageProcessing.vignetteWeight = t.vignette.weight), t.vignette.stretch !== void 0 && (n.imageProcessing.vignetteStretch = t.vignette.stretch), t.vignette.color && (n.imageProcessing.vignetteColor = new i(t.vignette.color.r, t.vignette.color.g, t.vignette.color.b, 1))), t.sharpen && (n.sharpenEnabled = !0, t.sharpen.edge !== void 0 && (n.sharpen.edgeAmount = t.sharpen.edge), t.sharpen.color !== void 0 && (n.sharpen.colorAmount = t.sharpen.color)), t.chromaticAberration && (n.chromaticAberrationEnabled = !0, t.chromaticAberration.amount !== void 0 && (n.chromaticAberration.aberrationAmount = t.chromaticAberration.amount)), t.ssao) {
1593
+ let n = new re("sage-ssao", e, {
1849
1594
  ssaoRatio: .5,
1850
1595
  blurRatio: 1
1851
1596
  });
@@ -1854,25 +1599,25 @@ function Pe(e, t) {
1854
1599
  }
1855
1600
  //#endregion
1856
1601
  //#region src/handlers/postProcessing.ts
1857
- async function Fe(e, t) {
1602
+ async function Ke(e, t) {
1858
1603
  if (t.renderer === "frameGraph") {
1859
- let { applyFrameGraphPostProcessing: n } = await import("./postProcessingFrameGraph-CaMgQzR-.js");
1604
+ let { applyFrameGraphPostProcessing: n } = await import("./postProcessingFrameGraph-C3Og4kaS.js");
1860
1605
  await n(e, t);
1861
- } else Pe(e, t);
1606
+ } else Ge(e, t);
1862
1607
  }
1863
1608
  //#endregion
1864
1609
  //#region src/utils/vectors.ts
1865
- function K(e) {
1610
+ function qe(e) {
1866
1611
  return {
1867
1612
  x: e.x,
1868
1613
  y: e.y,
1869
1614
  z: e.z
1870
1615
  };
1871
1616
  }
1872
- function q(e) {
1617
+ function K(e) {
1873
1618
  return new O(e.x, e.y, e.z);
1874
1619
  }
1875
- function Ie(e) {
1620
+ function Je(e) {
1876
1621
  return {
1877
1622
  x: e.x,
1878
1623
  y: e.y,
@@ -1880,18 +1625,18 @@ function Ie(e) {
1880
1625
  w: e.w
1881
1626
  };
1882
1627
  }
1883
- function Le(e) {
1884
- return new T(e.x, e.y, e.z, e.w);
1628
+ function Ye(e) {
1629
+ return new w(e.x, e.y, e.z, e.w);
1885
1630
  }
1886
- function Re(e) {
1631
+ function Xe(e) {
1887
1632
  e.computeWorldMatrix(!0);
1888
1633
  let t = e.getWorldMatrix().clone(), n = e.parent;
1889
1634
  for (; n;) {
1890
1635
  n.computeWorldMatrix(!0);
1891
1636
  let e = n.getWorldMatrix(), r = n.parent, i;
1892
- r ? (r.computeWorldMatrix(!0), i = e.multiply(v.Invert(r.getWorldMatrix()))) : i = e, i.determinant() < 0 && (t = v.Invert(i).multiply(t)), n = r;
1637
+ r ? (r.computeWorldMatrix(!0), i = e.multiply(_.Invert(r.getWorldMatrix()))) : i = e, i.determinant() < 0 && (t = _.Invert(i).multiply(t)), n = r;
1893
1638
  }
1894
- let r = new O(), i = new T(), a = new O();
1639
+ let r = new O(), i = new w(), a = new O();
1895
1640
  return t.decompose(a, i, r), {
1896
1641
  position: r,
1897
1642
  rotation: i,
@@ -1900,15 +1645,17 @@ function Re(e) {
1900
1645
  }
1901
1646
  //#endregion
1902
1647
  //#region src/classes/level.ts
1903
- var ze = class {
1648
+ var Ze = class {
1904
1649
  name;
1905
1650
  _log;
1906
1651
  _context;
1907
1652
  _scene = null;
1653
+ _forRestore = !1;
1654
+ _simulation = null;
1908
1655
  clusteredLights = null;
1909
1656
  outlines = null;
1910
1657
  constructor(e, t) {
1911
- this.name = e.name, this._context = t, this._log = t.logger?.getLogger(`Level:${e.name}`) ?? new N(`Level:${e.name}`, "info");
1658
+ this.name = e.name, this._context = t, this._log = t.logger?.getLogger(`Level:${e.name}`) ?? new j(`Level:${e.name}`, "info");
1912
1659
  }
1913
1660
  get scene() {
1914
1661
  return this._scene;
@@ -1922,6 +1669,12 @@ var ze = class {
1922
1669
  get propertyHandlers() {
1923
1670
  return this._context.propertyHandlers;
1924
1671
  }
1672
+ get $simulation() {
1673
+ return this._simulation;
1674
+ }
1675
+ $adoptSimulation(e) {
1676
+ this._simulation = e;
1677
+ }
1925
1678
  $emitProgress(e, t) {
1926
1679
  this.gameEngine.eventBus.publish({
1927
1680
  type: "level:progress",
@@ -1947,9 +1700,9 @@ var ze = class {
1947
1700
  this._log.error(`Error in property handler '${t}' for node '${e.name}':`, n);
1948
1701
  }
1949
1702
  }
1950
- async load() {
1703
+ async load(e) {
1951
1704
  if (this._scene) return this._log.warn(`Level ${this.name} is already loaded`), this._scene;
1952
- this._log.info(`Loading level: ${this.name}`), this._log.time(`level-${this.name}-load`);
1705
+ this._forRestore = e?.forRestore ?? !1, this._log.info(`Loading level: ${this.name}`), this._log.time(`level-${this.name}-load`);
1953
1706
  try {
1954
1707
  return this.$emitProgress(0, "Starting level load..."), this._scene = await this.buildScene(), this.$emitProgress(100, "Level loaded successfully"), this.gameEngine.eventBus.publish({
1955
1708
  type: "level:complete",
@@ -1970,83 +1723,10 @@ var ze = class {
1970
1723
  }), e;
1971
1724
  }
1972
1725
  }
1973
- async createEntityMesh(e, t = {}) {
1974
- if (!this._scene) return null;
1975
- let n = this.gameEngine.managers.entityManager.getDefinition(e.type);
1976
- if (!n?.mesh) return null;
1977
- let r = n.mesh, i = this._scene, a = new D(`entity-${e.id}`, i);
1978
- t.enabled === !1 && a.setEnabled(!1);
1979
- let o;
1980
- switch (r.source) {
1981
- case "box":
1982
- o = [b.CreateBox(`${e.type}-mesh`, {
1983
- size: r.params?.size ?? 1,
1984
- width: r.params?.width,
1985
- height: r.params?.height,
1986
- depth: r.params?.depth
1987
- }, i)];
1988
- break;
1989
- case "sphere":
1990
- o = [b.CreateSphere(`${e.type}-mesh`, {
1991
- diameter: r.params?.diameter ?? 1,
1992
- segments: r.params?.segments ?? 16
1993
- }, i)];
1994
- break;
1995
- case "capsule":
1996
- o = [b.CreateCapsule(`${e.type}-mesh`, {
1997
- height: r.params?.height ?? 1.8,
1998
- radius: r.params?.radius ?? .4
1999
- }, i)];
2000
- break;
2001
- case "cylinder":
2002
- o = [b.CreateCylinder(`${e.type}-mesh`, {
2003
- height: r.params?.height ?? 1,
2004
- diameter: r.params?.diameter ?? 1
2005
- }, i)];
2006
- break;
2007
- default: {
2008
- let e = await this.gameEngine.engines.sceneEngine.importMeshes([], r.source, i);
2009
- if (e.meshes.length === 0) return this._log.warn(`No meshes loaded from: ${r.source}`), a.dispose(), null;
2010
- o = e.meshes;
2011
- for (let t of e.transformNodes) t.parent ||= a;
2012
- break;
2013
- }
2014
- }
2015
- for (let e of o) e.parent ||= a;
2016
- t.position && a.position.copyFrom(t.position), t.rotation && (a.rotationQuaternion = t.rotation.clone()), t.scaling && a.scaling.copyFrom(t.scaling), r.scale && (typeof r.scale == "number" ? a.scaling.setAll(r.scale) : a.scaling.set(r.scale.x, r.scale.y, r.scale.z));
2017
- let s = r.material;
2018
- if (s?.color) {
2019
- let t = s.color;
2020
- if (s.type === "pbr") {
2021
- let n = new S(`${e.type}-material`, i);
2022
- n.albedoColor = this._toColor3(t), s.emissive && (n.emissiveColor = this._toColor3(s.emissive)), n.metallic = s.metallic ?? 0, n.roughness = s.roughness ?? 1;
2023
- for (let e of o) e.material = n;
2024
- } else {
2025
- let n = new E(`${e.type}-material`, i);
2026
- n.diffuseColor = this._toColor3(t), s.emissive && (n.emissiveColor = this._toColor3(s.emissive));
2027
- for (let e of o) e.material = n;
2028
- }
2029
- }
2030
- if (r.visible === !1) for (let e of o) e.isVisible = !1;
2031
- let c = a.getDescendants(!1).filter((e) => e instanceof D);
2032
- for (let e of c) {
2033
- let t = this._getNormalizedMetadata(e);
2034
- t && Object.keys(t).length > 0 && (e.metadata = {
2035
- ...e.metadata,
2036
- ...t
2037
- }, await this._runPropertyHandlers(e));
2038
- }
2039
- return this.gameEngine.managers.entityManager.attachToNode(e, a), a;
2040
- }
2041
1726
  async $dispose() {
2042
- if (this._scene) {
2043
- this._log.info(`Disposing level: ${this.name}`);
2044
- let e = this._context.gameEngine?.managers?.entityManager;
2045
- if (e?.getAllEntities) for (let t of e.getAllEntities()) t.node && t.node.getScene() === this._scene && e.detachFromNode(t);
2046
- this.outlines &&= (this.outlines.dispose(), null), this.clusteredLights &&= (this.clusteredLights.dispose(), null), this._scene.dispose(), this._scene = null;
2047
- }
1727
+ this._scene &&= (this._log.info(`Disposing level: ${this.name}`), this.outlines &&= (this.outlines.dispose(), null), this.clusteredLights &&= (this.clusteredLights.dispose(), null), this._scene.dispose(), null);
2048
1728
  }
2049
- }, Be = class {
1729
+ }, Qe = class {
2050
1730
  _scene;
2051
1731
  _layers = /* @__PURE__ */ new Map();
2052
1732
  constructor(e, t) {
@@ -2058,7 +1738,7 @@ var ze = class {
2058
1738
  create(e, t) {
2059
1739
  let n = this._layers.get(e);
2060
1740
  if (n) return n.layer;
2061
- let i = new ie(`sage-outline-${e}`, this._scene);
1741
+ let i = new ae(`sage-outline-${e}`, this._scene);
2062
1742
  return t?.color && (i.outlineColor = new r(t.color.r, t.color.g, t.color.b)), t?.thickness !== void 0 && (i.outlineThickness = t.thickness), t?.occlusionStrength !== void 0 && (i.occlusionStrength = t.occlusionStrength), this._layers.set(e, {
2063
1743
  layer: i,
2064
1744
  entities: /* @__PURE__ */ new Set()
@@ -2085,12 +1765,12 @@ var ze = class {
2085
1765
  }
2086
1766
  _rebuildSelection(e) {
2087
1767
  e.layer.clearSelection();
2088
- for (let t of e.entities) if (t.node) {
1768
+ for (let t of e.entities) {
2089
1769
  let n = t.node.getChildMeshes();
2090
1770
  n.length > 0 && e.layer.addSelection(n);
2091
1771
  }
2092
1772
  }
2093
- }, Ve = class extends ze {
1773
+ }, $e = class extends Ze {
2094
1774
  _config;
2095
1775
  _spawnPoints = [];
2096
1776
  _entityNodes = [];
@@ -2106,15 +1786,19 @@ var ze = class {
2106
1786
  get spawnedEntities() {
2107
1787
  return this._spawnedEntities;
2108
1788
  }
1789
+ get simulation() {
1790
+ if (this._simulation === null) throw Error(`Level ${this.name}: rebuildSimulation has not run against this level's scene yet.`);
1791
+ return this._simulation;
1792
+ }
2109
1793
  async buildScene() {
2110
1794
  let { sceneEngine: e } = this.gameEngine.engines, { assetManager: t } = this.gameEngine.managers;
2111
1795
  this._config.preload && this._config.preload.length > 0 && (this.$emitProgress(2, "Preloading assets..."), await t.preload(this._config.preload));
2112
1796
  let n = e.createScene();
2113
- if (this._scene = n, this._config.physics && (this.$emitProgress(5, "Initializing physics..."), await this._enablePhysics(n)), this._config.scene && (this.$emitProgress(10, "Loading scene file..."), await this._loadSceneFile(n)), this._config.environment && (this.$emitProgress(15, "Setting up environment..."), this._processEnvironment(n)), this._processCameras(n), this._processLights(n), this._setupClustering(n), this._config.postProcessing) {
1797
+ if (this._scene = n, this._simulation = this.gameEngine.rebuildSimulation(n, this._config.meshSource), this._config.physics && (this.$emitProgress(5, "Initializing physics..."), await this._enablePhysics(n)), this._config.scene && (this.$emitProgress(10, "Loading scene file..."), await this._loadSceneFile(n)), this._config.environment && (this.$emitProgress(15, "Setting up environment..."), this._processEnvironment(n)), this._processCameras(n), this._processLights(n), this._setupClustering(n), this._config.postProcessing) {
2114
1798
  let e = this._config.postProcessing.renderer ?? "pipeline";
2115
- this._log.info(`Applying post-processing with ${e} renderer`), await Fe(n, this._config.postProcessing);
1799
+ this._log.info(`Applying post-processing with ${e} renderer`), await Ke(n, this._config.postProcessing);
2116
1800
  }
2117
- return this.outlines = new Be(n, this._config.outlines), this.$emitProgress(50, "Processing scene properties..."), await this._processNodeProperties(n), this.$emitProgress(70, "Spawning entities..."), await this._processSpawnPoints(), this.$emitProgress(85, "Configuring entities..."), await this._processEntityNodes(), this._config.sounds && (this.$emitProgress(95, "Loading sounds..."), await this._processLevelSounds()), n;
1801
+ return this.outlines = new Qe(n, this._config.outlines), this.$emitProgress(50, "Processing scene properties..."), await this._processNodeProperties(n), this._forRestore || (this.$emitProgress(70, "Spawning entities..."), await this._processSpawnPoints(), this.$emitProgress(85, "Configuring entities..."), this._processEntityNodes()), this._config.sounds && (this.$emitProgress(95, "Loading sounds..."), await this._processLevelSounds()), n;
2118
1802
  }
2119
1803
  async _loadSceneFile(e) {
2120
1804
  let t = this._getScenePath();
@@ -2145,7 +1829,7 @@ var ze = class {
2145
1829
  }
2146
1830
  e.environmentTexture && e.createDefaultSkybox(e.environmentTexture, !0, t.skyboxSize ?? 1e3, 0, !1);
2147
1831
  } else {
2148
- let n = t.skyboxSize ?? 1e3, r = b.CreateSphere("skybox", {
1832
+ let n = t.skyboxSize ?? 1e3, r = y.CreateSphere("skybox", {
2149
1833
  diameter: n,
2150
1834
  segments: 32
2151
1835
  }, e), i = new E("skybox-mat", e);
@@ -2185,10 +1869,10 @@ var ze = class {
2185
1869
  }
2186
1870
  }
2187
1871
  _createCamera(e, t, r) {
2188
- let i = t.position ? q(t.position) : O.Zero(), a;
1872
+ let i = t.position ? K(t.position) : O.Zero(), a;
2189
1873
  switch (t.type) {
2190
1874
  case "arcRotate": {
2191
- let i = t.target ? q(t.target) : O.Zero();
1875
+ let i = t.target ? K(t.target) : O.Zero();
2192
1876
  a = new n(e, t.alpha ?? Math.PI / 2, t.beta ?? Math.PI / 3, t.radius ?? 10, i, r);
2193
1877
  break;
2194
1878
  }
@@ -2198,17 +1882,15 @@ var ze = class {
2198
1882
  case "geospatial": {
2199
1883
  if (!t.planetRadius) return this._log.warn(`Geospatial camera "${e}" requires planetRadius -- skipping`), new d(e, O.Zero(), r);
2200
1884
  let n = new de(e, r, { planetRadius: t.planetRadius });
2201
- t.center && (n.center = q(t.center)), t.yaw !== void 0 && (n.yaw = t.yaw), t.pitch !== void 0 && (n.pitch = t.pitch), t.radius !== void 0 && (n.radius = t.radius), t.checkCollisions !== void 0 && (n.checkCollisions = t.checkCollisions), t.radiusMin !== void 0 && (n.limits.radiusMin = t.radiusMin), t.radiusMax !== void 0 && (n.limits.radiusMax = t.radiusMax), t.pitchMin !== void 0 && (n.limits.pitchMin = t.pitchMin), t.pitchMax !== void 0 && (n.limits.pitchMax = t.pitchMax), t.yawMin !== void 0 && (n.limits.yawMin = t.yawMin), t.yawMax !== void 0 && (n.limits.yawMax = t.yawMax), a = n;
1885
+ t.center && (n.center = K(t.center)), t.yaw !== void 0 && (n.yaw = t.yaw), t.pitch !== void 0 && (n.pitch = t.pitch), t.radius !== void 0 && (n.radius = t.radius), t.checkCollisions !== void 0 && (n.checkCollisions = t.checkCollisions), t.radiusMin !== void 0 && (n.limits.radiusMin = t.radiusMin), t.radiusMax !== void 0 && (n.limits.radiusMax = t.radiusMax), t.pitchMin !== void 0 && (n.limits.pitchMin = t.pitchMin), t.pitchMax !== void 0 && (n.limits.pitchMax = t.pitchMax), t.yawMin !== void 0 && (n.limits.yawMin = t.yawMin), t.yawMax !== void 0 && (n.limits.yawMax = t.yawMax), a = n;
2202
1886
  break;
2203
1887
  }
2204
- default:
2205
- a = new d(e, i, r);
2206
- break;
1888
+ default: a = new d(e, i, r);
2207
1889
  }
2208
1890
  return this._applyCameraConfig(a, t), a;
2209
1891
  }
2210
1892
  _applyCameraConfig(e, t) {
2211
- t.fov !== void 0 && (e.fov = t.fov), t.position && (e.position = q(t.position)), t.minZ !== void 0 && (e.minZ = t.minZ), t.maxZ !== void 0 && (e.maxZ = t.maxZ), e instanceof d && (t.speed !== void 0 && (e.speed = t.speed), t.rotation && (e.rotation = q(t.rotation))), e instanceof n && (t.target && e.setTarget(q(t.target)), t.lowerRadiusLimit !== void 0 && (e.lowerRadiusLimit = t.lowerRadiusLimit), t.upperRadiusLimit !== void 0 && (e.upperRadiusLimit = t.upperRadiusLimit), t.lowerBetaLimit !== void 0 && (e.lowerBetaLimit = t.lowerBetaLimit), t.upperBetaLimit !== void 0 && (e.upperBetaLimit = t.upperBetaLimit), t.wheelPrecision !== void 0 && (e.wheelPrecision = t.wheelPrecision)), e instanceof de && (t.yaw !== void 0 && (e.yaw = t.yaw), t.pitch !== void 0 && (e.pitch = t.pitch), t.radius !== void 0 && (e.radius = t.radius), t.center && (e.center = q(t.center)), t.checkCollisions !== void 0 && (e.checkCollisions = t.checkCollisions), t.radiusMin !== void 0 && (e.limits.radiusMin = t.radiusMin), t.radiusMax !== void 0 && (e.limits.radiusMax = t.radiusMax), t.pitchMin !== void 0 && (e.limits.pitchMin = t.pitchMin), t.pitchMax !== void 0 && (e.limits.pitchMax = t.pitchMax));
1893
+ t.fov !== void 0 && (e.fov = t.fov), t.position && (e.position = K(t.position)), t.minZ !== void 0 && (e.minZ = t.minZ), t.maxZ !== void 0 && (e.maxZ = t.maxZ), e instanceof d && (t.speed !== void 0 && (e.speed = t.speed), t.rotation && (e.rotation = K(t.rotation))), e instanceof n && (t.target && e.setTarget(K(t.target)), t.lowerRadiusLimit !== void 0 && (e.lowerRadiusLimit = t.lowerRadiusLimit), t.upperRadiusLimit !== void 0 && (e.upperRadiusLimit = t.upperRadiusLimit), t.lowerBetaLimit !== void 0 && (e.lowerBetaLimit = t.lowerBetaLimit), t.upperBetaLimit !== void 0 && (e.upperBetaLimit = t.upperBetaLimit), t.wheelPrecision !== void 0 && (e.wheelPrecision = t.wheelPrecision)), e instanceof de && (t.yaw !== void 0 && (e.yaw = t.yaw), t.pitch !== void 0 && (e.pitch = t.pitch), t.radius !== void 0 && (e.radius = t.radius), t.center && (e.center = K(t.center)), t.checkCollisions !== void 0 && (e.checkCollisions = t.checkCollisions), t.radiusMin !== void 0 && (e.limits.radiusMin = t.radiusMin), t.radiusMax !== void 0 && (e.limits.radiusMax = t.radiusMax), t.pitchMin !== void 0 && (e.limits.pitchMin = t.pitchMin), t.pitchMax !== void 0 && (e.limits.pitchMax = t.pitchMax));
2212
1894
  }
2213
1895
  _processLights(e) {
2214
1896
  let t = this._config.lights;
@@ -2218,7 +1900,7 @@ var ze = class {
2218
1900
  }
2219
1901
  }
2220
1902
  _createLight(e, t, n) {
2221
- let r = t.direction ? q(t.direction) : new O(0, -1, 0), i = t.position ? q(t.position) : O.Zero();
1903
+ let r = t.direction ? K(t.direction) : new O(0, -1, 0), i = t.position ? K(t.position) : O.Zero();
2222
1904
  switch (t.type) {
2223
1905
  case "hemispheric": {
2224
1906
  let i = new m(e, r, n);
@@ -2231,17 +1913,17 @@ var ze = class {
2231
1913
  break;
2232
1914
  }
2233
1915
  case "point": {
2234
- let r = new ee(e, i, n);
1916
+ let r = new te(e, i, n);
2235
1917
  this._applyLightConfig(r, t);
2236
1918
  break;
2237
1919
  }
2238
1920
  case "spot": {
2239
- let a = new oe(e, i, r, t.angle ?? Math.PI / 3, t.exponent ?? 2, n);
1921
+ let a = new T(e, i, r, t.angle ?? Math.PI / 3, t.exponent ?? 2, n);
2240
1922
  this._applyLightConfig(a, t);
2241
1923
  break;
2242
1924
  }
2243
1925
  case "rectarea": {
2244
- let a = new te(e, i, t.width ?? 1, t.height ?? 1, n);
1926
+ let a = new ne(e, i, t.width ?? 1, t.height ?? 1, n);
2245
1927
  if (this._applyLightConfig(a, t), t.direction) {
2246
1928
  let t = new D(`${e}_pivot`, n);
2247
1929
  t.position = a.position.clone(), a.position = O.Zero(), a.parent = t, t.lookAt(t.position.subtract(r));
@@ -2264,7 +1946,7 @@ var ze = class {
2264
1946
  for (let t of n) e.removeLight(t);
2265
1947
  let r = new fe("sage-clustered", n, e);
2266
1948
  t.horizontalTiles !== void 0 && (r.horizontalTiles = t.horizontalTiles), t.verticalTiles !== void 0 && (r.verticalTiles = t.verticalTiles), t.depthSlices !== void 0 && (r.depthSlices = t.depthSlices), t.maxRange !== void 0 && (r.maxRange = t.maxRange), this.clusteredLights = r, this._log.debug(`Clustered lighting enabled: ${n.length} lights, ${r.horizontalTiles}x${r.verticalTiles} tiles, ${r.depthSlices} depth slices`);
2267
- for (let t of e.materials) t instanceof S && (t.useGLTFLightFalloff = !0);
1949
+ for (let t of e.materials) t instanceof x && (t.useGLTFLightFalloff = !0);
2268
1950
  }
2269
1951
  async _enablePhysics(e) {
2270
1952
  let t = this._config.physics, n = new O(0, -9.81, 0);
@@ -2285,7 +1967,7 @@ var ze = class {
2285
1967
  }
2286
1968
  async _processNodeMetadata(e) {
2287
1969
  if ("spawn" in e.metadata) {
2288
- let { position: t, rotation: n, scaling: r } = Re(e);
1970
+ let { position: t, rotation: n, scaling: r } = Xe(e);
2289
1971
  this._spawnPoints.push({
2290
1972
  name: e.metadata.spawn,
2291
1973
  position: t,
@@ -2308,50 +1990,40 @@ var ze = class {
2308
1990
  async _processSpawnPoint(e, t) {
2309
1991
  try {
2310
1992
  let n = await this._spawnEntity(t, e);
2311
- this._spawnedEntities.push(n), this._applyDebugCollider(n, t.debugCollider), e.node.dispose(), this._log.debug(`Spawned entity '${t.entity}' at spawn point '${e.name}'`);
1993
+ this._spawnedEntities.push(n), e.node.dispose(), this._log.debug(`Spawned entity '${t.entity}' at spawn point '${e.name}'`);
2312
1994
  } catch (t) {
2313
1995
  this._log.error(`Failed to spawn entity at spawn point '${e.name}':`, t);
2314
1996
  }
2315
1997
  }
2316
- _applyDebugCollider(e, t) {
2317
- let n = this.gameEngine.managers.entityManager.getDefinition(e.type)?.debugCollider, r = t ?? n;
2318
- r && e.showCollider(r);
2319
- }
2320
1998
  async _spawnEntity(e, t) {
2321
1999
  let n = {
2322
2000
  ...e.config,
2323
- position: K(t.position),
2324
- rotation: Ie(t.rotation),
2325
- scaling: K(t.scaling)
2326
- }, r = await this.gameEngine.managers.entityManager.createEntity(e.entity, {
2327
- name: e.name,
2328
- tags: e.tags,
2329
- initialState: n
2330
- });
2331
- return await this.createEntityMesh(r, {
2332
- position: t.position,
2333
- rotation: t.rotation,
2334
- scaling: t.scaling
2335
- }), r;
2001
+ ...e.name === void 0 ? {} : { displayName: e.name },
2002
+ ...e.debugCollider === void 0 ? {} : { debugCollider: e.debugCollider },
2003
+ tags: e.tags ?? [],
2004
+ position: qe(t.position),
2005
+ rotation: Je(t.rotation)
2006
+ };
2007
+ return this.simulation.spawn(e.entity, void 0, n);
2336
2008
  }
2337
- async _processEntityNodes() {
2338
- for (let e of this._entityNodes) await this._processEntityNode(e);
2009
+ _processEntityNodes() {
2010
+ for (let e of this._entityNodes) {
2011
+ let t = this._config.entities?.[e.type];
2012
+ t ? this._spawnEntityNode(t, e) : this._log.warn(`No entity definition found for '${e.type}', skipping`);
2013
+ }
2339
2014
  }
2340
- async _processEntityNode(e) {
2341
- let t = this._config.entities?.[e.type];
2015
+ _spawnEntityNode(e, t) {
2342
2016
  try {
2343
2017
  let n = {
2344
- ...t?.config,
2345
- position: K(e.node.position)
2346
- }, r = await this.gameEngine.managers.entityManager.createEntity(e.type, {
2347
- name: t?.name ?? e.node.name,
2348
- tags: t?.tags,
2349
- initialState: n,
2350
- node: e.node
2351
- });
2352
- this._spawnedEntities.push(r), this._applyDebugCollider(r, t?.debugCollider), this._log.debug(`Created entity '${e.type}' for node '${e.node.name}'`);
2353
- } catch (t) {
2354
- this._log.error(`Failed to create entity for node '${e.node.name}':`, t);
2018
+ ...e.config,
2019
+ ...e.name === void 0 ? {} : { displayName: e.name },
2020
+ ...e.debugCollider === void 0 ? {} : { debugCollider: e.debugCollider },
2021
+ tags: e.tags ?? [],
2022
+ nodeName: t.node.name
2023
+ }, r = this.simulation.spawn(e.entity, void 0, n);
2024
+ this._spawnedEntities.push(r), this._log.debug(`Spawned entity '${e.entity}' adopting node '${t.node.name}'`);
2025
+ } catch (e) {
2026
+ this._log.error(`Failed to spawn entity adopting node '${t.node.name}':`, e);
2355
2027
  }
2356
2028
  }
2357
2029
  async _processLevelSounds() {
@@ -2373,7 +2045,7 @@ var ze = class {
2373
2045
  }
2374
2046
  }
2375
2047
  async onDeactivate() {
2376
- for (let [e, t] of this._levelSounds) t.state === ae.Started && (this._playingSoundsBeforeDeactivate.add(e), t.pause());
2048
+ for (let [e, t] of this._levelSounds) t.state === oe.Started && (this._playingSoundsBeforeDeactivate.add(e), t.pause());
2377
2049
  }
2378
2050
  async onActivate() {
2379
2051
  for (let e of this._playingSoundsBeforeDeactivate) {
@@ -2383,18 +2055,12 @@ var ze = class {
2383
2055
  this._playingSoundsBeforeDeactivate.clear();
2384
2056
  }
2385
2057
  async $dispose() {
2386
- let { entityManager: e } = this.gameEngine.managers, t = this._spawnedEntities.map(async (t) => {
2387
- try {
2388
- await e.destroyEntity(t.id);
2389
- } catch (e) {
2390
- this._log.error(`Failed to destroy entity ${t.id}:`, e);
2391
- }
2392
- });
2393
- await Promise.all(t), this._spawnedEntities = [], this._spawnPoints = [], this._entityNodes = [];
2058
+ if (this._simulation !== null) for (let e of this._spawnedEntities) this._simulation.despawn(e.id);
2059
+ this._simulation = null, this._spawnedEntities = [], this._spawnPoints = [], this._entityNodes = [];
2394
2060
  for (let e of this._levelSounds.values()) e.dispose();
2395
2061
  this._levelSounds.clear(), this._playingSoundsBeforeDeactivate.clear(), await super.$dispose();
2396
2062
  }
2397
- }, He = class {
2063
+ }, et = class {
2398
2064
  _eventBus;
2399
2065
  _gameEngine = null;
2400
2066
  _log;
@@ -2416,7 +2082,7 @@ var ze = class {
2416
2082
  return this._propertyHandlers;
2417
2083
  }
2418
2084
  constructor(e, t) {
2419
- this._eventBus = e, this._logger = t, this._log = t?.getLogger("LevelManager") || new N("LevelManager"), this._eventUnsubscribers.push(this._eventBus.subscribe("level:progress", (e) => {
2085
+ this._eventBus = e, this._logger = t, this._log = t?.getLogger("LevelManager") || new j("LevelManager"), this._eventUnsubscribers.push(this._eventBus.subscribe("level:progress", (e) => {
2420
2086
  this._handleProgress(e.payload);
2421
2087
  })), this._eventUnsubscribers.push(this._eventBus.subscribe("level:complete", (e) => {
2422
2088
  this._handleComplete(e.payload);
@@ -2451,7 +2117,7 @@ var ze = class {
2451
2117
  if (!n) throw Error(`Level class '${e.class}' is not registered.`);
2452
2118
  return this._log.debug(`Creating level '${e.name}' using class '${e.class}'`), new n(e, t);
2453
2119
  }
2454
- return this._log.debug(`Creating level '${e.name}' using GameLevel`), new Ve(e, t);
2120
+ return this._log.debug(`Creating level '${e.name}' using GameLevel`), new $e(e, t);
2455
2121
  }
2456
2122
  registerLevelConfig(e) {
2457
2123
  this._levelConfigs.has(e.name) && this._log.warn(`Level config '${e.name}' is already registered. Overwriting.`), this._levelConfigs.set(e.name, e), this._log.info(`Registered level config: ${e.name}`);
@@ -2474,28 +2140,38 @@ var ze = class {
2474
2140
  getLevelConfig(e) {
2475
2141
  return this._levelConfigs.get(e) || null;
2476
2142
  }
2477
- async loadLevel(e) {
2478
- let t;
2143
+ async loadLevel(e, t) {
2144
+ let n;
2479
2145
  if (typeof e == "string") {
2480
- let n = this._levelConfigs.get(e);
2481
- if (!n) throw Error(`Level config '${e}' is not registered.`);
2482
- t = n;
2483
- } else t = e, this.registerLevelConfig(t);
2484
- let n = this._loadedLevels.get(t.name);
2485
- if (n) return this._log.warn(`Level '${t.name}' is already loaded`), n;
2486
- this._log.debug(`Loading level: ${t.name}`);
2487
- let r = this._createLevelInstance(t);
2488
- this._loadingLevel = r;
2146
+ let t = this._levelConfigs.get(e);
2147
+ if (!t) throw Error(`Level config '${e}' is not registered.`);
2148
+ n = t;
2149
+ } else n = e, this.registerLevelConfig(n);
2150
+ let r = this._loadedLevels.get(n.name);
2151
+ if (r) return this._log.warn(`Level '${n.name}' is already loaded`), r;
2152
+ this._log.debug(`Loading level: ${n.name}`);
2153
+ let i = this._createLevelInstance(n), a = this._gameEngine?.simulation ?? null;
2154
+ this._loadingLevel = i;
2489
2155
  try {
2490
- await r.load();
2156
+ await i.load(t);
2157
+ let e = this._gameEngine?.simulation ?? null;
2158
+ i.$simulation === null && e !== null && e !== a && i.$adoptSimulation(e);
2159
+ } catch (e) {
2160
+ throw await i.$dispose(), e;
2491
2161
  } finally {
2492
- this._loadingLevel = null;
2162
+ this._loadingLevel = null, this._gameEngine !== null && (this._gameEngine.simulation = a);
2493
2163
  }
2494
- return this._loadedLevels.set(t.name, r), r;
2164
+ return this._loadedLevels.set(n.name, i), i;
2165
+ }
2166
+ _bindSimulation(e) {
2167
+ this._gameEngine !== null && e.$simulation !== null && (this._gameEngine.simulation = e.$simulation);
2168
+ }
2169
+ $bindSimulation(e) {
2170
+ this._currentLevel !== null && this._currentLevel.$adoptSimulation(e), this._gameEngine !== null && (this._gameEngine.simulation = e);
2495
2171
  }
2496
2172
  async activateLevel(e) {
2497
2173
  let t = await this.loadLevel(e);
2498
- return this._currentLevel = t, this._log.info(`Activated level: ${t.name}`), t;
2174
+ return this._currentLevel = t, this._bindSimulation(t), this._log.info(`Activated level: ${t.name}`), t;
2499
2175
  }
2500
2176
  async unloadLevel(e) {
2501
2177
  let t = this._loadedLevels.get(e);
@@ -2505,7 +2181,7 @@ var ze = class {
2505
2181
  this._currentLevel ? await this.unloadLevel(this._currentLevel.name) : this._log.warn("No current level to unload");
2506
2182
  }
2507
2183
  async transition(e, t) {
2508
- let n = this._currentLevel;
2184
+ let n = this._currentLevel, r = this._gameEngine?.simulation ?? null;
2509
2185
  try {
2510
2186
  this._eventBus.publish({
2511
2187
  type: "level:transition:start",
@@ -2520,14 +2196,14 @@ var ze = class {
2520
2196
  levelName: e
2521
2197
  }
2522
2198
  });
2523
- let r = await this.loadLevel(e);
2199
+ let r = await this.loadLevel(e, t);
2524
2200
  if (t?.preloadOnly) return;
2525
- n && !t?.keepAlive && await this.unloadLevel(n.name), this._currentLevel = r, r.onActivate && await r.onActivate(), this._eventBus.publish({
2201
+ n && !t?.keepAlive && await this.unloadLevel(n.name), this._currentLevel = r, this._bindSimulation(r), r.onActivate && await r.onActivate(), this._eventBus.publish({
2526
2202
  type: "level:transition:complete",
2527
2203
  payload: { levelName: e }
2528
2204
  });
2529
2205
  } catch (t) {
2530
- throw this._eventBus.publish({
2206
+ throw this._gameEngine !== null && (this._gameEngine.simulation = r), this._eventBus.publish({
2531
2207
  type: "level:transition:error",
2532
2208
  payload: {
2533
2209
  from: n?.name,
@@ -2543,7 +2219,7 @@ var ze = class {
2543
2219
  for (let e of this._loadedLevels.values()) await e.$dispose();
2544
2220
  this._loadedLevels.clear(), this._levelConfigs.clear(), this._currentLevel = null;
2545
2221
  }
2546
- }, Ue = class {
2222
+ }, tt = class {
2547
2223
  _audioEngine;
2548
2224
  _channels = /* @__PURE__ */ new Map();
2549
2225
  _masterMuted = !1;
@@ -2581,672 +2257,185 @@ var ze = class {
2581
2257
  this._masterMuted ? this._masterVolumeBeforeMute = e : this._audioEngine.setMasterVolume(e);
2582
2258
  }
2583
2259
  getMasterVolume() {
2584
- return this._masterMuted ? this._masterVolumeBeforeMute : this._audioEngine.getMasterVolume();
2585
- }
2586
- setMasterMuted(e) {
2587
- e !== this._masterMuted && (this._masterMuted = e, e ? (this._masterVolumeBeforeMute = this._audioEngine.getMasterVolume(), this._audioEngine.setMasterVolume(0)) : this._audioEngine.setMasterVolume(this._masterVolumeBeforeMute));
2588
- }
2589
- isMasterMuted() {
2590
- return this._masterMuted;
2591
- }
2592
- setChannelVolume(e, t) {
2593
- let n = this._channels.get(e);
2594
- if (!n) {
2595
- this._log.warn(`Unknown audio channel: ${e}`);
2596
- return;
2597
- }
2598
- n.volume = t, n.muted || this._audioEngine.setBusVolume(n.bus, t);
2599
- }
2600
- getChannelVolume(e) {
2601
- return this._channels.get(e)?.volume ?? 1;
2602
- }
2603
- setChannelMuted(e, t) {
2604
- let n = this._channels.get(e);
2605
- if (!n) {
2606
- this._log.warn(`Unknown audio channel: ${e}`);
2607
- return;
2608
- }
2609
- t !== n.muted && (n.muted = t, this._audioEngine.setBusVolume(n.bus, t ? 0 : n.volume));
2610
- }
2611
- isChannelMuted(e) {
2612
- return this._channels.get(e)?.muted ?? !1;
2613
- }
2614
- getChannels() {
2615
- return Array.from(this._channels.keys());
2616
- }
2617
- }, We = class {
2618
- _entityManager;
2619
- _levelManager;
2620
- _log;
2621
- _beforeSerializeHooks = [];
2622
- _afterDeserializeHooks = [];
2623
- constructor(e, t, n) {
2624
- this._entityManager = e, this._levelManager = t, this._log = n?.getLogger("SaveManager") || new N("SaveManager"), this._log.info("SaveManager initialized");
2625
- }
2626
- onBeforeSerialize(e) {
2627
- this._beforeSerializeHooks.push(e);
2628
- }
2629
- onAfterDeserialize(e) {
2630
- this._afterDeserializeHooks.push(e);
2631
- }
2632
- serialize() {
2633
- this._log.debug("Serializing game state...");
2634
- let e = this._levelManager.currentLevel?.name ?? "", t = [];
2635
- for (let e of this._entityManager.getAllEntities()) {
2636
- let n = {
2637
- id: e.id,
2638
- type: e.type,
2639
- tags: Array.from(e.tags),
2640
- state: structuredClone(e.state)
2641
- };
2642
- if (e.name && (n.name = e.name), e.parent && (n.parentId = e.parent.id), e.node) {
2643
- let { position: t, rotation: r, scaling: i } = e.node;
2644
- n.transform = {
2645
- position: {
2646
- x: t.x,
2647
- y: t.y,
2648
- z: t.z
2649
- },
2650
- rotation: {
2651
- x: r.x,
2652
- y: r.y,
2653
- z: r.z
2654
- },
2655
- scaling: {
2656
- x: i.x,
2657
- y: i.y,
2658
- z: i.z
2659
- }
2660
- };
2661
- }
2662
- t.push(n);
2663
- }
2664
- let n = {};
2665
- for (let e of this._beforeSerializeHooks) {
2666
- let t = e();
2667
- n = {
2668
- ...n,
2669
- ...t
2670
- };
2671
- }
2672
- let r = {
2673
- version: 1,
2674
- levelName: e,
2675
- entities: t,
2676
- custom: n
2677
- };
2678
- return this._log.info(`Serialized ${t.length} entities from level "${e}"`), r;
2679
- }
2680
- async deserialize(e) {
2681
- this._log.debug(`Deserializing save data (version ${e.version}, level "${e.levelName}")...`), await this._levelManager.transition(e.levelName);
2682
- let t = [];
2683
- for (let e of this._entityManager.getAllEntities()) t.push(e.id);
2684
- for (let e of t) await this._entityManager.destroyEntity(e);
2685
- let n = /* @__PURE__ */ new Map();
2686
- for (let t of e.entities) {
2687
- let e = await this._entityManager.createEntity(t.type, {
2688
- name: t.name,
2689
- initialState: t.state,
2690
- tags: t.tags
2691
- });
2692
- if (n.set(t.id, e.id), t.transform && e.node) {
2693
- let { position: n, rotation: r, scaling: i } = t.transform;
2694
- e.node.position.x = n.x, e.node.position.y = n.y, e.node.position.z = n.z, e.node.rotation.x = r.x, e.node.rotation.y = r.y, e.node.rotation.z = r.z, e.node.scaling.x = i.x, e.node.scaling.y = i.y, e.node.scaling.z = i.z;
2695
- }
2696
- }
2697
- for (let t of e.entities) if (t.parentId) {
2698
- let e = n.get(t.parentId), r = n.get(t.id);
2699
- e && r ? this._entityManager.addChild(e, r) : this._log.warn(`Could not restore parent-child: ${t.id} -> ${t.parentId} (mapped: ${r} -> ${e})`);
2700
- }
2701
- for (let t of this._afterDeserializeHooks) t(e.custom);
2702
- this._log.info(`Deserialized ${e.entities.length} entities for level "${e.levelName}"`);
2703
- }
2704
- async $teardown() {
2705
- this._beforeSerializeHooks = [], this._afterDeserializeHooks = [], this._log.info("SaveManager torn down");
2706
- }
2707
- }, Ge = class {
2708
- _viewer = null;
2709
- _shown = /* @__PURE__ */ new Map();
2710
- _materials = /* @__PURE__ */ new Map();
2711
- showColliderForNode(e, t) {
2712
- if (!e.physicsBody || this._shown.has(e)) return;
2713
- let n = this._getViewer(e).showBody(e.physicsBody);
2714
- if (!n) return;
2715
- let r = { debugMesh: n };
2716
- if (t) {
2717
- let i = this._getColorMaterial(t, e);
2718
- n.material = i, r.colorMaterial = i;
2719
- }
2720
- this._shown.set(e, r);
2721
- }
2722
- hideColliderForNode(e) {
2723
- !this._shown.get(e) || !this._viewer || (e.physicsBody && this._viewer.hideBody(e.physicsBody), this._shown.delete(e));
2724
- }
2725
- hideAll() {
2726
- for (let [e] of this._shown) this.hideColliderForNode(e);
2727
- }
2728
- isShown(e) {
2729
- return this._shown.has(e);
2730
- }
2731
- async $teardown() {
2732
- this.dispose();
2733
- }
2734
- dispose() {
2735
- this._viewer &&= (this.hideAll(), this._viewer.dispose(), null), this._shown.clear();
2736
- for (let e of this._materials.values()) e.dispose();
2737
- this._materials.clear();
2738
- }
2739
- _getViewer(e) {
2740
- return this._viewer ||= new pe(e.getScene()), this._viewer;
2741
- }
2742
- _getColorMaterial(e, t) {
2743
- let n = this._materials.get(e);
2744
- return n || (n = new E(`sage-collider-debug-${e}`, t.getScene()), n.emissiveColor = r.FromHexString(e), n.disableLighting = !0, n.wireframe = !0, this._materials.set(e, n), n);
2745
- }
2746
- }, Ke = class {
2747
- _keyboardDevice;
2748
- _keysState = {};
2749
- _onDeviceConnected;
2750
- _onInputChanged;
2751
- constructor() {
2752
- this._keyboardDevice = {
2753
- id: "keyboard-0",
2754
- name: "Keyboard",
2755
- type: "keyboard",
2756
- connected: !0
2757
- }, this._setupKeyboardEvents(), setTimeout(() => this._notifyDeviceConnected(), 0);
2758
- }
2759
- onDeviceConnected(e) {
2760
- this._onDeviceConnected = e;
2761
- }
2762
- onInputChanged(e) {
2763
- this._onInputChanged = e;
2764
- }
2765
- getState() {
2766
- return {
2767
- type: "keyboard",
2768
- keys: { ...this._keysState },
2769
- delta: {}
2770
- };
2771
- }
2772
- getDevice() {
2773
- return { ...this._keyboardDevice };
2774
- }
2775
- $teardown() {
2776
- return window.removeEventListener("keydown", this._handleKeyDown), window.removeEventListener("keyup", this._handleKeyUp), Promise.resolve();
2777
- }
2778
- _setupKeyboardEvents() {
2779
- this._handleKeyDown = this._handleKeyDown.bind(this), this._handleKeyUp = this._handleKeyUp.bind(this), window.addEventListener("keydown", this._handleKeyDown), window.addEventListener("keyup", this._handleKeyUp);
2780
- }
2781
- _handleKeyDown(e) {
2782
- this._keysState[e.code] = !0;
2783
- let t = {};
2784
- t[e.code] = !0;
2785
- let n = {
2786
- type: "keyboard",
2787
- keys: { ...this._keysState },
2788
- delta: t,
2789
- event: e
2790
- };
2791
- this._notifyInputChanged(n);
2792
- }
2793
- _handleKeyUp(e) {
2794
- this._keysState[e.code] = !1;
2795
- let t = {};
2796
- t[e.code] = !1;
2797
- let n = {
2798
- type: "keyboard",
2799
- keys: { ...this._keysState },
2800
- delta: t,
2801
- event: e
2802
- };
2803
- this._notifyInputChanged(n);
2804
- }
2805
- _notifyDeviceConnected() {
2806
- this._onDeviceConnected && this._onDeviceConnected(this._keyboardDevice);
2807
- }
2808
- _notifyInputChanged(e) {
2809
- this._onInputChanged && this._onInputChanged(this._keyboardDevice, e);
2810
- }
2811
- }, qe = class {
2812
- _targetElement;
2813
- _mouseDevice;
2814
- _buttonState = {};
2815
- _axesState = {};
2816
- _position = {
2817
- absolute: {
2818
- x: 0,
2819
- y: 0
2820
- },
2821
- relative: {
2822
- x: 0,
2823
- y: 0
2824
- }
2825
- };
2826
- _wheelState = {
2827
- deltaX: 0,
2828
- deltaY: 0,
2829
- deltaZ: 0,
2830
- deltaMode: 0
2831
- };
2832
- _onDeviceConnected;
2833
- _onInputChanged;
2834
- constructor(e = document.body) {
2835
- this._targetElement = e, this._mouseDevice = {
2836
- id: "mouse-0",
2837
- name: "Mouse",
2838
- type: "mouse",
2839
- connected: !0
2840
- }, this._setupMouseEvents(), this._axesState["axis-x"] = 0, this._axesState["axis-y"] = 0, setTimeout(() => this._notifyDeviceConnected(), 0);
2841
- }
2842
- onDeviceConnected(e) {
2843
- this._onDeviceConnected = e;
2844
- }
2845
- onInputChanged(e) {
2846
- this._onInputChanged = e;
2847
- }
2848
- getState() {
2849
- return {
2850
- type: "mouse",
2851
- buttons: { ...this._buttonState },
2852
- axes: { ...this._axesState },
2853
- position: {
2854
- absolute: { ...this._position.absolute },
2855
- relative: { ...this._position.relative }
2856
- },
2857
- wheel: { ...this._wheelState }
2858
- };
2859
- }
2860
- getDevice() {
2861
- return { ...this._mouseDevice };
2862
- }
2863
- $teardown() {
2864
- return this._targetElement.removeEventListener("pointerdown", this._handlePointerDown), this._targetElement.removeEventListener("pointerup", this._handlePointerUp), this._targetElement.removeEventListener("pointermove", this._handlePointerMove), this._targetElement.removeEventListener("wheel", this._handleMouseWheel), Promise.resolve();
2865
- }
2866
- _setupMouseEvents() {
2867
- this._handlePointerDown = this._handlePointerDown.bind(this), this._handlePointerUp = this._handlePointerUp.bind(this), this._handlePointerMove = this._handlePointerMove.bind(this), this._handleMouseWheel = this._handleMouseWheel.bind(this), this._targetElement.addEventListener("pointerdown", this._handlePointerDown), this._targetElement.addEventListener("pointerup", this._handlePointerUp), this._targetElement.addEventListener("pointermove", this._handlePointerMove), this._targetElement.addEventListener("wheel", this._handleMouseWheel);
2868
- }
2869
- _handlePointerDown(e) {
2870
- if (e.pointerType !== "mouse") return;
2871
- let t = `button-${e.button}`;
2872
- this._buttonState[t] = { pressed: !0 }, this._notifyInputChanged({
2873
- type: "mouse",
2874
- event: e,
2875
- buttons: { ...this._buttonState },
2876
- axes: { ...this._axesState },
2877
- position: { ...this._position }
2878
- });
2879
- }
2880
- _handlePointerUp(e) {
2881
- if (e.pointerType !== "mouse") return;
2882
- let t = `button-${e.button}`;
2883
- this._buttonState[t] = { pressed: !1 }, this._notifyInputChanged({
2884
- type: "mouse",
2885
- event: e,
2886
- buttons: { ...this._buttonState },
2887
- axes: { ...this._axesState },
2888
- position: { ...this._position }
2889
- });
2890
- }
2891
- _handlePointerMove(e) {
2892
- e.pointerType === "mouse" && (this._position = {
2893
- absolute: {
2894
- x: e.clientX,
2895
- y: e.clientY
2896
- },
2897
- relative: {
2898
- x: e.movementX,
2899
- y: e.movementY
2900
- }
2901
- }, this._axesState["axis-x"] = e.clientX, this._axesState["axis-y"] = e.clientY, this._notifyInputChanged({
2902
- type: "mouse",
2903
- event: e,
2904
- buttons: { ...this._buttonState },
2905
- axes: { ...this._axesState },
2906
- position: { ...this._position }
2907
- }));
2908
- }
2909
- _handleMouseWheel(e) {
2910
- this._wheelState = {
2911
- deltaX: e.deltaX,
2912
- deltaY: e.deltaY,
2913
- deltaZ: e.deltaZ,
2914
- deltaMode: e.deltaMode
2915
- }, this._notifyWheelState(e), this._wheelState = {
2916
- deltaX: 0,
2917
- deltaY: 0,
2918
- deltaZ: 0,
2919
- deltaMode: 0
2920
- }, this._notifyWheelState(e);
2921
- }
2922
- _notifyWheelState(e) {
2923
- this._notifyInputChanged({
2924
- type: "mouse",
2925
- event: e,
2926
- buttons: { ...this._buttonState },
2927
- axes: { ...this._axesState },
2928
- position: { ...this._position },
2929
- wheel: { ...this._wheelState }
2930
- });
2931
- }
2932
- _notifyDeviceConnected() {
2933
- this._onDeviceConnected && this._onDeviceConnected(this._mouseDevice);
2934
- }
2935
- _notifyInputChanged(e) {
2936
- this._onInputChanged && this._onInputChanged(this._mouseDevice, e);
2937
- }
2938
- }, Je = class {
2939
- _gamepadDevices = {};
2940
- _buttonStates = {};
2941
- _axesStates = {};
2942
- _onDeviceConnected;
2943
- _onDeviceDisconnected;
2944
- _onInputChanged;
2945
- constructor() {
2946
- this._setupGamepadEvents();
2947
- }
2948
- onDeviceConnected(e) {
2949
- this._onDeviceConnected = e;
2260
+ return this._masterMuted ? this._masterVolumeBeforeMute : this._audioEngine.getMasterVolume();
2950
2261
  }
2951
- onDeviceDisconnected(e) {
2952
- this._onDeviceDisconnected = e;
2262
+ setMasterMuted(e) {
2263
+ e !== this._masterMuted && (this._masterMuted = e, e ? (this._masterVolumeBeforeMute = this._audioEngine.getMasterVolume(), this._audioEngine.setMasterVolume(0)) : this._audioEngine.setMasterVolume(this._masterVolumeBeforeMute));
2953
2264
  }
2954
- onInputChanged(e) {
2955
- this._onInputChanged = e;
2265
+ isMasterMuted() {
2266
+ return this._masterMuted;
2956
2267
  }
2957
- getDevices() {
2958
- return Object.values(this._gamepadDevices).map((e) => ({ ...e }));
2268
+ setChannelVolume(e, t) {
2269
+ let n = this._channels.get(e);
2270
+ if (!n) {
2271
+ this._log.warn(`Unknown audio channel: ${e}`);
2272
+ return;
2273
+ }
2274
+ n.volume = t, n.muted || this._audioEngine.setBusVolume(n.bus, t);
2959
2275
  }
2960
- getStates() {
2961
- let e = {};
2962
- return Object.keys(this._buttonStates).forEach((t) => {
2963
- let n = Number(t), r = this._buttonStates[n] || {}, i = this._axesStates[n] || {};
2964
- e[n] = {
2965
- type: "gamepad",
2966
- buttons: { ...r },
2967
- axes: { ...i }
2968
- };
2969
- }), e;
2970
- }
2971
- getDevice(e) {
2972
- let t = this._gamepadDevices[e];
2973
- return t ? { ...t } : null;
2974
- }
2975
- getState(e) {
2976
- let t = this._buttonStates[e], n = this._axesStates[e];
2977
- return !t && !n ? null : {
2978
- type: "gamepad",
2979
- buttons: t ? { ...t } : {},
2980
- axes: n ? { ...n } : {}
2981
- };
2276
+ getChannelVolume(e) {
2277
+ return this._channels.get(e)?.volume ?? 1;
2982
2278
  }
2983
- pollGamepads() {
2984
- if (!navigator.getGamepads) return;
2985
- let e = navigator.getGamepads();
2986
- for (let t of e) {
2987
- if (!t) continue;
2988
- let e = t.index;
2989
- if (!this._gamepadDevices[e]) {
2990
- this._handleGamepadConnected(t);
2991
- continue;
2992
- }
2993
- let n = this._gamepadDevices[e];
2994
- if (!n) continue;
2995
- let r = this._buttonStates[e] || {}, i = this._axesStates[e] || {}, a = {}, o = !1;
2996
- t.buttons.forEach((e, t) => {
2997
- let n = `button-${t}`, i = {
2998
- pressed: e.pressed,
2999
- touched: e.touched,
3000
- value: e.value
3001
- };
3002
- a[n] = i;
3003
- let s = r[n];
3004
- (!s || s.pressed !== i.pressed || s.touched !== i.touched || s.value !== i.value) && (o = !0);
3005
- });
3006
- let s = {}, c = !1;
3007
- if (t.axes.forEach((e, t) => {
3008
- let n = `axis-${t}`;
3009
- s[n] = e, i[n] !== e && (c = !0);
3010
- }), this._buttonStates[e] = a, this._axesStates[e] = s, o || c) {
3011
- let e = {
3012
- type: "gamepad",
3013
- buttons: { ...a },
3014
- axes: { ...s }
3015
- };
3016
- this._notifyInputChanged(n, e);
3017
- }
2279
+ setChannelMuted(e, t) {
2280
+ let n = this._channels.get(e);
2281
+ if (!n) {
2282
+ this._log.warn(`Unknown audio channel: ${e}`);
2283
+ return;
3018
2284
  }
2285
+ t !== n.muted && (n.muted = t, this._audioEngine.setBusVolume(n.bus, t ? 0 : n.volume));
3019
2286
  }
3020
- $teardown() {
3021
- return window.removeEventListener("gamepadconnected", this._handleGamepadConnected), window.removeEventListener("gamepaddisconnected", this._handleGamepadDisconnected), Promise.resolve();
2287
+ isChannelMuted(e) {
2288
+ return this._channels.get(e)?.muted ?? !1;
3022
2289
  }
3023
- _setupGamepadEvents() {
3024
- if (this._handleGamepadConnected = this._handleGamepadConnected.bind(this), this._handleGamepadDisconnected = this._handleGamepadDisconnected.bind(this), window.addEventListener("gamepadconnected", this._handleGamepadConnected), window.addEventListener("gamepaddisconnected", this._handleGamepadDisconnected), navigator.getGamepads) {
3025
- let e = navigator.getGamepads();
3026
- for (let t of e) t && this._handleGamepadConnected(t);
3027
- }
2290
+ getChannels() {
2291
+ return Array.from(this._channels.keys());
3028
2292
  }
3029
- _handleGamepadConnected(e) {
3030
- let t = e instanceof GamepadEvent ? e.gamepad : e, n = t.index, r = {
3031
- id: `gamepad-${n}`,
3032
- name: t.id,
3033
- type: "gamepad",
3034
- connected: !0,
3035
- index: n,
3036
- mapping: t.mapping,
3037
- axes: Array.from(t.axes),
3038
- buttons: Array.from(t.buttons)
3039
- };
3040
- this._gamepadDevices[n] = r;
3041
- let i = {};
3042
- Array.from(t.buttons).forEach((e, t) => {
3043
- i[`button-${t}`] = {
3044
- pressed: e.pressed,
3045
- touched: e.touched,
3046
- value: e.value
3047
- };
3048
- }), this._buttonStates[n] = i;
3049
- let a = {};
3050
- Array.from(t.axes).forEach((e, t) => {
3051
- a[`axis-${t}`] = e;
3052
- }), this._axesStates[n] = a, this._notifyDeviceConnected(r), this._notifyInputChanged(r, {
3053
- type: "gamepad",
3054
- buttons: { ...i },
3055
- axes: { ...a },
3056
- event: e instanceof GamepadEvent ? e : void 0
3057
- });
2293
+ }, nt = 1, rt = class {
2294
+ #e;
2295
+ #t;
2296
+ #n;
2297
+ #r = [];
2298
+ #i = null;
2299
+ constructor(e, t, n = Date.now) {
2300
+ this.#e = e, this.#t = t, this.#n = n;
3058
2301
  }
3059
- _handleGamepadDisconnected(e) {
3060
- let t = e.gamepad.index, n = this._gamepadDevices[t];
3061
- n && (n.connected = !1, this._notifyDeviceDisconnected(n), this._gamepadDevices[t] = void 0, this._buttonStates[t] = void 0, this._axesStates[t] = void 0);
2302
+ $setGameEngine(e) {
2303
+ this.#i = e;
3062
2304
  }
3063
- _notifyDeviceConnected(e) {
3064
- this._onDeviceConnected && this._onDeviceConnected(e);
2305
+ onBeforeSave(e) {
2306
+ this.#r.push(e);
3065
2307
  }
3066
- _notifyDeviceDisconnected(e) {
3067
- this._onDeviceDisconnected && this._onDeviceDisconnected(e);
2308
+ save(e) {
2309
+ let t = {};
2310
+ for (let e of this.#r) t = {
2311
+ ...t,
2312
+ ...e()
2313
+ };
2314
+ return {
2315
+ saveFormatVersion: nt,
2316
+ engineVersion: this.#t,
2317
+ level: this.#e.currentLevel?.name ?? "",
2318
+ timestamp: this.#n(),
2319
+ custom: t,
2320
+ snapshot: e.snapshot()
2321
+ };
3068
2322
  }
3069
- _notifyInputChanged(e, t) {
3070
- this._onInputChanged && this._onInputChanged(e, t);
2323
+ async load(e) {
2324
+ if (e.saveFormatVersion !== nt) throw Error(`The save format version "${e.saveFormatVersion}" is not one this engine knows how to load.`);
2325
+ if (this.#i === null) throw Error("SimulationSaveManager: gameEngine not set. Call $setGameEngine() first.");
2326
+ await this.#e.transition(e.level, { forRestore: !0 });
2327
+ let t = this.#i.simulation;
2328
+ if (t === null) throw Error("SimulationSaveManager: the transitioned level built no simulation to restore into.");
2329
+ let n = t.fromSnapshot(e.snapshot);
2330
+ return this.#e.$bindSimulation(n), {
2331
+ simulation: n,
2332
+ envelope: e
2333
+ };
3071
2334
  }
3072
- }, Ye = class {
3073
- _eventBus;
3074
- _keyboardRA;
3075
- _mouseRA;
3076
- _gamepadRA;
3077
- _log;
3078
- constructor(e, t, n) {
3079
- this._eventBus = e, this._log = n?.getLogger("UserInputManager") || new N("UserInputManager"), this._log.info("Initializing UserInputManager"), this._log.debug("Initializing input resource access classes"), this._keyboardRA = new Ke(), this._mouseRA = new qe(t), this._gamepadRA = new Je(), this._log.debug("Registering input event callbacks"), this._keyboardRA.onDeviceConnected(this._publishDeviceConnected.bind(this)), this._keyboardRA.onInputChanged(this._publishInputChanged.bind(this)), this._mouseRA.onDeviceConnected(this._publishDeviceConnected.bind(this)), this._mouseRA.onInputChanged(this._publishInputChanged.bind(this)), this._gamepadRA.onDeviceConnected(this._publishDeviceConnected.bind(this)), this._gamepadRA.onDeviceDisconnected(this._publishDeviceDisconnected.bind(this)), this._gamepadRA.onInputChanged(this._publishInputChanged.bind(this)), this._log.info("UserInputManager initialized successfully");
2335
+ async $teardown() {
2336
+ this.#r.length = 0;
3080
2337
  }
3081
- _publishDeviceConnected(e) {
3082
- this._log.debug(`Device connected: ${e.id} (${e.name})`), this._eventBus.publish({
3083
- type: "input:device:connected",
3084
- payload: { device: e }
3085
- });
2338
+ }, it = class {
2339
+ _viewer = null;
2340
+ _shown = /* @__PURE__ */ new Map();
2341
+ _materials = /* @__PURE__ */ new Map();
2342
+ showColliderForNode(e, t) {
2343
+ if (!e.physicsBody || this._shown.has(e)) return;
2344
+ let n = this._getViewer(e).showBody(e.physicsBody);
2345
+ if (!n) return;
2346
+ let r = { debugMesh: n };
2347
+ if (t) {
2348
+ let i = this._getColorMaterial(t, e);
2349
+ n.material = i, r.colorMaterial = i;
2350
+ }
2351
+ this._shown.set(e, r);
3086
2352
  }
3087
- _publishDeviceDisconnected(e) {
3088
- this._log.debug(`Device disconnected: ${e.id} (${e.name})`), this._eventBus.publish({
3089
- type: "input:device:disconnected",
3090
- payload: { device: e }
3091
- });
2353
+ hideColliderForNode(e) {
2354
+ !this._shown.get(e) || !this._viewer || (e.physicsBody && this._viewer.hideBody(e.physicsBody), this._shown.delete(e));
3092
2355
  }
3093
- _publishInputChanged(e, t) {
3094
- this._log.trace(`Input changed: ${e.id}`, t), this._eventBus.publish({
3095
- type: "input:changed",
3096
- payload: {
3097
- deviceId: e.id,
3098
- device: e,
3099
- state: t
3100
- }
3101
- });
2356
+ hideAll() {
2357
+ for (let [e] of this._shown) this.hideColliderForNode(e);
3102
2358
  }
3103
- $teardown() {
3104
- return this._log.info("Tearing down UserInputManager"), this._log.debug("Cleaning up input resource access instances"), Promise.all([
3105
- this._keyboardRA.$teardown(),
3106
- this._mouseRA.$teardown(),
3107
- this._gamepadRA.$teardown()
3108
- ]).then(() => {
3109
- this._log.info("UserInputManager torn down successfully");
3110
- });
2359
+ isShown(e) {
2360
+ return this._shown.has(e);
3111
2361
  }
3112
- listDevices() {
3113
- this._log.debug("Getting all connected input devices");
3114
- let e = [];
3115
- return e.push(this._keyboardRA.getDevice()), e.push(this._mouseRA.getDevice()), e.push(...this._gamepadRA.getDevices()), this._log.debug(`Found ${e.length} connected devices`), e;
2362
+ async $teardown() {
2363
+ this.dispose();
3116
2364
  }
3117
- getDevice(e) {
3118
- if (this._log.debug(`Getting device: ${e}`), e.startsWith("keyboard-")) return this._keyboardRA.getDevice();
3119
- if (e.startsWith("mouse-")) return this._mouseRA.getDevice();
3120
- if (e.startsWith("gamepad-")) {
3121
- let t = parseInt(e.split("-")[1], 10);
3122
- return this._gamepadRA.getDevice(t);
3123
- }
3124
- return this.listDevices().find((t) => t.id === e) || (this._log.warn(`Device not found: ${e}`), null);
2365
+ dispose() {
2366
+ this._viewer &&= (this.hideAll(), this._viewer.dispose(), null), this._shown.clear();
2367
+ for (let e of this._materials.values()) e.dispose();
2368
+ this._materials.clear();
2369
+ }
2370
+ _getViewer(e) {
2371
+ return this._viewer ||= new pe(e.getScene()), this._viewer;
3125
2372
  }
3126
- pollGamepads() {
3127
- this._gamepadRA.pollGamepads();
2373
+ _getColorMaterial(e, t) {
2374
+ let n = this._materials.get(e);
2375
+ return n || (n = new E(`sage-collider-debug-${e}`, t.getScene()), n.emissiveColor = r.FromHexString(e), n.disableLighting = !0, n.wireframe = !0, this._materials.set(e, n), n);
3128
2376
  }
3129
2377
  };
3130
2378
  //#endregion
3131
2379
  //#region src/utils/graphics.ts
3132
- async function Xe(e, t) {
2380
+ async function at() {
2381
+ return Pe() ? le.IsSupportedAsync : !1;
2382
+ }
2383
+ async function ot(e, t) {
3133
2384
  let n = new le(e, t);
3134
2385
  return await n.initAsync(), n;
3135
2386
  }
3136
- function J(e, t) {
2387
+ function st(e, t) {
3137
2388
  return new l(e, t.antialias, t.options, t.adaptToDeviceRatio);
3138
2389
  }
3139
- function Ze(e) {
3140
- return new x(e);
2390
+ function ct(e) {
2391
+ return new b(e);
3141
2392
  }
3142
- async function Qe(e, t, n = !1) {
3143
- if (e === null) return console.debug("Using Null Engine"), Ze(t);
3144
- if (n) if ("options" in t) {
3145
- let e = t;
3146
- t = {
3147
- ...e,
3148
- options: {
3149
- ...e.options,
3150
- useLargeWorldRendering: !0
3151
- }
2393
+ async function lt(e, t, n = !1) {
2394
+ if (e === null) return console.debug("Using Null Engine"), ct(t);
2395
+ if (n) {
2396
+ if ("options" in t) {
2397
+ let e = t;
2398
+ t = {
2399
+ ...e,
2400
+ options: {
2401
+ ...e.options,
2402
+ useLargeWorldRendering: !0
2403
+ }
2404
+ };
2405
+ } else t = {
2406
+ ...t,
2407
+ useLargeWorldRendering: !0
3152
2408
  };
3153
- } else t = {
3154
- ...t,
3155
- useLargeWorldRendering: !0
3156
- };
2409
+ }
3157
2410
  let r = t.engine || "auto";
3158
- if (r === "webgpu") if (De()) try {
3159
- return console.debug("Using forced WebGPU engine"), await Xe(e, t);
3160
- } catch (e) {
3161
- throw console.error("Forced WebGPU initialization failed:", e), Error("Forced WebGPU failed to initialize. If WebGPU is required, check browser compatibility.", { cause: e });
2411
+ if (r === "webgpu") {
2412
+ if (await at()) try {
2413
+ return console.debug("Using forced WebGPU engine"), await ot(e, t);
2414
+ } catch (e) {
2415
+ throw console.error("Forced WebGPU initialization failed:", e), Error("Forced WebGPU failed to initialize. If WebGPU is required, check browser compatibility.", { cause: e });
2416
+ }
2417
+ throw Error("WebGPU was forced but is not available in this browser.");
3162
2418
  }
3163
- else throw Error("WebGPU was forced but is not available in this browser.");
3164
- if (r === "webgl") return console.debug("Using forced WebGL engine"), J(e, t);
3165
- if (De()) try {
3166
- return console.debug("Using WebGPU"), Xe(e, t).catch((n) => (console.warn("WebGPU initialization failed, falling back to WebGL:", n), J(e, t)));
2419
+ if (r === "webgl") return console.debug("Using forced WebGL engine"), st(e, t);
2420
+ if (await at()) try {
2421
+ return console.debug("Using WebGPU"), await ot(e, t);
3167
2422
  } catch (e) {
3168
2423
  console.warn("WebGPU initialization failed, falling back to WebGL:", e);
3169
2424
  }
3170
2425
  else console.warn("WebGPU not supported, falling back to WebGL.");
3171
- return console.debug("Using WebGL"), J(e, t);
2426
+ return console.debug("Using WebGL"), st(e, t);
3172
2427
  }
3173
2428
  //#endregion
3174
2429
  //#region src/utils/physics.ts
3175
- async function $e() {
3176
- return await me();
2430
+ async function ut(e) {
2431
+ return await me(e ? { wasmBinary: e } : void 0);
3177
2432
  }
3178
- function et(e) {
2433
+ function dt(e) {
3179
2434
  return new p(!0, e);
3180
2435
  }
3181
2436
  //#endregion
3182
- //#region src/utils/raycast.ts
3183
- var tt = class {
3184
- _entityManager;
3185
- constructor(e) {
3186
- this._entityManager = e;
3187
- }
3188
- pickEntity(e, t, n, r) {
3189
- let i = e.pick(t, n);
3190
- return this._toEntityResult(i, r);
3191
- }
3192
- pickEntities(e, t, n, r) {
3193
- let i = e.multiPick(t, n);
3194
- if (!i) return [];
3195
- let a = [];
3196
- for (let e of i) {
3197
- let t = this._toEntityResult(e, r);
3198
- t && a.push(t);
3199
- }
3200
- return a;
3201
- }
3202
- pickEntityWithRay(e, t, n) {
3203
- let r = e.pickWithRay(t);
3204
- return r ? this._toEntityResult(r, n) : null;
3205
- }
3206
- pickEntitiesWithRay(e, t, n) {
3207
- let r = e.multiPickWithRay(t);
3208
- if (!r) return [];
3209
- let i = [];
3210
- for (let e of r) {
3211
- let t = this._toEntityResult(e, n);
3212
- t && i.push(t);
3213
- }
3214
- return i;
3215
- }
3216
- pickEntityForward(e, t, n = 1e3, r) {
3217
- let i = t.getForwardRay(n);
3218
- return this.pickEntityWithRay(e, i, r);
3219
- }
3220
- _toEntityResult(e, t) {
3221
- if (!e.hit || !e.pickedMesh || !e.pickedPoint) return null;
3222
- let n = e.pickedMesh, r = this._entityManager.getByNode(n);
3223
- if (!r) {
3224
- let e = n.parent;
3225
- for (; e && (r = this._entityManager.getByNode(e), !r);) e = e.parent;
3226
- }
3227
- if (!r) return null;
3228
- if (t) {
3229
- if (t.type && r.type !== t.type) return null;
3230
- if (t.tags) {
3231
- for (let e of t.tags) if (!r.hasTag(e)) return null;
3232
- }
3233
- if (t.predicate && !t.predicate(r)) return null;
3234
- }
3235
- let i = e.getNormal(!0, !0);
3236
- return {
3237
- entity: r,
3238
- point: e.pickedPoint,
3239
- distance: e.distance,
3240
- normal: i ?? {
3241
- x: 0,
3242
- y: 0,
3243
- z: 0
3244
- },
3245
- mesh: n,
3246
- pickingInfo: e
3247
- };
3248
- }
3249
- }, nt = class {
2437
+ //#region src/utils/timer.ts
2438
+ var ft = class {
3250
2439
  _nextId = 0;
3251
2440
  _delays = [];
3252
2441
  _intervals = [];
@@ -3287,359 +2476,181 @@ var tt = class {
3287
2476
  reset() {
3288
2477
  t.remaining = t.periodMs;
3289
2478
  }
3290
- };
3291
- }
3292
- cancelAll() {
3293
- this._delays = [], this._intervals = [];
3294
- for (let e of this._cooldowns) e.remaining = 0;
3295
- this._cooldowns = [];
3296
- }
3297
- tick(e) {
3298
- let t = [];
3299
- for (let n of this._delays) n.remaining -= e, n.remaining <= 0 && (n.callback(), t.push(n.id));
3300
- t.length > 0 && (this._delays = this._delays.filter((e) => !t.includes(e.id)));
3301
- for (let t of this._intervals) for (t.elapsed += e; t.elapsed >= t.periodMs;) t.callback(), t.elapsed -= t.periodMs;
3302
- for (let t of this._cooldowns) t.remaining > 0 && (t.remaining = Math.max(0, t.remaining - e));
3303
- }
3304
- };
3305
- //#endregion
3306
- //#region src/utils/entityProxy.ts
3307
- function rt(e) {
3308
- return new Proxy(e, { get(e, t) {
3309
- if (typeof t == "symbol") return Reflect.get(e, t);
3310
- if (t in e) {
3311
- let n = Reflect.get(e, t);
3312
- return typeof n == "function" ? n.bind(e) : n;
3313
- }
3314
- return e.getByName(t);
3315
- } });
3316
- }
3317
- //#endregion
3318
- //#region src/debug/builtins.ts
3319
- function it(e, t) {
3320
- return typeof e == "string" ? t.managers.entityManager.getByName(e) : e;
3321
- }
3322
- function at(e, t) {
3323
- let n = t.managers.entityManager;
3324
- if (e === void 0) return [...n.getAllEntities()];
3325
- if (typeof e != "string") return [e];
3326
- let r = n.getByName(e);
3327
- if (r) return [r];
3328
- let i = n.getByType(e);
3329
- return i.length > 0 ? i : (console.warn(`[sage] No entity found with name or type "${e}"`), []);
3330
- }
3331
- function ot(e, t) {
3332
- let n = t.managers.entityManager, r = t.managers.gameManager, i = t.managers.levelManager, a = [];
3333
- e.expose("engine", t), e.expose("events", t.eventBus), e.expose("physics", t.physics), e.expose("colliders", t.debug.colliders), e.expose("entities", rt(n)), e.expose("level", { get: () => i.currentLevel }), e.expose("scene", { get: () => i.currentLevel?.scene ?? null }), e.expose("tp", (e, n, r, i) => {
3334
- let a = it(e, t);
3335
- if (!a) {
3336
- console.warn(`[sage] Entity not found: ${e}`);
3337
- return;
3338
- }
3339
- if (!a.node) {
3340
- console.warn(`[sage] Entity "${a.name ?? a.id}" has no node`);
3341
- return;
3342
- }
3343
- a.node.position.x = n, a.node.position.y = r, a.node.position.z = i, console.log(`[sage] Teleported "${a.name ?? a.id}" to (${n}, ${r}, ${i})`);
3344
- }), e.expose("spawn", async (e, t, r, i) => {
3345
- let a = await n.createEntity(e, { initialState: { position: {
3346
- x: t,
3347
- y: r,
3348
- z: i
3349
- } } });
3350
- return console.log(`[sage] Spawned "${e}" (${a.id}) at (${t}, ${r}, ${i})`), a;
3351
- }), e.expose("list", (e) => {
3352
- let t;
3353
- t = e ? n.getByType(e) : [...n.getAllEntities()];
3354
- let r = t.map((e) => ({
3355
- id: e.id,
3356
- type: e.type,
3357
- name: e.name ?? "(unnamed)",
3358
- node: e.node?.name ?? "(no node)"
3359
- }));
3360
- return console.table(r), t;
3361
- }), e.expose("inspect", (e) => {
3362
- let n = it(e, t);
3363
- if (!n) {
3364
- console.warn(`[sage] Entity not found: ${e}`);
3365
- return;
3366
- }
3367
- let r = {
3368
- id: n.id,
3369
- type: n.type,
3370
- name: n.name,
3371
- state: n.state,
3372
- behaviors: n.behaviors.map((e) => e.name),
3373
- node: n.node?.name ?? null,
3374
- position: n.node?.position ?? null
3375
- };
3376
- return console.log("[sage] Entity info:", r), r;
3377
- }), e.expose("showColliders", (e) => {
3378
- let n = at(e, t);
3379
- for (let e of n) e.showCollider();
3380
- console.log(`[sage] Showing colliders for ${n.length} entity(s)`);
3381
- }), e.expose("hideColliders", (e) => {
3382
- let n = at(e, t);
3383
- for (let e of n) e.hideCollider();
3384
- console.log(`[sage] Hiding colliders for ${n.length} entity(s)`);
3385
- }), e.expose("logEvents", (e) => {
3386
- let n = e ?? "*", r = t.eventBus.subscribe(n, (e) => {
3387
- console.log(`[sage] Event: ${e.type}`, e.payload);
3388
- });
3389
- return a.push(r), console.log(`[sage] Logging events matching "${n}"`), r;
3390
- }), e.expose("stopLogging", () => {
3391
- for (let e of a) e();
3392
- console.log(`[sage] Stopped ${a.length} event logger(s)`), a.length = 0;
3393
- }), e.expose("pause", () => {
3394
- r.pause("debug console"), console.log("[sage] Game paused");
3395
- }), e.expose("resume", () => {
3396
- r.resume("debug console"), console.log("[sage] Game resumed");
3397
- }), e.expose("slow", (e) => {
3398
- t.renderEngine.timeStep = 1 / 60 / e, console.log(`[sage] Time scale set to ${e}x (timeStep=${1 / 60 / e})`);
3399
- });
3400
- }
3401
- //#endregion
3402
- //#region src/interfaces/logger.ts
3403
- var st = [
3404
- "trace",
3405
- "debug",
3406
- "info",
3407
- "warn",
3408
- "error",
3409
- "none"
3410
- ], ct = class extends G {
3411
- name = "sound";
3412
- eventSubscriptions = [];
3413
- _sounds = /* @__PURE__ */ new Map();
3414
- _initialized = !1;
3415
- _audioManager = null;
3416
- _node = null;
3417
- _log = new N("SoundBehavior");
3418
- onNodeAttached(e, t) {
3419
- if (this._initialized) return;
3420
- if (this._node = e, this._initialized = !0, this._log = t.logger.getLogger("SoundBehavior"), t.managers.audioManager) this._audioManager = t.managers.audioManager;
3421
- else {
3422
- this._log.warn("No AudioManager configured. Sounds will not be created.");
3423
- return;
3424
- }
3425
- if (!this.entity) return;
3426
- let n = this.entity.state.sounds;
3427
- if (n) for (let [e, t] of Object.entries(n)) this._createSound(e, t);
3428
- }
3429
- processEvent(e, t) {
3430
- return !1;
3431
- }
3432
- onReset(e) {
3433
- this._disposeSounds();
3434
- }
3435
- async destroy() {
3436
- this._disposeSounds();
3437
- }
3438
- _createSound(e, t) {
3439
- if (!this._audioManager || !this.entity) return;
3440
- let n = this.entity.id, r = this._node;
3441
- this._audioManager.createSound(`${n}_${e}`, t.url, t.channel, {
3442
- loop: t.loop ?? !1,
3443
- autoplay: t.autoplay ?? !1,
3444
- volume: t.volume ?? 1,
3445
- spatialEnabled: t.spatial ?? !1,
3446
- spatialMaxDistance: t.maxDistance ?? 100,
3447
- spatialDistanceModel: "linear"
3448
- }).then((n) => {
3449
- this._sounds.set(e, n), (t.spatial ?? !1) && r && n.spatial.attach(r);
3450
- }).catch((t) => {
3451
- this._log.error(`Failed to create sound "${e}": ${t}`);
3452
- });
3453
- }
3454
- _disposeSounds() {
3455
- for (let e of this._sounds.values()) e.dispose();
3456
- this._sounds.clear(), this._initialized = !1, this._node = null, this._audioManager = null;
3457
- }
3458
- play(e, t) {
3459
- let n = this._getSound(e);
3460
- n && (t === void 0 ? n.play() : n.play({ startOffset: t }));
3461
- }
3462
- stop(e) {
3463
- if (e) {
3464
- let t = this._sounds.get(e);
3465
- t && t.stop();
3466
- } else for (let e of this._sounds.values()) e.stop();
3467
- }
3468
- pause(e) {
3469
- let t = this._getSound(e);
3470
- t && t.pause();
3471
- }
3472
- setVolume(e, t) {
3473
- if (t) {
3474
- let n = this._sounds.get(t);
3475
- n && (n.volume = e);
3476
- } else for (let t of this._sounds.values()) t.volume = e;
3477
- }
3478
- isPlaying(e) {
3479
- return this._getSound(e)?.state === ae.Started;
3480
- }
3481
- getSoundNames() {
3482
- return Array.from(this._sounds.keys());
3483
- }
3484
- hasSound(e) {
3485
- return this._sounds.has(e);
3486
- }
3487
- registerSound(e, t) {
3488
- if (!this._initialized || !this._audioManager) throw Error("SoundBehavior must be initialized before registering sounds");
3489
- let n = this._sounds.get(e);
3490
- n && n.dispose(), this._createSound(e, t);
3491
- }
3492
- unregisterSound(e) {
3493
- let t = this._sounds.get(e);
3494
- t && (t.dispose(), this._sounds.delete(e));
3495
- }
3496
- _getSound(e) {
3497
- if (e) return this._sounds.get(e);
3498
- if (this._sounds.size === 1) return this._sounds.values().next().value;
3499
- }
3500
- }, Y = class {
3501
- _currentState;
3502
- transitions = /* @__PURE__ */ new Map();
3503
- wildcardTransitions = /* @__PURE__ */ new Map();
3504
- enterCallbacks = /* @__PURE__ */ new Map();
3505
- exitCallbacks = /* @__PURE__ */ new Map();
3506
- eventBus;
3507
- constructor(e, t) {
3508
- this._currentState = e, this.eventBus = t;
3509
- }
3510
- get currentState() {
3511
- return this._currentState;
3512
- }
3513
- addTransition(e, t, n) {
3514
- let r = `${e}->${t}`;
3515
- this.transitions.set(r, { guard: n });
3516
- }
3517
- addTransitionFromAny(e, t) {
3518
- this.wildcardTransitions.set(e, { guard: t });
3519
- }
3520
- onEnter(e, t) {
3521
- let n = this.enterCallbacks.get(e) ?? [];
3522
- n.push(t), this.enterCallbacks.set(e, n);
3523
- }
3524
- onExit(e, t) {
3525
- let n = this.exitCallbacks.get(e) ?? [];
3526
- n.push(t), this.exitCallbacks.set(e, n);
3527
- }
3528
- canTransition(e) {
3529
- let t = `${this._currentState}->${e}`;
3530
- return this.transitions.has(t) || this.wildcardTransitions.has(e);
3531
- }
3532
- transition(e) {
3533
- let t = `${this._currentState}->${e}`, n = this.transitions.get(t);
3534
- if (n ||= this.wildcardTransitions.get(e), !n) throw Error(`No transition defined from '${this._currentState}' to '${e}'.`);
3535
- if (n.guard && !n.guard()) throw Error(`Guard rejected transition from '${this._currentState}' to '${e}'.`);
3536
- let r = this._currentState, i = this.exitCallbacks.get(r);
3537
- if (i) for (let e of i) e();
3538
- this.eventBus && this.eventBus.publish({
3539
- type: `state:exit:${r}`,
3540
- payload: {
3541
- from: r,
3542
- to: e
3543
- }
3544
- }), this._currentState = e;
3545
- let a = this.enterCallbacks.get(e);
3546
- if (a) for (let e of a) e();
3547
- this.eventBus && this.eventBus.publish({
3548
- type: `state:enter:${e}`,
3549
- payload: {
3550
- from: r,
3551
- to: e
3552
- }
3553
- });
3554
- }
3555
- }, lt = class extends G {
3556
- name = "stateMachine";
3557
- eventSubscriptions = [];
3558
- stateMachine;
3559
- stateKey;
3560
- constructor() {
3561
- super(), this.stateMachine = new Y(""), this.stateKey = "";
2479
+ };
3562
2480
  }
3563
- get currentState() {
3564
- return this.stateMachine.currentState;
2481
+ cancelAll() {
2482
+ this._delays = [], this._intervals = [];
2483
+ for (let e of this._cooldowns) e.remaining = 0;
2484
+ this._cooldowns = [];
3565
2485
  }
3566
- transition(e) {
3567
- this.stateMachine.transition(e), this.entity && (this.entity.state[this.stateKey] = e, this.$emitStateChanged());
2486
+ tick(e) {
2487
+ let t = [];
2488
+ for (let n of this._delays) n.remaining -= e, n.remaining <= 0 && (n.callback(), t.push(n.id));
2489
+ t.length > 0 && (this._delays = this._delays.filter((e) => !t.includes(e.id)));
2490
+ for (let t of this._intervals) for (t.elapsed += e; t.elapsed >= t.periodMs;) t.callback(), t.elapsed -= t.periodMs;
2491
+ for (let t of this._cooldowns) t.remaining > 0 && (t.remaining = Math.max(0, t.remaining - e));
3568
2492
  }
3569
- processEvent(e, t) {
3570
- return !1;
2493
+ };
2494
+ //#endregion
2495
+ //#region src/debug/builtins.ts
2496
+ function q(e) {
2497
+ if (e.simulation === null) {
2498
+ console.warn("[sage] No simulation yet -- nothing has given the engine a scene to build one against.");
2499
+ return;
3571
2500
  }
3572
- static create(e) {
3573
- let { initialState: t, stateKey: n, transitions: r, wildcardTransitions: i } = e;
3574
- class a extends lt {
3575
- constructor() {
3576
- super(), this.stateKey = n, this.stateMachine = new Y(t);
3577
- for (let e of r) this.stateMachine.addTransition(e.from, e.to, e.guard);
3578
- if (i) for (let e of i) this.stateMachine.addTransitionFromAny(e.to, e.guard);
3579
- }
2501
+ return e.simulation;
2502
+ }
2503
+ function pt(e, t) {
2504
+ return typeof e == "string" ? q(t)?.getEntity(e) : e;
2505
+ }
2506
+ function mt(e, t) {
2507
+ let n = t.managers.gameManager, r = t.managers.levelManager, i = [];
2508
+ e.expose("engine", t), e.expose("events", t.eventBus), e.expose("physics", t.physics), e.expose("colliders", t.debug.colliders), e.expose("entities", new Proxy({}, { get(e, n) {
2509
+ if (typeof n == "symbol") return;
2510
+ let r = q(t)?.getEntity(n);
2511
+ return r || console.warn(`[sage] Entity not found: ${n}`), r;
2512
+ } })), e.expose("level", { get: () => r.currentLevel }), e.expose("scene", { get: () => r.currentLevel?.scene ?? null }), e.expose("tp", (e, n, r, i) => {
2513
+ let a = pt(e, t);
2514
+ if (!a) {
2515
+ console.warn(`[sage] Entity not found: ${e}`);
2516
+ return;
3580
2517
  }
3581
- return a;
3582
- }
3583
- }, X = new N("ColliderHandler");
3584
- function ut(e) {
3585
- let { min: t, max: n } = e.getHierarchyBoundingVectors(!0), r = n.subtract(t), i = t.add(n).scale(.5).subtract(e.absolutePosition), a = e.absoluteRotationQuaternion, o = T.Inverse(a), s = new O();
3586
- return i.rotateByQuaternionToRef(o, s), {
2518
+ if (!(a instanceof H)) {
2519
+ console.warn(`[sage] Entity "${a.id}" has no node`);
2520
+ return;
2521
+ }
2522
+ let o = a.state;
2523
+ o.nodeName === void 0 ? o.position = {
2524
+ x: n,
2525
+ y: r,
2526
+ z: i
2527
+ } : (a.node.position.x = n, a.node.position.y = r, a.node.position.z = i), console.log(`[sage] Teleported "${a.id}" to (${n}, ${r}, ${i})`);
2528
+ }), e.expose("spawn", (e, n, r, i) => {
2529
+ let a = q(t);
2530
+ if (!a) return;
2531
+ let o = a.spawn(e, void 0, { position: {
2532
+ x: n,
2533
+ y: r,
2534
+ z: i
2535
+ } });
2536
+ return console.log(`[sage] Spawned "${e}" (${o.id}) at (${n}, ${r}, ${i})`), o;
2537
+ }), e.expose("list", (e, n) => {
2538
+ let r = q(t);
2539
+ if (!r) return [];
2540
+ let i = r.entities;
2541
+ e !== void 0 && (i = i.filter((t) => t.name === e)), n !== void 0 && (i = i.filter((e) => e.state.tags.includes(n)));
2542
+ let a = i.map((e) => {
2543
+ let t = {
2544
+ id: e.id,
2545
+ name: e.name,
2546
+ node: e instanceof H ? e.node.name : "(no node)"
2547
+ };
2548
+ return e.hasBehavior(F) && (t.displayName = e.state.displayName), t;
2549
+ });
2550
+ return console.table(a), [...i];
2551
+ }), e.expose("inspect", (e) => {
2552
+ let n = pt(e, t);
2553
+ if (!n) {
2554
+ console.warn(`[sage] Entity not found: ${e}`);
2555
+ return;
2556
+ }
2557
+ let r = {
2558
+ id: n.id,
2559
+ state: n.state,
2560
+ node: n instanceof H ? n.node.name : null,
2561
+ position: n instanceof H ? n.node.position : null
2562
+ };
2563
+ return console.log("[sage] Entity info:", r), r;
2564
+ }), e.expose("logEvents", (e) => {
2565
+ let n = e ?? "*", r = t.eventBus.subscribe(n, (e) => {
2566
+ console.log(`[sage] Event: ${e.type}`, e.payload);
2567
+ });
2568
+ return i.push(r), console.log(`[sage] Logging events matching "${n}"`), r;
2569
+ }), e.expose("stopLogging", () => {
2570
+ for (let e of i) e();
2571
+ console.log(`[sage] Stopped ${i.length} event logger(s)`), i.length = 0;
2572
+ }), e.expose("pause", () => {
2573
+ n.pause("debug console"), console.log("[sage] Game paused");
2574
+ }), e.expose("resume", () => {
2575
+ n.resume("debug console"), console.log("[sage] Game resumed");
2576
+ }), e.expose("slow", (e) => {
2577
+ t.renderEngine.timeStep = 1 / 60 / e, console.log(`[sage] Time scale set to ${e}x (timeStep=${1 / 60 / e})`);
2578
+ });
2579
+ }
2580
+ //#endregion
2581
+ //#region src/interfaces/logger.ts
2582
+ var ht = [
2583
+ "trace",
2584
+ "debug",
2585
+ "info",
2586
+ "warn",
2587
+ "error",
2588
+ "none"
2589
+ ];
2590
+ //#endregion
2591
+ //#region src/utils/bounds.ts
2592
+ function gt(e) {
2593
+ let { min: t, max: n } = e.getHierarchyBoundingVectors(!0), r = n.subtract(t), i = t.add(n).scale(.5).subtract(e.absolutePosition), a = w.Inverse(e.absoluteRotationQuaternion), o = new O();
2594
+ return i.rotateByQuaternionToRef(a, o), {
3587
2595
  extents: r,
3588
- center: s
2596
+ center: o
3589
2597
  };
3590
2598
  }
3591
- function Z(e, t, n) {
2599
+ //#endregion
2600
+ //#region src/handlers/collider.ts
2601
+ var J = new j("ColliderHandler");
2602
+ function Y(e, t, n) {
3592
2603
  let r = e.getScene(), i = { mass: n };
3593
- if (!(e instanceof y) && (t === w.BOX || t === w.SPHERE)) {
3594
- let { extents: n, center: r } = ut(e);
3595
- i.center = r, t === w.BOX ? i.extents = n : i.radius = Math.max(n.x, n.y, n.z) / 2;
2604
+ if (!(e instanceof v) && (t === C.BOX || t === C.SPHERE)) {
2605
+ let { extents: n, center: r } = gt(e);
2606
+ i.center = r, t === C.BOX ? i.extents = n : i.radius = Math.max(n.x, n.y, n.z) / 2;
3596
2607
  }
3597
- new C(e, t, i, r);
2608
+ new S(e, t, i, r);
3598
2609
  }
3599
- function dt(e, t) {
2610
+ function _t(e, t) {
3600
2611
  let n = e.getChildMeshes().find((e) => e.metadata?.collider_mesh === !0);
3601
- n instanceof y ? (n.isVisible = !1, Z(n, w.MESH, t)) : Z(e, w.MESH, t);
2612
+ n instanceof v ? (n.isVisible = !1, Y(n, C.MESH, t)) : Y(e, C.MESH, t);
3602
2613
  }
3603
- function ft(t) {
2614
+ function vt(t) {
3604
2615
  t.registerPropertyHandler("collider", (t, n, r, i) => {
3605
2616
  let a = n;
3606
- if (X.debug(`Processing collider: ${t.name} -> ${a} (isMesh: ${t instanceof y})`), !r.scene) throw Error("Scene not available for collider handler");
3607
- if (!(t instanceof y) && a === "mesh") {
3608
- X.warn(`Skipping mesh collider for ${t.name}: not a Mesh instance`);
2617
+ if (J.debug(`Processing collider: ${t.name} -> ${a} (isMesh: ${t instanceof v})`), !r.scene) throw Error("Scene not available for collider handler");
2618
+ if (!(t instanceof v) && a === "mesh") {
2619
+ J.warn(`Skipping mesh collider for ${t.name}: not a Mesh instance`);
3609
2620
  return;
3610
2621
  }
3611
2622
  let o = t.metadata?.collider_mass ?? 0;
3612
2623
  switch (a) {
3613
2624
  case "box":
3614
- Z(t, w.BOX, o);
2625
+ Y(t, C.BOX, o);
3615
2626
  break;
3616
2627
  case "sphere":
3617
- Z(t, w.SPHERE, o);
2628
+ Y(t, C.SPHERE, o);
3618
2629
  break;
3619
2630
  case "mesh":
3620
- dt(t, o);
2631
+ _t(t, o);
3621
2632
  break;
3622
2633
  case "none":
3623
2634
  t instanceof e && (t.checkCollisions = !1);
3624
2635
  break;
3625
- default: X.warn(`Unknown collider type: ${a}`);
2636
+ default: J.warn(`Unknown collider type: ${a}`);
3626
2637
  }
3627
2638
  t.metadata?.collider_kinematic && t instanceof e && t.physicsBody && (t.physicsBody.disablePreStep = !1);
3628
2639
  });
3629
2640
  }
3630
2641
  //#endregion
3631
2642
  //#region src/handlers/lod.ts
3632
- var pt = new N("LodHandler");
3633
- function mt(e) {
2643
+ var yt = new j("LodHandler");
2644
+ function bt(e) {
3634
2645
  return e.split(",").map((e) => parseFloat(e.trim())).filter((e) => !isNaN(e));
3635
2646
  }
3636
- function ht(e) {
2647
+ function xt(e) {
3637
2648
  e.registerPropertyHandler("lod_distances", (e, t, n, r) => {
3638
2649
  let i = t;
3639
- if (!(e instanceof y)) return;
3640
- let a = mt(i);
2650
+ if (!(e instanceof v)) return;
2651
+ let a = bt(i);
3641
2652
  if (a.length === 0) {
3642
- pt.warn(`Invalid lod_distances value: ${i}`);
2653
+ yt.warn(`Invalid lod_distances value: ${i}`);
3643
2654
  return;
3644
2655
  }
3645
2656
  let o = e.getChildMeshes(!0), s = Math.min(a.length, o.length);
@@ -3650,14 +2661,14 @@ function ht(e) {
3650
2661
  }
3651
2662
  //#endregion
3652
2663
  //#region src/handlers/occluder.ts
3653
- function gt(e) {
2664
+ function St(e) {
3654
2665
  e.registerPropertyHandler("occluder", (e, t, n, r) => {
3655
- t && e instanceof y && (e.isOccluder = !0, e.isVisible = !1);
2666
+ t && e instanceof v && (e.isOccluder = !0, e.isVisible = !1);
3656
2667
  });
3657
2668
  }
3658
2669
  //#endregion
3659
2670
  //#region src/utils/metadata.ts
3660
- function _t(e, t) {
2671
+ function Ct(e, t) {
3661
2672
  let n = {}, r = `${t}_`;
3662
2673
  for (let [t, i] of Object.entries(e)) if (t.startsWith(r)) {
3663
2674
  let e = t.slice(r.length);
@@ -3667,14 +2678,14 @@ function _t(e, t) {
3667
2678
  }
3668
2679
  //#endregion
3669
2680
  //#region src/handlers/sound.ts
3670
- var vt = new N("SoundHandler");
3671
- function yt(e) {
2681
+ var wt = new j("SoundHandler");
2682
+ function Tt(e) {
3672
2683
  e.registerPropertyHandler("sound", (e, t, n, r) => {
3673
2684
  let i = t;
3674
2685
  if (!n.scene) throw Error("Scene not available for sound handler");
3675
- let a = _t(e.metadata, "sound"), o = a.volume ?? 1, s = a.loop ?? !0, c = a.spatial ?? !0, l = a.distance ?? 100, u = a.autoplay ?? !0, d = a.channel ?? "ambient", f = r.managers.audioManager;
2686
+ let a = Ct(e.metadata, "sound"), o = a.volume ?? 1, s = a.loop ?? !0, c = a.spatial ?? !0, l = a.distance ?? 100, u = a.autoplay ?? !0, d = a.channel ?? "ambient", f = r.managers.audioManager;
3676
2687
  if (!f) {
3677
- vt.warn(`No AudioManager available. Sound for "${e.name}" skipped.`);
2688
+ wt.warn(`No AudioManager available. Sound for "${e.name}" skipped.`);
3678
2689
  return;
3679
2690
  }
3680
2691
  f.createSound(`${e.name}_sound`, i, d, {
@@ -3687,13 +2698,13 @@ function yt(e) {
3687
2698
  }).then((t) => {
3688
2699
  c && t.spatial.attach(e);
3689
2700
  }).catch((t) => {
3690
- vt.error(`Failed to create sound for node "${e.name}": ${t}`);
2701
+ wt.error(`Failed to create sound for node "${e.name}": ${t}`);
3691
2702
  });
3692
2703
  });
3693
2704
  }
3694
2705
  //#endregion
3695
2706
  //#region src/handlers/trigger.ts
3696
- function Q(e, n, r, i, a) {
2707
+ function Et(e, n, r, i, a) {
3697
2708
  let o = a === "enter" ? t.OnIntersectionEnterTrigger : t.OnIntersectionExitTrigger, s = `trigger:${a}`;
3698
2709
  e.registerAction(new u({
3699
2710
  trigger: o,
@@ -3703,15 +2714,15 @@ function Q(e, n, r, i, a) {
3703
2714
  type: s,
3704
2715
  payload: {
3705
2716
  trigger: n,
3706
- other: e.source
2717
+ other: e.additionalData
3707
2718
  }
3708
2719
  });
3709
2720
  }));
3710
2721
  }
3711
- function bt(e, t, n, r) {
3712
- Q(e, t, n, r, "enter"), Q(e, t, n, r, "exit");
2722
+ function Dt(e, t, n, r) {
2723
+ Et(e, t, n, r, "enter"), Et(e, t, n, r, "exit");
3713
2724
  }
3714
- function xt(n) {
2725
+ function Ot(n) {
3715
2726
  n.registerPropertyHandler("trigger", (n, r, i, a) => {
3716
2727
  let o = r, s = i.scene;
3717
2728
  if (!s) throw Error("Scene not available for trigger handler");
@@ -3720,9 +2731,9 @@ function xt(n) {
3720
2731
  n.isVisible = !1, n.checkCollisions = !0;
3721
2732
  let l = n.actionManager ?? new t(s);
3722
2733
  n.actionManager = l;
3723
- for (let e of s.meshes) e !== n && !e.metadata?.trigger && bt(l, o, c, e);
2734
+ for (let e of s.meshes) e !== n && !e.metadata?.trigger && Dt(l, o, c, e);
3724
2735
  let u = s.onNewMeshAddedObservable.add((e) => {
3725
- e !== n && !e.metadata?.trigger && bt(l, o, c, e);
2736
+ e !== n && !e.metadata?.trigger && Dt(l, o, c, e);
3726
2737
  });
3727
2738
  n.onDisposeObservable.add(() => {
3728
2739
  s.onNewMeshAddedObservable.remove(u);
@@ -3731,7 +2742,7 @@ function xt(n) {
3731
2742
  }
3732
2743
  //#endregion
3733
2744
  //#region src/handlers/visible.ts
3734
- function $(t) {
2745
+ function kt(t) {
3735
2746
  t.registerPropertyHandler("visible", (t, n, r, i) => {
3736
2747
  if (!(t instanceof e)) return;
3737
2748
  let a = !0;
@@ -3740,60 +2751,493 @@ function $(t) {
3740
2751
  }
3741
2752
  //#endregion
3742
2753
  //#region src/handlers/index.ts
3743
- function St(e) {
3744
- ft(e), ht(e), gt(e), yt(e), xt(e), $(e);
2754
+ function At(e) {
2755
+ vt(e), xt(e), St(e), Tt(e), Ot(e), kt(e);
2756
+ }
2757
+ //#endregion
2758
+ //#region src/entities/defineEntity.ts
2759
+ function jt(e, t) {
2760
+ let n = t ?? {}, r = e.tags ?? [], i = n.tags ?? [];
2761
+ return {
2762
+ ...e.defaultState,
2763
+ ...n,
2764
+ tags: [.../* @__PURE__ */ new Set([...r, ...i])]
2765
+ };
2766
+ }
2767
+ function Mt(e) {
2768
+ class t extends H {
2769
+ static behaviors = e.behaviors;
2770
+ static meshConfig = e.mesh;
2771
+ static actions = e.actions;
2772
+ static create(t, n, r, i) {
2773
+ let a = jt(e, r);
2774
+ return super.create(t, n, a, i);
2775
+ }
2776
+ }
2777
+ return t;
2778
+ }
2779
+ //#endregion
2780
+ //#region src/entities/standardMeshSource.ts
2781
+ function X(e) {
2782
+ return new r(e.r, e.g, e.b);
2783
+ }
2784
+ function Nt(e, t, n) {
2785
+ let r = `Create${t.charAt(0).toUpperCase()}${t.slice(1)}`, i = y[r];
2786
+ if (typeof i != "function") throw Error(`No Babylon mesh builder provides the primitive shape "${t}".`);
2787
+ return i(t, n ?? {}, e);
2788
+ }
2789
+ function Pt(e, t, n) {
2790
+ if (n.type === "pbr") {
2791
+ let r = new x(`${t.name}-material`, e);
2792
+ n.color !== void 0 && (r.albedoColor = X(n.color)), n.emissive !== void 0 && (r.emissiveColor = X(n.emissive)), n.metallic !== void 0 && (r.metallic = n.metallic), n.roughness !== void 0 && (r.roughness = n.roughness), t.material = r;
2793
+ } else {
2794
+ let r = new E(`${t.name}-material`, e);
2795
+ n.color !== void 0 && (r.diffuseColor = X(n.color)), n.emissive !== void 0 && (r.emissiveColor = X(n.emissive)), t.material = r;
2796
+ }
2797
+ }
2798
+ async function Ft(e, t, n) {
2799
+ let r;
2800
+ return t.source.includes("#") ? (await n.load(t.source), r = n.clone(t.source)) : r = Nt(e, t.source, t.params), r.isVisible = t.visible ?? !0, t.material !== void 0 && Pt(e, r, t.material), r;
2801
+ }
2802
+ function It(e, t) {
2803
+ return async (n, r) => {
2804
+ let i = e[r]?.meshConfig;
2805
+ if (i !== void 0) return Ft(n, i, t);
2806
+ };
2807
+ }
2808
+ //#endregion
2809
+ //#region src/behaviors/sound.ts
2810
+ var Lt = class extends P {
2811
+ static ops = ["play", "stop"];
2812
+ defaults = { sounds: {} };
2813
+ #e = /* @__PURE__ */ new Map();
2814
+ #t = !1;
2815
+ onMeshLoaded() {
2816
+ let e = this.entity, t = e.audio;
2817
+ if (t !== void 0) for (let [n, r] of Object.entries(this.state.sounds)) t.createSound(n, r.url, r.channel, {
2818
+ volume: r.volume ?? 1,
2819
+ loop: r.loop ?? !1
2820
+ }).then((t) => {
2821
+ this.#n(n, r, e, t);
2822
+ });
2823
+ }
2824
+ onDestroy() {
2825
+ this.#t = !0;
2826
+ for (let e of this.#e.values()) e.stop(), e.dispose();
2827
+ this.#e.clear();
2828
+ }
2829
+ play(e) {
2830
+ this.#r(e)?.play();
2831
+ }
2832
+ stop(e) {
2833
+ this.#r(e)?.stop();
2834
+ }
2835
+ #n(e, t, n, r) {
2836
+ if (this.#t) {
2837
+ r.dispose();
2838
+ return;
2839
+ }
2840
+ (t.spatial ?? !1) && (r.spatial.attach(n.node), r.spatial.maxDistance = t.maxDistance ?? 100), this.#e.set(e, r), (t.loop ?? !1) && r.play();
2841
+ }
2842
+ #r(e) {
2843
+ if (!(e in this.state.sounds)) throw Error(`SoundBehavior: no sound named "${e}" is declared.`);
2844
+ return this.#e.get(e);
2845
+ }
2846
+ }, Rt = class {
2847
+ sourceType = "key";
2848
+ sourceKey;
2849
+ constructor(e) {
2850
+ this.sourceKey = e;
2851
+ }
2852
+ getValue(e) {
2853
+ return e.keys[this.sourceKey];
2854
+ }
2855
+ }, zt = class {
2856
+ sourceType;
2857
+ sourceKey;
2858
+ constructor(e, t) {
2859
+ this.sourceType = e, this.sourceKey = t;
2860
+ }
2861
+ getValue(e) {
2862
+ if (this.sourceType === "button") return e.buttons[this.sourceKey];
2863
+ if (this.sourceType === "movement") return this.sourceKey === "x" ? e.movement.x : this.sourceKey === "y" ? e.movement.y : void 0;
2864
+ if (this.sourceType === "position") return this.sourceKey === "x" ? e.position.x : this.sourceKey === "y" ? e.position.y : void 0;
2865
+ if (this.sourceType === "wheel") return this.sourceKey === "deltaX" ? e.wheel.deltaX : this.sourceKey === "deltaY" ? e.wheel.deltaY : this.sourceKey === "deltaZ" ? e.wheel.deltaZ : void 0;
2866
+ }
2867
+ }, Bt = class {
2868
+ sourceType;
2869
+ sourceKey;
2870
+ constructor(e, t) {
2871
+ this.sourceType = e, this.sourceKey = t;
2872
+ }
2873
+ getValue(e) {
2874
+ if (this.sourceType === "button") return e.buttons[this.sourceKey];
2875
+ if (this.sourceType === "axis") return e.axes[this.sourceKey];
2876
+ }
2877
+ }, Vt = class {
2878
+ kind = "trigger";
2879
+ action;
2880
+ device;
2881
+ context;
2882
+ preventDefault;
2883
+ #e;
2884
+ #t;
2885
+ #n;
2886
+ #r;
2887
+ constructor(e, t, n, r = {}, i) {
2888
+ this.action = e, this.device = t, this.context = i, this.preventDefault = r.preventDefault ?? !1, this.#e = n, this.#t = r.edge ?? "rising", this.#n = r.threshold;
2889
+ }
2890
+ get input() {
2891
+ return {
2892
+ device: this.device,
2893
+ sourceType: this.#e.sourceType,
2894
+ sourceKey: this.#e.sourceKey
2895
+ };
2896
+ }
2897
+ process(e) {
2898
+ let t = this.#a(this.#e.getValue(e)), n = this.#r;
2899
+ if (this.#r = t, n !== void 0 && this.#i(n, t)) return this.action.type === "analog" ? { value: this.#o(this.#e.getValue(e)) } : { value: t };
2900
+ }
2901
+ prime(e) {
2902
+ this.#r = this.#a(this.#e.getValue(e));
2903
+ }
2904
+ toDefinition() {
2905
+ let e = { edge: this.#t };
2906
+ return this.#n !== void 0 && (e.threshold = this.#n), this.preventDefault && (e.preventDefault = !0), {
2907
+ kind: "trigger",
2908
+ action: this.action.name,
2909
+ input: this.input,
2910
+ context: this.context,
2911
+ options: e
2912
+ };
2913
+ }
2914
+ #i(e, t) {
2915
+ return this.#t === "rising" ? !e && t : this.#t === "falling" ? e && !t : e !== t;
2916
+ }
2917
+ #a(e) {
2918
+ return typeof e == "boolean" ? e : typeof e == "number" ? this.#n === void 0 ? e !== 0 : e >= this.#n : !1;
2919
+ }
2920
+ #o(e) {
2921
+ return typeof e == "number" ? e : +(e === !0);
2922
+ }
2923
+ }, Ht = class {
2924
+ kind = "toggle";
2925
+ action;
2926
+ device;
2927
+ context;
2928
+ preventDefault;
2929
+ #e;
2930
+ #t;
2931
+ #n;
2932
+ #r;
2933
+ #i;
2934
+ #a;
2935
+ #o;
2936
+ constructor(e, t, n, r = {}, i) {
2937
+ this.action = e, this.device = t, this.context = i, this.preventDefault = r.preventDefault ?? !1, this.#e = n, this.#t = r.onValue ?? !0, this.#n = r.offValue ?? !1, this.#r = r.threshold, this.#i = r.invert ?? !1, this.#a = r.initialState;
2938
+ }
2939
+ get input() {
2940
+ return {
2941
+ device: this.device,
2942
+ sourceType: this.#e.sourceType,
2943
+ sourceKey: this.#e.sourceKey
2944
+ };
2945
+ }
2946
+ process(e) {
2947
+ let t = this.#s(this.#e.getValue(e)), n = this.#o;
2948
+ if (this.#o = t, n !== void 0 && !(n || !t)) return this.#a = !this.#a, this.#a ? { value: this.#t } : { value: this.#n };
2949
+ }
2950
+ prime(e) {
2951
+ this.#o = this.#s(this.#e.getValue(e));
2952
+ }
2953
+ toDefinition() {
2954
+ let e = {
2955
+ onValue: this.#t,
2956
+ offValue: this.#n,
2957
+ invert: this.#i
2958
+ };
2959
+ return this.#r !== void 0 && (e.threshold = this.#r), this.#a !== void 0 && (e.initialState = this.#a), this.preventDefault && (e.preventDefault = !0), {
2960
+ kind: "toggle",
2961
+ action: this.action.name,
2962
+ input: this.input,
2963
+ context: this.context,
2964
+ options: e
2965
+ };
2966
+ }
2967
+ #s(e) {
2968
+ let t = this.#c(e);
2969
+ return this.#i ? !t : t;
2970
+ }
2971
+ #c(e) {
2972
+ return typeof e == "boolean" ? e : typeof e == "number" ? this.#r === void 0 ? e !== 0 : e >= this.#r : !1;
2973
+ }
2974
+ }, Z = class {
2975
+ kind = "value";
2976
+ action;
2977
+ device;
2978
+ context;
2979
+ preventDefault;
2980
+ #e;
2981
+ #t;
2982
+ #n;
2983
+ #r;
2984
+ #i;
2985
+ #a;
2986
+ #o;
2987
+ constructor(e, t, n, r = {}, i) {
2988
+ this.action = e, this.device = t, this.context = i, this.preventDefault = r.preventDefault ?? !1, this.#e = n, this.#t = r.scale ?? 1, this.#n = r.offset ?? 0, this.#r = r.invert ?? !1, this.#i = r.deadzone ?? 0, this.#a = r.min, this.#o = r.max;
2989
+ }
2990
+ get input() {
2991
+ return {
2992
+ device: this.device,
2993
+ sourceType: this.#e.sourceType,
2994
+ sourceKey: this.#e.sourceKey
2995
+ };
2996
+ }
2997
+ process(e) {
2998
+ return { value: this.#s(e) };
2999
+ }
3000
+ prime(e) {}
3001
+ toDefinition() {
3002
+ let e = {
3003
+ scale: this.#t,
3004
+ offset: this.#n,
3005
+ invert: this.#r,
3006
+ deadzone: this.#i
3007
+ };
3008
+ return this.#a !== void 0 && (e.min = this.#a), this.#o !== void 0 && (e.max = this.#o), this.preventDefault && (e.preventDefault = !0), {
3009
+ kind: "value",
3010
+ action: this.action.name,
3011
+ input: this.input,
3012
+ context: this.context,
3013
+ options: e
3014
+ };
3015
+ }
3016
+ #s(e) {
3017
+ let t = this.#c(this.#e.getValue(e));
3018
+ return t *= this.#t, t += this.#n, this.#a !== void 0 && t < this.#a && (t = this.#a), this.#o !== void 0 && t > this.#o && (t = this.#o), this.#r && (t = -t), Math.abs(t) < this.#i && (t = 0), t;
3019
+ }
3020
+ #c(e) {
3021
+ return typeof e == "number" ? e : +(e === !0);
3022
+ }
3023
+ }, Ut = class {
3024
+ kind = "delta";
3025
+ action;
3026
+ device;
3027
+ context;
3028
+ preventDefault;
3029
+ #e;
3030
+ #t;
3031
+ #n;
3032
+ #r;
3033
+ constructor(e, t, n, r = {}, i) {
3034
+ this.action = e, this.device = t, this.context = i, this.preventDefault = r.preventDefault ?? !1, this.#e = n, this.#t = r.scale ?? 1, this.#n = r.invert ?? !1, this.#r = r.deadzone ?? 0;
3035
+ }
3036
+ get input() {
3037
+ return {
3038
+ device: this.device,
3039
+ sourceType: this.#e.sourceType,
3040
+ sourceKey: this.#e.sourceKey
3041
+ };
3042
+ }
3043
+ process(e) {
3044
+ let t = this.#i(this.#e.getValue(e));
3045
+ if (t *= this.#t, this.#n && (t = -t), Math.abs(t) < this.#r && (t = 0), t !== 0) return { value: t };
3046
+ }
3047
+ prime(e) {}
3048
+ toDefinition() {
3049
+ let e = {
3050
+ scale: this.#t,
3051
+ invert: this.#n,
3052
+ deadzone: this.#r
3053
+ };
3054
+ return this.preventDefault && (e.preventDefault = !0), {
3055
+ kind: "delta",
3056
+ action: this.action.name,
3057
+ input: this.input,
3058
+ context: this.context,
3059
+ options: e
3060
+ };
3061
+ }
3062
+ #i(e) {
3063
+ return typeof e == "number" ? e : +(e === !0);
3064
+ }
3065
+ };
3066
+ //#endregion
3067
+ //#region src/input/resolveBinding.ts
3068
+ function Wt(e, t, n) {
3069
+ let r = e.input.device, i = e.options ?? {};
3070
+ return e.kind === "trigger" ? new Vt(t, r, n, i, e.context) : e.kind === "toggle" ? new Ht(t, r, n, i, e.context) : e.kind === "delta" ? new Ut(t, r, n, i, e.context) : new Z(t, r, n, i, e.context);
3071
+ }
3072
+ //#endregion
3073
+ //#region src/input/inputCapture.ts
3074
+ var Gt = class {
3075
+ #e;
3076
+ #t;
3077
+ #n;
3078
+ #r;
3079
+ constructor(e = {}) {
3080
+ this.#e = e.deviceTypes, this.#t = e.sourceTypes, e.signal?.addEventListener("abort", () => {
3081
+ this.#r?.(e.signal?.reason ?? /* @__PURE__ */ Error("The capture was aborted.")), this.#n = void 0, this.#r = void 0;
3082
+ });
3083
+ }
3084
+ feed(e) {
3085
+ this.#n !== void 0 && this.#i(e.value) && (this.#e !== void 0 && !this.#e.includes(e.device.type) || this.#t !== void 0 && !this.#t.includes(e.sourceType) || (this.#n({
3086
+ device: e.device,
3087
+ sourceType: e.sourceType,
3088
+ sourceKey: e.sourceKey
3089
+ }), this.#n = void 0, this.#r = void 0));
3090
+ }
3091
+ wait() {
3092
+ return new Promise((e, t) => {
3093
+ this.#n = e, this.#r = t;
3094
+ });
3095
+ }
3096
+ #i(e) {
3097
+ return e === !0 || typeof e == "number" && e !== 0;
3098
+ }
3099
+ };
3100
+ //#endregion
3101
+ //#region src/input/configuration.ts
3102
+ function Kt(e, t, n) {
3103
+ return {
3104
+ actions: [...e],
3105
+ bindings: t.map((e) => e.toDefinition()),
3106
+ contexts: [...n]
3107
+ };
3108
+ }
3109
+ function qt(e, t, n) {
3110
+ for (let n of e.actions) t.register(n);
3111
+ for (let t of e.contexts) n.registerContext(t.name, t.exclusive);
3112
+ return [...e.bindings];
3113
+ }
3114
+ //#endregion
3115
+ //#region ../../node_modules/hexoid/dist/index.mjs
3116
+ for (var Q = 256, $ = []; Q--;) $[Q] = (Q + 256).toString(16).substring(1);
3117
+ function Jt(e) {
3118
+ e ||= 16;
3119
+ var t = "", n = 0;
3120
+ return function() {
3121
+ if (!t || n === 256) {
3122
+ for (t = "", n = (1 + e) / 2 | 0; n--;) t += $[256 * Math.random() | 0];
3123
+ t = t.substring(n = 0, e - 2);
3124
+ }
3125
+ return t + $[n++];
3126
+ };
3745
3127
  }
3746
3128
  //#endregion
3129
+ //#region src/utils/id.ts
3130
+ var Yt = Jt(16), Xt = class {
3131
+ _currentState;
3132
+ transitions = /* @__PURE__ */ new Map();
3133
+ wildcardTransitions = /* @__PURE__ */ new Map();
3134
+ enterCallbacks = /* @__PURE__ */ new Map();
3135
+ exitCallbacks = /* @__PURE__ */ new Map();
3136
+ eventBus;
3137
+ constructor(e, t) {
3138
+ this._currentState = e, this.eventBus = t;
3139
+ }
3140
+ get currentState() {
3141
+ return this._currentState;
3142
+ }
3143
+ addTransition(e, t, n) {
3144
+ let r = `${e}->${t}`;
3145
+ this.transitions.set(r, { guard: n });
3146
+ }
3147
+ addTransitionFromAny(e, t) {
3148
+ this.wildcardTransitions.set(e, { guard: t });
3149
+ }
3150
+ onEnter(e, t) {
3151
+ let n = this.enterCallbacks.get(e) ?? [];
3152
+ n.push(t), this.enterCallbacks.set(e, n);
3153
+ }
3154
+ onExit(e, t) {
3155
+ let n = this.exitCallbacks.get(e) ?? [];
3156
+ n.push(t), this.exitCallbacks.set(e, n);
3157
+ }
3158
+ canTransition(e) {
3159
+ let t = `${this._currentState}->${e}`;
3160
+ return this.transitions.has(t) || this.wildcardTransitions.has(e);
3161
+ }
3162
+ transition(e) {
3163
+ let t = `${this._currentState}->${e}`, n = this.transitions.get(t);
3164
+ if (n ||= this.wildcardTransitions.get(e), !n) throw Error(`No transition defined from '${this._currentState}' to '${e}'.`);
3165
+ if (n.guard && !n.guard()) throw Error(`Guard rejected transition from '${this._currentState}' to '${e}'.`);
3166
+ let r = this._currentState, i = this.exitCallbacks.get(r);
3167
+ if (i) for (let e of i) e();
3168
+ this.eventBus && this.eventBus.publish({
3169
+ type: `state:exit:${r}`,
3170
+ payload: {
3171
+ from: r,
3172
+ to: e
3173
+ }
3174
+ }), this._currentState = e;
3175
+ let a = this.enterCallbacks.get(e);
3176
+ if (a) for (let e of a) e();
3177
+ this.eventBus && this.eventBus.publish({
3178
+ type: `state:enter:${e}`,
3179
+ payload: {
3180
+ from: r,
3181
+ to: e
3182
+ }
3183
+ });
3184
+ }
3185
+ };
3186
+ //#endregion
3747
3187
  //#region src/sage.ts
3748
- async function Ct(e, t, n = {}) {
3749
- let r = new P(n.logLevel || "debug"), i = r.getLogger("SAGE");
3188
+ async function Zt(e, t, n = {}) {
3189
+ let r = new M(n.logLevel || "debug"), i = r.getLogger("SAGE");
3750
3190
  i.info(`Initializing SAGE Game Engine v${k}...`), i.debug("Creating rendering engine...");
3751
- let a = await Qe(e, {
3191
+ let a = await lt(e, {
3752
3192
  antialias: !0,
3753
3193
  adaptToDeviceRatio: !0,
3754
3194
  ...n.renderOptions
3755
3195
  }, n.largeWorldRendering ?? !1);
3756
3196
  i.debug("Creating physics engine...");
3757
- let o = await $e(), s = et(o);
3197
+ let o = await ut(n.havokBinary), s = dt(o);
3758
3198
  i.debug("Creating event bus...");
3759
- let c = new F(r);
3199
+ let c = new N(r);
3760
3200
  i.debug("Creating scene engine...");
3761
- let l = new L(e, a, o, r);
3201
+ let l = new je(e, a, o, r);
3762
3202
  i.debug("Creating managers...");
3763
- let u = new R(c, l, r), d = new Ye(c, e, r), f = new Ee(c, r), p = new Me(c, r, f), m = new He(c, r), h = new We(p, m, r), g = new Oe(a, c, p, d, m, r), _ = null;
3764
- n.debug !== !1 && (i.debug("Creating debug console..."), _ = new he((typeof n.debug == "object" ? n.debug.namespace : void 0) ?? "sage")), i.debug("Creating collider debug manager...");
3765
- let v = new Ge();
3766
- i.debug("Creating raycast helper...");
3767
- let y = new tt(p);
3768
- i.debug("Creating game timer...");
3769
- let b = new nt();
3770
- g.registerFrameCallback((e) => b.tick(e * 1e3));
3771
- let x, S;
3772
- n.audioChannels && n.audioChannels.length > 0 && (i.debug("Creating audio engine..."), x = new I(r), await x.initialize(), i.debug("Creating audio manager..."), S = new Ue(x, r), await S.initialize(n.audioChannels)), i.info(`SAGE Game Engine v${k} initialized successfully.`), i.debug("Loading entities...");
3773
- for (let e of t) p.registerEntityDefinition(e);
3774
- if (i.debug("Registering default input bindings..."), n.bindings) for (let e of n.bindings) f.registerBinding(e);
3775
- let C = new A(e, a, s, c, r, y, b, {
3203
+ let u = new Ne(c, l, r), d = new et(c, r), f = new rt(d, k), p = new Fe(a, c, d, r), m = new Ue();
3204
+ p.setInputManager(m);
3205
+ let h, g;
3206
+ n.audioChannels && n.audioChannels.length > 0 && (i.debug("Creating audio engine..."), h = new Ae(r), await h.initialize(), i.debug("Creating audio manager..."), g = new tt(h, r), await g.initialize(n.audioChannels));
3207
+ let ee = n.fixedStepDuration ?? 1 / 60, _ = async () => void 0;
3208
+ i.debug("Creating collider debug manager...");
3209
+ let v = new it(), y = (e, n) => new Oe({
3210
+ fixedStepDuration: ee,
3211
+ entityClasses: t,
3212
+ scene: e,
3213
+ pool: new ke(),
3214
+ loadMesh: (t, r) => (n ?? _)(e, t, r),
3215
+ audio: g,
3216
+ colliders: v
3217
+ }), b = null;
3218
+ n.debug !== !1 && (i.debug("Creating debug console..."), b = new he((typeof n.debug == "object" ? n.debug.namespace : void 0) ?? "sage")), i.debug("Creating game timer...");
3219
+ let x = new ft();
3220
+ p.registerFrameCallback((e) => x.tick(e * 1e3)), i.info(`SAGE Game Engine v${k} initialized successfully.`);
3221
+ let S = new ge(e, a, s, c, r, x, y, {
3776
3222
  sceneEngine: l,
3777
- audioEngine: x
3223
+ audioEngine: h
3778
3224
  }, {
3779
3225
  assetManager: u,
3780
- bindingManager: f,
3781
- entityManager: p,
3782
- gameManager: g,
3783
- inputManager: d,
3784
- levelManager: m,
3785
- saveManager: h,
3786
- audioManager: S
3226
+ gameManager: p,
3227
+ inputManager: m,
3228
+ levelManager: d,
3229
+ saveManager: f,
3230
+ audioManager: g
3787
3231
  }, n.largeWorldRendering ?? !1, {
3788
3232
  colliders: v,
3789
- console: _,
3233
+ console: b,
3790
3234
  expose: (e, t) => {
3791
- _?.expose(e, t);
3235
+ b?.expose(e, t);
3792
3236
  }
3793
3237
  });
3794
- return p.$setGameEngine(C), m.$setGameEngine(C), _ && ot(_, C), C;
3238
+ return d.$setGameEngine(S), p.$setGameEngine(S), f.$setGameEngine(S), b && mt(b, S), S;
3795
3239
  }
3796
3240
  //#endregion
3797
- export { R as AssetManager, I as AudioEngine, Ue as AudioManager, Ge as ColliderDebugManager, j as ConsoleBackend, he as DebugConsole, A as GameEngine, je as GameEntity, G as GameEntityBehavior, F as GameEventBus, Ve as GameLevel, nt as GameTimer, ze as Level, st as LogLevels, P as LoggingUtility, M as NullBackend, Be as OutlineManager, tt as RaycastHelper, N as SAGELogger, We as SaveManager, L as SceneEngine, ct as SoundBehavior, Y as StateMachine, lt as StateMachineBehavior, k as VERSION, Fe as applyPostProcessing, z as bindingTypes, _t as collectPrefixedProperties, rt as createEntityProxy, Ct as createGameEngine, Ae as generateId, Re as getCanonicalTransform, V as isGamepadState, _e as isKeyboardState, B as isMouseState, St as registerAllPropertyHandlers, ft as registerColliderHandler, ht as registerLodHandler, gt as registerOccluderHandler, yt as registerSoundHandler, xt as registerTriggerHandler, $ as registerVisibleHandler, Ie as toQuatObject, Le as toQuaternion, K as toVec3Object, q as toVector3, ge as validDeviceTypes };
3241
+ export { Ie as ActionContextRegistry, Le as ActionRegistry, Ne as AssetManager, Ae as AudioEngine, tt as AudioManager, P as Behavior, it as ColliderDebugManager, _e as ConsoleBackend, he as DebugConsole, Ut as DeltaBinding, L as EventBus, ge as GameEngine, Ce as GameEntity, N as GameEventBus, $e as GameLevel, we as GameSimulationManager, ft as GameTimer, Bt as GamepadReader, Gt as InputCapture, Ue as InputManager, Rt as KeyboardReader, Ze as Level, ht as LogLevels, M as LoggingUtility, zt as MouseReader, F as NamedBehavior, H as NodeEntity, ke as NodePool, Oe as NodeSimulation, A as NullBackend, Qe as OutlineManager, W as ROUTING_LOOP_SENDER_ID, j as SAGELogger, je as SceneEngine, rt as SimulationSaveManager, Lt as SoundBehavior, Xt as StateMachine, ye as StateMachineBehavior, Ht as ToggleBinding, Vt as TriggerBinding, k as VERSION, Z as ValueBinding, Ke as applyPostProcessing, It as buildStandardMeshSource, Ct as collectPrefixedProperties, gt as computeHierarchyBounds, Zt as createGameEngine, Mt as defineEntity, ve as defineStates, Re as deliverAction, Se as dilationLimit, xe as drainPassLimit, Kt as exportConfiguration, Yt as generateId, Xe as getCanonicalTransform, qt as importConfiguration, be as operationCallDepthLimit, At as registerAllPropertyHandlers, vt as registerColliderHandler, xt as registerLodHandler, St as registerOccluderHandler, Tt as registerSoundHandler, Ot as registerTriggerHandler, kt as registerVisibleHandler, Wt as resolveBinding, Je as toQuatObject, Ye as toQuaternion, qe as toVec3Object, K as toVector3 };
3798
3242
 
3799
3243
  //# sourceMappingURL=sage.es.js.map