@zylem/game-lib 0.6.3 → 0.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/dist/actions.d.ts +5 -5
  2. package/dist/actions.js +196 -32
  3. package/dist/actions.js.map +1 -1
  4. package/dist/behavior/jumper-2d.d.ts +114 -0
  5. package/dist/behavior/jumper-2d.js +711 -0
  6. package/dist/behavior/jumper-2d.js.map +1 -0
  7. package/dist/behavior/platformer-3d.d.ts +14 -14
  8. package/dist/behavior/platformer-3d.js +347 -104
  9. package/dist/behavior/platformer-3d.js.map +1 -1
  10. package/dist/behavior/ricochet-2d.d.ts +4 -3
  11. package/dist/behavior/ricochet-2d.js +53 -22
  12. package/dist/behavior/ricochet-2d.js.map +1 -1
  13. package/dist/behavior/ricochet-3d.d.ts +117 -0
  14. package/dist/behavior/ricochet-3d.js +443 -0
  15. package/dist/behavior/ricochet-3d.js.map +1 -0
  16. package/dist/behavior/screen-visibility.d.ts +79 -0
  17. package/dist/behavior/screen-visibility.js +358 -0
  18. package/dist/behavior/screen-visibility.js.map +1 -0
  19. package/dist/behavior/screen-wrap.d.ts +4 -3
  20. package/dist/behavior/screen-wrap.js +100 -49
  21. package/dist/behavior/screen-wrap.js.map +1 -1
  22. package/dist/behavior/shooter-2d.d.ts +79 -0
  23. package/dist/behavior/shooter-2d.js +180 -0
  24. package/dist/behavior/shooter-2d.js.map +1 -0
  25. package/dist/behavior/thruster.d.ts +5 -4
  26. package/dist/behavior/thruster.js +133 -75
  27. package/dist/behavior/thruster.js.map +1 -1
  28. package/dist/behavior/top-down-movement.d.ts +56 -0
  29. package/dist/behavior/top-down-movement.js +125 -0
  30. package/dist/behavior/top-down-movement.js.map +1 -0
  31. package/dist/behavior/world-boundary-2d.d.ts +4 -3
  32. package/dist/behavior/world-boundary-2d.js +90 -36
  33. package/dist/behavior/world-boundary-2d.js.map +1 -1
  34. package/dist/behavior/world-boundary-3d.d.ts +76 -0
  35. package/dist/behavior/world-boundary-3d.js +274 -0
  36. package/dist/behavior/world-boundary-3d.js.map +1 -0
  37. package/dist/{behavior-descriptor-BWNWmIjv.d.ts → behavior-descriptor-BXnVR8Ki.d.ts} +22 -5
  38. package/dist/{blueprints-BWGz8fII.d.ts → blueprints-DmbK2dki.d.ts} +2 -2
  39. package/dist/camera-4XO5gbQH.d.ts +905 -0
  40. package/dist/camera.d.ts +1 -1
  41. package/dist/camera.js +876 -289
  42. package/dist/camera.js.map +1 -1
  43. package/dist/{composition-DrzFrbqI.d.ts → composition-BASvMKrW.d.ts} +1 -1
  44. package/dist/{core-DAkskq6Y.d.ts → core-CARRaS55.d.ts} +57 -14
  45. package/dist/core.d.ts +9 -8
  46. package/dist/core.js +4519 -1255
  47. package/dist/core.js.map +1 -1
  48. package/dist/{entities-DC9ce_vx.d.ts → entities-ChFirVL9.d.ts} +22 -28
  49. package/dist/entities.d.ts +4 -4
  50. package/dist/entities.js +1231 -314
  51. package/dist/entities.js.map +1 -1
  52. package/dist/{entity-BpbZqg19.d.ts → entity-vj-HTjzU.d.ts} +80 -11
  53. package/dist/{global-change-Dc8uCKi2.d.ts → global-change-2JvMaz44.d.ts} +1 -1
  54. package/dist/main.d.ts +718 -19
  55. package/dist/main.js +12129 -5959
  56. package/dist/main.js.map +1 -1
  57. package/dist/physics-pose-DCc4oE44.d.ts +25 -0
  58. package/dist/physics-protocol-BDD3P5W2.d.ts +200 -0
  59. package/dist/physics-worker.d.ts +21 -0
  60. package/dist/physics-worker.js +306 -0
  61. package/dist/physics-worker.js.map +1 -0
  62. package/dist/physics.d.ts +205 -0
  63. package/dist/physics.js +577 -0
  64. package/dist/physics.js.map +1 -0
  65. package/dist/{stage-types-BFsm3qsZ.d.ts → stage-types-C19IhuzA.d.ts} +253 -89
  66. package/dist/stage.d.ts +9 -8
  67. package/dist/stage.js +3782 -1041
  68. package/dist/stage.js.map +1 -1
  69. package/dist/sync-state-machine-CZyspBpj.d.ts +16 -0
  70. package/dist/{thruster-DhRaJnoL.d.ts → thruster-23lzoPZd.d.ts} +16 -8
  71. package/dist/world-DfgxoNMt.d.ts +105 -0
  72. package/package.json +25 -1
  73. package/dist/camera-B5e4c78l.d.ts +0 -468
  74. package/dist/world-Be5m1XC1.d.ts +0 -31
