@zylem/behaviors 0.4.1 → 0.5.2

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 (148) hide show
  1. package/README.md +13 -1
  2. package/dist/{behavior-system-y8SGrGWy.d.ts → behavior-system-CldqNUgr.d.ts} +334 -19
  3. package/dist/{chunk-GFARAJV2.js → chunk-2PAHQZZD.js} +44 -73
  4. package/dist/chunk-2PAHQZZD.js.map +1 -0
  5. package/dist/chunk-4CEW64HO.js +210 -0
  6. package/dist/chunk-4CEW64HO.js.map +1 -0
  7. package/dist/chunk-4LLK2FJI.js +344 -0
  8. package/dist/chunk-4LLK2FJI.js.map +1 -0
  9. package/dist/chunk-4MZ57HPD.js +323 -0
  10. package/dist/chunk-4MZ57HPD.js.map +1 -0
  11. package/dist/chunk-52FJIDGL.js +30 -0
  12. package/dist/chunk-52FJIDGL.js.map +1 -0
  13. package/dist/{chunk-UYFOLI2X.js → chunk-5A5AYP2C.js} +1 -1
  14. package/dist/{chunk-UYFOLI2X.js.map → chunk-5A5AYP2C.js.map} +1 -1
  15. package/dist/chunk-5WRI5ZAA.js +31 -0
  16. package/dist/chunk-5WRI5ZAA.js.map +1 -0
  17. package/dist/{chunk-ZRQWSURL.js → chunk-5XPPLTC7.js} +2 -2
  18. package/dist/chunk-5XPPLTC7.js.map +1 -0
  19. package/dist/{chunk-VMQHNJJI.js → chunk-7DGXUAPV.js} +17 -23
  20. package/dist/chunk-7DGXUAPV.js.map +1 -0
  21. package/dist/{chunk-5SM5SH5O.js → chunk-7JLWZXPA.js} +2 -2
  22. package/dist/{chunk-QDCJLJUV.js → chunk-7W3KY55G.js} +22 -13
  23. package/dist/chunk-7W3KY55G.js.map +1 -0
  24. package/dist/chunk-AS3HR7AS.js +188 -0
  25. package/dist/chunk-AS3HR7AS.js.map +1 -0
  26. package/dist/chunk-BAXJ7XHJ.js +155 -0
  27. package/dist/chunk-BAXJ7XHJ.js.map +1 -0
  28. package/dist/chunk-DZ4LLQON.js +867 -0
  29. package/dist/chunk-DZ4LLQON.js.map +1 -0
  30. package/dist/{chunk-4L36OPY2.js → chunk-G2KUXVU6.js} +81 -135
  31. package/dist/chunk-G2KUXVU6.js.map +1 -0
  32. package/dist/{chunk-BXP4K7RF.js → chunk-JVADRLWX.js} +57 -186
  33. package/dist/chunk-JVADRLWX.js.map +1 -0
  34. package/dist/{chunk-ZA43LPRM.js → chunk-KIYUUSPK.js} +2 -2
  35. package/dist/chunk-LZIHSJZR.js +191 -0
  36. package/dist/chunk-LZIHSJZR.js.map +1 -0
  37. package/dist/{chunk-WWVD5DR5.js → chunk-M3QDKKDF.js} +2 -8
  38. package/dist/chunk-M3QDKKDF.js.map +1 -0
  39. package/dist/{chunk-FTDZAKZW.js → chunk-NQPYMUDF.js} +7 -5
  40. package/dist/{chunk-FTDZAKZW.js.map → chunk-NQPYMUDF.js.map} +1 -1
  41. package/dist/{chunk-XP3ASVGJ.js → chunk-NW4SE5XW.js} +2 -2
  42. package/dist/{chunk-KDY5N6J4.js → chunk-OPZ2LVS2.js} +1 -22
  43. package/dist/{chunk-KDY5N6J4.js.map → chunk-OPZ2LVS2.js.map} +1 -1
  44. package/dist/{chunk-5XZWTFGF.js → chunk-PLIXVF7B.js} +3 -3
  45. package/dist/chunk-PLIXVF7B.js.map +1 -0
  46. package/dist/{chunk-27UPCP5B.js → chunk-QS3VXWVO.js} +22 -13
  47. package/dist/chunk-QS3VXWVO.js.map +1 -0
  48. package/dist/{chunk-Y7YIAWPW.js → chunk-SGHIGTVZ.js} +1 -11
  49. package/dist/{chunk-Y7YIAWPW.js.map → chunk-SGHIGTVZ.js.map} +1 -1
  50. package/dist/{chunk-UL6Q5HDP.js → chunk-TBUKJKY6.js} +3 -25
  51. package/dist/chunk-TBUKJKY6.js.map +1 -0
  52. package/dist/{chunk-Z72F2ENM.js → chunk-WU6XXL3D.js} +17 -26
  53. package/dist/chunk-WU6XXL3D.js.map +1 -0
  54. package/dist/{chunk-A4CA35DQ.js → chunk-Y4PHT2HG.js} +25 -45
  55. package/dist/chunk-Y4PHT2HG.js.map +1 -0
  56. package/dist/components-BmievOxF.d.ts +30 -0
  57. package/dist/cooldown.d.ts +2 -2
  58. package/dist/cooldown.js +2 -1
  59. package/dist/coordinators/boundary-ricochet-3d.d.ts +4 -4
  60. package/dist/coordinators/boundary-ricochet-3d.js +1 -0
  61. package/dist/coordinators/boundary-ricochet.d.ts +4 -4
  62. package/dist/coordinators/boundary-ricochet.js +3 -2
  63. package/dist/coordinators/first-person-shooter.js +1 -0
  64. package/dist/coordinators/multidirectional-space-shooter.d.ts +3 -3
  65. package/dist/coordinators/multidirectional-space-shooter.js +5 -3
  66. package/dist/coordinators/top-down-shooter.d.ts +3 -3
  67. package/dist/coordinators/top-down-shooter.js +5 -3
  68. package/dist/core.d.ts +298 -8
  69. package/dist/core.js +502 -14
  70. package/dist/core.js.map +1 -1
  71. package/dist/destructible-3d.d.ts +32 -4
  72. package/dist/destructible-3d.js +2 -1
  73. package/dist/destructible-prebake.js +1 -0
  74. package/dist/{entity-types-CmtQ-IBp.d.ts → entity-types-DhfsZbSK.d.ts} +5 -3
  75. package/dist/first-person.d.ts +27 -38
  76. package/dist/first-person.js +8 -8
  77. package/dist/index.d.ts +14 -15
  78. package/dist/index.js +38 -53
  79. package/dist/jumper-2d.d.ts +3 -17
  80. package/dist/jumper-2d.js +4 -9
  81. package/dist/jumper-3d.d.ts +5 -39
  82. package/dist/jumper-3d.js +5 -10
  83. package/dist/{moveable-Cl9h-_w7.d.ts → moveable-rdIvWiak.d.ts} +21 -4
  84. package/dist/particle-emitter/presets.js +1 -0
  85. package/dist/particle-emitter.d.ts +3 -3
  86. package/dist/particle-emitter.js +3 -2
  87. package/dist/platformer-2d.d.ts +21 -82
  88. package/dist/platformer-2d.js +4 -5
  89. package/dist/platformer-3d.d.ts +21 -78
  90. package/dist/platformer-3d.js +4 -5
  91. package/dist/ricochet-2d.d.ts +3 -3
  92. package/dist/ricochet-2d.js +4 -3
  93. package/dist/ricochet-3d.d.ts +3 -3
  94. package/dist/ricochet-3d.js +4 -3
  95. package/dist/runtime-2d.d.ts +2 -2
  96. package/dist/runtime-2d.js +1 -0
  97. package/dist/runtime-2d.js.map +1 -1
  98. package/dist/screen-visibility.d.ts +2 -2
  99. package/dist/screen-visibility.js +1 -0
  100. package/dist/screen-wrap.d.ts +2 -2
  101. package/dist/screen-wrap.js +4 -3
  102. package/dist/shooter-2d.d.ts +3 -3
  103. package/dist/shooter-2d.js +4 -3
  104. package/dist/thruster.d.ts +5 -34
  105. package/dist/thruster.js +4 -6
  106. package/dist/top-down-movement.d.ts +9 -27
  107. package/dist/top-down-movement.js +6 -6
  108. package/dist/{vector-Bm65-FOG.d.ts → vector-DjhLUrak.d.ts} +2 -4
  109. package/dist/world-boundary-2d.d.ts +2 -2
  110. package/dist/world-boundary-2d.js +5 -4
  111. package/dist/world-boundary-3d.d.ts +2 -2
  112. package/dist/world-boundary-3d.js +4 -3
  113. package/package.json +4 -5
  114. package/dist/chunk-27UPCP5B.js.map +0 -1
  115. package/dist/chunk-4L36OPY2.js.map +0 -1
  116. package/dist/chunk-4URF65BR.js +0 -44
  117. package/dist/chunk-4URF65BR.js.map +0 -1
  118. package/dist/chunk-5XZWTFGF.js.map +0 -1
  119. package/dist/chunk-67XLJ26X.js +0 -536
  120. package/dist/chunk-67XLJ26X.js.map +0 -1
  121. package/dist/chunk-75FJIUIG.js +0 -240
  122. package/dist/chunk-75FJIUIG.js.map +0 -1
  123. package/dist/chunk-A4CA35DQ.js.map +0 -1
  124. package/dist/chunk-BXP4K7RF.js.map +0 -1
  125. package/dist/chunk-F72WX4MH.js +0 -422
  126. package/dist/chunk-F72WX4MH.js.map +0 -1
  127. package/dist/chunk-GFARAJV2.js.map +0 -1
  128. package/dist/chunk-JXMF4NUI.js +0 -309
  129. package/dist/chunk-JXMF4NUI.js.map +0 -1
  130. package/dist/chunk-OTLSUYQQ.js +0 -29
  131. package/dist/chunk-OTLSUYQQ.js.map +0 -1
  132. package/dist/chunk-Q75LKHDF.js +0 -56
  133. package/dist/chunk-Q75LKHDF.js.map +0 -1
  134. package/dist/chunk-QDCJLJUV.js.map +0 -1
  135. package/dist/chunk-RDHSHEZM.js +0 -479
  136. package/dist/chunk-RDHSHEZM.js.map +0 -1
  137. package/dist/chunk-UIG7MWS2.js +0 -518
  138. package/dist/chunk-UIG7MWS2.js.map +0 -1
  139. package/dist/chunk-UL6Q5HDP.js.map +0 -1
  140. package/dist/chunk-VMQHNJJI.js.map +0 -1
  141. package/dist/chunk-WWVD5DR5.js.map +0 -1
  142. package/dist/chunk-Z72F2ENM.js.map +0 -1
  143. package/dist/chunk-ZRQWSURL.js.map +0 -1
  144. package/dist/components-BWG1GkZA.d.ts +0 -20
  145. package/dist/use-behavior-B85d5u7-.d.ts +0 -13
  146. /package/dist/{chunk-5SM5SH5O.js.map → chunk-7JLWZXPA.js.map} +0 -0
  147. /package/dist/{chunk-ZA43LPRM.js.map → chunk-KIYUUSPK.js.map} +0 -0
  148. /package/dist/{chunk-XP3ASVGJ.js.map → chunk-NW4SE5XW.js.map} +0 -0
