@skewedaspect/sage 0.9.6 → 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 +6 -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 +1433 -2479
  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 -264
  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.6", 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,1300 +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
- _cloneDefaultState(e) {
1610
- try {
1611
- return structuredClone(e.defaultState);
1612
- } catch (t) {
1613
- throw Error(`Entity type '${e.type}' has a defaultState that cannot be structured-cloned. defaultState must be plain data (no functions, class instances, or DOM references).`, { cause: t });
1614
- }
1615
- }
1616
- async _buildDefinitionMesh(e, t) {
1617
- if (!t.mesh) return;
1618
- if (t.node) {
1619
- this._log.warn(`Ignoring 'mesh' option for entity ${e.id}: 'node' was supplied, and the two are exclusive.`);
1620
- return;
1621
- }
1622
- let { levelManager: n } = this._engine.managers, r = n.loadingLevel ?? n.currentLevel;
1623
- if (!r?.isLoaded) {
1624
- this._log.warn(`Cannot build a mesh for entity ${e.id}: no level is loaded.`);
1625
- return;
1626
- }
1627
- await r.createEntityMesh(e, { enabled: t.mesh === "enabled" });
1628
- }
1629
- registerEntityDefinition(e) {
1630
- this._log.debug(`Registering entity definition: ${e.type}`);
1631
- let t = e.extends ? this._resolveInheritance(e) : e;
1632
- this._registerEntityActions(t), this.entityDefinitions.set(t.type, t), t.poolSize && t.poolSize > 0 && this.prewarm(t.type, t.poolSize);
1633
- }
1634
- getDefinition(e) {
1635
- return this.entityDefinitions.get(e);
1636
- }
1637
- async createEntity(e, t = {}) {
1638
- this._log.debug(`Creating entity of type: ${e}`);
1639
- let n = this.entityDefinitions.get(e);
1640
- if (!n) {
1641
- let t = `Entity type ${e} is not registered.`;
1642
- throw this._log.error(t), Error(t);
1643
- }
1644
- if (n.poolable) {
1645
- let r = this._pools.get(e);
1646
- if (r && r.length > 0) {
1647
- this._log.trace(`Recycling entity from pool for type: ${e}`);
1648
- let i = r.pop();
1649
- if (i.$reset(this._cloneDefaultState(n), n.tags ?? []), i.$setEntityManager(this), t.initialState && (i.state = {
1650
- ...i.state,
1651
- ...t.initialState
1652
- }), t.tags) for (let e of t.tags) i.$addTag(e);
1653
- return t.node && i.$attachToNode(t.node, this._engine), this.entities.set(i.id, i), this._indexEntity(i), await this._buildDefinitionMesh(i, t), this._log.debug(`Recycled entity ${i.id} from pool`), i;
1654
- }
1655
- }
1656
- this._log.trace(`Using entity definition with ${n.behaviors?.length || 0} behaviors`);
1657
- let r = {
1658
- ...this._cloneDefaultState(n),
1659
- ...t.initialState
1660
- };
1661
- if (n.onBeforeCreate) {
1662
- this._log.trace(`Calling onBeforeCreate hook for entity type: ${e}`);
1663
- let t = await n.onBeforeCreate(r);
1664
- t !== void 0 && (r = t);
1665
- }
1666
- let i = t.name ?? n.name, a = new je(n.type, this.eventBus, r, n.behaviors, i);
1667
- if (a.$setEntityManager(this), t.node && a.$attachToNode(t.node, this._engine), n.tags) for (let e of n.tags) a.$addTag(e);
1668
- if (t.tags) for (let e of t.tags) a.$addTag(e);
1669
- if (this.entities.set(a.id, a), this._indexEntity(a), this._log.debug(`Entity created with ID: ${a.id}${i ? ` (name: ${i})` : ""}`), n.onCreate) {
1670
- this._log.trace(`Calling onCreate hook for entity type: ${e}`);
1671
- let t = await n.onCreate(a.state);
1672
- t !== void 0 && (a.state = t);
1673
- }
1674
- if (n.children) for (let e of n.children) {
1675
- let t = { ...e.initialState };
1676
- e.position && (t._position = e.position), e.rotation && (t._rotation = e.rotation);
1677
- let n = await this.createEntity(e.type, {
1678
- name: e.name,
1679
- initialState: t
1680
- });
1681
- a.$addChild(n);
1682
- }
1683
- return await this._buildDefinitionMesh(a, t), a;
1684
- }
1685
- async destroyEntity(e) {
1686
- this._log.debug(`Destroying entity: ${e}`);
1687
- let t = this.entities.get(e);
1688
- if (t) {
1689
- let n = this.entityDefinitions.get(t.type);
1690
- if (n?.poolable) {
1691
- this._log.trace(`Pooling entity ${e} instead of destroying`);
1692
- for (let e of [...t.children]) await this.destroyEntity(e.id);
1693
- t.parent && t.parent.$removeChild(t), this._unindexEntity(t), t.$reset(this._cloneDefaultState(n), n.tags ?? []);
1694
- let r = this._pools.get(t.type);
1695
- r || (r = [], this._pools.set(t.type, r)), r.push(t), this.entities.delete(e), this._log.debug(`Entity ${e} pooled`);
1696
- return;
1697
- }
1698
- for (let e of [...t.children]) await this.destroyEntity(e.id);
1699
- if (t.parent && t.parent.$removeChild(t), n?.onBeforeDestroy) {
1700
- this._log.trace(`Calling onBeforeDestroy hook for entity: ${e}`);
1701
- let r = await n.onBeforeDestroy(t.state);
1702
- r !== void 0 && (t.state = r);
1703
- }
1704
- this._unindexEntity(t), await t.$destroy(), n?.onDestroy && (this._log.trace(`Calling onDestroy hook for entity: ${e}`), await n.onDestroy(t.state)), this.entities.delete(e), this._log.debug(`Entity ${e} destroyed`);
1705
- } else this._log.warn(`Attempted to destroy non-existent entity: ${e}`);
1706
- }
1707
- getEntity(e) {
1708
- return this._log.trace(`Getting entity: ${e}`), this.entities.get(e) ?? null;
1709
- }
1710
- addEntity(e) {
1711
- this._log.debug(`Adding existing entity: ${e.id} (type: ${e.type})`), e.$setEntityManager(this), this.entities.set(e.id, e), this._indexEntity(e);
1712
- }
1713
- removeEntity(e) {
1714
- this._log.debug(`Removing entity: ${e}`);
1715
- let t = this.entities.get(e);
1716
- t ? (this._unindexEntity(t), this.entities.delete(e), this._log.debug(`Entity ${e} removed`)) : this._log.warn(`Attempted to remove non-existent entity: ${e}`);
1717
- }
1718
- addChild(e, t) {
1719
- let n = this.entities.get(e), r = this.entities.get(t);
1720
- return n ? r ? (n.$addChild(r), this._log.trace(`Added child ${t} to parent ${e}`), !0) : (this._log.warn(`addChild: child entity "${t}" not found`), !1) : (this._log.warn(`addChild: parent entity "${e}" not found`), !1);
1721
- }
1722
- removeChild(e, t) {
1723
- let n = this.entities.get(e), r = this.entities.get(t);
1724
- return n ? r ? (n.$removeChild(r), this._log.trace(`Removed child ${t} from parent ${e}`), !0) : (this._log.warn(`removeChild: child entity "${t}" not found`), !1) : (this._log.warn(`removeChild: parent entity "${e}" not found`), !1);
1725
- }
1726
- getByName(e) {
1727
- let t = this._entitiesByName.get(e);
1728
- if (t && t.size > 0) return t.values().next().value;
1729
- }
1730
- getEntitiesByName(e) {
1731
- let t = this._entitiesByName.get(e);
1732
- return t ? Array.from(t) : [];
1733
- }
1734
- getByType(e) {
1735
- let t = this._entitiesByType.get(e);
1736
- return t ? Array.from(t) : [];
1737
- }
1738
- getByTag(e) {
1739
- let t = this._entitiesByTag.get(e);
1740
- return t ? Array.from(t) : [];
1741
- }
1742
- getByTags(e, t = "all") {
1743
- if (e.length === 0) return [];
1744
- if (t === "any") {
1745
- let t = /* @__PURE__ */ new Set();
1746
- for (let n of e) {
1747
- let e = this._entitiesByTag.get(n);
1748
- if (e) for (let n of e) t.add(n);
1749
- }
1750
- return Array.from(t);
1751
- } else {
1752
- let t = e.map((e) => this._entitiesByTag.get(e)).filter((e) => e !== void 0);
1753
- if (t.length !== e.length) return [];
1754
- t.sort((e, t) => e.size - t.size);
1755
- let [n, ...r] = t;
1756
- return Array.from(n).filter((e) => r.every((t) => t.has(e)));
1757
- }
1758
- }
1759
- getAllEntities() {
1760
- return this.entities.values();
1761
- }
1762
- get entityCount() {
1763
- return this.entities.size;
1764
- }
1765
- async send(e, t, n, r) {
1766
- let i = this.entities.get(e) ?? this.getByName(e);
1767
- if (!i) {
1768
- this._log.warn(`send: entity "${e}" not found`);
1769
- return;
1770
- }
1771
- await i.$send(t, n, r);
1772
- }
1773
- async request(e, t, n, r) {
1774
- let i = this.entities.get(e) ?? this.getByName(e);
1775
- return i ? i.$request(t, n, r) : {
1776
- success: !1,
1777
- error: `Entity "${e}" not found`
1778
- };
1779
- }
1780
- addTag(e, t) {
1781
- let n = typeof e == "string" ? this.entities.get(e) : e;
1782
- return n ? n.hasTag(t) ? !1 : (n.$addTag(t), this._getOrCreateSet(this._entitiesByTag, t).add(n), this._log.trace(`Added tag "${t}" to entity ${n.id}`), !0) : (this._log.warn("addTag: entity not found"), !1);
1783
- }
1784
- removeTag(e, t) {
1785
- let n = typeof e == "string" ? this.entities.get(e) : e;
1786
- if (!n) return this._log.warn("removeTag: entity not found"), !1;
1787
- if (!n.$removeTag(t)) return !1;
1788
- let r = this._entitiesByTag.get(t);
1789
- return r && (r.delete(n), r.size === 0 && this._entitiesByTag.delete(t)), this._log.trace(`Removed tag "${t}" from entity ${n.id}`), !0;
1790
- }
1791
- getByNode(e) {
1792
- return this._entitiesByNode.get(e);
1793
- }
1794
- attachToNode(e, t) {
1795
- let n = typeof e == "string" ? this.entities.get(e) : e;
1796
- return n ? this._entitiesByNode.has(t) ? (this._log.warn("attachToNode: node already has an attached entity"), !1) : (n.node && this._entitiesByNode.delete(n.node), n.$attachToNode(t, this._engine), this._entitiesByNode.set(t, n), this._log.trace(`Attached entity ${n.id} to node "${t.name}"`), !0) : (this._log.warn("attachToNode: entity not found"), !1);
1797
- }
1798
- detachFromNode(e) {
1799
- let t = typeof e == "string" ? this.entities.get(e) : e;
1800
- if (!t) return this._log.warn("detachFromNode: entity not found"), !1;
1801
- if (!t.node) return !1;
1802
- this._entitiesByNode.delete(t.node);
1803
- let n = t.node.name;
1804
- return t.$detachFromNode(), this._log.trace(`Detached entity ${t.id} from node "${n}"`), !0;
1805
- }
1806
- async prewarm(e, t) {
1807
- this._log.debug(`Prewarming pool for "${e}" with ${t} entities`);
1808
- for (let n = 0; n < t; n++) {
1809
- let t = await this.createEntity(e);
1810
- await this.destroyEntity(t.id);
1811
- }
1812
- }
1813
- async drainPool(e) {
1814
- let t = this._pools.get(e);
1815
- if (t) {
1816
- this._log.debug(`Draining pool for "${e}" (${t.length} entities)`);
1817
- for (let e of t) await e.$destroy();
1818
- t.length = 0, this._pools.delete(e);
1819
- }
1820
- }
1821
- async $teardown() {
1822
- this._log.info(`Tearing down EntityManager with ${this.entities.size} entities`);
1823
- let e = [...this.entities.keys()];
1824
- for (let t of e) try {
1825
- await this.destroyEntity(t);
1826
- } catch (e) {
1827
- this._log.error(`Error destroying entity ${t}: ${e}`);
1828
- }
1829
- for (let e of [...this._pools.keys()]) try {
1830
- await this.drainPool(e);
1831
- } catch (t) {
1832
- this._log.error(`Error draining pool for "${e}": ${t}`);
1833
- }
1834
- this.entityDefinitions.clear(), this._entitiesByName.clear(), this._entitiesByType.clear(), this._entitiesByTag.clear(), this._entitiesByNode.clear(), this._log.info("EntityManager torn down successfully");
1835
- }
1836
- }, Ne = {
1171
+ }, Ee = {
1837
1172
  hable: h.TONEMAPPING_STANDARD,
1838
1173
  reinhard: h.TONEMAPPING_STANDARD,
1839
1174
  hejidawson: h.TONEMAPPING_STANDARD,
1840
1175
  photographic: h.TONEMAPPING_STANDARD,
1841
1176
  aces: h.TONEMAPPING_ACES
1842
1177
  };
