@zylem/game-lib 0.3.15 → 0.3.17

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 (119) hide show
  1. package/README.md +38 -13
  2. package/dist/.vite/manifest.json +665 -2
  3. package/dist/actions.d.ts +4 -0
  4. package/dist/actions.js +10 -0
  5. package/dist/behaviors.d.ts +3 -0
  6. package/dist/behaviors.js +8 -0
  7. package/dist/camera.d.ts +3 -0
  8. package/dist/camera.js +6 -0
  9. package/dist/core.d.ts +5 -0
  10. package/dist/core.js +11 -0
  11. package/dist/entities.d.ts +8 -0
  12. package/dist/entities.js +19 -0
  13. package/dist/lib/actions/behaviors/actions.js +35 -0
  14. package/dist/lib/actions/behaviors/boundaries/boundary.d.ts +1 -1
  15. package/dist/lib/actions/behaviors/boundaries/boundary.js +40 -0
  16. package/dist/lib/actions/behaviors/ricochet/ricochet-2d-collision.js +100 -0
  17. package/dist/lib/actions/behaviors/ricochet/ricochet-2d-in-bounds.js +37 -0
  18. package/dist/lib/actions/behaviors/ricochet/ricochet.d.ts +2 -0
  19. package/dist/lib/actions/behaviors/ricochet/ricochet.js +6 -0
  20. package/dist/lib/actions/capabilities/moveable.js +108 -0
  21. package/dist/lib/actions/capabilities/rotatable.js +82 -0
  22. package/dist/lib/actions/capabilities/transformable.js +9 -0
  23. package/dist/lib/actions/global-change.js +40 -0
  24. package/dist/lib/camera/camera.js +19 -0
  25. package/dist/lib/camera/fixed-2d.js +30 -0
  26. package/dist/lib/camera/perspective.js +10 -0
  27. package/dist/lib/camera/third-person.js +42 -0
  28. package/dist/lib/camera/zylem-camera.js +145 -0
  29. package/dist/lib/collision/collision-builder.js +46 -0
  30. package/dist/lib/collision/collision-delegate.js +6 -0
  31. package/dist/lib/collision/utils.js +24 -0
  32. package/dist/lib/collision/world.js +77 -0
  33. package/dist/lib/core/base-node-life-cycle.d.ts +14 -0
  34. package/dist/lib/core/base-node.d.ts +6 -2
  35. package/dist/lib/core/base-node.js +62 -0
  36. package/dist/lib/core/entity-asset-loader.js +57 -0
  37. package/dist/lib/core/lazy-loader.d.ts +2 -2
  38. package/dist/lib/core/lifecycle-base.js +20 -0
  39. package/dist/lib/core/preset-shader.js +30 -0
  40. package/dist/lib/core/three-addons/Timer.js +103 -0
  41. package/dist/lib/core/utility/nodes.d.ts +11 -0
  42. package/dist/lib/core/utility/nodes.js +27 -0
  43. package/dist/lib/core/utility/strings.d.ts +2 -0
  44. package/dist/lib/core/utility/strings.js +14 -0
  45. package/dist/lib/core/{utility.d.ts → utility/vector.d.ts} +0 -2
  46. package/dist/lib/core/utility/vector.js +8 -0
  47. package/dist/lib/core/vessel.d.ts +3 -1
  48. package/dist/lib/core/vessel.js +27 -0
  49. package/dist/lib/debug/console/console-state.js +11 -0
  50. package/dist/lib/debug/debug-state.js +40 -0
  51. package/dist/lib/device/aspect-ratio.d.ts +37 -0
  52. package/dist/lib/device/aspect-ratio.js +44 -0
  53. package/dist/lib/entities/actor.js +125 -0
  54. package/dist/lib/entities/box.js +68 -0
  55. package/dist/lib/entities/builder.js +79 -0
  56. package/dist/lib/entities/create.js +31 -0
  57. package/dist/lib/entities/delegates/animation.js +58 -0
  58. package/dist/lib/entities/delegates/debug.js +72 -0
  59. package/dist/lib/entities/delegates/loader.js +19 -0
  60. package/dist/lib/entities/destroy.js +15 -0
  61. package/dist/lib/entities/entity.d.ts +3 -1
  62. package/dist/lib/entities/entity.js +120 -0
  63. package/dist/lib/entities/plane.js +81 -0
  64. package/dist/lib/entities/rect.js +160 -0
  65. package/dist/lib/entities/sphere.js +68 -0
  66. package/dist/lib/entities/sprite.js +118 -0
  67. package/dist/lib/entities/text.js +111 -0
  68. package/dist/lib/entities/zone.js +103 -0
  69. package/dist/lib/game/game-blueprint.d.ts +44 -0
  70. package/dist/lib/game/game-canvas.d.ts +34 -0
  71. package/dist/lib/game/game-canvas.js +57 -0
  72. package/dist/lib/game/game-config.d.ts +47 -0
  73. package/dist/lib/game/game-config.js +53 -0
  74. package/dist/lib/game/game-default.d.ts +18 -0
  75. package/dist/lib/game/game-default.js +24 -0
  76. package/dist/lib/game/game-state.js +17 -0
  77. package/dist/lib/game/game.d.ts +2 -5
  78. package/dist/lib/game/game.js +133 -0
  79. package/dist/lib/game/zylem-game.d.ts +12 -1
  80. package/dist/lib/game/zylem-game.js +133 -0
  81. package/dist/lib/graphics/geometries/XZPlaneGeometry.js +34 -0
  82. package/dist/lib/graphics/material.d.ts +1 -1
  83. package/dist/lib/graphics/material.js +64 -0
  84. package/dist/lib/graphics/mesh.js +14 -0
  85. package/dist/lib/graphics/render-pass.js +56 -0
  86. package/dist/lib/graphics/shaders/fragment/debug.glsl.js +23 -0
  87. package/dist/lib/graphics/shaders/fragment/fire.glsl.js +52 -0
  88. package/dist/lib/graphics/shaders/fragment/standard.glsl.js +11 -0
  89. package/dist/lib/graphics/shaders/fragment/stars.glsl.js +44 -0
  90. package/dist/lib/graphics/shaders/vertex/debug.glsl.js +15 -0
  91. package/dist/lib/graphics/shaders/vertex/object-shader.glsl.js +11 -0
  92. package/dist/lib/graphics/shaders/vertex/standard.glsl.js +9 -0
  93. package/dist/lib/graphics/zylem-scene.d.ts +7 -7
  94. package/dist/lib/graphics/zylem-scene.js +75 -0
  95. package/dist/lib/input/gamepad-provider.js +58 -0
  96. package/dist/lib/input/input-manager.js +70 -0
  97. package/dist/lib/input/keyboard-provider.js +120 -0
  98. package/dist/lib/stage/debug-entity-cursor.js +53 -0
  99. package/dist/lib/stage/entity-spawner.js +27 -0
  100. package/dist/lib/stage/stage-blueprint.d.ts +44 -0
  101. package/dist/lib/stage/stage-blueprint.js +56 -0
  102. package/dist/lib/stage/stage-debug-delegate.js +100 -0
  103. package/dist/lib/stage/stage-default.d.ts +9 -0
  104. package/dist/lib/stage/stage-default.js +42 -0
  105. package/dist/lib/stage/stage-state.js +36 -0
  106. package/dist/lib/stage/stage.d.ts +2 -2
  107. package/dist/lib/stage/stage.js +60 -0
  108. package/dist/lib/stage/zylem-stage.d.ts +4 -3
  109. package/dist/lib/stage/zylem-stage.js +268 -0
  110. package/dist/lib/systems/transformable.system.js +43 -0
  111. package/dist/main.d.ts +6 -15
  112. package/dist/main.js +56 -45933
  113. package/dist/stage.d.ts +6 -0
  114. package/dist/stage.js +22 -0
  115. package/dist/tests/stage/stage-blueprint.spec.d.ts +1 -0
  116. package/package.json +35 -1
  117. package/dist/lib/actions/behaviors/index.d.ts +0 -1
  118. package/dist/lib/core/game-canvas.d.ts +0 -4
  119. package/dist/main.cjs +0 -4023