package/README.md CHANGED
@@ -1,6 +1,18 @@
1
1
  # Zylem Behaviors
2
2
 
3
- Tree-shakable Zylem behavior descriptors, systems, coordinators, and shared behavior helpers.
3
+ The simulation layer of the Zylem framework: tree-shakable behavior descriptors, FSMs, coordinators, and the `Simulation` API that owns the `@zylem/runtime` WASM module (ECS + Rapier physics).
4
+
5
+ `@zylem/behaviors` sits between the game framework and the runtime:
6
+
7
+ ```
8
+ @zylem/game-lib → @zylem/behaviors → @zylem/runtime (WASM)
9
+ ```
10
+
11
+ - **`createSimulation()` / `Simulation`** — loads and owns the WASM stage, exposes `spawn`/`despawn` with opaque `EntityHandle`s, a fixed-timestep `update(delta)` loop, snapshot/pose accessors, raycasts, debug rendering, and translated `SimulationEvent`s (collision start/stop with handles instead of raw slots).
12
+ - **Behavior descriptors** (`Platformer3DBehavior`, `TopDownMovementBehavior`, …) — attach WASM-side controllers to entities and forward per-frame input through slot-indexed buffers; FSM state is read back from snapshots.
13
+ - **`MockBehaviorRuntime`** — in-memory `BehaviorRuntime` implementation for unit-testing behaviors without loading WASM.
14
+
15
+ Physics simulation is WASM-only; there is no TypeScript physics fallback. Disposal chains downward: `Simulation.dispose()` destroys the WASM stage.
4
16
 