1843
- function Pe(e, t) {
1178
+ function De(e, t) {
1844
1179
  if (!e.activeCamera) return;
1845
1180
  t.volumetric && console.warn("[SAGE] Volumetric lighting requires renderer: \"frameGraph\". Ignored in pipeline mode.");
1846
1181
  let n = new s("sage-default", !0, e, e.cameras);
1847
- if (t.bloom && (n.bloomEnabled = !0, t.bloom.weight !== void 0 && (n.bloomWeight = t.bloom.weight), t.bloom.threshold !== void 0 && (n.bloomThreshold = t.bloom.threshold), t.bloom.scale !== void 0 && (n.bloomScale = t.bloom.scale), t.bloom.kernel !== void 0 && (n.bloomKernel = t.bloom.kernel)), t.tonemap && (n.imageProcessingEnabled = !0, n.imageProcessing.toneMappingEnabled = !0, t.tonemap.operator && (n.imageProcessing.toneMappingType = Ne[t.tonemap.operator] ?? h.TONEMAPPING_STANDARD)), t.grain && (n.grainEnabled = !0, t.grain.intensity !== void 0 && (n.grain.intensity = t.grain.intensity), t.grain.animated !== void 0 && (n.grain.animated = t.grain.animated)), t.vignette && (n.imageProcessingEnabled = !0, n.imageProcessing.vignetteEnabled = !0, t.vignette.weight !== void 0 && (n.imageProcessing.vignetteWeight = t.vignette.weight), t.vignette.stretch !== void 0 && (n.imageProcessing.vignetteStretch = t.vignette.stretch), t.vignette.color && (n.imageProcessing.vignetteColor = new i(t.vignette.color.r, t.vignette.color.g, t.vignette.color.b, 1))), t.sharpen && (n.sharpenEnabled = !0, t.sharpen.edge !== void 0 && (n.sharpen.edgeAmount = t.sharpen.edge), t.sharpen.color !== void 0 && (n.sharpen.colorAmount = t.sharpen.color)), t.chromaticAberration && (n.chromaticAberrationEnabled = !0, t.chromaticAberration.amount !== void 0 && (n.chromaticAberration.aberrationAmount = t.chromaticAberration.amount)), t.ssao) {
1848
- let n = new ne("sage-ssao", e, {
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, {
1849
1184
  ssaoRatio: .5,
1850
1185
  blurRatio: 1
1851
1186
  });
@@ -1854,25 +1189,25 @@ function Pe(e, t) {
1854
1189
  }
1855
1190
  //#endregion
1856
1191
  //#region src/handlers/postProcessing.ts
1857
- async function Fe(e, t) {
1192
+ async function Oe(e, t) {
1858
1193
  if (t.renderer === "frameGraph") {
1859
- let { applyFrameGraphPostProcessing: n } = await import("./postProcessingFrameGraph-CaMgQzR-.js");
1194
+ let { applyFrameGraphPostProcessing: n } = await import("./postProcessingFrameGraph-rr2DbgPi.js");
1860
1195
  await n(e, t);
1861
- } else Pe(e, t);
1196
+ } else De(e, t);
1862
1197
  }
1863
1198
  //#endregion
1864
1199
  //#region src/utils/vectors.ts
1865
- function K(e) {
1200
+ function ke(e) {
1866
1201
  return {
1867
1202
  x: e.x,
1868
1203
  y: e.y,
1869
1204
  z: e.z
1870
1205
  };
1871
1206
  }
1872
- function q(e) {
1873
- return new O(e.x, e.y, e.z);
1207
+ function G(e) {
1208
+ return new D(e.x, e.y, e.z);
1874
1209
  }
1875
- function Ie(e) {
1210
+ function K(e) {
1876
1211
  return {
1877
1212
  x: e.x,
1878
1213
  y: e.y,
@@ -1880,18 +1215,18 @@ function Ie(e) {
1880
1215
  w: e.w
1881
1216
  };
1882
1217
  }
1883
- function Le(e) {
1884
- 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);
1885
1220
  }
1886
- function Re(e) {
1221
+ function je(e) {
1887
1222
  e.computeWorldMatrix(!0);
1888
1223
  let t = e.getWorldMatrix().clone(), n = e.parent;
1889
1224
  for (; n;) {
1890
1225
  n.computeWorldMatrix(!0);
1891
1226
  let e = n.getWorldMatrix(), r = n.parent, i;
1892
- r ? (r.computeWorldMatrix(!0), i = e.multiply(v.Invert(r.getWorldMatrix()))) : i = e, i.determinant() < 0 && (t = v.Invert(i).multiply(t)), n = r;
1227
+ r ? (r.computeWorldMatrix(!0), i = e.multiply(_.Invert(r.getWorldMatrix()))) : i = e, i.determinant() < 0 && (t = _.Invert(i).multiply(t)), n = r;
1893
1228
  }
1894
- let r = new O(), i = new T(), a = new O();
1229
+ let r = new D(), i = new C(), a = new D();
1895
1230
  return t.decompose(a, i, r), {
1896
1231
  position: r,
1897
1232
  rotation: i,
@@ -1900,11 +1235,12 @@ function Re(e) {
1900
1235
  }
1901
1236
  //#endregion
1902
1237
  //#region src/classes/level.ts
1903
- var ze = class {
1238
+ var Me = class {
1904
1239
  name;
1905
1240
  _log;
1906
1241
  _context;
1907
1242
  _scene = null;
1243
+ _forRestore = !1;
1908
1244
  clusteredLights = null;
1909
1245
  outlines = null;
1910
1246
  constructor(e, t) {
@@ -1947,9 +1283,9 @@ var ze = class {
1947
1283
  this._log.error(`Error in property handler '${t}' for node '${e.name}':`, n);
1948
1284
  }
1949
1285
  }
1950
- async load() {
1286
+ async load(e) {
1951
1287
  if (this._scene) return this._log.warn(`Level ${this.name} is already loaded`), this._scene;
1952
- this._log.info(`Loading level: ${this.name}`), this._log.time(`level-${this.name}-load`);
1288
+ this._forRestore = e?.forRestore ?? !1, this._log.info(`Loading level: ${this.name}`), this._log.time(`level-${this.name}-load`);
1953
1289
  try {
1954
1290
  return this.$emitProgress(0, "Starting level load..."), this._scene = await this.buildScene(), this.$emitProgress(100, "Level loaded successfully"), this.gameEngine.eventBus.publish({
1955
1291
  type: "level:complete",
@@ -1970,83 +1306,10 @@ var ze = class {
1970
1306
  }), e;
1971
1307
  }
1972
1308
  }
1973
- async createEntityMesh(e, t = {}) {
1974
- if (!this._scene) return null;
1975
- let n = this.gameEngine.managers.entityManager.getDefinition(e.type);
1976
- if (!n?.mesh) return null;
1977
- let r = n.mesh, i = this._scene, a = new D(`entity-${e.id}`, i);
1978
- t.enabled === !1 && a.setEnabled(!1);
1979
- let o;
1980
- switch (r.source) {
1981
- case "box":
1982
- o = [b.CreateBox(`${e.type}-mesh`, {
1983
- size: r.params?.size ?? 1,
1984
- width: r.params?.width,
1985
- height: r.params?.height,
1986
- depth: r.params?.depth
1987
- }, i)];
1988
- break;
1989
- case "sphere":
1990
- o = [b.CreateSphere(`${e.type}-mesh`, {
1991
- diameter: r.params?.diameter ?? 1,
1992
- segments: r.params?.segments ?? 16
1993
- }, i)];
1994
- break;
1995
- case "capsule":
1996
- o = [b.CreateCapsule(`${e.type}-mesh`, {
1997
- height: r.params?.height ?? 1.8,
1998
- radius: r.params?.radius ?? .4
1999
- }, i)];
2000
- break;
2001
- case "cylinder":
2002
- o = [b.CreateCylinder(`${e.type}-mesh`, {
2003
- height: r.params?.height ?? 1,
2004
- diameter: r.params?.diameter ?? 1
2005
- }, i)];
2006
- break;
2007
- default: {
2008
- let e = await this.gameEngine.engines.sceneEngine.importMeshes([], r.source, i);
2009
- if (e.meshes.length === 0) return this._log.warn(`No meshes loaded from: ${r.source}`), a.dispose(), null;
2010
- o = e.meshes;
2011
- for (let t of e.transformNodes) t.parent ||= a;
2012
- break;
2013
- }
2014
- }
2015
- for (let e of o) e.parent ||= a;
2016
- t.position && a.position.copyFrom(t.position), t.rotation && (a.rotationQuaternion = t.rotation.clone()), t.scaling && a.scaling.copyFrom(t.scaling), r.scale && (typeof r.scale == "number" ? a.scaling.setAll(r.scale) : a.scaling.set(r.scale.x, r.scale.y, r.scale.z));
2017
- let s = r.material;
2018
- if (s?.color) {
2019
- let t = s.color;
2020
- if (s.type === "pbr") {
2021
- let n = new S(`${e.type}-material`, i);
2022
- n.albedoColor = this._toColor3(t), s.emissive && (n.emissiveColor = this._toColor3(s.emissive)), n.metallic = s.metallic ?? 0, n.roughness = s.roughness ?? 1;
2023
- for (let e of o) e.material = n;
2024
- } else {
2025
- let n = new E(`${e.type}-material`, i);
2026
- n.diffuseColor = this._toColor3(t), s.emissive && (n.emissiveColor = this._toColor3(s.emissive));
2027
- for (let e of o) e.material = n;
2028
- }
2029
- }
2030
- if (r.visible === !1) for (let e of o) e.isVisible = !1;
2031
- let c = a.getDescendants(!1).filter((e) => e instanceof D);
2032
- for (let e of c) {
2033
- let t = this._getNormalizedMetadata(e);
2034
- t && Object.keys(t).length > 0 && (e.metadata = {
2035
- ...e.metadata,
2036
- ...t
2037
- }, await this._runPropertyHandlers(e));
2038
- }
2039
- return this.gameEngine.managers.entityManager.attachToNode(e, a), a;
2040
- }
2041
1309
  async $dispose() {
2042
- if (this._scene) {
2043
- this._log.info(`Disposing level: ${this.name}`);
2044
- let e = this._context.gameEngine?.managers?.entityManager;
2045
- if (e?.getAllEntities) for (let t of e.getAllEntities()) t.node && t.node.getScene() === this._scene && e.detachFromNode(t);
2046
- this.outlines &&= (this.outlines.dispose(), null), this.clusteredLights &&= (this.clusteredLights.dispose(), null), this._scene.dispose(), this._scene = null;
2047
- }
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);
2048
1311
  }
2049
- }, Be = class {
1312
+ }, Ne = class {
2050
1313
  _scene;
2051
1314
  _layers = /* @__PURE__ */ new Map();
2052
1315
  constructor(e, t) {
@@ -2058,7 +1321,7 @@ var ze = class {
2058
1321
  create(e, t) {
2059
1322
  let n = this._layers.get(e);
2060
1323
  if (n) return n.layer;
2061
- let i = new ie(`sage-outline-${e}`, this._scene);
1324
+ let i = new ae(`sage-outline-${e}`, this._scene);
2062
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, {
2063
1326
  layer: i,
2064
1327
  entities: /* @__PURE__ */ new Set()
@@ -2085,12 +1348,12 @@ var ze = class {
2085
1348
  }
2086
1349
  _rebuildSelection(e) {
2087
1350
  e.layer.clearSelection();
2088
- for (let t of e.entities) if (t.node) {
1351
+ for (let t of e.entities) {
2089
1352
  let n = t.node.getChildMeshes();
2090
1353
  n.length > 0 && e.layer.addSelection(n);
2091
1354
  }
2092
1355
  }
2093
- }, Ve = class extends ze {
1356
+ }, Pe = class extends Me {
2094
1357
  _config;
2095
1358
  _spawnPoints = [];
2096
1359
  _entityNodes = [];
@@ -2110,11 +1373,11 @@ var ze = class {
2110
1373
  let { sceneEngine: e } = this.gameEngine.engines, { assetManager: t } = this.gameEngine.managers;
2111
1374
  this._config.preload && this._config.preload.length > 0 && (this.$emitProgress(2, "Preloading assets..."), await t.preload(this._config.preload));
2112
1375
  let n = e.createScene();
2113
- if (this._scene = n, this._config.physics && (this.$emitProgress(5, "Initializing physics..."), await this._enablePhysics(n)), this._config.scene && (this.$emitProgress(10, "Loading scene file..."), await this._loadSceneFile(n)), this._config.environment && (this.$emitProgress(15, "Setting up environment..."), this._processEnvironment(n)), this._processCameras(n), this._processLights(n), this._setupClustering(n), this._config.postProcessing) {
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) {
2114
1377
  let e = this._config.postProcessing.renderer ?? "pipeline";
2115
- 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);
2116
1379
  }
2117
- return this.outlines = new Be(n, this._config.outlines), this.$emitProgress(50, "Processing scene properties..."), await this._processNodeProperties(n), this.$emitProgress(70, "Spawning entities..."), await this._processSpawnPoints(), this.$emitProgress(85, "Configuring entities..."), await this._processEntityNodes(), this._config.sounds && (this.$emitProgress(95, "Loading sounds..."), await this._processLevelSounds()), n;
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;
2118
1381
  }
2119
1382
  async _loadSceneFile(e) {
2120
1383
  let t = this._getScenePath();
@@ -2145,11 +1408,11 @@ var ze = class {
2145
1408
  }
2146
1409
  e.environmentTexture && e.createDefaultSkybox(e.environmentTexture, !0, t.skyboxSize ?? 1e3, 0, !1);
2147
1410
  } else {
2148
- let n = t.skyboxSize ?? 1e3, r = b.CreateSphere("skybox", {
1411
+ let n = t.skyboxSize ?? 1e3, r = y.CreateSphere("skybox", {
2149
1412
  diameter: n,
2150
1413
  segments: 32
2151
- }, e), i = new E("skybox-mat", e);
2152
- 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;
2153
1416
  }
2154
1417
  this._log.debug(`Skybox set from: ${t.skybox}`);
2155
1418
  }
@@ -2185,30 +1448,28 @@ var ze = class {
2185
1448
  }
2186
1449
  }
2187
1450
  _createCamera(e, t, r) {
2188
- let i = t.position ? q(t.position) : O.Zero(), a;
1451
+ let i = t.position ? G(t.position) : D.Zero(), a;
2189
1452
  switch (t.type) {
2190
1453
  case "arcRotate": {
2191
- let i = t.target ? q(t.target) : O.Zero();
1454
+ let i = t.target ? G(t.target) : D.Zero();
2192
1455
  a = new n(e, t.alpha ?? Math.PI / 2, t.beta ?? Math.PI / 3, t.radius ?? 10, i, r);
2193
1456
  break;
2194
1457
  }
2195
1458
  case "universal":
2196
- a = new ce(e, i, r);
1459
+ a = new le(e, i, r);
2197
1460
  break;
2198
1461
  case "geospatial": {
2199
- if (!t.planetRadius) return this._log.warn(`Geospatial camera "${e}" requires planetRadius -- skipping`), new d(e, O.Zero(), r);
2200
- let n = new de(e, r, { planetRadius: t.planetRadius });
2201
- t.center && (n.center = q(t.center)), t.yaw !== void 0 && (n.yaw = t.yaw), t.pitch !== void 0 && (n.pitch = t.pitch), t.radius !== void 0 && (n.radius = t.radius), t.checkCollisions !== void 0 && (n.checkCollisions = t.checkCollisions), t.radiusMin !== void 0 && (n.limits.radiusMin = t.radiusMin), t.radiusMax !== void 0 && (n.limits.radiusMax = t.radiusMax), t.pitchMin !== void 0 && (n.limits.pitchMin = t.pitchMin), t.pitchMax !== void 0 && (n.limits.pitchMax = t.pitchMax), t.yawMin !== void 0 && (n.limits.yawMin = t.yawMin), t.yawMax !== void 0 && (n.limits.yawMax = t.yawMax), a = n;
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;
2202
1465
  break;
2203
1466
  }
2204
- default:
2205
- a = new d(e, i, r);
2206
- break;
1467
+ default: a = new d(e, i, r);
2207
1468
  }
2208
1469
  return this._applyCameraConfig(a, t), a;
2209
1470
  }
2210
1471
  _applyCameraConfig(e, t) {
2211
- t.fov !== void 0 && (e.fov = t.fov), t.position && (e.position = q(t.position)), t.minZ !== void 0 && (e.minZ = t.minZ), t.maxZ !== void 0 && (e.maxZ = t.maxZ), e instanceof d && (t.speed !== void 0 && (e.speed = t.speed), t.rotation && (e.rotation = q(t.rotation))), e instanceof n && (t.target && e.setTarget(q(t.target)), t.lowerRadiusLimit !== void 0 && (e.lowerRadiusLimit = t.lowerRadiusLimit), t.upperRadiusLimit !== void 0 && (e.upperRadiusLimit = t.upperRadiusLimit), t.lowerBetaLimit !== void 0 && (e.lowerBetaLimit = t.lowerBetaLimit), t.upperBetaLimit !== void 0 && (e.upperBetaLimit = t.upperBetaLimit), t.wheelPrecision !== void 0 && (e.wheelPrecision = t.wheelPrecision)), e instanceof de && (t.yaw !== void 0 && (e.yaw = t.yaw), t.pitch !== void 0 && (e.pitch = t.pitch), t.radius !== void 0 && (e.radius = t.radius), t.center && (e.center = q(t.center)), t.checkCollisions !== void 0 && (e.checkCollisions = t.checkCollisions), t.radiusMin !== void 0 && (e.limits.radiusMin = t.radiusMin), t.radiusMax !== void 0 && (e.limits.radiusMax = t.radiusMax), t.pitchMin !== void 0 && (e.limits.pitchMin = t.pitchMin), t.pitchMax !== void 0 && (e.limits.pitchMax = t.pitchMax));
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));
2212
1473
  }
2213
1474
  _processLights(e) {
2214
1475
  let t = this._config.lights;
@@ -2218,7 +1479,7 @@ var ze = class {
2218
1479
  }
2219
1480
  }
2220
1481
  _createLight(e, t, n) {
2221
- let r = t.direction ? q(t.direction) : new O(0, -1, 0), i = t.position ? q(t.position) : O.Zero();
1482
+ let r = t.direction ? G(t.direction) : new D(0, -1, 0), i = t.position ? G(t.position) : D.Zero();
2222
1483
  switch (t.type) {
2223
1484
  case "hemispheric": {
2224
1485
  let i = new m(e, r, n);
@@ -2231,20 +1492,20 @@ var ze = class {
2231
1492
  break;
2232
1493
  }
2233
1494
  case "point": {
2234
- let r = new ee(e, i, n);
1495
+ let r = new ne(e, i, n);
2235
1496
  this._applyLightConfig(r, t);
2236
1497
  break;
2237
1498
  }
2238
1499
  case "spot": {
2239
- 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);
2240
1501
  this._applyLightConfig(a, t);
2241
1502
  break;
2242
1503
  }
2243
1504
  case "rectarea": {
2244
- 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);
2245
1506
  if (this._applyLightConfig(a, t), t.direction) {
2246
- let t = new D(`${e}_pivot`, n);
2247
- 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));
2248
1509
  }
2249
1510
  break;
2250
1511
  }
@@ -2256,19 +1517,19 @@ var ze = class {
2256
1517
  _setupClustering(e) {
2257
1518
  let t = this._config.clustering;
2258
1519
  if (!t?.enabled) return;
2259
- let n = e.lights.filter((e) => fe.IsLightSupported(e));
1520
+ let n = e.lights.filter((e) => pe.IsLightSupported(e));
2260
1521
  if (n.length === 0) {
2261
1522
  this._log.debug("Clustering enabled but no eligible lights found");
2262
1523
  return;
2263
1524
  }
2264
1525
  for (let t of n) e.removeLight(t);
2265
- let r = new fe("sage-clustered", n, e);
1526
+ let r = new pe("sage-clustered", n, e);
2266
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`);
2267
- 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);
2268
1529
  }
2269
1530
  async _enablePhysics(e) {
2270
- let t = this._config.physics, n = new O(0, -9.81, 0);
2271
- 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));
2272
1533
  let r = this.gameEngine.largeWorldRendering ? 1e5 : void 0;
2273
1534
  this._log.debug(`Enabling physics with gravity: ${n.toString()}`), await this.gameEngine.engines.sceneEngine.enablePhysics(e, n, r);
2274
1535
  }
@@ -2285,7 +1546,7 @@ var ze = class {
2285
1546
  }
2286
1547
  async _processNodeMetadata(e) {
2287
1548
  if ("spawn" in e.metadata) {
2288
- let { position: t, rotation: n, scaling: r } = Re(e);
1549
+ let { position: t, rotation: n, scaling: r } = je(e);
2289
1550
  this._spawnPoints.push({
2290
1551
  name: e.metadata.spawn,
2291
1552
  position: t,
@@ -2308,50 +1569,41 @@ var ze = class {
2308
1569
  async _processSpawnPoint(e, t) {
2309
1570
  try {
2310
1571
  let n = await this._spawnEntity(t, e);
2311
- this._spawnedEntities.push(n), this._applyDebugCollider(n, t.debugCollider), e.node.dispose(), this._log.debug(`Spawned entity '${t.entity}' at spawn point '${e.name}'`);
1572
+ this._spawnedEntities.push(n), e.node.dispose(), this._log.debug(`Spawned entity '${t.entity}' at spawn point '${e.name}'`);
2312
1573
  } catch (t) {
2313
1574
  this._log.error(`Failed to spawn entity at spawn point '${e.name}':`, t);
2314
1575
  }
2315
1576
  }
2316
- _applyDebugCollider(e, t) {
2317
- let n = this.gameEngine.managers.entityManager.getDefinition(e.type)?.debugCollider, r = t ?? n;
2318
- r && e.showCollider(r);
2319
- }
2320
1577
  async _spawnEntity(e, t) {
2321
1578
  let n = {
2322
1579
  ...e.config,
2323
- position: K(t.position),
2324
- rotation: Ie(t.rotation),
2325
- scaling: K(t.scaling)
2326
- }, r = await this.gameEngine.managers.entityManager.createEntity(e.entity, {
2327
- name: e.name,
2328
- tags: e.tags,
2329
- initialState: n
2330
- });
2331
- return await this.createEntityMesh(r, {
2332
- position: t.position,
2333
- rotation: t.rotation,
2334
- scaling: t.scaling
2335
- }), r;
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);
2336
1587
  }
2337
- async _processEntityNodes() {
2338
- 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
+ }
2339
1593
  }
2340
- async _processEntityNode(e) {
2341
- let t = this._config.entities?.[e.type];
1594
+ _spawnEntityNode(e, t) {
2342
1595
  try {
2343
1596
  let n = {
2344
- ...t?.config,
2345
- position: K(e.node.position)
2346
- }, r = await this.gameEngine.managers.entityManager.createEntity(e.type, {
2347
- name: t?.name ?? e.node.name,
2348
- tags: t?.tags,
2349
- initialState: n,
2350
- node: e.node
2351
- });
2352
- this._spawnedEntities.push(r), this._applyDebugCollider(r, t?.debugCollider), this._log.debug(`Created entity '${e.type}' for node '${e.node.name}'`);
2353
- } catch (t) {
2354
- this._log.error(`Failed to create entity for node '${e.node.name}':`, t);
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);
2355
1607
  }
2356
1608
  }
2357
1609
  async _processLevelSounds() {
@@ -2373,7 +1625,7 @@ var ze = class {
2373
1625
  }
2374
1626
  }
2375
1627
  async onDeactivate() {
2376
- 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());
2377
1629
  }
2378
1630
  async onActivate() {
2379
1631
  for (let e of this._playingSoundsBeforeDeactivate) {
@@ -2383,18 +1635,13 @@ var ze = class {
2383
1635
  this._playingSoundsBeforeDeactivate.clear();
2384
1636
  }
2385
1637
  async $dispose() {
2386
- let { entityManager: e } = this.gameEngine.managers, t = this._spawnedEntities.map(async (t) => {
2387
- try {
2388
- await e.destroyEntity(t.id);
2389
- } catch (e) {
2390
- this._log.error(`Failed to destroy entity ${t.id}:`, e);
2391
- }
2392
- });
2393
- await Promise.all(t), this._spawnedEntities = [], this._spawnPoints = [], this._entityNodes = [];
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 = [];
2394
1641
  for (let e of this._levelSounds.values()) e.dispose();
2395
1642
  this._levelSounds.clear(), this._playingSoundsBeforeDeactivate.clear(), await super.$dispose();
2396
1643
  }
2397
- }, He = class {
1644
+ }, Fe = class {
2398
1645
  _eventBus;
2399
1646
  _gameEngine = null;
2400
1647
  _log;
@@ -2451,7 +1698,7 @@ var ze = class {
2451
1698
  if (!n) throw Error(`Level class '${e.class}' is not registered.`);
2452
1699
  return this._log.debug(`Creating level '${e.name}' using class '${e.class}'`), new n(e, t);
2453
1700
  }
2454
- 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);
2455
1702
  }
2456
1703
  registerLevelConfig(e) {
2457
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}`);
@@ -2474,24 +1721,24 @@ var ze = class {
2474
1721
  getLevelConfig(e) {
2475
1722
  return this._levelConfigs.get(e) || null;
2476
1723
  }
2477
- async loadLevel(e) {
2478
- let t;
1724
+ async loadLevel(e, t) {
1725
+ let n;
2479
1726
  if (typeof e == "string") {
2480
- let n = this._levelConfigs.get(e);
2481
- if (!n) throw Error(`Level config '${e}' is not registered.`);
2482
- t = n;
2483
- } else t = e, this.registerLevelConfig(t);
2484
- let n = this._loadedLevels.get(t.name);
2485
- if (n) return this._log.warn(`Level '${t.name}' is already loaded`), n;
2486
- this._log.debug(`Loading level: ${t.name}`);
2487
- let r = this._createLevelInstance(t);
2488
- this._loadingLevel = r;
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;
2489
1736
  try {
2490
- await r.load();
1737
+ await i.load(t);
2491
1738
  } finally {
2492
1739
  this._loadingLevel = null;
2493
1740
  }
2494
- return this._loadedLevels.set(t.name, r), r;
1741
+ return this._loadedLevels.set(n.name, i), i;
2495
1742
  }
2496
1743
  async activateLevel(e) {
2497
1744
  let t = await this.loadLevel(e);
@@ -2520,7 +1767,7 @@ var ze = class {
2520
1767
  levelName: e
2521
1768
  }
2522
1769
  });
2523
- let r = await this.loadLevel(e);
1770
+ let r = await this.loadLevel(e, t);
2524
1771
  if (t?.preloadOnly) return;
2525
1772
  n && !t?.keepAlive && await this.unloadLevel(n.name), this._currentLevel = r, r.onActivate && await r.onActivate(), this._eventBus.publish({
2526
1773
  type: "level:transition:complete",
@@ -2543,7 +1790,7 @@ var ze = class {
2543
1790
  for (let e of this._loadedLevels.values()) await e.$dispose();
2544
1791
  this._loadedLevels.clear(), this._levelConfigs.clear(), this._currentLevel = null;
2545
1792
  }
2546
- }, Ue = class {
1793
+ }, Ie = class {
2547
1794
  _audioEngine;
2548
1795
  _channels = /* @__PURE__ */ new Map();
2549
1796
  _masterMuted = !1;
@@ -2587,666 +1834,167 @@ var ze = class {
2587
1834
  e !== this._masterMuted && (this._masterMuted = e, e ? (this._masterVolumeBeforeMute = this._audioEngine.getMasterVolume(), this._audioEngine.setMasterVolume(0)) : this._audioEngine.setMasterVolume(this._masterVolumeBeforeMute));
2588
1835
  }
2589
1836
  isMasterMuted() {
2590
- return this._masterMuted;
2591
- }
2592
- setChannelVolume(e, t) {
2593
- let n = this._channels.get(e);
2594
- if (!n) {
2595
- this._log.warn(`Unknown audio channel: ${e}`);
2596
- return;
2597
- }
2598
- n.volume = t, n.muted || this._audioEngine.setBusVolume(n.bus, t);
2599
- }
2600
- getChannelVolume(e) {
2601
- return this._channels.get(e)?.volume ?? 1;
2602
- }
2603
- setChannelMuted(e, t) {
2604
- let n = this._channels.get(e);
2605
- if (!n) {
2606
- this._log.warn(`Unknown audio channel: ${e}`);
2607
- return;
2608
- }
2609
- t !== n.muted && (n.muted = t, this._audioEngine.setBusVolume(n.bus, t ? 0 : n.volume));
2610
- }
2611
- isChannelMuted(e) {
2612
- return this._channels.get(e)?.muted ?? !1;
2613
- }
2614
- getChannels() {
2615
- return Array.from(this._channels.keys());
2616
- }
2617
- }, We = class {
2618
- _entityManager;
2619
- _levelManager;
2620
- _log;
2621
- _beforeSerializeHooks = [];
2622
- _afterDeserializeHooks = [];
2623
- constructor(e, t, n) {
2624
- this._entityManager = e, this._levelManager = t, this._log = n?.getLogger("SaveManager") || new N("SaveManager"), this._log.info("SaveManager initialized");
2625
- }
2626
- onBeforeSerialize(e) {
2627
- this._beforeSerializeHooks.push(e);
2628
- }
2629
- onAfterDeserialize(e) {
2630
- this._afterDeserializeHooks.push(e);
2631
- }
2632
- serialize() {
2633
- this._log.debug("Serializing game state...");
2634
- let e = this._levelManager.currentLevel?.name ?? "", t = [];
2635
- for (let e of this._entityManager.getAllEntities()) {
2636
- let n = {
2637
- id: e.id,
2638
- type: e.type,
2639
- tags: Array.from(e.tags),
2640
- state: structuredClone(e.state)
2641
- };
2642
- if (e.name && (n.name = e.name), e.parent && (n.parentId = e.parent.id), e.node) {
2643
- let { position: t, rotation: r, scaling: i } = e.node;
2644
- n.transform = {
2645
- position: {
2646
- x: t.x,
2647
- y: t.y,
2648
- z: t.z
2649
- },
2650
- rotation: {
2651
- x: r.x,
2652
- y: r.y,
2653
- z: r.z
2654
- },
2655
- scaling: {
2656
- x: i.x,
2657
- y: i.y,
2658
- z: i.z
2659
- }
2660
- };
2661
- }
2662
- t.push(n);
2663
- }
2664
- let n = {};
2665
- for (let e of this._beforeSerializeHooks) {
2666
- let t = e();
2667
- n = {
2668
- ...n,
2669
- ...t
2670
- };
2671
- }
2672
- let r = {
2673
- version: 1,
2674
- levelName: e,
2675
- entities: t,
2676
- custom: n
2677
- };
2678
- return this._log.info(`Serialized ${t.length} entities from level "${e}"`), r;
2679
- }
2680
- async deserialize(e) {
2681
- this._log.debug(`Deserializing save data (version ${e.version}, level "${e.levelName}")...`), await this._levelManager.transition(e.levelName);
2682
- let t = [];
2683
- for (let e of this._entityManager.getAllEntities()) t.push(e.id);
2684
- for (let e of t) await this._entityManager.destroyEntity(e);
2685
- let n = /* @__PURE__ */ new Map();
2686
- for (let t of e.entities) {
2687
- let e = await this._entityManager.createEntity(t.type, {
2688
- name: t.name,
2689
- initialState: t.state,
2690
- tags: t.tags
2691
- });
2692
- if (n.set(t.id, e.id), t.transform && e.node) {
2693
- let { position: n, rotation: r, scaling: i } = t.transform;
2694
- e.node.position.x = n.x, e.node.position.y = n.y, e.node.position.z = n.z, e.node.rotation.x = r.x, e.node.rotation.y = r.y, e.node.rotation.z = r.z, e.node.scaling.x = i.x, e.node.scaling.y = i.y, e.node.scaling.z = i.z;
2695
- }
2696
- }
2697
- for (let t of e.entities) if (t.parentId) {
2698
- let e = n.get(t.parentId), r = n.get(t.id);
2699
- e && r ? this._entityManager.addChild(e, r) : this._log.warn(`Could not restore parent-child: ${t.id} -> ${t.parentId} (mapped: ${r} -> ${e})`);
2700
- }
2701
- for (let t of this._afterDeserializeHooks) t(e.custom);
2702
- this._log.info(`Deserialized ${e.entities.length} entities for level "${e.levelName}"`);
2703
- }
2704
- async $teardown() {
2705
- this._beforeSerializeHooks = [], this._afterDeserializeHooks = [], this._log.info("SaveManager torn down");
2706
- }
2707
- }, Ge = class {
2708
- _viewer = null;
2709
- _shown = /* @__PURE__ */ new Map();
2710
- _materials = /* @__PURE__ */ new Map();
2711
- showColliderForNode(e, t) {
2712
- if (!e.physicsBody || this._shown.has(e)) return;
2713
- let n = this._getViewer(e).showBody(e.physicsBody);
2714
- if (!n) return;
2715
- let r = { debugMesh: n };
2716
- if (t) {
2717
- let i = this._getColorMaterial(t, e);
2718
- n.material = i, r.colorMaterial = i;
2719
- }
2720
- this._shown.set(e, r);
2721
- }
2722
- hideColliderForNode(e) {
2723
- !this._shown.get(e) || !this._viewer || (e.physicsBody && this._viewer.hideBody(e.physicsBody), this._shown.delete(e));
2724
- }
2725
- hideAll() {
2726
- for (let [e] of this._shown) this.hideColliderForNode(e);
2727
- }
2728
- isShown(e) {
2729
- return this._shown.has(e);
2730
- }
2731
- async $teardown() {
2732
- this.dispose();
2733
- }
2734
- dispose() {
2735
- this._viewer &&= (this.hideAll(), this._viewer.dispose(), null), this._shown.clear();
2736
- for (let e of this._materials.values()) e.dispose();
2737
- this._materials.clear();
2738
- }
2739
- _getViewer(e) {
2740
- return this._viewer ||= new pe(e.getScene()), this._viewer;
2741
- }
2742
- _getColorMaterial(e, t) {
2743
- let n = this._materials.get(e);
2744
- return n || (n = new E(`sage-collider-debug-${e}`, t.getScene()), n.emissiveColor = r.FromHexString(e), n.disableLighting = !0, n.wireframe = !0, this._materials.set(e, n), n);
2745
- }
2746
- }, Ke = class {
2747
- _keyboardDevice;
2748
- _keysState = {};
2749
- _onDeviceConnected;
2750
- _onInputChanged;
2751
- constructor() {
2752
- this._keyboardDevice = {
2753
- id: "keyboard-0",
2754
- name: "Keyboard",
2755
- type: "keyboard",
2756
- connected: !0
2757
- }, this._setupKeyboardEvents(), setTimeout(() => this._notifyDeviceConnected(), 0);
2758
- }
2759
- onDeviceConnected(e) {
2760
- this._onDeviceConnected = e;
2761
- }
2762
- onInputChanged(e) {
2763
- this._onInputChanged = e;
2764
- }
2765
- getState() {
2766
- return {
2767
- type: "keyboard",
2768
- keys: { ...this._keysState },
2769
- delta: {}
2770
- };
2771
- }
2772
- getDevice() {
2773
- return { ...this._keyboardDevice };
2774
- }
2775
- $teardown() {
2776
- return window.removeEventListener("keydown", this._handleKeyDown), window.removeEventListener("keyup", this._handleKeyUp), Promise.resolve();
2777
- }
2778
- _setupKeyboardEvents() {
2779
- this._handleKeyDown = this._handleKeyDown.bind(this), this._handleKeyUp = this._handleKeyUp.bind(this), window.addEventListener("keydown", this._handleKeyDown), window.addEventListener("keyup", this._handleKeyUp);
2780
- }
2781
- _handleKeyDown(e) {
2782
- this._keysState[e.code] = !0;
2783
- let t = {};
2784
- t[e.code] = !0;
2785
- let n = {
2786
- type: "keyboard",
2787
- keys: { ...this._keysState },
2788
- delta: t,
2789
- event: e
2790
- };
2791
- this._notifyInputChanged(n);
2792
- }
2793
- _handleKeyUp(e) {
2794
- this._keysState[e.code] = !1;
2795
- let t = {};
2796
- t[e.code] = !1;
2797
- let n = {
2798
- type: "keyboard",
2799
- keys: { ...this._keysState },
2800
- delta: t,
2801
- event: e
2802
- };
2803
- this._notifyInputChanged(n);
2804
- }
2805
- _notifyDeviceConnected() {
2806
- this._onDeviceConnected && this._onDeviceConnected(this._keyboardDevice);
2807
- }
2808
- _notifyInputChanged(e) {
2809
- this._onInputChanged && this._onInputChanged(this._keyboardDevice, e);
2810
- }
2811
- }, qe = class {
2812
- _targetElement;
2813
- _mouseDevice;
2814
- _buttonState = {};
2815
- _axesState = {};
2816
- _position = {
2817
- absolute: {
2818
- x: 0,
2819
- y: 0
2820
- },
2821
- relative: {
2822
- x: 0,
2823
- y: 0
2824
- }
2825
- };
2826
- _wheelState = {
2827
- deltaX: 0,
2828
- deltaY: 0,
2829
- deltaZ: 0,
2830
- deltaMode: 0
2831
- };
2832
- _onDeviceConnected;
2833
- _onInputChanged;
2834
- constructor(e = document.body) {
2835
- this._targetElement = e, this._mouseDevice = {
2836
- id: "mouse-0",
2837
- name: "Mouse",
2838
- type: "mouse",
2839
- connected: !0
2840
- }, this._setupMouseEvents(), this._axesState["axis-x"] = 0, this._axesState["axis-y"] = 0, setTimeout(() => this._notifyDeviceConnected(), 0);
2841
- }
2842
- onDeviceConnected(e) {
2843
- this._onDeviceConnected = e;
2844
- }
2845
- onInputChanged(e) {
2846
- this._onInputChanged = e;
2847
- }
2848
- getState() {
2849
- return {
2850
- type: "mouse",
2851
- buttons: { ...this._buttonState },
2852
- axes: { ...this._axesState },
2853
- position: {
2854
- absolute: { ...this._position.absolute },
2855
- relative: { ...this._position.relative }
2856
- },
2857
- wheel: { ...this._wheelState }
2858
- };
2859
- }
2860
- getDevice() {
2861
- return { ...this._mouseDevice };
2862
- }
2863
- $teardown() {
2864
- return this._targetElement.removeEventListener("pointerdown", this._handlePointerDown), this._targetElement.removeEventListener("pointerup", this._handlePointerUp), this._targetElement.removeEventListener("pointermove", this._handlePointerMove), this._targetElement.removeEventListener("wheel", this._handleMouseWheel), Promise.resolve();
2865
- }
2866
- _setupMouseEvents() {
2867
- this._handlePointerDown = this._handlePointerDown.bind(this), this._handlePointerUp = this._handlePointerUp.bind(this), this._handlePointerMove = this._handlePointerMove.bind(this), this._handleMouseWheel = this._handleMouseWheel.bind(this), this._targetElement.addEventListener("pointerdown", this._handlePointerDown), this._targetElement.addEventListener("pointerup", this._handlePointerUp), this._targetElement.addEventListener("pointermove", this._handlePointerMove), this._targetElement.addEventListener("wheel", this._handleMouseWheel);
2868
- }
2869
- _handlePointerDown(e) {
2870
- if (e.pointerType !== "mouse") return;
2871
- let t = `button-${e.button}`;
2872
- this._buttonState[t] = { pressed: !0 }, this._notifyInputChanged({
2873
- type: "mouse",
2874
- event: e,
2875
- buttons: { ...this._buttonState },
2876
- axes: { ...this._axesState },
2877
- position: { ...this._position }
2878
- });
2879
- }
2880
- _handlePointerUp(e) {
2881
- if (e.pointerType !== "mouse") return;
2882
- let t = `button-${e.button}`;
2883
- this._buttonState[t] = { pressed: !1 }, this._notifyInputChanged({
2884
- type: "mouse",
2885
- event: e,
2886
- buttons: { ...this._buttonState },
2887
- axes: { ...this._axesState },
2888
- position: { ...this._position }
2889
- });
2890
- }
2891
- _handlePointerMove(e) {
2892
- e.pointerType === "mouse" && (this._position = {
2893
- absolute: {
2894
- x: e.clientX,
2895
- y: e.clientY
2896
- },
2897
- relative: {
2898
- x: e.movementX,
2899
- y: e.movementY
2900
- }
2901
- }, this._axesState["axis-x"] = e.clientX, this._axesState["axis-y"] = e.clientY, this._notifyInputChanged({
2902
- type: "mouse",
2903
- event: e,
2904
- buttons: { ...this._buttonState },
2905
- axes: { ...this._axesState },
2906
- position: { ...this._position }
2907
- }));
2908
- }
2909
- _handleMouseWheel(e) {
2910
- this._wheelState = {
2911
- deltaX: e.deltaX,
2912
- deltaY: e.deltaY,
2913
- deltaZ: e.deltaZ,
2914
- deltaMode: e.deltaMode
2915
- }, this._notifyWheelState(e), this._wheelState = {
2916
- deltaX: 0,
2917
- deltaY: 0,
2918
- deltaZ: 0,
2919
- deltaMode: 0
2920
- }, this._notifyWheelState(e);
2921
- }
2922
- _notifyWheelState(e) {
2923
- this._notifyInputChanged({
2924
- type: "mouse",
2925
- event: e,
2926
- buttons: { ...this._buttonState },
2927
- axes: { ...this._axesState },
2928
- position: { ...this._position },
2929
- wheel: { ...this._wheelState }
2930
- });
2931
- }
2932
- _notifyDeviceConnected() {
2933
- this._onDeviceConnected && this._onDeviceConnected(this._mouseDevice);
2934
- }
2935
- _notifyInputChanged(e) {
2936
- this._onInputChanged && this._onInputChanged(this._mouseDevice, e);
2937
- }
2938
- }, Je = class {
2939
- _gamepadDevices = {};
2940
- _buttonStates = {};
2941
- _axesStates = {};
2942
- _onDeviceConnected;
2943
- _onDeviceDisconnected;
2944
- _onInputChanged;
2945
- constructor() {
2946
- this._setupGamepadEvents();
2947
- }
2948
- onDeviceConnected(e) {
2949
- this._onDeviceConnected = e;
2950
- }
2951
- onDeviceDisconnected(e) {
2952
- this._onDeviceDisconnected = e;
2953
- }
2954
- onInputChanged(e) {
2955
- this._onInputChanged = e;
1837
+ return this._masterMuted;
2956
1838
  }
2957
- getDevices() {
2958
- 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);
2959
1846
  }
2960
- getStates() {
2961
- let e = {};
2962
- return Object.keys(this._buttonStates).forEach((t) => {
2963
- let n = Number(t), r = this._buttonStates[n] || {}, i = this._axesStates[n] || {};
2964
- e[n] = {
2965
- type: "gamepad",
2966
- buttons: { ...r },
2967
- axes: { ...i }
2968
- };
2969
- }), e;
2970
- }
2971
- getDevice(e) {
2972
- let t = this._gamepadDevices[e];
2973
- return t ? { ...t } : null;
2974
- }
2975
- getState(e) {
2976
- let t = this._buttonStates[e], n = this._axesStates[e];
2977
- return !t && !n ? null : {
2978
- type: "gamepad",
2979
- buttons: t ? { ...t } : {},
2980
- axes: n ? { ...n } : {}
2981
- };
1847
+ getChannelVolume(e) {
1848
+ return this._channels.get(e)?.volume ?? 1;
2982
1849
  }
2983
- pollGamepads() {
2984
- if (!navigator.getGamepads) return;
2985
- let e = navigator.getGamepads();
2986
- for (let t of e) {
2987
- if (!t) continue;
2988
- let e = t.index;
2989
- if (!this._gamepadDevices[e]) {
2990
- this._handleGamepadConnected(t);
2991
- continue;
2992
- }
2993
- let n = this._gamepadDevices[e];
2994
- if (!n) continue;
2995
- let r = this._buttonStates[e] || {}, i = this._axesStates[e] || {}, a = {}, o = !1;
2996
- t.buttons.forEach((e, t) => {
2997
- let n = `button-${t}`, i = {
2998
- pressed: e.pressed,
2999
- touched: e.touched,
3000
- value: e.value
3001
- };
3002
- a[n] = i;
3003
- let s = r[n];
3004
- (!s || s.pressed !== i.pressed || s.touched !== i.touched || s.value !== i.value) && (o = !0);
3005
- });
3006
- let s = {}, c = !1;
3007
- if (t.axes.forEach((e, t) => {
3008
- let n = `axis-${t}`;
3009
- s[n] = e, i[n] !== e && (c = !0);
3010
- }), this._buttonStates[e] = a, this._axesStates[e] = s, o || c) {
3011
- let e = {
3012
- type: "gamepad",
3013
- buttons: { ...a },
3014
- axes: { ...s }
3015
- };
3016
- this._notifyInputChanged(n, e);
3017
- }
1850
+ setChannelMuted(e, t) {
1851
+ let n = this._channels.get(e);
1852
+ if (!n) {
1853
+ this._log.warn(`Unknown audio channel: ${e}`);
1854
+ return;
3018
1855
  }
1856
+ t !== n.muted && (n.muted = t, this._audioEngine.setBusVolume(n.bus, t ? 0 : n.volume));
3019
1857
  }
3020
- $teardown() {
3021
- return window.removeEventListener("gamepadconnected", this._handleGamepadConnected), window.removeEventListener("gamepaddisconnected", this._handleGamepadDisconnected), Promise.resolve();
1858
+ isChannelMuted(e) {
1859
+ return this._channels.get(e)?.muted ?? !1;
3022
1860
  }
3023
- _setupGamepadEvents() {
3024
- if (this._handleGamepadConnected = this._handleGamepadConnected.bind(this), this._handleGamepadDisconnected = this._handleGamepadDisconnected.bind(this), window.addEventListener("gamepadconnected", this._handleGamepadConnected), window.addEventListener("gamepaddisconnected", this._handleGamepadDisconnected), navigator.getGamepads) {
3025
- let e = navigator.getGamepads();
3026
- for (let t of e) t && this._handleGamepadConnected(t);
3027
- }
1861
+ getChannels() {
1862
+ return Array.from(this._channels.keys());
3028
1863
  }
3029
- _handleGamepadConnected(e) {
3030
- let t = e instanceof GamepadEvent ? e.gamepad : e, n = t.index, r = {
3031
- id: `gamepad-${n}`,
3032
- name: t.id,
3033
- type: "gamepad",
3034
- connected: !0,
3035
- index: n,
3036
- mapping: t.mapping,
3037
- axes: Array.from(t.axes),
3038
- buttons: Array.from(t.buttons)
3039
- };
3040
- this._gamepadDevices[n] = r;
3041
- let i = {};
3042
- Array.from(t.buttons).forEach((e, t) => {
3043
- i[`button-${t}`] = {
3044
- pressed: e.pressed,
3045
- touched: e.touched,
3046
- value: e.value
3047
- };
3048
- }), this._buttonStates[n] = i;
3049
- let a = {};
3050
- Array.from(t.axes).forEach((e, t) => {
3051
- a[`axis-${t}`] = e;
3052
- }), this._axesStates[n] = a, this._notifyDeviceConnected(r), this._notifyInputChanged(r, {
3053
- type: "gamepad",
3054
- buttons: { ...i },
3055
- axes: { ...a },
3056
- event: e instanceof GamepadEvent ? e : void 0
3057
- });
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;
3058
1871
  }
3059
- _handleGamepadDisconnected(e) {
3060
- let t = e.gamepad.index, n = this._gamepadDevices[t];
3061
- n && (n.connected = !1, this._notifyDeviceDisconnected(n), this._gamepadDevices[t] = void 0, this._buttonStates[t] = void 0, this._axesStates[t] = void 0);
1872
+ onBeforeSave(e) {
1873
+ this.#r.push(e);
3062
1874
  }
3063
- _notifyDeviceConnected(e) {
3064
- 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
+ };
3065
1889
  }
3066
- _notifyDeviceDisconnected(e) {
3067
- 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
+ };
3068
1896
  }
3069
- _notifyInputChanged(e, t) {
3070
- this._onInputChanged && this._onInputChanged(e, t);
1897
+ async $teardown() {
1898
+ this.#r.length = 0;
3071
1899
  }
3072
- }, Ye = class {
3073
- _eventBus;
3074
- _keyboardRA;
3075
- _mouseRA;
3076
- _gamepadRA;
3077
- _log;
3078
- constructor(e, t, n) {
3079
- this._eventBus = e, this._log = n?.getLogger("UserInputManager") || new N("UserInputManager"), this._log.info("Initializing UserInputManager"), this._log.debug("Initializing input resource access classes"), this._keyboardRA = new Ke(), this._mouseRA = new qe(t), this._gamepadRA = new Je(), this._log.debug("Registering input event callbacks"), this._keyboardRA.onDeviceConnected(this._publishDeviceConnected.bind(this)), this._keyboardRA.onInputChanged(this._publishInputChanged.bind(this)), this._mouseRA.onDeviceConnected(this._publishDeviceConnected.bind(this)), this._mouseRA.onInputChanged(this._publishInputChanged.bind(this)), this._gamepadRA.onDeviceConnected(this._publishDeviceConnected.bind(this)), this._gamepadRA.onDeviceDisconnected(this._publishDeviceDisconnected.bind(this)), this._gamepadRA.onInputChanged(this._publishInputChanged.bind(this)), this._log.info("UserInputManager initialized successfully");
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);
3080
1914
  }
3081
- _publishDeviceConnected(e) {
3082
- this._log.debug(`Device connected: ${e.id} (${e.name})`), this._eventBus.publish({
3083
- type: "input:device:connected",
3084
- payload: { device: e }
3085
- });
1915
+ hideColliderForNode(e) {
1916
+ !this._shown.get(e) || !this._viewer || (e.physicsBody && this._viewer.hideBody(e.physicsBody), this._shown.delete(e));
3086
1917
  }
3087
- _publishDeviceDisconnected(e) {
3088
- this._log.debug(`Device disconnected: ${e.id} (${e.name})`), this._eventBus.publish({
3089
- type: "input:device:disconnected",
3090
- payload: { device: e }
3091
- });
1918
+ hideAll() {
1919
+ for (let [e] of this._shown) this.hideColliderForNode(e);
3092
1920
  }
3093
- _publishInputChanged(e, t) {
3094
- this._log.trace(`Input changed: ${e.id}`, t), this._eventBus.publish({
3095
- type: "input:changed",
3096
- payload: {
3097
- deviceId: e.id,
3098
- device: e,
3099
- state: t
3100
- }
3101
- });
1921
+ isShown(e) {
1922
+ return this._shown.has(e);
3102
1923
  }
3103
- $teardown() {
3104
- return this._log.info("Tearing down UserInputManager"), this._log.debug("Cleaning up input resource access instances"), Promise.all([
3105
- this._keyboardRA.$teardown(),
3106
- this._mouseRA.$teardown(),
3107
- this._gamepadRA.$teardown()
3108
- ]).then(() => {
3109
- this._log.info("UserInputManager torn down successfully");
3110
- });
1924
+ async $teardown() {
1925
+ this.dispose();
3111
1926
  }
3112
- listDevices() {
3113
- this._log.debug("Getting all connected input devices");
3114
- let e = [];
3115
- return e.push(this._keyboardRA.getDevice()), e.push(this._mouseRA.getDevice()), e.push(...this._gamepadRA.getDevices()), this._log.debug(`Found ${e.length} connected devices`), e;
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();
3116
1931
  }
3117
- getDevice(e) {
3118
- if (this._log.debug(`Getting device: ${e}`), e.startsWith("keyboard-")) return this._keyboardRA.getDevice();
3119
- if (e.startsWith("mouse-")) return this._mouseRA.getDevice();
3120
- if (e.startsWith("gamepad-")) {
3121
- let t = parseInt(e.split("-")[1], 10);
3122
- return this._gamepadRA.getDevice(t);
3123
- }
3124
- return this.listDevices().find((t) => t.id === e) || (this._log.warn(`Device not found: ${e}`), null);
1932
+ _getViewer(e) {
1933
+ return this._viewer ||= new me(e.getScene()), this._viewer;
3125
1934
  }
3126
- pollGamepads() {
3127
- 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);
3128
1938
  }
3129
1939
  };
3130
1940
  //#endregion
3131
1941
  //#region src/utils/graphics.ts
3132
- async function Xe(e, t) {
3133
- let n = new le(e, t);
1942
+ async function Be(e, t) {
1943
+ let n = new ue(e, t);
3134
1944
  return await n.initAsync(), n;
3135
1945
  }
3136
- function J(e, t) {
1946
+ function q(e, t) {
3137
1947
  return new l(e, t.antialias, t.options, t.adaptToDeviceRatio);
3138
1948
  }
3139
- function Ze(e) {
3140
- return new x(e);
1949
+ function Ve(e) {
1950
+ return new b(e);
3141
1951
  }
3142
- async function Qe(e, t, n = !1) {
3143
- if (e === null) return console.debug("Using Null Engine"), Ze(t);
3144
- if (n) if ("options" in t) {
3145
- let e = t;
3146
- t = {
3147
- ...e,
3148
- options: {
3149
- ...e.options,
3150
- useLargeWorldRendering: !0
3151
- }
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
3152
1967
  };
3153
- } else t = {
3154
- ...t,
3155
- useLargeWorldRendering: !0
3156
- };
1968
+ }
3157
1969
  let r = t.engine || "auto";
3158
- if (r === "webgpu") if (De()) try {
3159
- return console.debug("Using forced WebGPU engine"), await Xe(e, t);
3160
- } catch (e) {
3161
- throw console.error("Forced WebGPU initialization failed:", e), Error("Forced WebGPU failed to initialize. If WebGPU is required, check browser compatibility.", { cause: e });
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.");
3162
1977
  }
3163
- else throw Error("WebGPU was forced but is not available in this browser.");
3164
- if (r === "webgl") return console.debug("Using forced WebGL engine"), J(e, t);
3165
- if (De()) try {
3166
- return console.debug("Using WebGPU"), Xe(e, t).catch((n) => (console.warn("WebGPU initialization failed, falling back to WebGL:", n), J(e, t)));
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)));
3167
1981
  } catch (e) {
3168
1982
  console.warn("WebGPU initialization failed, falling back to WebGL:", e);
3169
1983
  }
3170
1984
  else console.warn("WebGPU not supported, falling back to WebGL.");
3171
- return console.debug("Using WebGL"), J(e, t);
1985
+ return console.debug("Using WebGL"), q(e, t);
3172
1986
  }
3173
1987
  //#endregion
3174
1988
  //#region src/utils/physics.ts
3175
- async function $e() {
3176
- return await me();
1989
+ async function Ue(e) {
1990
+ return await he(e ? { wasmBinary: e } : void 0);
3177
1991
  }
3178
- function et(e) {
1992
+ function We(e) {
3179
1993
  return new p(!0, e);
3180
1994
  }
3181
1995
  //#endregion
3182
- //#region src/utils/raycast.ts
3183
- var tt = class {
3184
- _entityManager;
3185
- constructor(e) {
3186
- this._entityManager = e;
3187
- }
3188
- pickEntity(e, t, n, r) {
3189
- let i = e.pick(t, n);
3190
- return this._toEntityResult(i, r);
3191
- }
3192
- pickEntities(e, t, n, r) {
3193
- let i = e.multiPick(t, n);
3194
- if (!i) return [];
3195
- let a = [];
3196
- for (let e of i) {
3197
- let t = this._toEntityResult(e, r);
3198
- t && a.push(t);
3199
- }
3200
- return a;
3201
- }
3202
- pickEntityWithRay(e, t, n) {
3203
- let r = e.pickWithRay(t);
3204
- return r ? this._toEntityResult(r, n) : null;
3205
- }
3206
- pickEntitiesWithRay(e, t, n) {
3207
- let r = e.multiPickWithRay(t);
3208
- if (!r) return [];
3209
- let i = [];
3210
- for (let e of r) {
3211
- let t = this._toEntityResult(e, n);
3212
- t && i.push(t);
3213
- }
3214
- return i;
3215
- }
3216
- pickEntityForward(e, t, n = 1e3, r) {
3217
- let i = t.getForwardRay(n);
3218
- return this.pickEntityWithRay(e, i, r);
3219
- }
3220
- _toEntityResult(e, t) {
3221
- if (!e.hit || !e.pickedMesh || !e.pickedPoint) return null;
3222
- let n = e.pickedMesh, r = this._entityManager.getByNode(n);
3223
- if (!r) {
3224
- let e = n.parent;
3225
- for (; e && (r = this._entityManager.getByNode(e), !r);) e = e.parent;
3226
- }
3227
- if (!r) return null;
3228
- if (t) {
3229
- if (t.type && r.type !== t.type) return null;
3230
- if (t.tags) {
3231
- for (let e of t.tags) if (!r.hasTag(e)) return null;
3232
- }
3233
- if (t.predicate && !t.predicate(r)) return null;
3234
- }
3235
- let i = e.getNormal(!0, !0);
3236
- return {
3237
- entity: r,
3238
- point: e.pickedPoint,
3239
- distance: e.distance,
3240
- normal: i ?? {
3241
- x: 0,
3242
- y: 0,
3243
- z: 0
3244
- },
3245
- mesh: n,
3246
- pickingInfo: e
3247
- };
3248
- }
3249
- }, nt = class {
1996
+ //#region src/utils/timer.ts
1997
+ var Ge = class {
3250
1998
  _nextId = 0;
3251
1999
  _delays = [];
3252
2000
  _intervals = [];
@@ -3263,383 +2011,185 @@ var tt = class {
3263
2011
  };
3264
2012
  }
3265
2013
  interval(e, t) {
3266
- if (e <= 0) throw RangeError(`interval() requires ms > 0, got ${e}`);
3267
- let n = this._nextId++;
3268
- return this._intervals.push({
3269
- id: n,
3270
- periodMs: e,
3271
- elapsed: 0,
3272
- callback: t
3273
- }), () => {
3274
- this._intervals = this._intervals.filter((e) => e.id !== n);
3275
- };
3276
- }
3277
- cooldown(e) {
3278
- let t = {
3279
- id: this._nextId++,
3280
- periodMs: e,
3281
- remaining: 0
3282
- };
3283
- return this._cooldowns.push(t), {
3284
- get ready() {
3285
- return t.remaining <= 0;
3286
- },
3287
- reset() {
3288
- t.remaining = t.periodMs;
3289
- }
3290
- };
3291
- }
3292
- cancelAll() {
3293
- this._delays = [], this._intervals = [];
3294
- for (let e of this._cooldowns) e.remaining = 0;
3295
- this._cooldowns = [];
3296
- }
3297
- tick(e) {
3298
- let t = [];
3299
- for (let n of this._delays) n.remaining -= e, n.remaining <= 0 && (n.callback(), t.push(n.id));
3300
- t.length > 0 && (this._delays = this._delays.filter((e) => !t.includes(e.id)));
3301
- for (let t of this._intervals) for (t.elapsed += e; t.elapsed >= t.periodMs;) t.callback(), t.elapsed -= t.periodMs;
3302
- for (let t of this._cooldowns) t.remaining > 0 && (t.remaining = Math.max(0, t.remaining - e));
3303
- }
3304
- };
3305
- //#endregion
3306
- //#region src/utils/entityProxy.ts
3307
- function rt(e) {
3308
- return new Proxy(e, { get(e, t) {
3309
- if (typeof t == "symbol") return Reflect.get(e, t);
3310
- if (t in e) {
3311
- let n = Reflect.get(e, t);
3312
- return typeof n == "function" ? n.bind(e) : n;
3313
- }
3314
- return e.getByName(t);
3315
- } });
3316
- }
3317
- //#endregion
3318
- //#region src/debug/builtins.ts
3319
- function it(e, t) {
3320
- return typeof e == "string" ? t.managers.entityManager.getByName(e) : e;
3321
- }
3322
- function at(e, t) {
3323
- let n = t.managers.entityManager;
3324
- if (e === void 0) return [...n.getAllEntities()];
3325
- if (typeof e != "string") return [e];
3326
- let r = n.getByName(e);
3327
- if (r) return [r];
3328
- let i = n.getByType(e);
3329
- return i.length > 0 ? i : (console.warn(`[sage] No entity found with name or type "${e}"`), []);
3330
- }
3331
- function ot(e, t) {
3332
- let n = t.managers.entityManager, r = t.managers.gameManager, i = t.managers.levelManager, a = [];
3333
- e.expose("engine", t), e.expose("events", t.eventBus), e.expose("physics", t.physics), e.expose("colliders", t.debug.colliders), e.expose("entities", rt(n)), e.expose("level", { get: () => i.currentLevel }), e.expose("scene", { get: () => i.currentLevel?.scene ?? null }), e.expose("tp", (e, n, r, i) => {
3334
- let a = it(e, t);
3335
- if (!a) {
3336
- console.warn(`[sage] Entity not found: ${e}`);
3337
- return;
3338
- }
3339
- if (!a.node) {
3340
- console.warn(`[sage] Entity "${a.name ?? a.id}" has no node`);
3341
- return;
3342
- }
3343
- a.node.position.x = n, a.node.position.y = r, a.node.position.z = i, console.log(`[sage] Teleported "${a.name ?? a.id}" to (${n}, ${r}, ${i})`);
3344
- }), e.expose("spawn", async (e, t, r, i) => {
3345
- let a = await n.createEntity(e, { initialState: { position: {
3346
- x: t,
3347
- y: r,
3348
- z: i
3349
- } } });
3350
- return console.log(`[sage] Spawned "${e}" (${a.id}) at (${t}, ${r}, ${i})`), a;
3351
- }), e.expose("list", (e) => {
3352
- let t;
3353
- t = e ? n.getByType(e) : [...n.getAllEntities()];
3354
- let r = t.map((e) => ({
3355
- id: e.id,
3356
- type: e.type,
3357
- name: e.name ?? "(unnamed)",
3358
- node: e.node?.name ?? "(no node)"
3359
- }));
3360
- return console.table(r), t;
3361
- }), e.expose("inspect", (e) => {
3362
- let n = it(e, t);
3363
- if (!n) {
3364
- console.warn(`[sage] Entity not found: ${e}`);
3365
- return;
3366
- }
3367
- let r = {
3368
- id: n.id,
3369
- type: n.type,
3370
- name: n.name,
3371
- state: n.state,
3372
- behaviors: n.behaviors.map((e) => e.name),
3373
- node: n.node?.name ?? null,
3374
- position: n.node?.position ?? null
3375
- };
3376
- return console.log("[sage] Entity info:", r), r;
3377
- }), e.expose("showColliders", (e) => {
3378
- let n = at(e, t);
3379
- for (let e of n) e.showCollider();
3380
- console.log(`[sage] Showing colliders for ${n.length} entity(s)`);
3381
- }), e.expose("hideColliders", (e) => {
3382
- let n = at(e, t);
3383
- for (let e of n) e.hideCollider();
3384
- console.log(`[sage] Hiding colliders for ${n.length} entity(s)`);
3385
- }), e.expose("logEvents", (e) => {
3386
- let n = e ?? "*", r = t.eventBus.subscribe(n, (e) => {
3387
- console.log(`[sage] Event: ${e.type}`, e.payload);
3388
- });
3389
- return a.push(r), console.log(`[sage] Logging events matching "${n}"`), r;
3390
- }), e.expose("stopLogging", () => {
3391
- for (let e of a) e();
3392
- console.log(`[sage] Stopped ${a.length} event logger(s)`), a.length = 0;
3393
- }), e.expose("pause", () => {
3394
- r.pause("debug console"), console.log("[sage] Game paused");
3395
- }), e.expose("resume", () => {
3396
- r.resume("debug console"), console.log("[sage] Game resumed");
3397
- }), e.expose("slow", (e) => {
3398
- t.renderEngine.timeStep = 1 / 60 / e, console.log(`[sage] Time scale set to ${e}x (timeStep=${1 / 60 / e})`);
3399
- });
3400
- }
3401
- //#endregion
3402
- //#region src/interfaces/logger.ts
3403
- var st = [
3404
- "trace",
3405
- "debug",
3406
- "info",
3407
- "warn",
3408
- "error",
3409
- "none"
3410
- ], ct = class extends G {
3411
- name = "sound";
3412
- eventSubscriptions = [];
3413
- _sounds = /* @__PURE__ */ new Map();
3414
- _initialized = !1;
3415
- _audioManager = null;
3416
- _node = null;
3417
- _log = new N("SoundBehavior");
3418
- onNodeAttached(e, t) {
3419
- if (this._initialized) return;
3420
- if (this._node = e, this._initialized = !0, this._log = t.logger.getLogger("SoundBehavior"), t.managers.audioManager) this._audioManager = t.managers.audioManager;
3421
- else {
3422
- this._log.warn("No AudioManager configured. Sounds will not be created.");
3423
- return;
3424
- }
3425
- if (!this.entity) return;
3426
- let n = this.entity.state.sounds;
3427
- if (n) for (let [e, t] of Object.entries(n)) this._createSound(e, t);
3428
- }
3429
- processEvent(e, t) {
3430
- return !1;
3431
- }
3432
- onReset(e) {
3433
- this._disposeSounds();
3434
- }
3435
- async destroy() {
3436
- this._disposeSounds();
3437
- }
3438
- _createSound(e, t) {
3439
- if (!this._audioManager || !this.entity) return;
3440
- let n = this.entity.id, r = this._node;
3441
- this._audioManager.createSound(`${n}_${e}`, t.url, t.channel, {
3442
- loop: t.loop ?? !1,
3443
- autoplay: t.autoplay ?? !1,
3444
- volume: t.volume ?? 1,
3445
- spatialEnabled: t.spatial ?? !1,
3446
- spatialMaxDistance: t.maxDistance ?? 100,
3447
- spatialDistanceModel: "linear"
3448
- }).then((n) => {
3449
- this._sounds.set(e, n), (t.spatial ?? !1) && r && n.spatial.attach(r);
3450
- }).catch((t) => {
3451
- this._log.error(`Failed to create sound "${e}": ${t}`);
3452
- });
3453
- }
3454
- _disposeSounds() {
3455
- for (let e of this._sounds.values()) e.dispose();
3456
- this._sounds.clear(), this._initialized = !1, this._node = null, this._audioManager = null;
3457
- }
3458
- play(e, t) {
3459
- let n = this._getSound(e);
3460
- n && (t === void 0 ? n.play() : n.play({ startOffset: t }));
3461
- }
3462
- stop(e) {
3463
- if (e) {
3464
- let t = this._sounds.get(e);
3465
- t && t.stop();
3466
- } else for (let e of this._sounds.values()) e.stop();
3467
- }
3468
- pause(e) {
3469
- let t = this._getSound(e);
3470
- t && t.pause();
3471
- }
3472
- setVolume(e, t) {
3473
- if (t) {
3474
- let n = this._sounds.get(t);
3475
- n && (n.volume = e);
3476
- } else for (let t of this._sounds.values()) t.volume = e;
3477
- }
3478
- isPlaying(e) {
3479
- return this._getSound(e)?.state === ae.Started;
3480
- }
3481
- getSoundNames() {
3482
- return Array.from(this._sounds.keys());
3483
- }
3484
- hasSound(e) {
3485
- return this._sounds.has(e);
3486
- }
3487
- registerSound(e, t) {
3488
- if (!this._initialized || !this._audioManager) throw Error("SoundBehavior must be initialized before registering sounds");
3489
- let n = this._sounds.get(e);
3490
- n && n.dispose(), this._createSound(e, t);
3491
- }
3492
- unregisterSound(e) {
3493
- let t = this._sounds.get(e);
3494
- t && (t.dispose(), this._sounds.delete(e));
3495
- }
3496
- _getSound(e) {
3497
- if (e) return this._sounds.get(e);
3498
- if (this._sounds.size === 1) return this._sounds.values().next().value;
3499
- }
3500
- }, Y = class {
3501
- _currentState;
3502
- transitions = /* @__PURE__ */ new Map();
3503
- wildcardTransitions = /* @__PURE__ */ new Map();
3504
- enterCallbacks = /* @__PURE__ */ new Map();
3505
- exitCallbacks = /* @__PURE__ */ new Map();
3506
- eventBus;
3507
- constructor(e, t) {
3508
- this._currentState = e, this.eventBus = t;
3509
- }
3510
- get currentState() {
3511
- return this._currentState;
3512
- }
3513
- addTransition(e, t, n) {
3514
- let r = `${e}->${t}`;
3515
- this.transitions.set(r, { guard: n });
3516
- }
3517
- addTransitionFromAny(e, t) {
3518
- this.wildcardTransitions.set(e, { guard: t });
3519
- }
3520
- onEnter(e, t) {
3521
- let n = this.enterCallbacks.get(e) ?? [];
3522
- n.push(t), this.enterCallbacks.set(e, n);
3523
- }
3524
- onExit(e, t) {
3525
- let n = this.exitCallbacks.get(e) ?? [];
3526
- n.push(t), this.exitCallbacks.set(e, n);
3527
- }
3528
- canTransition(e) {
3529
- let t = `${this._currentState}->${e}`;
3530
- return this.transitions.has(t) || this.wildcardTransitions.has(e);
3531
- }
3532
- transition(e) {
3533
- let t = `${this._currentState}->${e}`, n = this.transitions.get(t);
3534
- if (n ||= this.wildcardTransitions.get(e), !n) throw Error(`No transition defined from '${this._currentState}' to '${e}'.`);
3535
- if (n.guard && !n.guard()) throw Error(`Guard rejected transition from '${this._currentState}' to '${e}'.`);
3536
- let r = this._currentState, i = this.exitCallbacks.get(r);
3537
- if (i) for (let e of i) e();
3538
- this.eventBus && this.eventBus.publish({
3539
- type: `state:exit:${r}`,
3540
- payload: {
3541
- from: r,
3542
- to: e
3543
- }
3544
- }), this._currentState = e;
3545
- let a = this.enterCallbacks.get(e);
3546
- if (a) for (let e of a) e();
3547
- this.eventBus && this.eventBus.publish({
3548
- type: `state:enter:${e}`,
3549
- payload: {
3550
- from: r,
3551
- to: e
3552
- }
3553
- });
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
+ };
3554
2024
  }
3555
- }, lt = class extends G {
3556
- name = "stateMachine";
3557
- eventSubscriptions = [];
3558
- stateMachine;
3559
- stateKey;
3560
- constructor() {
3561
- 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
+ };
3562
2039
  }
3563
- get currentState() {
3564
- return this.stateMachine.currentState;
2040
+ cancelAll() {
2041
+ this._delays = [], this._intervals = [];
2042
+ for (let e of this._cooldowns) e.remaining = 0;
2043
+ this._cooldowns = [];
3565
2044
  }
3566
- transition(e) {
3567
- 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));
3568
2051
  }
3569
- processEvent(e, t) {
3570
- 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;
3571
2059
  }
3572
- static create(e) {
3573
- let { initialState: t, stateKey: n, transitions: r, wildcardTransitions: i } = e;
3574
- class a extends lt {
3575
- constructor() {
3576
- super(), this.stateKey = n, this.stateMachine = new Y(t);
3577
- for (let e of r) this.stateMachine.addTransition(e.from, e.to, e.guard);
3578
- if (i) for (let e of i) this.stateMachine.addTransitionFromAny(e.to, e.guard);
3579
- }
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;
3580
2072
  }
3581
- return a;
3582
- }
3583
- }, X = new N("ColliderHandler");
3584
- function ut(e) {
3585
- let { min: t, max: n } = e.getHierarchyBoundingVectors(!0), r = n.subtract(t), i = t.add(n).scale(.5).subtract(e.absolutePosition), a = e.absoluteRotationQuaternion, o = T.Inverse(a), s = new O();
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();
3586
2136
  return i.rotateByQuaternionToRef(o, s), {
3587
2137
  extents: r,
3588
2138
  center: s
3589
2139
  };
3590
2140
  }
3591
- function Z(e, t, n) {
2141
+ function X(e, t, n) {
3592
2142
  let r = e.getScene(), i = { mass: n };
3593
- if (!(e instanceof y) && (t === w.BOX || t === w.SPHERE)) {
3594
- let { extents: n, center: r } = ut(e);
3595
- i.center = r, t === w.BOX ? i.extents = n : i.radius = Math.max(n.x, n.y, n.z) / 2;
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;
3596
2146
  }
3597
- new C(e, t, i, r);
2147
+ new te(e, t, i, r);
3598
2148
  }
3599
- function dt(e, t) {
2149
+ function Xe(e, t) {
3600
2150
  let n = e.getChildMeshes().find((e) => e.metadata?.collider_mesh === !0);
3601
- n instanceof y ? (n.isVisible = !1, Z(n, w.MESH, t)) : Z(e, w.MESH, t);
2151
+ n instanceof v ? (n.isVisible = !1, X(n, S.MESH, t)) : X(e, S.MESH, t);
3602
2152
  }
3603
- function ft(t) {
2153
+ function Ze(t) {
3604
2154
  t.registerPropertyHandler("collider", (t, n, r, i) => {
3605
2155
  let a = n;
3606
- if (X.debug(`Processing collider: ${t.name} -> ${a} (isMesh: ${t instanceof y})`), !r.scene) throw Error("Scene not available for collider handler");
3607
- if (!(t instanceof y) && a === "mesh") {
3608
- X.warn(`Skipping mesh collider for ${t.name}: not a Mesh instance`);
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`);
3609
2159
  return;
3610
2160
  }
3611
2161
  let o = t.metadata?.collider_mass ?? 0;
3612
2162
  switch (a) {
3613
2163
  case "box":
3614
- Z(t, w.BOX, o);
2164
+ X(t, S.BOX, o);
3615
2165
  break;
3616
2166
  case "sphere":
3617
- Z(t, w.SPHERE, o);
2167
+ X(t, S.SPHERE, o);
3618
2168
  break;
3619
2169
  case "mesh":
3620
- dt(t, o);
2170
+ Xe(t, o);
3621
2171
  break;
3622
2172
  case "none":
3623
2173
  t instanceof e && (t.checkCollisions = !1);
3624
2174
  break;
3625
- default: X.warn(`Unknown collider type: ${a}`);
2175
+ default: Y.warn(`Unknown collider type: ${a}`);
3626
2176
  }
3627
2177
  t.metadata?.collider_kinematic && t instanceof e && t.physicsBody && (t.physicsBody.disablePreStep = !1);
3628
2178
  });
3629
2179
  }
3630
2180
  //#endregion
3631
2181
  //#region src/handlers/lod.ts
3632
- var pt = new N("LodHandler");
3633
- function mt(e) {
2182
+ var Qe = new N("LodHandler");
2183
+ function $e(e) {
3634
2184
  return e.split(",").map((e) => parseFloat(e.trim())).filter((e) => !isNaN(e));
3635
2185
  }
3636
- function ht(e) {
2186
+ function et(e) {
3637
2187
  e.registerPropertyHandler("lod_distances", (e, t, n, r) => {
3638
2188
  let i = t;
3639
- if (!(e instanceof y)) return;
3640
- let a = mt(i);
2189
+ if (!(e instanceof v)) return;
2190
+ let a = $e(i);
3641
2191
  if (a.length === 0) {
3642
- pt.warn(`Invalid lod_distances value: ${i}`);
2192
+ Qe.warn(`Invalid lod_distances value: ${i}`);
3643
2193
  return;
3644
2194
  }
3645
2195
  let o = e.getChildMeshes(!0), s = Math.min(a.length, o.length);
@@ -3650,14 +2200,14 @@ function ht(e) {
3650
2200
  }
3651
2201
  //#endregion
3652
2202
  //#region src/handlers/occluder.ts
3653
- function gt(e) {
2203
+ function tt(e) {
3654
2204
  e.registerPropertyHandler("occluder", (e, t, n, r) => {
3655
- t && e instanceof y && (e.isOccluder = !0, e.isVisible = !1);
2205
+ t && e instanceof v && (e.isOccluder = !0, e.isVisible = !1);
3656
2206
  });
3657
2207
  }
3658
2208
  //#endregion
3659
2209
  //#region src/utils/metadata.ts
3660
- function _t(e, t) {
2210
+ function nt(e, t) {
3661
2211
  let n = {}, r = `${t}_`;
3662
2212
  for (let [t, i] of Object.entries(e)) if (t.startsWith(r)) {
3663
2213
  let e = t.slice(r.length);
@@ -3667,14 +2217,14 @@ function _t(e, t) {
3667
2217
  }
3668
2218
  //#endregion
3669
2219
  //#region src/handlers/sound.ts
3670
- var vt = new N("SoundHandler");
3671
- function yt(e) {
2220
+ var rt = new N("SoundHandler");
2221
+ function it(e) {
3672
2222
  e.registerPropertyHandler("sound", (e, t, n, r) => {
3673
2223
  let i = t;
3674
2224
  if (!n.scene) throw Error("Scene not available for sound handler");
3675
- let a = _t(e.metadata, "sound"), o = a.volume ?? 1, s = a.loop ?? !0, c = a.spatial ?? !0, l = a.distance ?? 100, u = a.autoplay ?? !0, d = a.channel ?? "ambient", f = r.managers.audioManager;
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;
3676
2226
  if (!f) {
3677
- vt.warn(`No AudioManager available. Sound for "${e.name}" skipped.`);
2227
+ rt.warn(`No AudioManager available. Sound for "${e.name}" skipped.`);
3678
2228
  return;
3679
2229
  }
3680
2230
  f.createSound(`${e.name}_sound`, i, d, {
@@ -3687,13 +2237,13 @@ function yt(e) {
3687
2237
  }).then((t) => {
3688
2238
  c && t.spatial.attach(e);
3689
2239
  }).catch((t) => {
3690
- vt.error(`Failed to create sound for node "${e.name}": ${t}`);
2240
+ rt.error(`Failed to create sound for node "${e.name}": ${t}`);
3691
2241
  });
3692
2242
  });
3693
2243
  }
3694
2244
  //#endregion
3695
2245
  //#region src/handlers/trigger.ts
3696
- function Q(e, n, r, i, a) {
2246
+ function at(e, n, r, i, a) {
3697
2247
  let o = a === "enter" ? t.OnIntersectionEnterTrigger : t.OnIntersectionExitTrigger, s = `trigger:${a}`;
3698
2248
  e.registerAction(new u({
3699
2249
  trigger: o,
@@ -3708,10 +2258,10 @@ function Q(e, n, r, i, a) {
3708
2258
  });
3709
2259
  }));
3710
2260
  }
3711
- function bt(e, t, n, r) {
3712
- 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");
3713
2263
  }
3714
- function xt(n) {
2264
+ function st(n) {
3715
2265
  n.registerPropertyHandler("trigger", (n, r, i, a) => {
3716
2266
  let o = r, s = i.scene;
3717
2267
  if (!s) throw Error("Scene not available for trigger handler");
@@ -3720,9 +2270,9 @@ function xt(n) {
3720
2270
  n.isVisible = !1, n.checkCollisions = !0;
3721
2271
  let l = n.actionManager ?? new t(s);
3722
2272
  n.actionManager = l;
3723
- 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);
3724
2274
  let u = s.onNewMeshAddedObservable.add((e) => {
3725
- e !== n && !e.metadata?.trigger && bt(l, o, c, e);
2275
+ e !== n && !e.metadata?.trigger && ot(l, o, c, e);
3726
2276
  });
3727
2277
  n.onDisposeObservable.add(() => {
3728
2278
  s.onNewMeshAddedObservable.remove(u);
@@ -3731,7 +2281,7 @@ function xt(n) {
3731
2281
  }
3732
2282
  //#endregion
3733
2283
  //#region src/handlers/visible.ts
3734
- function $(t) {
2284
+ function ct(t) {
3735
2285
  t.registerPropertyHandler("visible", (t, n, r, i) => {
3736
2286
  if (!(t instanceof e)) return;
3737
2287
  let a = !0;
@@ -3740,60 +2290,464 @@ function $(t) {
3740
2290
  }
3741
2291
  //#endregion
3742
2292
  //#region src/handlers/index.ts
3743
- function St(e) {
3744
- 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
+ };
3745
2642
  }
3746
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
3747
2702
  //#region src/sage.ts
3748
- async function Ct(e, t, n = {}) {
2703
+ async function Mt(e, t, n = {}) {
3749
2704
  let r = new P(n.logLevel || "debug"), i = r.getLogger("SAGE");
3750
2705
  i.info(`Initializing SAGE Game Engine v${k}...`), i.debug("Creating rendering engine...");
3751
- let a = await Qe(e, {
2706
+ let a = await He(e, {
3752
2707
  antialias: !0,
3753
2708
  adaptToDeviceRatio: !0,
3754
2709
  ...n.renderOptions
3755
2710
  }, n.largeWorldRendering ?? !1);
3756
2711
  i.debug("Creating physics engine...");
3757
- let o = await $e(), s = et(o);
2712
+ let o = await Ue(n.havokBinary), s = We(o);
3758
2713
  i.debug("Creating event bus...");
3759
2714
  let c = new F(r);
3760
2715
  i.debug("Creating scene engine...");
3761
- let l = new L(e, a, o, r);
2716
+ let l = new Se(e, a, o, r);
3762
2717
  i.debug("Creating managers...");
3763
- let u = new R(c, l, r), d = new Ye(c, e, r), f = new Ee(c, r), p = new Me(c, r, f), m = new He(c, r), h = new We(p, m, r), g = new Oe(a, c, p, d, m, r), _ = null;
3764
- n.debug !== !1 && (i.debug("Creating debug console..."), _ = new he((typeof n.debug == "object" ? n.debug.namespace : void 0) ?? "sage")), i.debug("Creating collider debug manager...");
3765
- let v = new Ge();
3766
- i.debug("Creating raycast helper...");
3767
- let y = new tt(p);
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();
3768
2727
  i.debug("Creating game timer...");
3769
- let b = new nt();
3770
- g.registerFrameCallback((e) => b.tick(e * 1e3));
3771
- let x, S;
3772
- n.audioChannels && n.audioChannels.length > 0 && (i.debug("Creating audio engine..."), x = new I(r), await x.initialize(), i.debug("Creating audio manager..."), S = new Ue(x, r), await S.initialize(n.audioChannels)), i.info(`SAGE Game Engine v${k} initialized successfully.`), i.debug("Loading entities...");
3773
- for (let e of t) p.registerEntityDefinition(e);
3774
- if (i.debug("Registering default input bindings..."), n.bindings) for (let e of n.bindings) f.registerBinding(e);
3775
- let C = new A(e, a, s, c, r, y, b, {
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, {
3776
2733
  sceneEngine: l,
3777
- audioEngine: x
2734
+ audioEngine: y
3778
2735
  }, {
3779
2736
  assetManager: u,
3780
- bindingManager: f,
3781
- entityManager: p,
3782
- gameManager: g,
3783
- inputManager: d,
3784
- levelManager: m,
3785
- saveManager: h,
3786
- audioManager: S
2737
+ gameManager: p,
2738
+ levelManager: d,
2739
+ saveManager: f,
2740
+ audioManager: b
3787
2741
  }, n.largeWorldRendering ?? !1, {
3788
- colliders: v,
3789
- console: _,
2742
+ colliders: _,
2743
+ console: g,
3790
2744
  expose: (e, t) => {
3791
- _?.expose(e, t);
2745
+ g?.expose(e, t);
3792
2746
  }
3793
2747
  });
3794
- return p.$setGameEngine(C), m.$setGameEngine(C), _ && ot(_, C), C;
2748
+ return d.$setGameEngine(x), p.$setGameEngine(x), g && qe(g, x), x;
3795
2749
  }
3796
2750
  //#endregion
3797
- export { R as AssetManager, I as AudioEngine, Ue as AudioManager, Ge as ColliderDebugManager, j as ConsoleBackend, he as DebugConsole, A as GameEngine, je as GameEntity, G as GameEntityBehavior, F as GameEventBus, Ve as GameLevel, nt as GameTimer, ze as Level, st as LogLevels, P as LoggingUtility, M as NullBackend, Be as OutlineManager, tt as RaycastHelper, N as SAGELogger, We as SaveManager, L as SceneEngine, ct as SoundBehavior, Y as StateMachine, lt as StateMachineBehavior, k as VERSION, Fe as applyPostProcessing, z as bindingTypes, _t as collectPrefixedProperties, rt as createEntityProxy, Ct as createGameEngine, Ae as generateId, Re as getCanonicalTransform, V as isGamepadState, _e as isKeyboardState, B as isMouseState, St as registerAllPropertyHandlers, ft as registerColliderHandler, ht as registerLodHandler, gt as registerOccluderHandler, yt as registerSoundHandler, xt as registerTriggerHandler, $ as registerVisibleHandler, Ie as toQuatObject, Le as toQuaternion, K as toVec3Object, q as toVector3, ge as validDeviceTypes };
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 };
3798
2752
 
3799
2753
  //# sourceMappingURL=sage.es.js.map