@@ -0,0 +1,70 @@
1
+ import { KeyboardProvider as s } from "./keyboard-provider.js";
2
+ import { GamepadProvider as r } from "./gamepad-provider.js";
3
+ class B {
4
+ inputMap = /* @__PURE__ */ new Map();
5
+ currentInputs = {};
6
+ previousInputs = {};
7
+ constructor(t) {
8
+ t?.p1?.key ? this.addInputProvider(1, new s(t.p1.key, { includeDefaultBase: !1 })) : this.addInputProvider(1, new s()), this.addInputProvider(1, new r(0)), t?.p2?.key && this.addInputProvider(2, new s(t.p2.key, { includeDefaultBase: !1 })), this.addInputProvider(2, new r(1)), t?.p3?.key && this.addInputProvider(3, new s(t.p3.key, { includeDefaultBase: !1 })), this.addInputProvider(3, new r(2)), t?.p4?.key && this.addInputProvider(4, new s(t.p4.key, { includeDefaultBase: !1 })), this.addInputProvider(4, new r(3)), t?.p5?.key && this.addInputProvider(5, new s(t.p5.key, { includeDefaultBase: !1 })), this.addInputProvider(5, new r(4)), t?.p6?.key && this.addInputProvider(6, new s(t.p6.key, { includeDefaultBase: !1 })), this.addInputProvider(6, new r(5)), t?.p7?.key && this.addInputProvider(7, new s(t.p7.key, { includeDefaultBase: !1 })), this.addInputProvider(7, new r(6)), t?.p8?.key && this.addInputProvider(8, new s(t.p8.key, { includeDefaultBase: !1 })), this.addInputProvider(8, new r(7));
9
+ }
10
+ addInputProvider(t, e) {
11
+ this.inputMap.has(t) || this.inputMap.set(t, []), this.inputMap.get(t)?.push(e);
12
+ }
13
+ getInputs(t) {
14
+ const e = {};
15
+ return this.inputMap.forEach((i, n) => {
16
+ const u = `p${n}`, d = i.reduce((a, o) => {
17
+ const p = o.getInput(t);
18
+ return this.mergeInputs(a, p);
19
+ }, {});
20
+ e[u] = {
21
+ playerNumber: n,
22
+ ...d
23
+ };
24
+ }), e;
25
+ }
26
+ mergeButtonState(t, e) {
27
+ return {
28
+ pressed: t?.pressed || e?.pressed || !1,
29
+ released: t?.released || e?.released || !1,
30
+ held: (t?.held || 0) + (e?.held || 0)
31
+ };
32
+ }
33
+ mergeAnalogState(t, e) {
34
+ return {
35
+ value: (t?.value || 0) + (e?.value || 0),
36
+ held: (t?.held || 0) + (e?.held || 0)
37
+ };
38
+ }
39
+ mergeInputs(t, e) {
40
+ return {
41
+ buttons: {
42
+ A: this.mergeButtonState(t.buttons?.A, e.buttons?.A),
43
+ B: this.mergeButtonState(t.buttons?.B, e.buttons?.B),
44
+ X: this.mergeButtonState(t.buttons?.X, e.buttons?.X),
45
+ Y: this.mergeButtonState(t.buttons?.Y, e.buttons?.Y),
46
+ Start: this.mergeButtonState(t.buttons?.Start, e.buttons?.Start),
47
+ Select: this.mergeButtonState(t.buttons?.Select, e.buttons?.Select),
48
+ L: this.mergeButtonState(t.buttons?.L, e.buttons?.L),
49
+ R: this.mergeButtonState(t.buttons?.R, e.buttons?.R)
50
+ },
51
+ directions: {
52
+ Up: this.mergeButtonState(t.directions?.Up, e.directions?.Up),
53
+ Down: this.mergeButtonState(t.directions?.Down, e.directions?.Down),
54
+ Left: this.mergeButtonState(t.directions?.Left, e.directions?.Left),
55
+ Right: this.mergeButtonState(t.directions?.Right, e.directions?.Right)
56
+ },
57
+ axes: {
58
+ Horizontal: this.mergeAnalogState(t.axes?.Horizontal, e.axes?.Horizontal),
59
+ Vertical: this.mergeAnalogState(t.axes?.Vertical, e.axes?.Vertical)
60
+ },
61
+ shoulders: {
62
+ LTrigger: this.mergeButtonState(t.shoulders?.LTrigger, e.shoulders?.LTrigger),
63
+ RTrigger: this.mergeButtonState(t.shoulders?.RTrigger, e.shoulders?.RTrigger)
64
+ }
65
+ };
66
+ }
67
+ }
68
+ export {
69
+ B as InputManager
70
+ };
@@ -0,0 +1,120 @@
1
+ class p {
2
+ keyStates = /* @__PURE__ */ new Map();
3
+ keyButtonStates = /* @__PURE__ */ new Map();
4
+ mapping = null;
5
+ includeDefaultBase = !0;
6
+ constructor(t, s) {
7
+ this.mapping = t ?? null, this.includeDefaultBase = s?.includeDefaultBase ?? !0, window.addEventListener("keydown", ({ key: e }) => this.keyStates.set(e, !0)), window.addEventListener("keyup", ({ key: e }) => this.keyStates.set(e, !1));
8
+ }
9
+ isKeyPressed(t) {
10
+ return this.keyStates.get(t) || !1;
11
+ }
12
+ handleButtonState(t, s) {
13
+ let e = this.keyButtonStates.get(t);
14
+ const o = this.isKeyPressed(t);
15
+ return e || (e = { pressed: !1, released: !1, held: 0 }, this.keyButtonStates.set(t, e)), o ? (e.held === 0 ? e.pressed = !0 : e.pressed = !1, e.held += s, e.released = !1) : (e.held > 0 ? (e.released = !0, e.held = 0) : e.released = !1, e.pressed = !1), e;
16
+ }
17
+ handleAnalogState(t, s, e) {
18
+ return { value: this.getAxisValue(t, s), held: e };
19
+ }
20
+ mergeButtonState(t, s) {
21
+ return {
22
+ pressed: t?.pressed || s?.pressed || !1,
23
+ released: t?.released || s?.released || !1,
24
+ held: (t?.held || 0) + (s?.held || 0)
25
+ };
26
+ }
27
+ applyCustomMapping(t, s) {
28
+ if (!this.mapping)
29
+ return t;
30
+ for (const [e, o] of Object.entries(this.mapping)) {
31
+ if (!o || o.length === 0)
32
+ continue;
33
+ const a = this.handleButtonState(e, s);
34
+ for (const c of o) {
35
+ const [u, l] = (c || "").split(".");
36
+ if (!u || !l)
37
+ continue;
38
+ const i = u.toLowerCase(), h = l.toLowerCase();
39
+ if (i === "buttons") {
40
+ const n = {
41
+ a: "A",
42
+ b: "B",
43
+ x: "X",
44
+ y: "Y",
45
+ start: "Start",
46
+ select: "Select",
47
+ l: "L",
48
+ r: "R"
49
+ }[h];
50
+ if (!n)
51
+ continue;
52
+ const r = t.buttons || {};
53
+ r[n] = this.mergeButtonState(r[n], a), t.buttons = r;
54
+ continue;
55
+ }
56
+ if (i === "directions") {
57
+ const n = {
58
+ up: "Up",
59
+ down: "Down",
60
+ left: "Left",
61
+ right: "Right"
62
+ }[h];
63
+ if (!n)
64
+ continue;
65
+ const r = t.directions || {};
66
+ r[n] = this.mergeButtonState(r[n], a), t.directions = r;
67
+ continue;
68
+ }
69
+ if (i === "shoulders") {
70
+ const n = {
71
+ ltrigger: "LTrigger",
72
+ rtrigger: "RTrigger"
73
+ }[h];
74
+ if (!n)
75
+ continue;
76
+ const r = t.shoulders || {};
77
+ r[n] = this.mergeButtonState(r[n], a), t.shoulders = r;
78
+ continue;
79
+ }
80
+ }
81
+ }
82
+ return t;
83
+ }
84
+ getInput(t) {
85
+ const s = {};
86
+ return this.includeDefaultBase && (s.buttons = {
87
+ A: this.handleButtonState("z", t),
88
+ B: this.handleButtonState("x", t),
89
+ X: this.handleButtonState("a", t),
90
+ Y: this.handleButtonState("s", t),
91
+ Start: this.handleButtonState(" ", t),
92
+ Select: this.handleButtonState("Enter", t),
93
+ L: this.handleButtonState("q", t),
94
+ R: this.handleButtonState("e", t)
95
+ }, s.directions = {
96
+ Up: this.handleButtonState("ArrowUp", t),
97
+ Down: this.handleButtonState("ArrowDown", t),
98
+ Left: this.handleButtonState("ArrowLeft", t),
99
+ Right: this.handleButtonState("ArrowRight", t)
100
+ }, s.axes = {
101
+ Horizontal: this.handleAnalogState("ArrowLeft", "ArrowRight", t),
102
+ Vertical: this.handleAnalogState("ArrowUp", "ArrowDown", t)
103
+ }, s.shoulders = {
104
+ LTrigger: this.handleButtonState("Q", t),
105
+ RTrigger: this.handleButtonState("E", t)
106
+ }), this.applyCustomMapping(s, t);
107
+ }
108
+ getName() {
109
+ return "keyboard";
110
+ }
111
+ getAxisValue(t, s) {
112
+ return (this.isKeyPressed(s) ? 1 : 0) - (this.isKeyPressed(t) ? 1 : 0);
113
+ }
114
+ isConnected() {
115
+ return !0;
116
+ }
117
+ }
118
+ export {
119
+ p as KeyboardProvider
120
+ };
@@ -0,0 +1,53 @@
1
+ import { Color as r, Box3 as h, Vector3 as s, BoxGeometry as n, Mesh as a, MeshBasicMaterial as l, EdgesGeometry as o, LineSegments as c, LineBasicMaterial as d, Group as m } from "three";
2
+ class u {
3
+ scene;
4
+ container;
5
+ fillMesh;
6
+ edgeLines;
7
+ currentColor = new r(65280);
8
+ bbox = new h();
9
+ size = new s();
10
+ center = new s();
11
+ constructor(e) {
12
+ this.scene = e;
13
+ const i = new n(1, 1, 1);
14
+ this.fillMesh = new a(i, new l({
15
+ color: this.currentColor,
16
+ transparent: !0,
17
+ opacity: 0.12,
18
+ depthWrite: !1
19
+ }));
20
+ const t = new o(i);
21
+ this.edgeLines = new c(t, new d({ color: this.currentColor, linewidth: 1 })), this.container = new m(), this.container.name = "DebugEntityCursor", this.container.add(this.fillMesh), this.container.add(this.edgeLines), this.container.visible = !1, this.scene.add(this.container);
22
+ }
23
+ setColor(e) {
24
+ this.currentColor.set(e), this.fillMesh.material.color.set(this.currentColor), this.edgeLines.material.color.set(this.currentColor);
25
+ }
26
+ /**
27
+ * Update the cursor to enclose the provided Object3D using a world-space AABB.
28
+ */
29
+ updateFromObject(e) {
30
+ if (!e) {
31
+ this.hide();
32
+ return;
33
+ }
34
+ if (this.bbox.setFromObject(e), !isFinite(this.bbox.min.x) || !isFinite(this.bbox.max.x)) {
35
+ this.hide();
36
+ return;
37
+ }
38
+ this.bbox.getSize(this.size), this.bbox.getCenter(this.center);
39
+ const i = new n(Math.max(this.size.x, 1e-6), Math.max(this.size.y, 1e-6), Math.max(this.size.z, 1e-6));
40
+ this.fillMesh.geometry.dispose(), this.fillMesh.geometry = i;
41
+ const t = new o(i);
42
+ this.edgeLines.geometry.dispose(), this.edgeLines.geometry = t, this.container.position.copy(this.center), this.container.visible = !0;
43
+ }
44
+ hide() {
45
+ this.container.visible = !1;
46
+ }
47
+ dispose() {
48
+ this.scene.remove(this.container), this.fillMesh.geometry.dispose(), this.fillMesh.material.dispose(), this.edgeLines.geometry.dispose(), this.edgeLines.material.dispose();
49
+ }
50
+ }
51
+ export {
52
+ u as DebugEntityCursor
53
+ };
@@ -0,0 +1,27 @@
1
+ import { Vector2 as l, Quaternion as m, Euler as p } from "three";
2
+ function b(s) {
3
+ return {
4
+ spawn: async (n, r, t) => {
5
+ const e = await Promise.resolve(s(r, t));
6
+ return n.add(e), e;
7
+ },
8
+ spawnRelative: async (n, r, t = new l(0, 1)) => {
9
+ if (!n.body) {
10
+ console.warn("body missing for entity during spawnRelative");
11
+ return;
12
+ }
13
+ const { x: e, y: c, z: u } = n.body.translation();
14
+ let a = n._rotation2DAngle ?? 0;
15
+ try {
16
+ const o = n.body.rotation(), d = new m(o.x, o.y, o.z, o.w);
17
+ a = new p().setFromQuaternion(d, "XYZ").z;
18
+ } catch {
19
+ }
20
+ const w = Math.sin(-a) * (t.x ?? 0), y = Math.cos(-a) * (t.y ?? 0), i = await Promise.resolve(s(e + w, c + y));
21
+ return r.add(i), i;
22
+ }
23
+ };
24
+ }
25
+ export {
26
+ b as entitySpawner
27
+ };
@@ -0,0 +1,44 @@
1
+ import type { Stage } from './stage';
2
+ import type { StageOptions, ZylemStageConfig } from './zylem-stage';
3
+ /**
4
+ * A lightweight, serializable blueprint representing the initial configuration
5
+ * of a `ZylemStage`. It is intentionally minimal and should not include
6
+ * entities, functions, or runtime references. Use blueprints only to build
7
+ * stages.
8
+ */
9
+ export interface StageBlueprint {
10
+ id: string;
11
+ name?: string;
12
+ config: Partial<ZylemStageConfig>;
13
+ }
14
+ export declare const stageBlueprintsState: {
15
+ byId: Record<string, StageBlueprint>;
16
+ order: string[];
17
+ currentId: string | null;
18
+ };
19
+ /** Reset the blueprints store back to its initial empty state. */
20
+ export declare function resetStageBlueprints(): void;
21
+ /** Create and register a new `StageBlueprint`. */
22
+ export declare function createStageBlueprint(config: Partial<ZylemStageConfig>, options?: {
23
+ id?: string;
24
+ name?: string;
25
+ setCurrent?: boolean;
26
+ }): StageBlueprint;
27
+ /** Upsert a blueprint into the store. */
28
+ export declare function upsertStageBlueprint(blueprint: StageBlueprint): void;
29
+ /** Remove a blueprint by id. */
30
+ export declare function removeStageBlueprint(id: string): void;
31
+ /** Get a blueprint by id. */
32
+ export declare function getStageBlueprint(id: string): StageBlueprint | undefined;
33
+ /** List all blueprints in insertion order. */
34
+ export declare function listStageBlueprints(): StageBlueprint[];
35
+ /** Set the current blueprint id (or clear by passing null). */
36
+ export declare function setCurrentStageBlueprint(id: string | null): void;
37
+ /** Get the current blueprint object, if any. */
38
+ export declare function getCurrentStageBlueprint(): StageBlueprint | null;
39
+ /**
40
+ * Build a `Stage` instance from a blueprint and optional extra `StageOptions`
41
+ * (e.g., entities or a camera wrapper). This does not load the stage; callers
42
+ * should pass the returned `Stage` to the game and call `load` as usual.
43
+ */
44
+ export declare function buildStageFromBlueprint(input: string | StageBlueprint, ...extras: StageOptions): Stage;
@@ -0,0 +1,56 @@
1
+ import { proxy as d } from "valtio/vanilla";
2
+ import { deepClone as i } from "valtio/utils";
3
+ import { nanoid as c } from "nanoid";
4
+ import { stage as l } from "./stage.js";
5
+ const u = {
6
+ byId: {},
7
+ order: [],
8
+ currentId: null
9
+ }, e = d(i(u));
10
+ function m() {
11
+ const r = i(u);
12
+ Object.keys(r).forEach((t) => {
13
+ e[t] = r[t];
14
+ });
15
+ }
16
+ function I(r, t) {
17
+ const n = t?.id ?? c(), o = { id: n, name: t?.name, config: { ...r } };
18
+ return e.byId[n] = o, e.order.includes(n) || (e.order = [...e.order, n]), t?.setCurrent && (e.currentId = n), o;
19
+ }
20
+ function S(r) {
21
+ e.byId[r.id] = { ...r, config: { ...r.config } }, e.order.includes(r.id) || (e.order = [...e.order, r.id]);
22
+ }
23
+ function B(r) {
24
+ delete e.byId[r], e.order = e.order.filter((t) => t !== r), e.currentId === r && (e.currentId = null);
25
+ }
26
+ function f(r) {
27
+ return e.byId[r];
28
+ }
29
+ function b() {
30
+ return e.order.map((r) => e.byId[r]).filter((r) => !!r);
31
+ }
32
+ function y(r) {
33
+ e.currentId = r;
34
+ }
35
+ function C() {
36
+ const r = e.currentId;
37
+ return r ? e.byId[r] ?? null : null;
38
+ }
39
+ function h(r, ...t) {
40
+ const n = typeof r == "string" ? f(r) : r;
41
+ if (!n)
42
+ throw new Error("Stage blueprint not found");
43
+ return l(n.config, ...t);
44
+ }
45
+ export {
46
+ h as buildStageFromBlueprint,
47
+ I as createStageBlueprint,
48
+ C as getCurrentStageBlueprint,
49
+ f as getStageBlueprint,
50
+ b as listStageBlueprints,
51
+ B as removeStageBlueprint,
52
+ m as resetStageBlueprints,
53
+ y as setCurrentStageBlueprint,
54
+ e as stageBlueprintsState,
55
+ S as upsertStageBlueprint
56
+ };
@@ -0,0 +1,100 @@
1
+ import { Ray as b } from "@dimforge/rapier3d-compat";
2
+ import { Vector2 as E, Raycaster as f, LineSegments as L, BufferGeometry as p, LineBasicMaterial as w, BufferAttribute as m } from "three";
3
+ import { debugState as C, getDebugTool as y, setHoveredEntity as D, resetHoveredEntity as v, getHoveredEntity as R, DebugTools as d, setSelectedEntity as T } from "../debug/debug-state.js";
4
+ import { DebugEntityCursor as O } from "./debug-entity-cursor.js";
5
+ const F = 2293538, x = 16724787;
6
+ class A {
7
+ stage;
8
+ options;
9
+ mouseNdc = new E(-2, -2);
10
+ raycaster = new f();
11
+ isMouseDown = !1;
12
+ disposeFns = [];
13
+ debugCursor = null;
14
+ debugLines = null;
15
+ constructor(e, s) {
16
+ this.stage = e, this.options = {
17
+ maxRayDistance: s?.maxRayDistance ?? 5e3,
18
+ addEntityFactory: s?.addEntityFactory ?? null
19
+ }, this.stage.scene && (this.debugLines = new L(new p(), new w({ vertexColors: !0 })), this.stage.scene.scene.add(this.debugLines), this.debugLines.visible = !0, this.debugCursor = new O(this.stage.scene.scene)), this.attachDomListeners();
20
+ }
21
+ update() {
22
+ if (!C.on || !this.stage.scene || !this.stage.world || !this.stage.cameraRef)
23
+ return;
24
+ const { world: e, cameraRef: s } = this.stage;
25
+ if (this.debugLines) {
26
+ const { vertices: l, colors: c } = e.world.debugRender();
27
+ this.debugLines.geometry.setAttribute("position", new m(l, 3)), this.debugLines.geometry.setAttribute("color", new m(c, 4));
28
+ }
29
+ const i = y(), n = i === d.SELECT || i === d.DELETE;
30
+ this.raycaster.setFromCamera(this.mouseNdc, s.camera);
31
+ const t = this.raycaster.ray.origin.clone(), o = this.raycaster.ray.direction.clone().normalize(), r = new b({ x: t.x, y: t.y, z: t.z }, { x: o.x, y: o.y, z: o.z }), a = e.world.castRay(r, this.options.maxRayDistance, !0);
32
+ if (a && n) {
33
+ const c = a.collider?._parent?.userData?.uuid;
34
+ c ? D(c) : v(), this.isMouseDown && this.handleActionOnHit(c ?? null, t, o, a.toi);
35
+ }
36
+ this.isMouseDown = !1;
37
+ const u = R();
38
+ if (!u) {
39
+ this.debugCursor?.hide();
40
+ return;
41
+ }
42
+ const h = this.stage._debugMap.get(`${u}`), g = h?.group ?? h?.mesh ?? null;
43
+ if (!g) {
44
+ this.debugCursor?.hide();
45
+ return;
46
+ }
47
+ switch (i) {
48
+ case d.SELECT:
49
+ this.debugCursor?.setColor(F);
50
+ break;
51
+ case d.DELETE:
52
+ this.debugCursor?.setColor(x);
53
+ break;
54
+ default:
55
+ this.debugCursor?.setColor(16777215);
56
+ break;
57
+ }
58
+ this.debugCursor?.updateFromObject(g);
59
+ }
60
+ dispose() {
61
+ this.disposeFns.forEach((e) => e()), this.disposeFns = [], this.debugCursor?.dispose(), this.debugLines && this.stage.scene && (this.stage.scene.scene.remove(this.debugLines), this.debugLines.geometry.dispose(), this.debugLines.material.dispose(), this.debugLines = null);
62
+ }
63
+ handleActionOnHit(e, s, i, n) {
64
+ switch (y()) {
65
+ case "SELECT": {
66
+ e && T(e);
67
+ break;
68
+ }
69
+ case "DELETE": {
70
+ e && this.stage.removeEntityByUuid(e);
71
+ break;
72
+ }
73
+ case "ADD": {
74
+ if (!this.options.addEntityFactory)
75
+ break;
76
+ const o = s.clone().add(i.clone().multiplyScalar(n)), r = this.options.addEntityFactory({ position: o });
77
+ r && Promise.resolve(r).then((a) => {
78
+ a && this.stage.spawnEntity(a);
79
+ }).catch(() => {
80
+ });
81
+ break;
82
+ }
83
+ }
84
+ }
85
+ attachDomListeners() {
86
+ const e = this.stage.cameraRef?.renderer.domElement ?? this.stage.scene?.zylemCamera.renderer.domElement;
87
+ if (!e)
88
+ return;
89
+ const s = (n) => {
90
+ const t = e.getBoundingClientRect(), o = (n.clientX - t.left) / t.width * 2 - 1, r = -((n.clientY - t.top) / t.height * 2 - 1);
91
+ this.mouseNdc.set(o, r);
92
+ }, i = (n) => {
93
+ this.isMouseDown = !0;
94
+ };
95
+ e.addEventListener("mousemove", s), e.addEventListener("mousedown", i), this.disposeFns.push(() => e.removeEventListener("mousemove", s)), this.disposeFns.push(() => e.removeEventListener("mousedown", i));
96
+ }
97
+ }
98
+ export {
99
+ A as StageDebugDelegate
100
+ };
@@ -0,0 +1,9 @@
1
+ import type { StageOptions, ZylemStageConfig } from './zylem-stage';
2
+ export declare const stageDefaultsState: Partial<ZylemStageConfig>;
3
+ /** Replace multiple defaults at once (shallow merge). */
4
+ export declare function setStageDefaults(partial: Partial<ZylemStageConfig>): void;
5
+ /** Reset defaults back to library defaults. */
6
+ export declare function resetStageDefaults(): void;
7
+ export declare function getStageOptions(options: StageOptions): StageOptions;
8
+ /** Get a plain object copy of the current defaults. */
9
+ export declare function getStageDefaultConfig(): Partial<ZylemStageConfig>;
@@ -0,0 +1,42 @@
1
+ import { proxy as i } from "valtio/vanilla";
2
+ import { Vector3 as r } from "three";
3
+ import { ZylemBlueColor as g } from "../core/utility/vector.js";
4
+ const o = {
5
+ backgroundColor: g,
6
+ backgroundImage: null,
7
+ inputs: {
8
+ p1: ["gamepad-1", "keyboard"],
9
+ p2: ["gamepad-2", "keyboard"]
10
+ },
11
+ gravity: new r(0, 0, 0),
12
+ variables: {}
13
+ }, t = i({
14
+ ...o
15
+ });
16
+ function b(a) {
17
+ Object.assign(t, a);
18
+ }
19
+ function d() {
20
+ Object.assign(t, o);
21
+ }
22
+ function m(a) {
23
+ const n = u();
24
+ let e = {};
25
+ return typeof a[0] == "object" && (e = a.shift() ?? {}), [{ ...n, ...e }, ...a];
26
+ }
27
+ function u() {
28
+ return {
29
+ backgroundColor: t.backgroundColor,
30
+ backgroundImage: t.backgroundImage ?? null,
31
+ inputs: t.inputs ? { ...t.inputs } : void 0,
32
+ gravity: t.gravity,
33
+ variables: t.variables ? { ...t.variables } : void 0
34
+ };
35
+ }
36
+ export {
37
+ u as getStageDefaultConfig,
38
+ m as getStageOptions,
39
+ d as resetStageDefaults,
40
+ b as setStageDefaults,
41
+ t as stageDefaultsState
42
+ };
@@ -0,0 +1,36 @@
1
+ import { Vector3 as t, Color as r } from "three";
2
+ import { proxy as s } from "valtio/vanilla";
3
+ const e = s({
4
+ backgroundColor: new r(r.NAMES.cornflowerblue),
5
+ backgroundImage: null,
6
+ inputs: {
7
+ p1: ["gamepad-1", "keyboard-1"],
8
+ p2: ["gamepad-2", "keyboard-2"]
9
+ },
10
+ variables: {},
11
+ gravity: new t(0, 0, 0),
12
+ entities: []
13
+ }), l = (a) => {
14
+ e.backgroundColor = a;
15
+ }, b = (a) => {
16
+ e.backgroundImage = a;
17
+ }, i = (a, o) => {
18
+ e.variables[a] = o;
19
+ }, c = (a) => {
20
+ if (e.variables.hasOwnProperty(a))
21
+ return e.variables[a];
22
+ console.warn(`Stage variable ${a} not found`);
23
+ }, d = (a) => {
24
+ e.variables = { ...a };
25
+ }, u = () => {
26
+ e.variables = {};
27
+ };
28
+ export {
29
+ c as getStageVariable,
30
+ u as resetStageVariables,
31
+ l as setStageBackgroundColor,
32
+ b as setStageBackgroundImage,
33
+ i as setStageVariable,
34
+ d as setStageVariables,
35
+ e as stageState
36
+ };
@@ -1,6 +1,6 @@
1
1
  import { BaseNode } from '../core/base-node';