5
17
  Use per-behavior entrypoints when you want bundlers to pull only the behavior family you import:
6
18
 
@@ -1,4 +1,4 @@
1
- import { RigidBody, Collider, World } from '@dimforge/rapier3d-compat';
1
+ import { StageWasmExports } from '@zylem/runtime';
2
2
 
3
3
  /**
4
4
  * BehaviorDescriptor
@@ -113,7 +113,7 @@ interface VelocityIntent {
113
113
  priority?: number;
114
114
  }
115
115
  /**
116
- * Transform state managed by Valtio for batched physics updates.
116
+ * Transform state managed by Valtio for per-frame physics intent accumulation.
117
117
  *
118
118
  * This store accumulates transformation intents during the frame,
119
119
  * then applies them all at once after onUpdate() callbacks complete.
@@ -199,8 +199,9 @@ declare class GameEntity<TOptions = unknown> {
199
199
  group: any;
200
200
  mesh?: any;
201
201
  materials?: any[];
202
- body: RigidBody | null;
203
- collider: Collider | null;
202
+ /** Opaque host-owned physics references (never inspected by behaviors). */
203
+ body: unknown | null;
204
+ collider: unknown | null;
204
205
  colliderDesc?: any;
205
206
  colliderDescs: any[];
206
207
  bodyDesc?: any;
