@skewedaspect/sage 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sage.es.js CHANGED
@@ -1,10 +1,10 @@
1
- var M = Object.defineProperty;
2
- var k = (r, e, t) => e in r ? M(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
1
+ var L = Object.defineProperty;
2
+ var k = (r, e, t) => e in r ? L(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
3
3
  var n = (r, e, t) => k(r, typeof e != "symbol" ? e + "" : e, t);
4
- import { Scene as L, Vector3 as C, FreeCamera as A, HemisphericLight as I, DirectionalLight as B, PointLight as G, SpotLight as V, MeshBuilder as v, PhysicsAggregate as K, Sound as T, LoadAssetContainerAsync as U, ImportMeshAsync as R, NullEngine as z, WebGPUEngine as P, Engine as O, HavokPlugin as H } from "@babylonjs/core";
5
- import W from "@babylonjs/havok";
6
- const b = "0.7.0";
7
- class F {
4
+ import { Scene as A, Vector3 as E, FreeCamera as I, HemisphericLight as B, DirectionalLight as G, PointLight as V, SpotLight as K, MeshBuilder as v, PhysicsAggregate as T, Sound as U, LoadAssetContainerAsync as R, ImportMeshAsync as z, NullEngine as P, WebGPUEngine as H, Engine as W, HavokPlugin as O } from "@babylonjs/core";
5
+ import F from "@babylonjs/havok";
6
+ const m = "0.7.1";
7
+ class N {
8
8
  /**
9
9
  * Creates an instance of SkewedAspectGameEngine.
10
10
  * @param canvas - The game canvas.
@@ -68,14 +68,14 @@ class F {
68
68
  * Starts the game engine.
69
69
  */
70
70
  async start() {
71
- this.started ? this._log.warn("Game engine is already started. Skipping start.") : (this._log.info(`Starting SkewedAspect Game Engine (Version: ${b})...`), 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);
71
+ this.started ? this._log.warn("Game engine is already started. Skipping start.") : (this._log.info(`Starting SkewedAspect Game Engine (Version: ${m})...`), 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);
72
72
  }
73
73
  /**
74
74
  * Stops the game engine.
75
75
  */
76
76
  async stop() {
77
77
  if (this.started) {
78
- this._log.info(`Stopping SkewedAspect Game Engine (Version: ${b})...`);
78
+ this._log.info(`Stopping SkewedAspect Game Engine (Version: ${m})...`);
79
79
  let e = null;
80
80
  if (this._onTeardownHook)
81
81
  try {
@@ -112,7 +112,7 @@ class F {
112
112
  this._log.warn("Game engine is not started. Skipping stop.");
113
113
  }
114
114
  }
115
- class N {
115
+ class J {
116
116
  constructor() {
117
117
  n(this, "timers");
118
118
  this.timers = /* @__PURE__ */ new Map();
@@ -201,7 +201,7 @@ class N {
201
201
  console.warn(`[${e}]: Timer '${t}' does not exist`);
202
202
  }
203
203
  }
204
- class J {
204
+ class Y {
205
205
  trace(e, t, ...s) {
206
206
  }
207
207
  debug(e, t, ...s) {
@@ -218,7 +218,7 @@ class J {
218
218
  }
219
219
  }
220
220
  class u {
221
- constructor(e, t = "none", s = new J()) {
221
+ constructor(e, t = "none", s = new Y()) {
222
222
  n(this, "category");
223
223
  n(this, "backend");
224
224
  n(this, "minLevel");
@@ -273,14 +273,14 @@ class u {
273
273
  }
274
274
  }
275
275
  }
276
- class Y {
276
+ class j {
277
277
  /**
278
278
  * Create a new LoggingUtility.
279
279
  *
280
280
  * @param level - The minimum logging level (defaults to INFO)
281
281
  * @param backend - The logging backend to use (defaults to ConsoleBackend)
282
282
  */
283
- constructor(e = "debug", t = new N()) {
283
+ constructor(e = "debug", t = new J()) {
284
284
  n(this, "backend");
285
285
  n(this, "level");
286
286
  n(this, "loggers");
@@ -326,7 +326,7 @@ class Y {
326
326
  return t;
327
327
  }
328
328
  }
329
- class j {
329
+ class X {
330
330
  /**
331
331
  * Creates a new GameEventBus instance
332
332
  *
@@ -430,22 +430,22 @@ class j {
430
430
  t === 0 ? this._log.debug(`No subscribers found for event: ${e.type}`) : this._log.trace(`Event ${e.type} dispatched to ${t} subscribers`);
431
431
  }
432
432
  }
433
- class X {
433
+ class Z {
434
434
  constructor(e, t, s, i) {
435
435
  n(this, "_canvas");
436
436
  n(this, "_engine");
437
437
  n(this, "_physics");
438
438
  n(this, "_log");
439
- this._canvas = e, this._engine = t, this._physics = s, this._log = (i == null ? void 0 : i.getLogger("SceneEngine")) || new u("SceneEngine");
439
+ this._canvas = e, this._engine = t, this._physics = s, this._log = i.getLogger("SceneEngine");
440
440
  }
441
441
  /**
442
442
  * Creates a new scene with physics enabled
443
443
  * @returns A new Scene instance with physics enabled
444
444
  */
445
445
  createScene() {
446
- return this._log.debug("Creating new scene..."), new L(this._engine);
446
+ return new A(this._engine);
447
447
  }
448
- enablePhysics(e, t = new C(0, -9.8, 0)) {
448
+ enablePhysics(e, t = new E(0, -9.8, 0)) {
449
449
  this._log.debug(
450
450
  `Enabling physics with gravity (${t.x}, ${t.y}, ${t.z})...`
451
451
  ), e.enablePhysics(t, this._physics);
@@ -460,9 +460,8 @@ class X {
460
460
  * @returns A new FreeCamera instance
461
461
  */
462
462
  createFreeCamera(e, t, s, i) {
463
- this._log.debug(`Creating free camera: ${e}`);
464
- const o = new A(e, t, s);
465
- return o.setTarget(C.Zero()), i = i ?? this._canvas, i && o.attachControl(i, !0), o;
463
+ const o = new I(e, t, s);
464
+ return o.setTarget(E.Zero()), i = i ?? this._canvas, i && o.attachControl(i, !0), o;
466
465
  }
467
466
  // Lighting Utilities
468
467
  /**
@@ -474,8 +473,7 @@ class X {
474
473
  * @returns A new HemisphericLight instance
475
474
  */
476
475
  createHemisphericLight(e, t, s, i = 0.7) {
477
- this._log.debug(`Creating hemispheric light: ${e}`);
478
- const o = new I(e, t, s);
476
+ const o = new B(e, t, s);
479
477
  return o.intensity = i, o;
480
478
  }
481
479
  /**
@@ -487,8 +485,7 @@ class X {
487
485
  * @returns A new DirectionalLight instance
488
486
  */
489
487
  createDirectionalLight(e, t, s, i = 1) {
490
- this._log.debug(`Creating directional light: ${e}`);
491
- const o = new B(e, t, s);
488
+ const o = new G(e, t, s);
492
489
  return o.intensity = i, o;
493
490
  }
494
491
  /**
@@ -500,12 +497,11 @@ class X {
500
497
  * @returns A new PointLight instance
501
498
  */
502
499
  createPointLight(e, t, s, i = 1) {
503
- this._log.debug(`Creating point light: ${e}`);
504
- const o = new G(e, t, s);
500
+ const o = new V(e, t, s);
505
501
  return o.intensity = i, o;
506
502
  }
507
503
  /**
508
- * Creates a spot light (flashlight-like lighting)
504
+ * Creates a spotlight (flashlight-like lighting)
509
505
  * @param name - The name for the light
510
506
  * @param position - The position of the light
511
507
  * @param direction - The direction of the light
@@ -516,8 +512,7 @@ class X {
516
512
  * @returns A new SpotLight instance
517
513
  */
518
514
  createSpotLight(e, t, s, i, o, c, a = 1) {
519
- this._log.debug(`Creating spot light: ${e}`);
520
- const h = new V(e, t, s, i, o, c);
515
+ const h = new K(e, t, s, i, o, c);
521
516
  return h.intensity = a, h;
522
517
  }
523
518
  // Mesh Creation Utilities
@@ -529,7 +524,6 @@ class X {
529
524
  * @returns A new sphere Mesh instance
530
525
  */
531
526
  createSphere(e, t = {}, s) {
532
- this._log.debug(`Creating sphere: ${e}`);
533
527
  const i = { diameter: 1, segments: 32 };
534
528
  return v.CreateSphere(e, { ...i, ...t }, s);
535
529
  }
@@ -541,7 +535,6 @@ class X {
541
535
  * @returns A new box Mesh instance
542
536
  */
543
537
  createBox(e, t = {}, s) {
544
- this._log.debug(`Creating box: ${e}`);
545
538
  const i = { size: 1 };
546
539
  return v.CreateBox(e, { ...i, ...t }, s);
547
540
  }
@@ -553,7 +546,6 @@ class X {
553
546
  * @returns A new ground Mesh instance
554
547
  */
555
548
  createGround(e, t = {}, s) {
556
- this._log.debug(`Creating ground: ${e}`);
557
549
  const i = { width: 6, height: 6, subdivisions: 2 };
558
550
  return v.CreateGround(e, { ...i, ...t }, s);
559
551
  }
@@ -565,7 +557,6 @@ class X {
565
557
  * @returns A new cylinder Mesh instance
566
558
  */
567
559
  createCylinder(e, t = {}, s) {
568
- this._log.debug(`Creating cylinder: ${e}`);
569
560
  const i = { height: 2, diameterTop: 1, diameterBottom: 1 };
570
561
  return v.CreateCylinder(e, { ...i, ...t }, s);
571
562
  }
@@ -579,9 +570,8 @@ class X {
579
570
  * @returns A new PhysicsAggregate instance
580
571
  */
581
572
  addPhysics(e, t, s = {}, i) {
582
- this._log.debug(`Adding physics to mesh: ${e.name}`);
583
573
  const o = { mass: 1, restitution: 0.75, friction: 0.5 };
584
- return new K(e, t, { ...o, ...s }, i);
574
+ return new T(e, t, { ...o, ...s }, i);
585
575
  }
586
576
  // Audio Utilities
587
577
  /**
@@ -593,9 +583,8 @@ class X {
593
583
  * @returns A new Sound instance
594
584
  */
595
585
  createSound(e, t, s, i = {}) {
596
- this._log.debug(`Creating sound: ${e}`);
597
586
  const c = { ...{ loop: !1, autoplay: !1, volume: 1, playbackRate: 1 }, ...i };
598
- return new T(
587
+ return new U(
599
588
  e,
600
589
  t,
601
590
  s,
@@ -607,35 +596,34 @@ class X {
607
596
  // Model Loading Utilities
608
597
  /**
609
598
  * Loads a 3D model/asset from a file
610
- * @param rootUrl - The root URL where the file is located
611
599
  * @param sceneFilename - The filename of the scene file
612
600
  * @param scene - The scene to load the model into
613
601
  * @returns Promise that resolves with the loaded AssetContainer
614
602
  */
615
- async loadModel(e, t, s) {
616
- this._log.debug(`Loading model: ${e}${t}`);
603
+ async loadModel(e, t) {
604
+ this._log.debug(`Loading model: ${e}`);
617
605
  try {
618
- const i = await U(`${e}${t}`, s);
619
- return this._log.debug(`Model loaded successfully: ${t}`), i;
620
- } catch (i) {
621
- throw this._log.error(`Failed to load model: ${t}`, i), i;
606
+ const s = await R(`${e}`, t);
607
+ return this._log.debug(`Model loaded successfully: ${e}`), s;
608
+ } catch (s) {
609
+ throw this._log.error(`Failed to load model: ${e}`, s), s;
622
610
  }
623
611
  }
624
612
  /**
625
613
  * Imports meshes from a file
626
614
  * @param meshNames - Array of mesh names to import (empty array imports all)
627
- * @param rootUrl - The root URL where the file is located
628
615
  * @param sceneFilename - The filename of the scene file
629
616
  * @param scene - The scene to import the meshes into
617
+ *
630
618
  * @returns Promise that resolves with the import result
631
619
  */
632
- async importMeshes(e, t, s, i) {
633
- this._log.debug(`Importing meshes from: ${t}${s}`);
620
+ async importMeshes(e, t, s) {
621
+ this._log.debug(`Importing meshes from: ${t}`);
634
622
  try {
635
- const o = await R(`${t}${s}`, i, { meshNames: e });
636
- return this._log.debug(`Meshes imported successfully: ${e.length > 0 ? e.join(", ") : "all"}`), o;
637
- } catch (o) {
638
- throw this._log.error(`Failed to import meshes from: ${s}`, o), o;
623
+ const i = await z(`${t}`, s, { meshNames: e });
624
+ return this._log.debug(`Meshes imported successfully: ${e.length > 0 ? e.join(", ") : "all"}`), i;
625
+ } catch (i) {
626
+ throw this._log.error(`Failed to import meshes from: ${t}`, i), i;
639
627
  }
640
628
  }
641
629
  /**
@@ -645,12 +633,12 @@ class X {
645
633
  return this._log.info("Tearing down SceneEngine"), this._log.info("SceneEngine torn down successfully"), Promise.resolve();
646
634
  }
647
635
  }
648
- const Z = [
636
+ const q = [
649
637
  "trigger",
650
638
  "toggle",
651
639
  "value"
652
640
  ];
653
- class q {
641
+ class Q {
654
642
  //------------------------------------------------------------------------------------------------------------------
655
643
  /**
656
644
  * Create a new trigger binding
@@ -751,7 +739,7 @@ class q {
751
739
  };
752
740
  }
753
741
  }
754
- class Q {
742
+ class ee {
755
743
  //------------------------------------------------------------------------------------------------------------------
756
744
  /**
757
745
  * Create a new toggle binding
@@ -880,7 +868,7 @@ class Q {
880
868
  };
881
869
  }
882
870
  }
883
- class ee {
871
+ class te {
884
872
  //------------------------------------------------------------------------------------------------------------------
885
873
  /**
886
874
  * Create a new value binding
@@ -1196,7 +1184,7 @@ class x {
1196
1184
  };
1197
1185
  }
1198
1186
  }
1199
- class te {
1187
+ class se {
1200
1188
  /**
1201
1189
  * Creates an instance of BindingManager.
1202
1190
  *
@@ -1277,7 +1265,7 @@ class te {
1277
1265
  const { deviceID: s, ...i } = e.input;
1278
1266
  switch (e.type) {
1279
1267
  case "trigger":
1280
- return new q(
1268
+ return new Q(
1281
1269
  t,
1282
1270
  s,
1283
1271
  this._createInputSourceFromDefinition(i),
@@ -1287,7 +1275,7 @@ class te {
1287
1275
  }
1288
1276
  );
1289
1277
  case "toggle":
1290
- return new Q(
1278
+ return new ee(
1291
1279
  t,
1292
1280
  s,
1293
1281
  this._createInputSourceFromDefinition(i),
@@ -1297,7 +1285,7 @@ class te {
1297
1285
  }
1298
1286
  );
1299
1287
  case "value":
1300
- return new ee(
1288
+ return new te(
1301
1289
  t,
1302
1290
  s,
1303
1291
  this._createInputSourceFromDefinition(i),
@@ -1464,7 +1452,7 @@ class te {
1464
1452
  */
1465
1453
  $registerBinding(e) {
1466
1454
  var t;
1467
- if (!Z.includes(e.type))
1455
+ if (!q.includes(e.type))
1468
1456
  throw new Error(`Invalid binding type: ${e.type}`);
1469
1457
  e.context && !this._contexts.has(e.context) && this.registerContext(e.context), this._bindings.has(e.deviceID) || this._bindings.set(e.deviceID, []), (t = this._bindings.get(e.deviceID)) == null || t.push(e), this._log.debug(`Registered ${e.type} binding for "${e.action.name}" in context "${e.context || null}"`);
1470
1458
  }
@@ -1570,10 +1558,10 @@ class te {
1570
1558
  function w() {
1571
1559
  return typeof window < "u" && typeof window.document < "u";
1572
1560
  }
1573
- function E() {
1561
+ function C() {
1574
1562
  return w() && !!window.navigator.gpu;
1575
1563
  }
1576
- class se {
1564
+ class ie {
1577
1565
  //------------------------------------------------------------------------------------------------------------------
1578
1566
  constructor(e, t, s, i, o) {
1579
1567
  n(this, "_engine");
@@ -1613,7 +1601,7 @@ class se {
1613
1601
  this._log.info("Tearing down GameManager"), this.started && await this.stop(), w() && window.removeEventListener("resize", this._boundResizeHandler), this._log.info("GameManager torn down successfully");
1614
1602
  }
1615
1603
  }
1616
- class fe {
1604
+ class ye {
1617
1605
  constructor() {
1618
1606
  n(this, "entity", null);
1619
1607
  }
@@ -1633,7 +1621,7 @@ class fe {
1633
1621
  this.entity = e;
1634
1622
  }
1635
1623
  }
1636
- class ie {
1624
+ class ne {
1637
1625
  /**
1638
1626
  * Creates an instance of GameEntityBase.
1639
1627
  * @param type - The type of the entity.
@@ -1729,7 +1717,7 @@ class ie {
1729
1717
  }
1730
1718
  }
1731
1719
  }
1732
- class ne {
1720
+ class oe {
1733
1721
  /**
1734
1722
  * Creates an instance of EntityManager.
1735
1723
  * @param eventBus - The event bus for the entity manager.
@@ -1815,7 +1803,7 @@ class ne {
1815
1803
  const a = await s.onBeforeCreate(i);
1816
1804
  a !== void 0 && (i = a);
1817
1805
  }
1818
- const o = new ie(
1806
+ const o = new ne(
1819
1807
  s.type,
1820
1808
  this.eventBus,
1821
1809
  i,
@@ -1884,7 +1872,81 @@ class ne {
1884
1872
  this.entityDefinitions.clear(), this._log.info("EntityManager torn down successfully");
1885
1873
  }
1886
1874
  }
1887
- class oe {
1875
+ class D {
1876
+ //------------------------------------------------------------------------------------------------------------------
1877
+ constructor(e) {
1878
+ n(this, "name");
1879
+ n(this, "_log");
1880
+ n(this, "_sceneEngine");
1881
+ n(this, "_eventBus");
1882
+ n(this, "_scene", null);
1883
+ this.name = e, this._log = new u(`Level:${e}`, "info");
1884
+ }
1885
+ /**
1886
+ * The current scene for this level (null if not loaded)
1887
+ */
1888
+ get scene() {
1889
+ return this._scene;
1890
+ }
1891
+ /**
1892
+ * Whether this level has been loaded
1893
+ */
1894
+ get isLoaded() {
1895
+ return this._scene !== null;
1896
+ }
1897
+ //------------------------------------------------------------------------------------------------------------------
1898
+ /**
1899
+ * Emit a progress event during loading
1900
+ */
1901
+ $emitProgress(e, t) {
1902
+ if (!this._eventBus)
1903
+ throw new Error("Event bus is not initialized. Call loadScene() first.");
1904
+ this._eventBus.publish({
1905
+ type: "level:progress",
1906
+ levelName: this.name,
1907
+ progress: e,
1908
+ message: t
1909
+ });
1910
+ }
1911
+ //------------------------------------------------------------------------------------------------------------------
1912
+ /**
1913
+ * Load and create the scene for this level.
1914
+ * Progress events will be emitted during loading.
1915
+ *
1916
+ * @param eventBus - The game event bus for publishing events
1917
+ * @param sceneEngine - The scene engine used to create the scene
1918
+ *
1919
+ * @returns Promise that resolves to the loaded scene
1920
+ */
1921
+ async loadScene(e, t) {
1922
+ if (this._scene)
1923
+ return this._log.warn(`Level ${this.name} is already loaded`), this._scene;
1924
+ this._eventBus = e, this._sceneEngine = t, this._log.info(`Loading level: ${this.name}`), this._log.time(`level-${this.name}-load`);
1925
+ try {
1926
+ return this.$emitProgress(0, "Starting level load..."), this._scene = await this.buildScene(t), this.$emitProgress(100, "Level loaded successfully"), this._eventBus.publish({
1927
+ type: "level:complete",
1928
+ levelName: this.name,
1929
+ message: "Level loaded successfully"
1930
+ }), this._log.timeEnd(`level-${this.name}-load`), this._log.info(`Level ${this.name} loaded successfully`), this._scene;
1931
+ } catch (s) {
1932
+ throw this._log.error(`Failed to load level ${this.name}:`, s), this._eventBus.publish({
1933
+ type: "level:error",
1934
+ levelName: this.name,
1935
+ message: "Failed to load level",
1936
+ error: s
1937
+ }), s;
1938
+ }
1939
+ }
1940
+ //------------------------------------------------------------------------------------------------------------------
1941
+ /**
1942
+ * Dispose of this level's resources
1943
+ */
1944
+ dispose() {
1945
+ this._scene && (this._log.info(`Disposing level: ${this.name}`), this._scene.dispose(), this._scene = null);
1946
+ }
1947
+ }
1948
+ class ae {
1949
+ //------------------------------------------------------------------------------------------------------------------
1888
1950
  constructor(e, t, s) {
1889
1951
  n(this, "_eventBus");
1890
1952
  n(this, "_sceneEngine");
@@ -1897,6 +1959,14 @@ class oe {
1897
1959
  i.payload && this._handleLevelEvent(i.payload);
1898
1960
  }), this._log.info("LevelManager initialized");
1899
1961
  }
1962
+ //------------------------------------------------------------------------------------------------------------------
1963
+ /**
1964
+ * Gets the currently active level
1965
+ */
1966
+ get currentLevel() {
1967
+ return this._currentLevel;
1968
+ }
1969
+ //------------------------------------------------------------------------------------------------------------------
1900
1970
  /**
1901
1971
  * Handles level events from the event bus
1902
1972
  */
@@ -1913,36 +1983,51 @@ class oe {
1913
1983
  break;
1914
1984
  }
1915
1985
  }
1986
+ //------------------------------------------------------------------------------------------------------------------
1987
+ /**
1988
+ * Gets a loaded level by name
1989
+ */
1990
+ getLevel(e) {
1991
+ return this._registeredLevels.get(e) || null;
1992
+ }
1916
1993
  /**
1917
1994
  * Registers a level class that can be instantiated later
1918
- * @param name - The name to register the level under
1919
1995
  * @param level - The level class instance
1920
1996
  */
1921
- registerLevel(e, t) {
1922
- this._registeredLevels.has(e) && this._log.warn(`Level '${e}' is already registered. Overwriting.`), this._registeredLevels.set(e, t), this._log.info(`Registered level: ${e}`);
1997
+ registerLevel(e) {
1998
+ this._registeredLevels.has(e.name) && this._log.warn(`Level '${e.name}' is already registered. Overwriting.`), this._registeredLevels.set(e.name, e), this._log.info(`Registered level: ${e.name}`);
1923
1999
  }
1924
2000
  /**
1925
- * Loads and activates a level by name
1926
- * @param levelName - The name of the level to load
2001
+ * Loads a level. If a name is passed, the level must already be registered. If a `Level` instance is passed, it
2002
+ * will be registered automatically.
2003
+ *
2004
+ * @param levelOrName - The name of the level to load, or a Level instance.
2005
+ *
1927
2006
  * @returns Promise that resolves when the level is loaded
1928
2007
  */
1929
2008
  async loadLevel(e) {
1930
- const t = this._registeredLevels.get(e);
1931
- if (!t)
2009
+ let t;
2010
+ if (e instanceof D)
2011
+ this.registerLevel(e), t = e;
2012
+ else if (t = this.getLevel(e), !t)
1932
2013
  throw new Error(`Level '${e}' is not registered.`);
1933
- t.isLoaded || (this._log.debug(`Loading level: ${e}`), await t.loadScene(this._eventBus, this._sceneEngine)), this._currentLevel = t, this._log.info(`Activated level: ${e}`);
1934
- }
1935
- /**
1936
- * Gets the currently active level
1937
- */
1938
- get currentLevel() {
1939
- return this._currentLevel;
2014
+ t.isLoaded || (this._log.debug(`Loading level: ${t.name}`), await t.loadScene(this._eventBus, this._sceneEngine));
1940
2015
  }
1941
2016
  /**
1942
- * Gets a loaded level by name
2017
+ * Activates a level, loading it if necessary. If a level name is provided, it must already be registered.
2018
+ * If a `Level` instance is provided, it will be registered automatically.
2019
+ *
2020
+ * @param levelOrName - The name of the level to activate, or a Level instance.
2021
+ *
2022
+ * @returns Promise that resolves when the level is activated.
1943
2023
  */
1944
- getLevel(e) {
1945
- return this._registeredLevels.get(e) || null;
2024
+ async activateLevel(e) {
2025
+ let t;
2026
+ if (e instanceof D)
2027
+ this.registerLevel(e), t = e;
2028
+ else if (t = this.getLevel(e), !t)
2029
+ throw new Error(`Level '${e}' is not registered.`);
2030
+ t.isLoaded || await this.loadLevel(t), this._currentLevel = t, this._log.info(`Activated level: ${t.name}`);
1946
2031
  }
1947
2032
  /**
1948
2033
  * Unloads a level and disposes its resources
@@ -1964,10 +2049,10 @@ class oe {
1964
2049
  async $teardown() {
1965
2050
  for (const e of this._registeredLevels.values())
1966
2051
  e.dispose();
1967
- return this._registeredLevels.clear(), this._currentLevel = null, Promise.resolve();
2052
+ this._registeredLevels.clear(), this._currentLevel = null;
1968
2053
  }
1969
2054
  }
1970
- class ae {
2055
+ class re {
1971
2056
  //------------------------------------------------------------------------------------------------------------------
1972
2057
  /**
1973
2058
  * Create a new KeyboardResourceAccess
@@ -2078,7 +2163,7 @@ class ae {
2078
2163
  this._onInputChanged && this._onInputChanged(this._keyboardDevice, e);
2079
2164
  }
2080
2165
  }
2081
- class re {
2166
+ class ce {
2082
2167
  //------------------------------------------------------------------------------------------------------------------
2083
2168
  /**
2084
2169
  * Create a new MouseResourceAccess
@@ -2247,7 +2332,7 @@ class re {
2247
2332
  this._onInputChanged && this._onInputChanged(this._mouseDevice, e);
2248
2333
  }
2249
2334
  }
2250
- class ce {
2335
+ class he {
2251
2336
  //------------------------------------------------------------------------------------------------------------------
2252
2337
  /**
2253
2338
  * Create a new GamepadResourceAccess
@@ -2454,7 +2539,7 @@ class ce {
2454
2539
  this._onInputChanged && this._onInputChanged(e, t);
2455
2540
  }
2456
2541
  }
2457
- class he {
2542
+ class le {
2458
2543
  //------------------------------------------------------------------------------------------------------------------
2459
2544
  /**
2460
2545
  * Create a new UserInputManager
@@ -2470,7 +2555,7 @@ class he {
2470
2555
  n(this, "_gamepadRA");
2471
2556
  /** Logger instance */
2472
2557
  n(this, "_log");
2473
- this._eventBus = e, this._log = (s == null ? void 0 : s.getLogger("UserInputManager")) || new u("UserInputManager"), this._log.info("Initializing UserInputManager"), this._log.debug("Initializing input resource access classes"), this._keyboardRA = new ae(), this._mouseRA = new re(t), this._gamepadRA = new ce(), 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");
2558
+ this._eventBus = e, this._log = (s == null ? void 0 : s.getLogger("UserInputManager")) || new u("UserInputManager"), this._log.info("Initializing UserInputManager"), this._log.debug("Initializing input resource access classes"), this._keyboardRA = new re(), this._mouseRA = new ce(t), this._gamepadRA = new he(), 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");
2474
2559
  }
2475
2560
  //------------------------------------------------------------------------------------------------------------------
2476
2561
  // Private methods
@@ -2570,24 +2655,24 @@ class he {
2570
2655
  this._gamepadRA.pollGamepads();
2571
2656
  }
2572
2657
  }
2573
- async function D(r, e) {
2574
- const t = new P(r, e);
2658
+ async function M(r, e) {
2659
+ const t = new H(r, e);
2575
2660
  return await t.initAsync(), t;
2576
2661
  }
2577
- function m(r, e) {
2578
- return new O(r, e.antialias, e.options, e.adaptToDeviceRatio);
2662
+ function b(r, e) {
2663
+ return new W(r, e.antialias, e.options, e.adaptToDeviceRatio);
2579
2664
  }
2580
- function le(r) {
2581
- return new z(r);
2665
+ function de(r) {
2666
+ return new P(r);
2582
2667
  }
2583
- async function de(r, e) {
2668
+ async function ue(r, e) {
2584
2669
  if (r === null)
2585
- return console.debug("Using Null Engine"), le(e);
2670
+ return console.debug("Using Null Engine"), de(e);
2586
2671
  const t = e.engine || "auto";
2587
2672
  if (t === "webgpu")
2588
- if (E())
2673
+ if (C())
2589
2674
  try {
2590
- return console.debug("Using forced WebGPU engine"), await D(r, e);
2675
+ return console.debug("Using forced WebGPU engine"), await M(r, e);
2591
2676
  } catch (s) {
2592
2677
  throw console.error("Forced WebGPU initialization failed:", s), new Error(
2593
2678
  "Forced WebGPU failed to initialize. If WebGPU is required, check browser compatibility."
@@ -2596,22 +2681,22 @@ async function de(r, e) {
2596
2681
  else
2597
2682
  throw new Error("WebGPU was forced but is not available in this browser.");
2598
2683
  if (t === "webgl")
2599
- return console.debug("Using forced WebGL engine"), m(r, e);
2600
- if (E())
2684
+ return console.debug("Using forced WebGL engine"), b(r, e);
2685
+ if (C())
2601
2686
  try {
2602
- return console.debug("Using WebGPU"), D(r, e).catch((s) => (console.warn("WebGPU initialization failed, falling back to WebGL:", s), m(r, e)));
2687
+ return console.debug("Using WebGPU"), M(r, e).catch((s) => (console.warn("WebGPU initialization failed, falling back to WebGL:", s), b(r, e)));
2603
2688
  } catch (s) {
2604
2689
  console.warn("WebGPU initialization failed, falling back to WebGL:", s);
2605
2690
  }
2606
2691
  else
2607
2692
  console.warn("WebGPU not supported, falling back to WebGL.");
2608
- return console.debug("Using WebGL"), m(r, e);
2693
+ return console.debug("Using WebGL"), b(r, e);
2609
2694
  }
2610
- async function ue() {
2611
- const r = await W();
2612
- return new H(!0, r);
2695
+ async function ge() {
2696
+ const r = await F();
2697
+ return new O(!0, r);
2613
2698
  }
2614
- const ye = ["keyboard", "mouse", "gamepad"], ve = [
2699
+ const ve = ["keyboard", "mouse", "gamepad"], me = [
2615
2700
  "trace",
2616
2701
  "debug",
2617
2702
  "info",
@@ -2619,104 +2704,25 @@ const ye = ["keyboard", "mouse", "gamepad"], ve = [
2619
2704
  "error",
2620
2705
  "none"
2621
2706
  ];
2622
- class be {
2623
- //------------------------------------------------------------------------------------------------------------------
2624
- constructor(e) {
2625
- n(this, "_name");
2626
- n(this, "_sceneEngine");
2627
- n(this, "_eventBus");
2628
- n(this, "_scene", null);
2629
- n(this, "_log");
2630
- this._name = e, this._log = new u(`Level:${e}`, "info");
2631
- }
2632
- /**
2633
- * The name of this level
2634
- */
2635
- get name() {
2636
- return this._name;
2637
- }
2638
- /**
2639
- * The current scene for this level (null if not loaded)
2640
- */
2641
- get scene() {
2642
- return this._scene;
2643
- }
2644
- /**
2645
- * Whether this level has been loaded
2646
- */
2647
- get isLoaded() {
2648
- return this._scene !== null;
2649
- }
2650
- //------------------------------------------------------------------------------------------------------------------
2651
- /**
2652
- * Emit a progress event during loading
2653
- */
2654
- _emitProgress(e, t) {
2655
- if (!this._eventBus)
2656
- throw new Error("Event bus is not initialized. Call loadScene() first.");
2657
- this._eventBus.publish({
2658
- type: "level:progress",
2659
- levelName: this._name,
2660
- progress: e,
2661
- message: t
2662
- });
2663
- }
2664
- //------------------------------------------------------------------------------------------------------------------
2665
- /**
2666
- * Load and create the scene for this level.
2667
- * Progress events will be emitted during loading.
2668
- *
2669
- * @param eventBus - The game event bus for publishing events
2670
- * @param sceneEngine - The scene engine used to create the scene
2671
- *
2672
- * @returns Promise that resolves to the loaded scene
2673
- */
2674
- async loadScene(e, t) {
2675
- if (this._scene)
2676
- return this._log.warn(`Level ${this._name} is already loaded`), this._scene;
2677
- this._eventBus = e, this._sceneEngine = t, this._log.info(`Loading level: ${this._name}`), this._log.time(`level-${this._name}-load`);
2678
- try {
2679
- return this._emitProgress(0, "Starting level load..."), this._scene = await this.buildScene(), this._emitProgress(100, "Level loaded successfully"), this._eventBus.publish({
2680
- type: "level:complete",
2681
- levelName: this._name,
2682
- message: "Level loaded successfully"
2683
- }), this._log.timeEnd(`level-${this._name}-load`), this._log.info(`Level ${this._name} loaded successfully`), this._scene;
2684
- } catch (s) {
2685
- throw this._log.error(`Failed to load level ${this._name}:`, s), this._eventBus.publish({
2686
- type: "level:error",
2687
- levelName: this._name,
2688
- message: "Failed to load level",
2689
- error: s
2690
- }), s;
2691
- }
2692
- }
2693
- //------------------------------------------------------------------------------------------------------------------
2694
- /**
2695
- * Dispose of this level's resources
2696
- */
2697
- dispose() {
2698
- this._scene && (this._log.info(`Disposing level: ${this._name}`), this._scene.dispose(), this._scene = null);
2699
- }
2700
- }
2701
- async function me(r, e, t = {}) {
2702
- const s = new Y(t.logLevel || "debug"), i = s.getLogger("SAGE");
2703
- i.info(`Initializing SAGE Game Engine v${b}...`), i.debug("Creating rendering engine...");
2704
- const o = await de(r, t.renderOptions || {});
2707
+ async function be(r, e, t = {}) {
2708
+ const s = new j(t.logLevel || "debug"), i = s.getLogger("SAGE");
2709
+ i.info(`Initializing SAGE Game Engine v${m}...`), i.debug("Creating rendering engine...");
2710
+ const o = await ue(r, t.renderOptions || {});
2705
2711
  i.debug("Creating physics engine...");
2706
- const c = await ue();
2712
+ const c = await ge();
2707
2713
  i.debug("Creating event bus...");
2708
- const a = new j(s);
2714
+ const a = new X(s);
2709
2715
  i.debug("Creating scene engine...");
2710
- const h = new X(r, o, c, s);
2716
+ const h = new Z(r, o, c, s);
2711
2717
  i.debug("Creating managers...");
2712
- const l = new he(a, r, s), _ = new te(a, s), d = new ne(a, s, _), f = new oe(a, h, s), p = new se(o, d, l, f, s);
2713
- i.info(`SAGE Game Engine v${b} initialized successfully.`), i.debug("Loading entities...");
2718
+ const l = new le(a, r, s), _ = new se(a, s), d = new oe(a, s, _), f = new ae(a, h, s), p = new ie(o, d, l, f, s);
2719
+ i.info(`SAGE Game Engine v${m} initialized successfully.`), i.debug("Loading entities...");
2714
2720
  for (const g of e)
2715
2721
  d.registerEntityDefinition(g);
2716
2722
  if (i.debug("Registering default input bindings..."), t.bindings)
2717
2723
  for (const g of t.bindings)
2718
2724
  _.registerBinding(g);
2719
- return new F(
2725
+ return new N(
2720
2726
  r,
2721
2727
  o,
2722
2728
  c,
@@ -2737,19 +2743,20 @@ async function me(r, e, t = {}) {
2737
2743
  );
2738
2744
  }
2739
2745
  export {
2740
- N as ConsoleBackend,
2741
- ie as GameEntity,
2742
- fe as GameEntityBehavior,
2743
- j as GameEventBus,
2744
- be as Level,
2745
- ve as LogLevels,
2746
- Y as LoggingUtility,
2747
- J as NullBackend,
2746
+ J as ConsoleBackend,
2747
+ ne as GameEntity,
2748
+ ye as GameEntityBehavior,
2749
+ X as GameEventBus,
2750
+ D as Level,
2751
+ me as LogLevels,
2752
+ j as LoggingUtility,
2753
+ Y as NullBackend,
2748
2754
  u as SAGELogger,
2749
- F as SkewedAspectGameEngine,
2750
- b as VERSION,
2751
- Z as bindingTypes,
2752
- me as createGameEngine,
2753
- ye as validDeviceTypes
2755
+ Z as SceneEngine,
2756
+ N as SkewedAspectGameEngine,
2757
+ m as VERSION,
2758
+ q as bindingTypes,
2759
+ be as createGameEngine,
2760
+ ve as validDeviceTypes
2754
2761
  };
2755
2762
  //# sourceMappingURL=sage.es.js.map