2
2
  import { DestroyFunction, SetupContext, SetupFunction, UpdateFunction } from '../core/base-node-life-cycle';
3
- import { StageOptions, ZylemStage } from './zylem-stage';
3
+ import { StageOptionItem, StageOptions, ZylemStage } from './zylem-stage';
4
4
  import { ZylemCamera } from '../camera/zylem-camera';
5
5
  import { CameraWrapper } from '../camera/camera';
6
6
  type NodeLike = {
@@ -10,7 +10,7 @@ type AnyNode = NodeLike | Promise<NodeLike>;
10
10
  type EntityInput = AnyNode | (() => AnyNode) | (() => Promise<any>);
11
11
  export declare class Stage {
12
12
  stageRef: ZylemStage;
13
- options: StageOptions;
13
+ options: StageOptionItem[];
14
14
  update: UpdateFunction<ZylemStage>;
15
15
  setup: SetupFunction<ZylemStage>;
16
16
  destroy: DestroyFunction<ZylemStage>;
@@ -0,0 +1,60 @@
1
+ import { ZylemStage as n } from "./zylem-stage.js";
2
+ import { CameraWrapper as r } from "../camera/camera.js";
3
+ import { stageState as i, setStageVariable as g, getStageVariable as p } from "./stage-state.js";
4
+ import { getStageOptions as f } from "./stage-default.js";
5
+ class d {
6
+ stageRef;
7
+ options = [];
8
+ update = () => {
9
+ };
10
+ setup = () => {
11
+ };
12
+ destroy = () => {
13
+ };
14
+ constructor(t) {
15
+ this.options = t, this.stageRef = new n(this.options);
16
+ }
17
+ async load(t, e) {
18
+ this.stageRef.wrapperRef = this;
19
+ const s = e instanceof r ? e.cameraRef : e;
20
+ await this.stageRef.load(t, s);
21
+ }
22
+ async addEntities(t) {
23
+ this.options.push(...t), this.stageRef.enqueue(...t);
24
+ }
25
+ add(...t) {
26
+ this.stageRef.enqueue(...t);
27
+ }
28
+ start(t) {
29
+ this.stageRef?.nodeSetup(t), this.stageRef.onEntityAdded((e) => {
30
+ const s = this.stageRef.buildEntityState(e);
31
+ i.entities = [...i.entities, s];
32
+ }, { replayExisting: !0 });
33
+ }
34
+ onUpdate(...t) {
35
+ this.stageRef.update = (e) => {
36
+ const s = { ...e, stage: this };
37
+ t.forEach((o) => o(s));
38
+ };
39
+ }
40
+ onSetup(t) {
41
+ this.stageRef.setup = t;
42
+ }
43
+ onDestroy(t) {
44
+ this.stageRef.destroy = t;
45
+ }
46
+ setVariable(t, e) {
47
+ g(t, e);
48
+ }
49
+ getVariable(t) {
50
+ return p(t);
51
+ }
52
+ }
53
+ function l(...a) {
54
+ const t = f(a);
55
+ return new d([...t]);
56
+ }
57
+ export {
58
+ d as Stage,
59
+ l as stage
60
+ };
@@ -12,7 +12,7 @@ import { StageDebugDelegate } from './stage-debug-delegate';
12
12
  import { BaseEntityInterface } from '../types/entity-types';
13
13
  export interface ZylemStageConfig {
14
14
  inputs: Record<string, string[]>;
15
- backgroundColor: Color;
15
+ backgroundColor: Color | string;
16
16
  backgroundImage: string | null;
17
17
  gravity: Vector3;
18
18
  variables: Record<string, any>;
@@ -21,8 +21,9 @@ export interface ZylemStageConfig {
21
21
  type NodeLike = {
22
22
  create: Function;
23
23
  };
24
- type StageEntityInput = NodeLike | Promise<any> | (() => NodeLike | Promise<any>);
25
- export type StageOptions = Array<Partial<ZylemStageConfig> | CameraWrapper | StageEntityInput>;
24
+ export type StageEntityInput = NodeLike | Promise<any> | (() => NodeLike | Promise<any>);
25
+ export type StageOptionItem = Partial<ZylemStageConfig> | CameraWrapper | StageEntityInput;
26
+ export type StageOptions = [] | [Partial<ZylemStageConfig>, ...StageOptionItem[]];
26
27
  export type StageState = ZylemStageConfig & {
27
28
  entities: GameEntityInterface[];
28
29
  };