@@ -233,12 +234,24 @@ declare class GameEntity<TOptions = unknown> {
233
234
  */
234
235
  type CreateEntityFn = (options?: Partial<GameEntityOptions>) => GameEntity<GameEntityOptions>;
235
236
 
237
+ /**
238
+ * `WasmStageRuntime` — owns one wasm `WebAssembly.Instance` of
239
+ * `@zylem/runtime` and exposes the unified-Stage FFI as typed TypeScript
240
+ * methods. This is the single simulation adapter for the whole framework:
241
+ * behavior systems talk to it through the {@link BehaviorRuntime} contract,
242
+ * and hosts (e.g. `@zylem/game-lib`) drive it through
243
+ * {@link createSimulation} in `./simulation`.
244
+ */
245
+
246
+ /** Sentinel handle for "no entity / failed allocation". Mirrors `INVALID_SLOT` in Rust. */
247
+ declare const STAGE_INVALID_SLOT = 4294967295;
236
248
  declare const StageBodyKind: {
237
249
  readonly Dynamic: 0;
238
250
  readonly Static: 1;
239
251
  readonly KinematicPosition: 2;
240
252
  readonly KinematicVelocity: 3;
241
253
  };
254
+ type StageBodyKindValue = (typeof StageBodyKind)[keyof typeof StageBodyKind];
242
255
  declare const StageBoundaryDim: {
243
256
  readonly Two: 2;
244
257
  readonly Three: 3;
@@ -359,7 +372,19 @@ interface StagePlatformer3DOptions {
359
372
  snapToGroundDistance?: number;
360
373
  /** KCC collision offset between collider and environment (default 0.05). */
361
374
  characterOffset?: number;
375
+ /** Collider local offset X (fallback / override). */
376
+ offsetX?: number;
377
+ /** Collider local offset Y (fallback / override). */
378
+ offsetY?: number;
379
+ /** Collider local offset Z (fallback / override). */
380
+ offsetZ?: number;
381
+ /** 0 = auto-read attached collider; 1 = use stored shape fields. */
382
+ shapeSource?: number;
362
383
  }
384
+ declare const StagePlatformerShapeSource: {
385
+ readonly Auto: 0;
386
+ readonly Override: 1;
387
+ };
363
388
  interface StagePlatformer2DOptions {
364
389
  halfHeight: number;
365
390
  radius: number;
@@ -388,6 +413,14 @@ interface StagePlatformer2DOptions {
388
413
  snapToGroundDistance?: number;
389
414
  /** KCC collision offset between collider and environment (default 0.05). */
390
415
  characterOffset?: number;
416
+ /** Collider local offset X (fallback / override). */
417
+ offsetX?: number;
418
+ /** Collider local offset Y (fallback / override). */
419
+ offsetY?: number;
420
+ /** Collider local offset Z (fallback / override). */
421
+ offsetZ?: number;
422
+ /** 0 = auto-read attached collider; 1 = use stored shape fields. */
423
+ shapeSource?: number;
391
424
  }
392
425
  interface StageFirstPersonOptions {
393
426
  walkSpeed: number;
@@ -402,7 +435,7 @@ interface StageFirstPersonInput {
402
435
  lookPitchDelta: number;
403
436
  run: boolean;
404
437
  }
405
- /** Button bits for the batched input buffer's bitmask field. */
438
+ /** Button bits for the slot-indexed input buffer's bitmask field. */
406
439
  declare const STAGE_INPUT_BUTTON_JUMP = 1;
407
440
  declare const STAGE_INPUT_BUTTON_RUN = 2;
408
441
  /**
@@ -426,7 +459,7 @@ interface StageBehaviorSnapshot {
426
459
  * a duplicate TS FSM (or hardcoded defaults).
427
460
  */
428
461
  interface WasmSnapshotBackref {
429
- __wasmStage?: WasmStageRuntime | null;
462
+ __wasmStage?: BehaviorRuntime | null;
430
463
  __entity?: {
431
464
  runtimeHandle?: number;
432
465
  } | null;
@@ -439,21 +472,24 @@ interface WasmSnapshotBackref {
439
472
  */
440
473
  declare function readBehaviorSnapshot(ref: object): StageBehaviorSnapshot | null;
441
474
  /**
442
- * Typed FFI surface of the wasm unified Stage runtime that behaviors rely on.
443
- *
444
- * The concrete implementation lives in `@zylem/game-lib`
445
- * (`wasm-stage-runtime.ts`); this contract mirrors the slice of its methods
446
- * that behavior systems call so descriptors stay runtime-agnostic.
475
+ * Runtime surface behavior systems rely on. `WasmStageRuntime` is the real
476
+ * wasm-backed implementation; `MockBehaviorRuntime` (see
477
+ * `./mock-behavior-runtime`) implements the same contract for unit tests, so
478
+ * descriptors stay runtime-agnostic.
447
479
  */
448
- interface WasmStageRuntime {
480
+ interface BehaviorRuntime {
449
481
  getPose(handle: number, out?: StagePose): StagePose | null;
482
+ setPosition(handle: number, x: number, y: number, z: number): boolean;
483
+ setRotation(handle: number, x: number, y: number, z: number, w: number): boolean;
450
484
  writeInputAxes(handle: number, axisA: number, axisB: number): boolean;
451
485
  writeInputLook(handle: number, yawDelta: number, pitchDelta: number): boolean;
486
+ /** Write reserved input slots (thruster world-space vector X/Y). */
487
+ writeInputReserved(handle: number, reservedA: number, reservedB: number): boolean;
452
488
  writeInputButton(handle: number, buttonMask: number, pressed: boolean): boolean;
453
489
  /** Read the per-slot behavior snapshot written at the end of the previous step. */
454
490
  readSnapshot(handle: number, out?: StageBehaviorSnapshot): StageBehaviorSnapshot | null;
455
491
  attachThruster(handle: number, opts: StageThrusterOptions): boolean;
456
- setThrusterInput(handle: number, thrust: number, rotate: number): void;
492
+ setThrusterInput(handle: number, thrust: number, rotate: number, vectorX?: number, vectorY?: number): void;
457
493
  attachTopDown(handle: number, opts: StageTopDownOptions): boolean;
458
494
  setTopDownInput(handle: number, moveX: number, moveY: number): void;
459
495
  attachShooter2D(handle: number, opts: StageShooter2DOptions): boolean;
@@ -486,20 +522,299 @@ interface WasmStageRuntimeOptions {
486
522
  initialCapacity?: number;
487
523
  gravity?: readonly [number, number, number];
488
524
  imports?: WebAssembly.Imports;
525
+ /**
526
+ * Custom wasm source. Defaults to the `zylem_runtime.wasm` bundled with
527
+ * `@zylem/runtime`.
528
+ */
529
+ source?: RequestInfo | URL | ArrayBuffer | Uint8Array;
530
+ }
531
+ type StageEventTypeValue = (typeof StageEventType)[keyof typeof StageEventType];
532
+ /** One decoded event drained from the runtime's per-step event buffer. */
533
+ interface StageEvent {
534
+ type: StageEventTypeValue;
535
+ primarySlot: number | null;
536
+ secondarySlot: number | null;
537
+ payload: [number, number, number];
538
+ }
539
+ /**
540
+ * Decoded view of one entity's slot in the unified render buffer.
541
+ *
542
+ * Mirrors the `STAGE_RENDER_STRIDE` (12-float) packing documented in
543
+ * `runtime/stage/render.rs`:
544
+ * `[0..3]` position, `[3..7]` rotation xyzw, `[7]` uniform scale,
545
+ * `[8..12]` custom0..custom3 (per-behavior shading hints).
546
+ */
547
+ interface StageRenderSlot {
548
+ position: [number, number, number];
549
+ rotation: [number, number, number, number];
550
+ scale: number;
551
+ custom: [number, number, number, number];
552
+ }
553
+ /**
554
+ * Read a single entity slot out of a unified-Stage render buffer view.
555
+ *
556
+ * @param view The `Float32Array` over wasm memory (e.g. `WasmStageRuntime.render`).
557
+ * @param slot The entity's wasm slot id (its `runtimeHandle`).
558
+ * @param out Optional target object to write into (avoids per-call allocation).
559
+ * @returns The decoded slot, or `null` when the slot is out of range.
560
+ */
561
+ declare function readStageRenderSlot(view: Float32Array, slot: number, out?: StageRenderSlot): StageRenderSlot | null;
562
+ interface StageBodyConfig {
563
+ kind: StageBodyKindValue;
564
+ position: readonly [number, number, number];
565
+ rotation: readonly [number, number, number, number];
566
+ linearDamping: number;
567
+ angularDamping: number;
568
+ gravityScale: number;
569
+ canSleep: boolean;
570
+ ccdEnabled: boolean;
571
+ lockRotation: readonly [boolean, boolean, boolean];
572
+ lockTranslation: readonly [boolean, boolean, boolean];
573
+ }
574
+ type StageColliderShape = {
575
+ type: 'box';
576
+ halfExtents: readonly [number, number, number];
577
+ } | {
578
+ type: 'sphere';
579
+ radius: number;
580
+ } | {
581
+ type: 'capsule';
582
+ halfHeight: number;
583
+ radius: number;
584
+ } | {
585
+ type: 'cylinder';
586
+ halfHeight: number;
587
+ radius: number;
588
+ } | {
589
+ type: 'cone';
590
+ halfHeight: number;
591
+ radius: number;
592
+ } | {
593
+ type: 'convexHull';
594
+ vertices: Float32Array;
595
+ } | {
596
+ type: 'trimesh';
597
+ vertices: Float32Array;
598
+ indices: Uint32Array;
599
+ } | {
600
+ type: 'heightfield';
601
+ rows: number;
602
+ cols: number;
603
+ scale: readonly [number, number, number];
604
+ heights: Float32Array;
605
+ };
606
+ interface StageColliderConfig {
607
+ shape: StageColliderShape;
608
+ offset: readonly [number, number, number];
609
+ friction: number;
610
+ restitution: number;
611
+ sensor: boolean;
612
+ /** Packed interaction-groups: high 16 bits = membership, low 16 bits = filter. */
613
+ collisionGroups: number;
614
+ }
615
+ /** Result of a physics raycast against the stage. */
616
+ interface StageRaycastHit {
617
+ slot: number;
618
+ distance: number;
619
+ normal: [number, number, number];
620
+ }
621
+ /** Body introspection payload for debug tooling. */
622
+ interface StageBodyInfo {
623
+ bodyType: number;
624
+ mass: number;
625
+ isSleeping: boolean;
626
+ isEnabled: boolean;
627
+ linearVelocity: [number, number, number];
489
628
  }
629
+ /** Line-list wireframe for physics debug rendering. */
630
+ interface StageDebugRender {
631
+ /** `[x, y, z]` per vertex, two vertices per line. */
632
+ vertices: Float32Array;
633
+ /** RGBA per vertex. */
634
+ colors: Float32Array;
635
+ }
636
+ /**
637
+ * Owns the wasm instance plus the live float-views over its render / event /
638
+ * pose / scratch buffers. One instance per logical stage; each stage gets
639
+ * its own `WebAssembly.Instance` so the singleton inside `stage_ffi.rs`
640
+ * stays single-stage scoped (today's `thread_local!` contract).
641
+ */
642
+ declare class WasmStageRuntime implements BehaviorRuntime {
643
+ readonly exports: StageWasmExports;
644
+ private readonly memory;
645
+ private renderView;
646
+ private inputView;
647
+ private snapshotView;
648
+ private eventView;
649
+ private poseView;
650
+ private vec3View;
651
+ private queryView;
652
+ private scratchView;
653
+ constructor(exports: StageWasmExports, options?: WasmStageRuntimeOptions);
654
+ /** Recreate typed views over wasm memory. Call after step() or whenever memory may have grown. */
655
+ refreshViews(): void;
656
+ /** Step the simulation by `dt` seconds. Refreshes views afterwards. */
657
+ step(dt: number): number;
658
+ dispose(): void;
659
+ get tickCount(): number;
660
+ get activeCount(): number;
661
+ setGravity(x: number, y: number, z: number): void;
662
+ /**
663
+ * Toggle per-step collision-event collection in the wasm stage. Hosts
664
+ * with no collision listeners should disable it — with thousands of
665
+ * touching bodies the per-step contact-pair hashing is a significant
666
+ * fraction of `step()`.
667
+ */
668
+ setEventsEnabled(enabled: boolean): void;
669
+ createEntity(): number;
670
+ destroyEntity(slot: number): boolean;
671
+ attachBody(slot: number, config: StageBodyConfig): boolean;
672
+ addCollider(slot: number, config: StageColliderConfig): boolean;
673
+ private stageScratch;
674
+ private stageScratchIndices;
675
+ getPose(slot: number, out?: StagePose): StagePose | null;
676
+ setPosition(slot: number, x: number, y: number, z: number): boolean;
677
+ setRotation(slot: number, x: number, y: number, z: number, w: number): boolean;
678
+ setLinearVelocity(slot: number, x: number, y: number, z: number): boolean;
679
+ getLinearVelocity(slot: number, out?: [number, number, number]): [number, number, number] | null;
680
+ setAngularVelocity(slot: number, x: number, y: number, z: number): boolean;
681
+ getAngularVelocity(slot: number, out?: [number, number, number]): [number, number, number] | null;
682
+ applyImpulse(slot: number, x: number, y: number, z: number): boolean;
683
+ /** Cast a ray against the physics world. Returns the closest hit or `null`. */
684
+ castRay(origin: readonly [number, number, number], dir: readonly [number, number, number], maxDistance: number, solidOnly?: boolean): StageRaycastHit | null;
685
+ /** Body introspection for debug tooling. */
686
+ getBodyInfo(slot: number): StageBodyInfo | null;
687
+ /** Wireframe debug render of every collider (all shapes). */
688
+ getDebugRender(): StageDebugRender | null;
689
+ /** Read-only view over the render buffer; one slot occupies {@link STAGE_RENDER_STRIDE} floats. */
690
+ get render(): Float32Array;
691
+ get renderStride(): number;
692
+ /**
693
+ * Decode a single entity slot from the live render buffer. Convenience
694
+ * wrapper over {@link readStageRenderSlot} bound to this runtime's view.
695
+ */
696
+ readRenderSlot(slot: number, out?: StageRenderSlot): StageRenderSlot | null;
697
+ /** Drain the wasm event buffer into a fresh array of typed events. */
698
+ drainEvents(): StageEvent[];
699
+ /** Writable view over the slot-indexed input buffer ({@link STAGE_INPUT_STRIDE} floats/slot). */
700
+ get input(): Float32Array;
701
+ get inputStride(): number;
702
+ /** Read-only view over the per-slot behavior snapshot buffer ({@link STAGE_SNAPSHOT_STRIDE} floats/slot). */
703
+ get snapshot(): Float32Array;
704
+ get snapshotStride(): number;
705
+ /**
706
+ * Write the primary movement axes for a slot into the slot-indexed input
707
+ * buffer and mark the slot dirty. Field-scoped (doesn't touch look
708
+ * deltas or buttons) so multiple behaviors composed on one entity can
709
+ * each write their part.
710
+ */
711
+ writeInputAxes(slot: number, axisA: number, axisB: number): boolean;
712
+ /** Write the look deltas (first-person yaw/pitch) for a slot. */
713
+ writeInputLook(slot: number, yawDelta: number, pitchDelta: number): boolean;
714
+ /** Write reserved input slots (thruster world-space vector X/Y). */
715
+ writeInputReserved(slot: number, reservedA: number, reservedB: number): boolean;
716
+ /**
717
+ * Set or clear one button bit ({@link STAGE_INPUT_BUTTON_JUMP} /
718
+ * {@link STAGE_INPUT_BUTTON_RUN}) in a slot's input bitmask.
719
+ */
720
+ writeInputButton(slot: number, buttonMask: number, pressed: boolean): boolean;
721
+ /**
722
+ * Decode a slot's behavior snapshot from the buffer written at the end of
723
+ * the previous step. Returns `null` when the slot has no behavior data.
724
+ */
725
+ readSnapshot(slot: number, out?: StageBehaviorSnapshot): StageBehaviorSnapshot | null;
726
+ get queryScratch(): Float32Array;
727
+ attachCooldown(slot: number): boolean;
728
+ registerCooldown(slot: number, id: number, durationSeconds: number, immediate?: boolean): boolean;
729
+ fireCooldown(slot: number, id: number): boolean;
730
+ resetCooldown(slot: number, id: number): boolean;
731
+ cooldownRemaining(slot: number, id: number): number;
732
+ attachWorldBoundary(slot: number, dim: StageBoundaryDimValue, bounds: StageWorldBoundaryOptions): boolean;
733
+ queryWorldBoundary(slot: number): {
734
+ hits: number;
735
+ clamped: [number, number, number];
736
+ } | null;
737
+ attachScreenWrap(slot: number, opts: StageScreenWrapOptions): boolean;
738
+ queryScreenWrap(slot: number): {
739
+ fsm: number;
740
+ lastWrappedAxes: number;
741
+ } | null;
742
+ attachRicochet(slot: number, dim: StageRicochetDimValue, opts: StageRicochetOptions): boolean;
743
+ queryRicochet(slot: number): {
744
+ bounces: number;
745
+ lastKind: number;
746
+ } | null;
747
+ attachThruster(slot: number, opts: StageThrusterOptions): boolean;
748
+ setThrusterInput(slot: number, thrust: number, turn: number, vectorX?: number, vectorY?: number): void;
749
+ queryThruster(slot: number): {
750
+ headingRad: number;
751
+ speed: number;
752
+ } | null;
753
+ attachTopDown(slot: number, opts: StageTopDownOptions): boolean;
754
+ setTopDownInput(slot: number, axisA: number, axisB: number): void;
755
+ attachJumper2D(slot: number, opts: StageJumper2DOptions): boolean;
756
+ setJumper2DInput(slot: number, jumpPressed: boolean): void;
757
+ queryJumper2D(slot: number): {
758
+ grounded: boolean;
759
+ jumpCount: number;
760
+ coyote: number;
761
+ jumpBuffer: number;
762
+ } | null;
763
+ attachJumper3D(slot: number, opts: StageJumper3DOptions): boolean;
764
+ setJumper3DInput(slot: number, jump: boolean): void;
765
+ queryJumper3D(slot: number): {
766
+ grounded: boolean;
767
+ jumpCount: number;
768
+ verticalVelocity: number;
769
+ } | null;
770
+ attachShooter2D(slot: number, opts: StageShooter2DOptions): boolean;
771
+ fireShooter2D(slot: number, x: number, y: number, z: number, yaw: number): boolean;
772
+ queryShooter2D(slot: number): {
773
+ cooldown: number;
774
+ firedCount: number;
775
+ } | null;
776
+ attachPlatformer3D(slot: number, opts: StagePlatformer3DOptions): boolean;
777
+ setPlatformer3DInputAxes(slot: number, moveX: number, moveZ: number): void;
778
+ setPlatformer3DInputButtons(slot: number, jump: boolean, run: boolean): void;
779
+ queryPlatformer3D(slot: number): {
780
+ grounded: boolean;
781
+ jumpCount: number;
782
+ fsmState: number;
783
+ speed: number;
784
+ } | null;
785
+ attachPlatformer2D(slot: number, opts: StagePlatformer2DOptions): boolean;
786
+ setPlatformer2DInputAxes(slot: number, moveX: number): void;
787
+ setPlatformer2DInputButtons(slot: number, jump: boolean, run: boolean): void;
788
+ queryPlatformer2D(slot: number): {
789
+ grounded: boolean;
790
+ jumpCount: number;
791
+ fsmState: number;
792
+ verticalVelocity: number;
793
+ } | null;
794
+ attachFirstPerson(slot: number, opts: StageFirstPersonOptions): boolean;
795
+ setFirstPersonInput(slot: number, input: StageFirstPersonInput): void;
796
+ queryFirstPerson(slot: number): {
797
+ yaw: number;
798
+ pitch: number;
799
+ speed: number;
800
+ eyeHeight: number;
801
+ } | null;
802
+ }
803
+ /**
804
+ * Load the bundled `@zylem/runtime` wasm (or a custom `source`), instantiate
805
+ * it, and construct a `WasmStageRuntime` around the exports.
806
+ */
807
+ declare function createWasmStageRuntime(options?: WasmStageRuntimeOptions): Promise<WasmStageRuntime>;
490
808
 
491
809
  /**
492
810
  * Structural stand-in for the engine world wrapper. The engine's world
493
- * delegate exposes the raw Rapier world plus an entity lookup map; behaviors
494
- * only rely on this slice.
811
+ * delegate exposes an entity lookup map; behaviors only rely on this slice.
495
812
  *
496
813
  * The map value is intentionally `unknown` (not the `GameEntity` stub class):
497
814
  * the engine's concrete entity class is a different nominal type, and systems
498
815
  * that iterate the map narrow entities themselves.
499
816
  */
500
817
  interface ZylemWorld {
501
- /** Raw Rapier physics world (present when the Rapier path is active). */
502
- world?: World;
503
818
  collisionMap?: Map<string, unknown>;
504
819
  }
505
820
 
@@ -553,7 +868,7 @@ interface BehaviorSystemContext {
553
868
  /** Host scene wrapper (engine-specific); behaviors only call `add`/`remove`-style methods on it. */
554
869
  scene: any;
555
870
  /** Wasm-driven Stage runtime; omitted when the stage has no wasm module. */
556
- wasmStage?: WasmStageRuntime | null;
871
+ wasmStage?: BehaviorRuntime | null;
557
872
  /**
558
873
  * Returns live behavior links for a descriptor key.
559
874
  * O(1) lookup into a pre-built stage index.
@@ -577,4 +892,4 @@ interface BehaviorSystemContext {
577
892
  */
578
893
  type BehaviorSystemFactory<T extends BehaviorSystem = BehaviorSystem> = (stage: BehaviorSystemContext) => T;
579
894
 
580
- export { type StageScreenWrapOptions as A, type BaseBehaviorHandle as B, type CreateEntityFn as C, type DefineBehaviorConfig as D, type StageShooter2DOptions as E, type StageThrusterOptions as F, GameEntity as G, type StageTopDownOptions as H, StageTopDownPlane as I, type StageTopDownPlaneValue as J, type StageWorldBoundaryOptions as K, type VelocityIntentMode as L, type WasmStageRuntime as M, type WasmStageRuntimeOptions as N, createTransformStore as O, defineBehavior as P, readBehaviorSnapshot as Q, STAGE_INPUT_BUTTON_JUMP as S, type TransformState as T, type VelocityIntent as V, type WasmSnapshotBackref as W, type ZylemWorld as Z, type BehaviorDescriptor as a, type BehaviorEntityLink as b, type BehaviorHandle as c, type BehaviorRef as d, type BehaviorSystem as e, type BehaviorSystemContext as f, type BehaviorSystemFactory as g, type GameEntityOptions as h, STAGE_INPUT_BUTTON_RUN as i, type StageBehaviorSnapshot as j, StageBodyKind as k, StageBoundaryDim as l, type StageBoundaryDimValue as m, StageEventType as n, type StageFirstPersonInput as o, type StageFirstPersonOptions as p, type StageJumper2DOptions as q, type StageJumper3DOptions as r, type StagePlatformer2DOptions as s, type StagePlatformer3DOptions as t, type StagePose as u, StageRicochetDim as v, type StageRicochetDimValue as w, type StageRicochetOptions as x, StageRicochetReflection as y, type StageRicochetReflectionValue as z };
895
+ export { type VelocityIntentMode as $, type StageJumper2DOptions as A, type BaseBehaviorHandle as B, type CreateEntityFn as C, type DefineBehaviorConfig as D, type StageJumper3DOptions as E, type StagePlatformer2DOptions as F, GameEntity as G, type StagePlatformer3DOptions as H, StagePlatformerShapeSource as I, type StagePose as J, type StageRaycastHit as K, type StageRenderSlot as L, StageRicochetDim as M, type StageRicochetDimValue as N, type StageRicochetOptions as O, StageRicochetReflection as P, type StageRicochetReflectionValue as Q, type StageScreenWrapOptions as R, STAGE_INPUT_BUTTON_JUMP as S, type StageShooter2DOptions as T, type StageThrusterOptions as U, type StageTopDownOptions as V, StageTopDownPlane as W, type StageTopDownPlaneValue as X, type StageWorldBoundaryOptions as Y, type TransformState as Z, type VelocityIntent as _, type BehaviorDescriptor as a, type WasmSnapshotBackref as a0, WasmStageRuntime as a1, type WasmStageRuntimeOptions as a2, createTransformStore as a3, createWasmStageRuntime as a4, defineBehavior as a5, readBehaviorSnapshot as a6, readStageRenderSlot as a7, type BehaviorEntityLink as b, type BehaviorHandle as c, type BehaviorRef as d, type BehaviorRuntime as e, type BehaviorSystem as f, type BehaviorSystemContext as g, type BehaviorSystemFactory as h, type GameEntityOptions as i, STAGE_INPUT_BUTTON_RUN as j, STAGE_INVALID_SLOT as k, type StageBehaviorSnapshot as l, type StageBodyConfig as m, type StageBodyInfo as n, StageBodyKind as o, type StageBodyKindValue as p, StageBoundaryDim as q, type StageBoundaryDimValue as r, type StageColliderConfig as s, type StageColliderShape as t, type StageDebugRender as u, type StageEvent as v, StageEventType as w, type StageEventTypeValue as x, type StageFirstPersonInput as y, type StageFirstPersonOptions as z };
@@ -1,11 +1,10 @@
1
1
  import {
2
- createBounds2DRect,
3
- wrapPoint2D
4
- } from "./chunk-KDY5N6J4.js";
2
+ createBounds2DRect
3
+ } from "./chunk-OPZ2LVS2.js";
5
4
  import {
6
5
  SyncStateMachine,
7
- t
8
- } from "./chunk-4URF65BR.js";
6
+ import_typescript_fsm
7
+ } from "./chunk-AS3HR7AS.js";
9
8
  import {
10
9
  defineBehavior
11
10
  } from "./chunk-EZNCCO4L.js";
@@ -36,33 +35,33 @@ var ScreenWrapFSM = class {
36
35
  "center" /* Center */,
37
36
  [
38
37
  // From Center
39
- t("center" /* Center */, "approach-left" /* ApproachLeft */, "near-edge-left" /* NearEdgeLeft */),
40
- t("center" /* Center */, "approach-right" /* ApproachRight */, "near-edge-right" /* NearEdgeRight */),
41
- t("center" /* Center */, "approach-top" /* ApproachTop */, "near-edge-top" /* NearEdgeTop */),
42
- t("center" /* Center */, "approach-bottom" /* ApproachBottom */, "near-edge-bottom" /* NearEdgeBottom */),
38
+ (0, import_typescript_fsm.t)("center" /* Center */, "approach-left" /* ApproachLeft */, "near-edge-left" /* NearEdgeLeft */),
39
+ (0, import_typescript_fsm.t)("center" /* Center */, "approach-right" /* ApproachRight */, "near-edge-right" /* NearEdgeRight */),
40
+ (0, import_typescript_fsm.t)("center" /* Center */, "approach-top" /* ApproachTop */, "near-edge-top" /* NearEdgeTop */),
41
+ (0, import_typescript_fsm.t)("center" /* Center */, "approach-bottom" /* ApproachBottom */, "near-edge-bottom" /* NearEdgeBottom */),
43
42
  // From NearEdge to Wrapped
44
- t("near-edge-left" /* NearEdgeLeft */, "wrap" /* Wrap */, "wrapped" /* Wrapped */),
45
- t("near-edge-right" /* NearEdgeRight */, "wrap" /* Wrap */, "wrapped" /* Wrapped */),
46
- t("near-edge-top" /* NearEdgeTop */, "wrap" /* Wrap */, "wrapped" /* Wrapped */),
47
- t("near-edge-bottom" /* NearEdgeBottom */, "wrap" /* Wrap */, "wrapped" /* Wrapped */),
43
+ (0, import_typescript_fsm.t)("near-edge-left" /* NearEdgeLeft */, "wrap" /* Wrap */, "wrapped" /* Wrapped */),
44
+ (0, import_typescript_fsm.t)("near-edge-right" /* NearEdgeRight */, "wrap" /* Wrap */, "wrapped" /* Wrapped */),
45
+ (0, import_typescript_fsm.t)("near-edge-top" /* NearEdgeTop */, "wrap" /* Wrap */, "wrapped" /* Wrapped */),
46
+ (0, import_typescript_fsm.t)("near-edge-bottom" /* NearEdgeBottom */, "wrap" /* Wrap */, "wrapped" /* Wrapped */),
48
47
  // From NearEdge back to Center
49
- t("near-edge-left" /* NearEdgeLeft */, "enter-center" /* EnterCenter */, "center" /* Center */),
50
- t("near-edge-right" /* NearEdgeRight */, "enter-center" /* EnterCenter */, "center" /* Center */),
51
- t("near-edge-top" /* NearEdgeTop */, "enter-center" /* EnterCenter */, "center" /* Center */),
52
- t("near-edge-bottom" /* NearEdgeBottom */, "enter-center" /* EnterCenter */, "center" /* Center */),
48
+ (0, import_typescript_fsm.t)("near-edge-left" /* NearEdgeLeft */, "enter-center" /* EnterCenter */, "center" /* Center */),
49
+ (0, import_typescript_fsm.t)("near-edge-right" /* NearEdgeRight */, "enter-center" /* EnterCenter */, "center" /* Center */),
50
+ (0, import_typescript_fsm.t)("near-edge-top" /* NearEdgeTop */, "enter-center" /* EnterCenter */, "center" /* Center */),
51
+ (0, import_typescript_fsm.t)("near-edge-bottom" /* NearEdgeBottom */, "enter-center" /* EnterCenter */, "center" /* Center */),
53
52
  // From Wrapped back to Center
54
- t("wrapped" /* Wrapped */, "enter-center" /* EnterCenter */, "center" /* Center */),
53
+ (0, import_typescript_fsm.t)("wrapped" /* Wrapped */, "enter-center" /* EnterCenter */, "center" /* Center */),
55
54
  // From Wrapped to NearEdge (landed near opposite edge)
56
- t("wrapped" /* Wrapped */, "approach-left" /* ApproachLeft */, "near-edge-left" /* NearEdgeLeft */),
57
- t("wrapped" /* Wrapped */, "approach-right" /* ApproachRight */, "near-edge-right" /* NearEdgeRight */),
58
- t("wrapped" /* Wrapped */, "approach-top" /* ApproachTop */, "near-edge-top" /* NearEdgeTop */),
59
- t("wrapped" /* Wrapped */, "approach-bottom" /* ApproachBottom */, "near-edge-bottom" /* NearEdgeBottom */),
55
+ (0, import_typescript_fsm.t)("wrapped" /* Wrapped */, "approach-left" /* ApproachLeft */, "near-edge-left" /* NearEdgeLeft */),
56
+ (0, import_typescript_fsm.t)("wrapped" /* Wrapped */, "approach-right" /* ApproachRight */, "near-edge-right" /* NearEdgeRight */),
57
+ (0, import_typescript_fsm.t)("wrapped" /* Wrapped */, "approach-top" /* ApproachTop */, "near-edge-top" /* NearEdgeTop */),
58
+ (0, import_typescript_fsm.t)("wrapped" /* Wrapped */, "approach-bottom" /* ApproachBottom */, "near-edge-bottom" /* NearEdgeBottom */),
60
59
  // Self-transitions (no-ops for redundant events)
61
- t("center" /* Center */, "enter-center" /* EnterCenter */, "center" /* Center */),
62
- t("near-edge-left" /* NearEdgeLeft */, "approach-left" /* ApproachLeft */, "near-edge-left" /* NearEdgeLeft */),
63
- t("near-edge-right" /* NearEdgeRight */, "approach-right" /* ApproachRight */, "near-edge-right" /* NearEdgeRight */),
64
- t("near-edge-top" /* NearEdgeTop */, "approach-top" /* ApproachTop */, "near-edge-top" /* NearEdgeTop */),
65
- t("near-edge-bottom" /* NearEdgeBottom */, "approach-bottom" /* ApproachBottom */, "near-edge-bottom" /* NearEdgeBottom */)
60
+ (0, import_typescript_fsm.t)("center" /* Center */, "enter-center" /* EnterCenter */, "center" /* Center */),
61
+ (0, import_typescript_fsm.t)("near-edge-left" /* NearEdgeLeft */, "approach-left" /* ApproachLeft */, "near-edge-left" /* NearEdgeLeft */),
62
+ (0, import_typescript_fsm.t)("near-edge-right" /* NearEdgeRight */, "approach-right" /* ApproachRight */, "near-edge-right" /* NearEdgeRight */),
63
+ (0, import_typescript_fsm.t)("near-edge-top" /* NearEdgeTop */, "approach-top" /* ApproachTop */, "near-edge-top" /* NearEdgeTop */),
64
+ (0, import_typescript_fsm.t)("near-edge-bottom" /* NearEdgeBottom */, "approach-bottom" /* ApproachBottom */, "near-edge-bottom" /* NearEdgeBottom */)
66
65
  ]
67
66
  );
68
67
  }
@@ -130,41 +129,24 @@ var ScreenWrapSystem = class {
130
129
  wrapRef.fsm = new ScreenWrapFSM();
131
130
  }
132
131
  const handle = gameEntity.runtimeHandle ?? -1;
133
- if (this.wasmStage && handle >= 0) {
134
- this.ensureWasmAttached(handle, options);
135
- const pose = this.wasmStage.getPose(handle);
136
- const query = this.wasmStage.queryScreenWrap(handle);
137
- if (pose && query) {
138
- const bounds2 = createBounds2DRect(options);
139
- wrapRef.fsm.update(
140
- { x: pose.position[0], y: pose.position[1] },
141
- {
142
- minX: bounds2.minX,
143
- maxX: bounds2.maxX,
144
- minY: bounds2.minY,
145
- maxY: bounds2.maxY,
146
- edgeThreshold: options.edgeThreshold
147
- },
148
- query.lastWrappedAxes !== 0
149
- );
150
- continue;
151
- }
132
+ if (!this.wasmStage || handle < 0) continue;
133
+ this.ensureWasmAttached(handle, options);
134
+ const pose = this.wasmStage.getPose(handle);
135
+ const query = this.wasmStage.queryScreenWrap(handle);
136
+ if (pose && query) {
137
+ const bounds = createBounds2DRect(options);
138
+ wrapRef.fsm.update(
139
+ { x: pose.position[0], y: pose.position[1] },
140
+ {
141
+ minX: bounds.minX,
142
+ maxX: bounds.maxX,
143
+ minY: bounds.minY,
144
+ maxY: bounds.maxY,
145
+ edgeThreshold: options.edgeThreshold
146
+ },
147
+ query.lastWrappedAxes !== 0
148
+ );
152
149
  }
153
- if (!gameEntity.body) continue;
154
- const wrapped = this.wrapEntity(gameEntity, options);
155
- const pos = gameEntity.body.translation();
156
- const bounds = createBounds2DRect(options);
157
- wrapRef.fsm.update(
158
- { x: pos.x, y: pos.y },
159
- {
160
- minX: bounds.minX,
161
- maxX: bounds.maxX,
162
- minY: bounds.minY,
163
- maxY: bounds.maxY,
164
- edgeThreshold: options.edgeThreshold
165
- },
166
- wrapped
167
- );
168
150
  }
169
151
  }
170
152
  ensureWasmAttached(handle, options) {
@@ -178,17 +160,6 @@ var ScreenWrapSystem = class {
178
160
  });
179
161
  this.attachedRuntimeSlots.add(handle);
180
162
  }
181
- wrapEntity(entity, options) {
182
- const body = entity.body;
183
- if (!body) return false;
184
- const pos = body.translation();
185
- const bounds = createBounds2DRect(options);
186
- const result = wrapPoint2D({ x: pos.x, y: pos.y }, bounds);
187
- if (result.wrapped) {
188
- body.setTranslation({ x: result.x, y: result.y, z: pos.z }, true);
189
- }
190
- return result.wrapped;
191
- }
192
163
  destroy(_ecs) {
193
164
  this.attachedRuntimeSlots.clear();
194
165
  }
@@ -205,4 +176,4 @@ export {
205
176
  ScreenWrapFSM,
206
177
  ScreenWrapBehavior
207
178
  };
208
- //# sourceMappingURL=chunk-GFARAJV2.js.map
179
+ //# sourceMappingURL=chunk-2PAHQZZD.js.map