@skewedaspect/sage 0.9.5 → 0.10.0-beta.1

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