@@ -0,0 +1,79 @@
1
+ import { c as BehaviorDescriptor } from '../behavior-descriptor-BXnVR8Ki.js';
2
+ import { I as GameEntity } from '../entity-vj-HTjzU.js';
3
+ import 'bitecs';
4
+ import 'three';
5
+ import '@dimforge/rapier3d-compat';
6
+ import 'mitt';
7
+
8
+ interface ScreenVisibilitySnapshot {
9
+ initialized: boolean;
10
+ visible: boolean;
11
+ justEntered: boolean;
12
+ justExited: boolean;
13
+ visibleCameraNames: string[];
14
+ }
15
+ declare class ScreenVisibilityFSM {
16
+ private initialized;
17
+ private visible;
18
+ private justEntered;
19
+ private justExited;
20
+ private visibleCameraNames;
21
+ update(visible: boolean, visibleCameraNames: readonly string[]): void;
22
+ isInitialized(): boolean;
23
+ isVisible(): boolean;
24
+ wasJustEntered(): boolean;
25
+ wasJustExited(): boolean;
26
+ getVisibleCameraNames(): string[];
27
+ getState(): ScreenVisibilitySnapshot;
28
+ }
29
+
30
+ interface ScreenVisibilitySize {
31
+ x: number;
32
+ y: number;
33
+ z: number;
34
+ }
35
+ interface ScreenVisibilityChangeContext {
36
+ entity: GameEntity<any>;
37
+ visible: boolean;
38
+ wasVisible: boolean;
39
+ justEntered: boolean;
40
+ justExited: boolean;
41
+ visibleCameraNames: string[];
42
+ cameraName: string | null;
43
+ }
44
+ interface ScreenVisibilityOptions {
45
+ /**
46
+ * Restrict visibility checks to one active camera by name.
47
+ * When omitted, any active camera can make the entity visible.
48
+ */
49
+ cameraName: string | null;
50
+ /**
51
+ * Require the full entity bounds to remain inside the camera frustum.
52
+ * Defaults to partial visibility (any intersection counts).
53
+ */
54
+ requireFullyVisible: boolean;
55
+ /**
56
+ * Expand or shrink the computed bounds in world units.
57
+ * Positive values make visibility checks more generous.
58
+ */
59
+ padding: number;
60
+ /**
61
+ * Optional bounds to use when the entity has no renderable mesh/group.
62
+ * Falls back to the entity's configured size when available.
63
+ */
64
+ fallbackSize: ScreenVisibilitySize | null;
65
+ onChange?: (context: ScreenVisibilityChangeContext) => void;
66
+ onEnter?: (context: ScreenVisibilityChangeContext) => void;
67
+ onExit?: (context: ScreenVisibilityChangeContext) => void;
68
+ }
69
+ interface ScreenVisibilityHandle {
70
+ isVisible(): boolean;
71
+ isOffscreen(): boolean;
72
+ wasJustEntered(): boolean;
73
+ wasJustExited(): boolean;
74
+ getVisibleCameraNames(): string[];
75
+ getState(): ScreenVisibilitySnapshot | null;
76
+ }
77
+ declare const ScreenVisibilityBehavior: BehaviorDescriptor<ScreenVisibilityOptions, ScreenVisibilityHandle, unknown>;
78
+
79
+ export { ScreenVisibilityBehavior, type ScreenVisibilityChangeContext, ScreenVisibilityFSM, type ScreenVisibilityHandle, type ScreenVisibilityOptions, type ScreenVisibilitySize, type ScreenVisibilitySnapshot };
@@ -0,0 +1,358 @@
1
+ // src/lib/behaviors/screen-visibility/screen-visibility.descriptor.ts
2
+ import {
3
+ Box3,
4
+ Frustum,
5
+ Matrix4,
6
+ Quaternion,
7
+ Vector3
8
+ } from "three";
9
+
10
+ // src/lib/behaviors/behavior-descriptor.ts
11
+ function defineBehavior(config) {
12
+ return {
13
+ key: /* @__PURE__ */ Symbol.for(`zylem:behavior:${config.name}`),
14
+ defaultOptions: config.defaultOptions,
15
+ systemFactory: config.systemFactory,
16
+ createHandle: config.createHandle
17
+ };
18
+ }
19
+
20
+ // src/lib/behaviors/screen-visibility/screen-visibility-fsm.ts
21
+ var ScreenVisibilityFSM = class {
22
+ initialized = false;
23
+ visible = false;
24
+ justEntered = false;
25
+ justExited = false;
26
+ visibleCameraNames = [];
27
+ update(visible, visibleCameraNames) {
28
+ const wasVisible = this.visible;
29
+ this.justEntered = !wasVisible && visible;
30
+ this.justExited = wasVisible && !visible;
31
+ if (!this.initialized) {
32
+ this.justEntered = visible;
33
+ this.justExited = false;
34
+ }
35
+ this.initialized = true;
36
+ this.visible = visible;
37
+ this.visibleCameraNames = [...visibleCameraNames];
38
+ }
39
+ isInitialized() {
40
+ return this.initialized;
41
+ }
42
+ isVisible() {
43
+ return this.visible;
44
+ }
45
+ wasJustEntered() {
46
+ return this.justEntered;
47
+ }
48
+ wasJustExited() {
49
+ return this.justExited;
50
+ }
51
+ getVisibleCameraNames() {
52
+ return [...this.visibleCameraNames];
53
+ }
54
+ getState() {
55
+ return {
56
+ initialized: this.initialized,
57
+ visible: this.visible,
58
+ justEntered: this.justEntered,
59
+ justExited: this.justExited,
60
+ visibleCameraNames: this.getVisibleCameraNames()
61
+ };
62
+ }
63
+ };
64
+
65
+ // src/lib/behaviors/screen-visibility/screen-visibility.descriptor.ts
66
+ var defaultOptions = {
67
+ cameraName: null,
68
+ requireFullyVisible: false,
69
+ padding: 0,
70
+ fallbackSize: null,
71
+ onChange: void 0,
72
+ onEnter: void 0,
73
+ onExit: void 0
74
+ };
75
+ var SCREEN_VISIBILITY_BEHAVIOR_KEY = /* @__PURE__ */ Symbol.for(
76
+ "zylem:behavior:screen-visibility"
77
+ );
78
+ var ScreenVisibilitySystem = class {
79
+ constructor(scene, getBehaviorLinks) {
80
+ this.scene = scene;
81
+ this.getBehaviorLinks = getBehaviorLinks;
82
+ }
83
+ worldBounds = new Box3();
84
+ projectionMatrix = new Matrix4();
85
+ frustum = new Frustum();
86
+ savedPosition = new Vector3();
87
+ savedQuaternion = new Quaternion();
88
+ worldPosition = new Vector3();
89
+ fallbackMin = new Vector3();
90
+ fallbackMax = new Vector3();
91
+ corners = Array.from({ length: 8 }, () => new Vector3());
92
+ boundsCache = /* @__PURE__ */ new Map();
93
+ update(_ecs, _delta) {
94
+ const links = this.getBehaviorLinks?.(SCREEN_VISIBILITY_BEHAVIOR_KEY);
95
+ if (!links) return;
96
+ for (const link of links) {
97
+ const entity = link.entity;
98
+ const visibilityRef = link.ref;
99
+ const options = visibilityRef.options;
100
+ if (!visibilityRef.fsm) {
101
+ visibilityRef.fsm = new ScreenVisibilityFSM();
102
+ }
103
+ const fsm = visibilityRef.fsm;
104
+ const previousState = fsm.getState();
105
+ const cameras = this.resolveActiveCameras(options.cameraName);
106
+ const visibleCameraNames = [];
107
+ const bounds = this.computeWorldBounds(entity, visibilityRef, options);
108
+ if (bounds) {
109
+ for (let index = 0; index < cameras.length; index++) {
110
+ const cameraRef = cameras[index];
111
+ if (this.isBoundsVisible(bounds, cameraRef, options.requireFullyVisible)) {
112
+ visibleCameraNames.push(this.getCameraLabel(cameraRef, index));
113
+ }
114
+ }
115
+ }
116
+ fsm.update(visibleCameraNames.length > 0, visibleCameraNames);
117
+ this.notifyVisibilityChange(entity, options, previousState, fsm.getState());
118
+ }
119
+ }
120
+ resolveActiveCameras(cameraName) {
121
+ const activeCameras = this.scene?.cameraManager?.activeCameras?.length ? [...this.scene.cameraManager.activeCameras] : this.scene?.zylemCamera ? [this.scene.zylemCamera] : [];
122
+ if (!cameraName) {
123
+ return activeCameras;
124
+ }
125
+ return activeCameras.filter((camera) => camera.name === cameraName);
126
+ }
127
+ computeWorldBounds(entity, ref, options) {
128
+ const cacheKey = this.getBoundsCacheKey(entity, options);
129
+ const cached = this.boundsCache.get(entity.uuid);
130
+ if (cached && cached.key === cacheKey) {
131
+ return cached.bounds;
132
+ }
133
+ const target = entity.group ?? entity.mesh;
134
+ this.worldBounds.makeEmpty();
135
+ if (target) {
136
+ const body = entity.body;
137
+ if (body) {
138
+ this.savedPosition.copy(target.position);
139
+ this.savedQuaternion.copy(target.quaternion);
140
+ const translation = body.translation();
141
+ target.position.set(translation.x, translation.y, translation.z);
142
+ if (!entity.controlledRotation) {
143
+ const rotation = body.rotation();
144
+ target.quaternion.set(rotation.x, rotation.y, rotation.z, rotation.w);
145
+ }
146
+ target.updateWorldMatrix(true, true);
147
+ this.worldBounds.setFromObject(target);
148
+ target.position.copy(this.savedPosition);
149
+ target.quaternion.copy(this.savedQuaternion);
150
+ target.updateWorldMatrix(true, true);
151
+ } else {
152
+ target.updateWorldMatrix(true, true);
153
+ this.worldBounds.setFromObject(target);
154
+ }
155
+ }
156
+ if (this.worldBounds.isEmpty()) {
157
+ const fallbackSize = options.fallbackSize ?? (entity.options?.size ?? null);
158
+ this.resolveFallbackCenter(entity, target);
159
+ const halfX = (fallbackSize?.x ?? 0) / 2;
160
+ const halfY = (fallbackSize?.y ?? 0) / 2;
161
+ const halfZ = (fallbackSize?.z ?? 0) / 2;
162
+ this.fallbackMin.set(
163
+ this.worldPosition.x - halfX,
164
+ this.worldPosition.y - halfY,
165
+ this.worldPosition.z - halfZ
166
+ );
167
+ this.fallbackMax.set(
168
+ this.worldPosition.x + halfX,
169
+ this.worldPosition.y + halfY,
170
+ this.worldPosition.z + halfZ
171
+ );
172
+ this.worldBounds.set(this.fallbackMin, this.fallbackMax);
173
+ }
174
+ if (options.padding !== 0) {
175
+ this.worldBounds.expandByScalar(options.padding);
176
+ }
177
+ if (this.worldBounds.isEmpty()) {
178
+ this.boundsCache.delete(entity.uuid);
179
+ return null;
180
+ }
181
+ const cachedBounds = cached?.bounds ?? new Box3();
182
+ cachedBounds.copy(this.worldBounds);
183
+ this.boundsCache.set(entity.uuid, {
184
+ bounds: cachedBounds,
185
+ key: cacheKey
186
+ });
187
+ ref.__screenVisibilityBoundsKey = cacheKey;
188
+ return cachedBounds;
189
+ }
190
+ getBoundsCacheKey(entity, options) {
191
+ const body = entity.body;
192
+ if (body) {
193
+ const translation = body.translation();
194
+ const rotation = body.rotation();
195
+ return [
196
+ "b",
197
+ translation.x.toFixed(3),
198
+ translation.y.toFixed(3),
199
+ translation.z.toFixed(3),
200
+ rotation.x.toFixed(3),
201
+ rotation.y.toFixed(3),
202
+ rotation.z.toFixed(3),
203
+ rotation.w.toFixed(3),
204
+ options.padding,
205
+ options.requireFullyVisible,
206
+ options.fallbackSize?.x ?? "",
207
+ options.fallbackSize?.y ?? "",
208
+ options.fallbackSize?.z ?? ""
209
+ ].join("|");
210
+ }
211
+ const target = entity.group ?? entity.mesh;
212
+ if (target) {
213
+ const position2 = target.position;
214
+ const quaternion = target.quaternion;
215
+ const scale = target.scale;
216
+ return [
217
+ "o",
218
+ position2.x.toFixed(3),
219
+ position2.y.toFixed(3),
220
+ position2.z.toFixed(3),
221
+ quaternion.x.toFixed(3),
222
+ quaternion.y.toFixed(3),
223
+ quaternion.z.toFixed(3),
224
+ quaternion.w.toFixed(3),
225
+ scale.x.toFixed(3),
226
+ scale.y.toFixed(3),
227
+ scale.z.toFixed(3),
228
+ options.padding,
229
+ options.requireFullyVisible,
230
+ options.fallbackSize?.x ?? "",
231
+ options.fallbackSize?.y ?? "",
232
+ options.fallbackSize?.z ?? ""
233
+ ].join("|");
234
+ }
235
+ const position = entity.options?.position ?? { x: 0, y: 0, z: 0 };
236
+ const size = entity.options?.size ?? { x: 0, y: 0, z: 0 };
237
+ return [
238
+ "s",
239
+ position.x,
240
+ position.y,
241
+ position.z,
242
+ size.x,
243
+ size.y,
244
+ size.z,
245
+ options.padding,
246
+ options.requireFullyVisible,
247
+ options.fallbackSize?.x ?? "",
248
+ options.fallbackSize?.y ?? "",
249
+ options.fallbackSize?.z ?? ""
250
+ ].join("|");
251
+ }
252
+ resolveFallbackCenter(entity, target) {
253
+ const body = entity.body;
254
+ if (body) {
255
+ const translation = body.translation();
256
+ this.worldPosition.set(translation.x, translation.y, translation.z);
257
+ return;
258
+ }
259
+ if (target) {
260
+ target.updateWorldMatrix(true, false);
261
+ target.getWorldPosition(this.worldPosition);
262
+ return;
263
+ }
264
+ const position = entity.options?.position ?? { x: 0, y: 0, z: 0 };
265
+ this.worldPosition.set(position.x, position.y, position.z);
266
+ }
267
+ isBoundsVisible(bounds, cameraRef, requireFullyVisible) {
268
+ const camera = cameraRef.camera;
269
+ camera.updateMatrixWorld(true);
270
+ this.projectionMatrix.multiplyMatrices(
271
+ camera.projectionMatrix,
272
+ camera.matrixWorldInverse
273
+ );
274
+ this.frustum.setFromProjectionMatrix(this.projectionMatrix);
275
+ if (!requireFullyVisible) {
276
+ return this.frustum.intersectsBox(bounds);
277
+ }
278
+ return this.getCorners(bounds).every((corner) => this.frustum.containsPoint(corner));
279
+ }
280
+ getCorners(bounds) {
281
+ const { min, max } = bounds;
282
+ this.corners[0].set(min.x, min.y, min.z);
283
+ this.corners[1].set(min.x, min.y, max.z);
284
+ this.corners[2].set(min.x, max.y, min.z);
285
+ this.corners[3].set(min.x, max.y, max.z);
286
+ this.corners[4].set(max.x, min.y, min.z);
287
+ this.corners[5].set(max.x, min.y, max.z);
288
+ this.corners[6].set(max.x, max.y, min.z);
289
+ this.corners[7].set(max.x, max.y, max.z);
290
+ return this.corners;
291
+ }
292
+ getCameraLabel(camera, index) {
293
+ return camera.name || (index === 0 ? "primary" : `camera-${index}`);
294
+ }
295
+ notifyVisibilityChange(entity, options, previousState, nextState) {
296
+ if (!nextState.justEntered && !nextState.justExited) {
297
+ return;
298
+ }
299
+ const context = {
300
+ entity,
301
+ visible: nextState.visible,
302
+ wasVisible: previousState.visible,
303
+ justEntered: nextState.justEntered,
304
+ justExited: nextState.justExited,
305
+ visibleCameraNames: [...nextState.visibleCameraNames],
306
+ cameraName: options.cameraName
307
+ };
308
+ if (nextState.justEntered) {
309
+ options.onEnter?.(context);
310
+ }
311
+ if (nextState.justExited) {
312
+ options.onExit?.(context);
313
+ }
314
+ options.onChange?.(context);
315
+ }
316
+ destroy(_ecs) {
317
+ this.boundsCache.clear();
318
+ }
319
+ };
320
+ function createScreenVisibilityHandle(ref) {
321
+ return {
322
+ isVisible: () => {
323
+ const fsm = ref.fsm;
324
+ return fsm?.isVisible() ?? false;
325
+ },
326
+ isOffscreen: () => {
327
+ const fsm = ref.fsm;
328
+ return !(fsm?.isVisible() ?? false);
329
+ },
330
+ wasJustEntered: () => {
331
+ const fsm = ref.fsm;
332
+ return fsm?.wasJustEntered() ?? false;
333
+ },
334
+ wasJustExited: () => {
335
+ const fsm = ref.fsm;
336
+ return fsm?.wasJustExited() ?? false;
337
+ },
338
+ getVisibleCameraNames: () => {
339
+ const fsm = ref.fsm;
340
+ return fsm?.getVisibleCameraNames() ?? [];
341
+ },
342
+ getState: () => {
343
+ const fsm = ref.fsm;
344
+ return fsm?.getState() ?? null;
345
+ }
346
+ };
347
+ }
348
+ var ScreenVisibilityBehavior = defineBehavior({
349
+ name: "screen-visibility",
350
+ defaultOptions,
351
+ systemFactory: (ctx) => new ScreenVisibilitySystem(ctx.scene, ctx.getBehaviorLinks),
352
+ createHandle: createScreenVisibilityHandle
353
+ });
354
+ export {
355
+ ScreenVisibilityBehavior,
356
+ ScreenVisibilityFSM
357
+ };
358
+ //# sourceMappingURL=screen-visibility.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/behaviors/screen-visibility/screen-visibility.descriptor.ts","../../src/lib/behaviors/behavior-descriptor.ts","../../src/lib/behaviors/screen-visibility/screen-visibility-fsm.ts"],"sourcesContent":["import type { IWorld } from 'bitecs';\nimport {\n\tBox3,\n\tFrustum,\n\tMatrix4,\n\tQuaternion,\n\tVector3,\n\ttype Object3D,\n} from 'three';\n\nimport { defineBehavior, type BehaviorRef } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport { ScreenVisibilityFSM, type ScreenVisibilitySnapshot } from './screen-visibility-fsm';\nimport type { GameEntity } from '../../entities/entity';\nimport type { ZylemCamera } from '../../camera/zylem-camera';\n\nexport interface ScreenVisibilitySize {\n\tx: number;\n\ty: number;\n\tz: number;\n}\n\nexport interface ScreenVisibilityChangeContext {\n\tentity: GameEntity<any>;\n\tvisible: boolean;\n\twasVisible: boolean;\n\tjustEntered: boolean;\n\tjustExited: boolean;\n\tvisibleCameraNames: string[];\n\tcameraName: string | null;\n}\n\nexport interface ScreenVisibilityOptions {\n\t/**\n\t * Restrict visibility checks to one active camera by name.\n\t * When omitted, any active camera can make the entity visible.\n\t */\n\tcameraName: string | null;\n\t/**\n\t * Require the full entity bounds to remain inside the camera frustum.\n\t * Defaults to partial visibility (any intersection counts).\n\t */\n\trequireFullyVisible: boolean;\n\t/**\n\t * Expand or shrink the computed bounds in world units.\n\t * Positive values make visibility checks more generous.\n\t */\n\tpadding: number;\n\t/**\n\t * Optional bounds to use when the entity has no renderable mesh/group.\n\t * Falls back to the entity's configured size when available.\n\t */\n\tfallbackSize: ScreenVisibilitySize | null;\n\tonChange?: (context: ScreenVisibilityChangeContext) => void;\n\tonEnter?: (context: ScreenVisibilityChangeContext) => void;\n\tonExit?: (context: ScreenVisibilityChangeContext) => void;\n}\n\nexport interface ScreenVisibilityHandle {\n\tisVisible(): boolean;\n\tisOffscreen(): boolean;\n\twasJustEntered(): boolean;\n\twasJustExited(): boolean;\n\tgetVisibleCameraNames(): string[];\n\tgetState(): ScreenVisibilitySnapshot | null;\n}\n\nconst defaultOptions: ScreenVisibilityOptions = {\n\tcameraName: null,\n\trequireFullyVisible: false,\n\tpadding: 0,\n\tfallbackSize: null,\n\tonChange: undefined,\n\tonEnter: undefined,\n\tonExit: undefined,\n};\n\nconst SCREEN_VISIBILITY_BEHAVIOR_KEY = Symbol.for(\n\t'zylem:behavior:screen-visibility',\n);\n\nclass ScreenVisibilitySystem implements BehaviorSystem {\n\tprivate readonly worldBounds = new Box3();\n\tprivate readonly projectionMatrix = new Matrix4();\n\tprivate readonly frustum = new Frustum();\n\tprivate readonly savedPosition = new Vector3();\n\tprivate readonly savedQuaternion = new Quaternion();\n\tprivate readonly worldPosition = new Vector3();\n\tprivate readonly fallbackMin = new Vector3();\n\tprivate readonly fallbackMax = new Vector3();\n\tprivate readonly corners = Array.from({ length: 8 }, () => new Vector3());\n\tprivate readonly boundsCache = new Map<string, {\n\t\tbounds: Box3;\n\t\tkey: string;\n\t}>();\n\n\tconstructor(\n\t\tprivate scene: any,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) { }\n\n\tupdate(_ecs: IWorld, _delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(SCREEN_VISIBILITY_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst entity = link.entity as GameEntity<any>;\n\t\t\tconst visibilityRef = link.ref as BehaviorRef<ScreenVisibilityOptions>;\n\t\t\tconst options = visibilityRef.options;\n\n\t\t\tif (!visibilityRef.fsm) {\n\t\t\t\tvisibilityRef.fsm = new ScreenVisibilityFSM();\n\t\t\t}\n\n\t\t\tconst fsm = visibilityRef.fsm as ScreenVisibilityFSM;\n\t\t\tconst previousState = fsm.getState();\n\t\t\tconst cameras = this.resolveActiveCameras(options.cameraName);\n\t\t\tconst visibleCameraNames: string[] = [];\n\n\t\t\tconst bounds = this.computeWorldBounds(entity, visibilityRef, options);\n\t\t\tif (bounds) {\n\t\t\t\tfor (let index = 0; index < cameras.length; index++) {\n\t\t\t\t\tconst cameraRef = cameras[index];\n\t\t\t\t\tif (this.isBoundsVisible(bounds, cameraRef, options.requireFullyVisible)) {\n\t\t\t\t\t\tvisibleCameraNames.push(this.getCameraLabel(cameraRef, index));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfsm.update(visibleCameraNames.length > 0, visibleCameraNames);\n\t\t\tthis.notifyVisibilityChange(entity, options, previousState, fsm.getState());\n\t\t}\n\t}\n\n\tprivate resolveActiveCameras(cameraName: string | null): ZylemCamera[] {\n\t\tconst activeCameras = this.scene?.cameraManager?.activeCameras?.length\n\t\t\t? [...this.scene.cameraManager.activeCameras]\n\t\t\t: this.scene?.zylemCamera\n\t\t\t\t? [this.scene.zylemCamera]\n\t\t\t\t: [];\n\n\t\tif (!cameraName) {\n\t\t\treturn activeCameras;\n\t\t}\n\n\t\treturn activeCameras.filter((camera: ZylemCamera) => camera.name === cameraName);\n\t}\n\n\tprivate computeWorldBounds(\n\t\tentity: GameEntity<any>,\n\t\tref: BehaviorRef<ScreenVisibilityOptions>,\n\t\toptions: ScreenVisibilityOptions,\n\t): Box3 | null {\n\t\tconst cacheKey = this.getBoundsCacheKey(entity, options);\n\t\tconst cached = this.boundsCache.get(entity.uuid);\n\t\tif (cached && cached.key === cacheKey) {\n\t\t\treturn cached.bounds;\n\t\t}\n\n\t\tconst target = (entity.group ?? entity.mesh) as Object3D | undefined;\n\t\tthis.worldBounds.makeEmpty();\n\n\t\tif (target) {\n\t\t\tconst body = (entity as any).body;\n\t\t\tif (body) {\n\t\t\t\tthis.savedPosition.copy(target.position);\n\t\t\t\tthis.savedQuaternion.copy(target.quaternion);\n\n\t\t\t\tconst translation = body.translation();\n\t\t\t\ttarget.position.set(translation.x, translation.y, translation.z);\n\n\t\t\t\tif (!(entity as any).controlledRotation) {\n\t\t\t\t\tconst rotation = body.rotation();\n\t\t\t\t\ttarget.quaternion.set(rotation.x, rotation.y, rotation.z, rotation.w);\n\t\t\t\t}\n\n\t\t\t\ttarget.updateWorldMatrix(true, true);\n\t\t\t\tthis.worldBounds.setFromObject(target);\n\n\t\t\t\ttarget.position.copy(this.savedPosition);\n\t\t\t\ttarget.quaternion.copy(this.savedQuaternion);\n\t\t\t\ttarget.updateWorldMatrix(true, true);\n\t\t\t} else {\n\t\t\t\ttarget.updateWorldMatrix(true, true);\n\t\t\t\tthis.worldBounds.setFromObject(target);\n\t\t\t}\n\t\t}\n\n\t\tif (this.worldBounds.isEmpty()) {\n\t\t\tconst fallbackSize = options.fallbackSize\n\t\t\t\t?? ((entity.options?.size as ScreenVisibilitySize | undefined) ?? null);\n\t\t\tthis.resolveFallbackCenter(entity, target);\n\n\t\t\tconst halfX = (fallbackSize?.x ?? 0) / 2;\n\t\t\tconst halfY = (fallbackSize?.y ?? 0) / 2;\n\t\t\tconst halfZ = (fallbackSize?.z ?? 0) / 2;\n\n\t\t\tthis.fallbackMin.set(\n\t\t\t\tthis.worldPosition.x - halfX,\n\t\t\t\tthis.worldPosition.y - halfY,\n\t\t\t\tthis.worldPosition.z - halfZ,\n\t\t\t);\n\t\t\tthis.fallbackMax.set(\n\t\t\t\tthis.worldPosition.x + halfX,\n\t\t\t\tthis.worldPosition.y + halfY,\n\t\t\t\tthis.worldPosition.z + halfZ,\n\t\t\t);\n\t\t\tthis.worldBounds.set(this.fallbackMin, this.fallbackMax);\n\t\t}\n\n\t\tif (options.padding !== 0) {\n\t\t\tthis.worldBounds.expandByScalar(options.padding);\n\t\t}\n\n\t\tif (this.worldBounds.isEmpty()) {\n\t\t\tthis.boundsCache.delete(entity.uuid);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst cachedBounds = cached?.bounds ?? new Box3();\n\t\tcachedBounds.copy(this.worldBounds);\n\t\tthis.boundsCache.set(entity.uuid, {\n\t\t\tbounds: cachedBounds,\n\t\t\tkey: cacheKey,\n\t\t});\n\t\t(ref as any).__screenVisibilityBoundsKey = cacheKey;\n\t\treturn cachedBounds;\n\t}\n\n\tprivate getBoundsCacheKey(\n\t\tentity: GameEntity<any>,\n\t\toptions: ScreenVisibilityOptions,\n\t): string {\n\t\tconst body = (entity as any).body;\n\t\tif (body) {\n\t\t\tconst translation = body.translation();\n\t\t\tconst rotation = body.rotation();\n\t\t\treturn [\n\t\t\t\t'b',\n\t\t\t\ttranslation.x.toFixed(3),\n\t\t\t\ttranslation.y.toFixed(3),\n\t\t\t\ttranslation.z.toFixed(3),\n\t\t\t\trotation.x.toFixed(3),\n\t\t\t\trotation.y.toFixed(3),\n\t\t\t\trotation.z.toFixed(3),\n\t\t\t\trotation.w.toFixed(3),\n\t\t\t\toptions.padding,\n\t\t\t\toptions.requireFullyVisible,\n\t\t\t\toptions.fallbackSize?.x ?? '',\n\t\t\t\toptions.fallbackSize?.y ?? '',\n\t\t\t\toptions.fallbackSize?.z ?? '',\n\t\t\t].join('|');\n\t\t}\n\n\t\tconst target = (entity.group ?? entity.mesh) as Object3D | undefined;\n\t\tif (target) {\n\t\t\tconst position = target.position;\n\t\t\tconst quaternion = target.quaternion;\n\t\t\tconst scale = target.scale;\n\t\t\treturn [\n\t\t\t\t'o',\n\t\t\t\tposition.x.toFixed(3),\n\t\t\t\tposition.y.toFixed(3),\n\t\t\t\tposition.z.toFixed(3),\n\t\t\t\tquaternion.x.toFixed(3),\n\t\t\t\tquaternion.y.toFixed(3),\n\t\t\t\tquaternion.z.toFixed(3),\n\t\t\t\tquaternion.w.toFixed(3),\n\t\t\t\tscale.x.toFixed(3),\n\t\t\t\tscale.y.toFixed(3),\n\t\t\t\tscale.z.toFixed(3),\n\t\t\t\toptions.padding,\n\t\t\t\toptions.requireFullyVisible,\n\t\t\t\toptions.fallbackSize?.x ?? '',\n\t\t\t\toptions.fallbackSize?.y ?? '',\n\t\t\t\toptions.fallbackSize?.z ?? '',\n\t\t\t].join('|');\n\t\t}\n\n\t\tconst position = entity.options?.position ?? { x: 0, y: 0, z: 0 };\n\t\tconst size = entity.options?.size ?? { x: 0, y: 0, z: 0 };\n\t\treturn [\n\t\t\t's',\n\t\t\tposition.x,\n\t\t\tposition.y,\n\t\t\tposition.z,\n\t\t\tsize.x,\n\t\t\tsize.y,\n\t\t\tsize.z,\n\t\t\toptions.padding,\n\t\t\toptions.requireFullyVisible,\n\t\t\toptions.fallbackSize?.x ?? '',\n\t\t\toptions.fallbackSize?.y ?? '',\n\t\t\toptions.fallbackSize?.z ?? '',\n\t\t].join('|');\n\t}\n\n\tprivate resolveFallbackCenter(\n\t\tentity: GameEntity<any>,\n\t\ttarget: Object3D | undefined,\n\t): void {\n\t\tconst body = (entity as any).body;\n\t\tif (body) {\n\t\t\tconst translation = body.translation();\n\t\t\tthis.worldPosition.set(translation.x, translation.y, translation.z);\n\t\t\treturn;\n\t\t}\n\n\t\tif (target) {\n\t\t\ttarget.updateWorldMatrix(true, false);\n\t\t\ttarget.getWorldPosition(this.worldPosition);\n\t\t\treturn;\n\t\t}\n\n\t\tconst position = entity.options?.position ?? { x: 0, y: 0, z: 0 };\n\t\tthis.worldPosition.set(position.x, position.y, position.z);\n\t}\n\n\tprivate isBoundsVisible(\n\t\tbounds: Box3,\n\t\tcameraRef: ZylemCamera,\n\t\trequireFullyVisible: boolean,\n\t): boolean {\n\t\tconst camera = cameraRef.camera;\n\t\tcamera.updateMatrixWorld(true);\n\t\tthis.projectionMatrix.multiplyMatrices(\n\t\t\tcamera.projectionMatrix,\n\t\t\tcamera.matrixWorldInverse,\n\t\t);\n\t\tthis.frustum.setFromProjectionMatrix(this.projectionMatrix);\n\n\t\tif (!requireFullyVisible) {\n\t\t\treturn this.frustum.intersectsBox(bounds);\n\t\t}\n\n\t\treturn this.getCorners(bounds).every((corner) => this.frustum.containsPoint(corner));\n\t}\n\n\tprivate getCorners(bounds: Box3): Vector3[] {\n\t\tconst { min, max } = bounds;\n\t\tthis.corners[0].set(min.x, min.y, min.z);\n\t\tthis.corners[1].set(min.x, min.y, max.z);\n\t\tthis.corners[2].set(min.x, max.y, min.z);\n\t\tthis.corners[3].set(min.x, max.y, max.z);\n\t\tthis.corners[4].set(max.x, min.y, min.z);\n\t\tthis.corners[5].set(max.x, min.y, max.z);\n\t\tthis.corners[6].set(max.x, max.y, min.z);\n\t\tthis.corners[7].set(max.x, max.y, max.z);\n\t\treturn this.corners;\n\t}\n\n\tprivate getCameraLabel(camera: ZylemCamera, index: number): string {\n\t\treturn camera.name || (index === 0 ? 'primary' : `camera-${index}`);\n\t}\n\n\tprivate notifyVisibilityChange(\n\t\tentity: GameEntity<any>,\n\t\toptions: ScreenVisibilityOptions,\n\t\tpreviousState: ScreenVisibilitySnapshot,\n\t\tnextState: ScreenVisibilitySnapshot,\n\t): void {\n\t\tif (!nextState.justEntered && !nextState.justExited) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst context: ScreenVisibilityChangeContext = {\n\t\t\tentity,\n\t\t\tvisible: nextState.visible,\n\t\t\twasVisible: previousState.visible,\n\t\t\tjustEntered: nextState.justEntered,\n\t\t\tjustExited: nextState.justExited,\n\t\t\tvisibleCameraNames: [...nextState.visibleCameraNames],\n\t\t\tcameraName: options.cameraName,\n\t\t};\n\n\t\tif (nextState.justEntered) {\n\t\t\toptions.onEnter?.(context);\n\t\t}\n\n\t\tif (nextState.justExited) {\n\t\t\toptions.onExit?.(context);\n\t\t}\n\n\t\toptions.onChange?.(context);\n\t}\n\n\tdestroy(_ecs: IWorld): void {\n\t\tthis.boundsCache.clear();\n\t}\n}\n\nfunction createScreenVisibilityHandle(\n\tref: BehaviorRef<ScreenVisibilityOptions>,\n): ScreenVisibilityHandle {\n\treturn {\n\t\tisVisible: () => {\n\t\t\tconst fsm = ref.fsm as ScreenVisibilityFSM | undefined;\n\t\t\treturn fsm?.isVisible() ?? false;\n\t\t},\n\t\tisOffscreen: () => {\n\t\t\tconst fsm = ref.fsm as ScreenVisibilityFSM | undefined;\n\t\t\treturn !(fsm?.isVisible() ?? false);\n\t\t},\n\t\twasJustEntered: () => {\n\t\t\tconst fsm = ref.fsm as ScreenVisibilityFSM | undefined;\n\t\t\treturn fsm?.wasJustEntered() ?? false;\n\t\t},\n\t\twasJustExited: () => {\n\t\t\tconst fsm = ref.fsm as ScreenVisibilityFSM | undefined;\n\t\t\treturn fsm?.wasJustExited() ?? false;\n\t\t},\n\t\tgetVisibleCameraNames: () => {\n\t\t\tconst fsm = ref.fsm as ScreenVisibilityFSM | undefined;\n\t\t\treturn fsm?.getVisibleCameraNames() ?? [];\n\t\t},\n\t\tgetState: () => {\n\t\t\tconst fsm = ref.fsm as ScreenVisibilityFSM | undefined;\n\t\t\treturn fsm?.getState() ?? null;\n\t\t},\n\t};\n}\n\nexport const ScreenVisibilityBehavior = defineBehavior<\n\tScreenVisibilityOptions,\n\tScreenVisibilityHandle\n>({\n\tname: 'screen-visibility',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew ScreenVisibilitySystem(ctx.scene, ctx.getBehaviorLinks),\n\tcreateHandle: createScreenVisibilityHandle,\n});\n","/**\n * BehaviorDescriptor\n *\n * Type-safe behavior descriptors that provide options inference.\n * Used with entity.use() to declaratively attach behaviors to entities.\n *\n * Each behavior can define its own handle type via `createHandle`,\n * providing behavior-specific methods with full type safety.\n */\n\nimport type { BehaviorSystemFactory } from './behavior-system';\n\n/**\n * Base handle returned by entity.use() for lazy access to behavior runtime.\n * FSM is null until entity is spawned and components are initialized.\n */\nexport interface BaseBehaviorHandle<\n O extends Record<string, any> = Record<string, any>,\n> {\n /** Get the FSM instance (null until entity is spawned) */\n getFSM(): any | null;\n /** Get the current options */\n getOptions(): O;\n /** Access the underlying behavior ref */\n readonly ref: BehaviorRef<O>;\n}\n\n/**\n * Reference to a behavior stored on an entity\n */\nexport interface BehaviorRef<\n O extends Record<string, any> = Record<string, any>,\n> {\n /** The behavior descriptor */\n descriptor: BehaviorDescriptor<O, any>;\n /** Merged options (defaults + overrides) */\n options: O;\n /** Optional FSM instance - set lazily when entity is spawned */\n fsm?: any;\n}\n\n/**\n * A typed behavior descriptor that associates a symbol key with:\n * - Default options (providing type inference)\n * - A system factory to create the behavior system\n * - An optional handle factory for behavior-specific methods\n */\nexport interface BehaviorDescriptor<\n O extends Record<string, any> = Record<string, any>,\n H extends Record<string, any> = Record<string, never>,\n I = unknown,\n> {\n /** Unique symbol identifying this behavior */\n readonly key: symbol;\n /** Default options (used for type inference) */\n readonly defaultOptions: O;\n /** Factory to create the behavior system */\n readonly systemFactory: BehaviorSystemFactory;\n /**\n * Optional factory to create behavior-specific handle methods.\n * These methods are merged into the handle returned by entity.use().\n */\n readonly createHandle?: (ref: BehaviorRef<O>) => H;\n}\n\n/**\n * The full handle type returned by entity.use().\n * Combines base handle with behavior-specific methods.\n */\nexport type BehaviorHandle<\n O extends Record<string, any> = Record<string, any>,\n H extends Record<string, any> = Record<string, never>,\n> = BaseBehaviorHandle<O> & H;\n\n/**\n * Configuration for defining a new behavior\n */\nexport interface DefineBehaviorConfig<\n O extends Record<string, any>,\n H extends Record<string, any> = Record<string, never>,\n I = unknown,\n> {\n /** Human-readable name for debugging */\n name: string;\n /** Default options - these define the type */\n defaultOptions: O;\n /** Factory function to create the system */\n systemFactory: BehaviorSystemFactory;\n /**\n * Optional factory to create behavior-specific handle methods.\n * The returned object is merged into the handle returned by entity.use().\n *\n * @example\n * ```typescript\n * createHandle: (ref) => ({\n * getLastHits: () => ref.fsm?.getLastHits() ?? null,\n * getMovement: (moveX, moveY) => ref.fsm?.getMovement(moveX, moveY) ?? { moveX, moveY },\n * }),\n * ```\n */\n createHandle?: (ref: BehaviorRef<O>) => H;\n}\n\n/**\n * Define a typed behavior descriptor.\n *\n * @example\n * ```typescript\n * export const WorldBoundary2DBehavior = defineBehavior({\n * name: 'world-boundary-2d',\n * defaultOptions: { boundaries: { top: 0, bottom: 0, left: 0, right: 0 } },\n * systemFactory: (ctx) => new WorldBoundary2DSystem(ctx.world),\n * createHandle: (ref) => ({\n * getLastHits: () => ref.fsm?.getLastHits() ?? null,\n * getMovement: (moveX: number, moveY: number) =>\n * ref.fsm?.getMovement(moveX, moveY) ?? { moveX, moveY },\n * }),\n * });\n *\n * // Usage - handle has getLastHits and getMovement with full types\n * const boundary = ship.use(WorldBoundary2DBehavior, { ... });\n * const hits = boundary.getLastHits(); // Fully typed!\n * ```\n */\nexport function defineBehavior<\n O extends Record<string, any>,\n H extends Record<string, any> = Record<string, never>,\n I = unknown,\n>(\n config: DefineBehaviorConfig<O, H, I>,\n): BehaviorDescriptor<O, H, I> {\n return {\n key: Symbol.for(`zylem:behavior:${config.name}`),\n defaultOptions: config.defaultOptions,\n systemFactory: config.systemFactory,\n createHandle: config.createHandle,\n };\n}\n","export interface ScreenVisibilitySnapshot {\n\tinitialized: boolean;\n\tvisible: boolean;\n\tjustEntered: boolean;\n\tjustExited: boolean;\n\tvisibleCameraNames: string[];\n}\n\nexport class ScreenVisibilityFSM {\n\tprivate initialized = false;\n\tprivate visible = false;\n\tprivate justEntered = false;\n\tprivate justExited = false;\n\tprivate visibleCameraNames: string[] = [];\n\n\tupdate(visible: boolean, visibleCameraNames: readonly string[]): void {\n\t\tconst wasVisible = this.visible;\n\n\t\tthis.justEntered = !wasVisible && visible;\n\t\tthis.justExited = wasVisible && !visible;\n\n\t\tif (!this.initialized) {\n\t\t\tthis.justEntered = visible;\n\t\t\tthis.justExited = false;\n\t\t}\n\n\t\tthis.initialized = true;\n\t\tthis.visible = visible;\n\t\tthis.visibleCameraNames = [...visibleCameraNames];\n\t}\n\n\tisInitialized(): boolean {\n\t\treturn this.initialized;\n\t}\n\n\tisVisible(): boolean {\n\t\treturn this.visible;\n\t}\n\n\twasJustEntered(): boolean {\n\t\treturn this.justEntered;\n\t}\n\n\twasJustExited(): boolean {\n\t\treturn this.justExited;\n\t}\n\n\tgetVisibleCameraNames(): string[] {\n\t\treturn [...this.visibleCameraNames];\n\t}\n\n\tgetState(): ScreenVisibilitySnapshot {\n\t\treturn {\n\t\t\tinitialized: this.initialized,\n\t\t\tvisible: this.visible,\n\t\t\tjustEntered: this.justEntered,\n\t\t\tjustExited: this.justExited,\n\t\t\tvisibleCameraNames: this.getVisibleCameraNames(),\n\t\t};\n\t}\n}\n"],"mappings":"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","names":["position"]}
@@ -1,6 +1,7 @@
1
- import { b as BehaviorDescriptor } from '../behavior-descriptor-BWNWmIjv.js';
2
- import { StateMachine } from 'typescript-fsm';
1
+ import { c as BehaviorDescriptor } from '../behavior-descriptor-BXnVR8Ki.js';
2
+ import { S as SyncStateMachine } from '../sync-state-machine-CZyspBpj.js';
3
3
  import 'bitecs';
4
+ import 'typescript-fsm';
4
5
 
5
6
  /**
6
7
  * ScreenWrapBehavior
@@ -64,7 +65,7 @@ declare enum ScreenWrapEvent {
64
65
  Wrap = "wrap"
65
66
  }
66
67
  declare class ScreenWrapFSM {
67
- machine: StateMachine<ScreenWrapState, ScreenWrapEvent, never>;
68
+ machine: SyncStateMachine<ScreenWrapState, ScreenWrapEvent, never>;
68
69
  constructor();
69
70
  getState(): ScreenWrapState;
70
71
  dispatch(event: ScreenWrapEvent): void;