@zylem/behaviors 0.5.1 → 0.5.5

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 (84) hide show
  1. package/README.md +1 -1
  2. package/dist/{behavior-system-CeJXzNvr.d.ts → behavior-system-HEt67el5.d.ts} +46 -6
  3. package/dist/{chunk-5EBIIYZD.js → chunk-3QUECYMT.js} +2 -2
  4. package/dist/{chunk-E4X4YJZB.js → chunk-4GW6DCYF.js} +54 -6
  5. package/dist/chunk-4GW6DCYF.js.map +1 -0
  6. package/dist/{chunk-ZRQWSURL.js → chunk-5XPPLTC7.js} +2 -2
  7. package/dist/chunk-5XPPLTC7.js.map +1 -0
  8. package/dist/{chunk-5NJGASUJ.js → chunk-B2ERQ6HD.js} +2 -2
  9. package/dist/{chunk-VFDUKGRZ.js → chunk-BAXJ7XHJ.js} +1 -1
  10. package/dist/chunk-BAXJ7XHJ.js.map +1 -0
  11. package/dist/{chunk-KOWGILCN.js → chunk-D7N6SC4D.js} +2 -2
  12. package/dist/{chunk-JGXRQUTC.js → chunk-DWVLGXMF.js} +2 -2
  13. package/dist/{chunk-AEBDZWCP.js → chunk-GL5JGXPR.js} +2 -2
  14. package/dist/{chunk-7JLWZXPA.js → chunk-GLXEJD2P.js} +2 -2
  15. package/dist/{chunk-VT3H43QA.js → chunk-IRMJTAIK.js} +41 -6
  16. package/dist/chunk-IRMJTAIK.js.map +1 -0
  17. package/dist/{chunk-F6ESSHQK.js → chunk-JACX7ZMJ.js} +2 -2
  18. package/dist/{chunk-W26PHBME.js → chunk-S5HFWDGM.js} +41 -6
  19. package/dist/chunk-S5HFWDGM.js.map +1 -0
  20. package/dist/{chunk-7JJEIADR.js → chunk-USFIJUDN.js} +300 -157
  21. package/dist/chunk-USFIJUDN.js.map +1 -0
  22. package/dist/{chunk-5UMCWV5A.js → chunk-WQUPSOFV.js} +2 -2
  23. package/dist/{chunk-GQAPBNGT.js → chunk-ZOYA3TZG.js} +2 -2
  24. package/dist/{components-BANNjAZP.d.ts → components-JZQoO2sU.d.ts} +1 -1
  25. package/dist/cooldown.d.ts +1 -1
  26. package/dist/cooldown.js +1 -1
  27. package/dist/coordinators/boundary-ricochet-3d.d.ts +2 -2
  28. package/dist/coordinators/boundary-ricochet.d.ts +2 -2
  29. package/dist/coordinators/multidirectional-space-shooter.d.ts +1 -1
  30. package/dist/coordinators/top-down-shooter.d.ts +1 -1
  31. package/dist/core.d.ts +32 -7
  32. package/dist/core.js +49 -5
  33. package/dist/core.js.map +1 -1
  34. package/dist/destructible-3d.d.ts +1 -1
  35. package/dist/first-person.d.ts +1 -1
  36. package/dist/first-person.js +2 -2
  37. package/dist/index.d.ts +4 -4
  38. package/dist/index.js +15 -15
  39. package/dist/jumper-2d.d.ts +1 -1
  40. package/dist/jumper-2d.js +2 -2
  41. package/dist/jumper-3d.d.ts +1 -1
  42. package/dist/jumper-3d.js +2 -2
  43. package/dist/{moveable-XhzWPAw5.d.ts → moveable-BdFmI3s1.d.ts} +1 -1
  44. package/dist/particle-emitter/presets.d.ts +1 -1
  45. package/dist/particle-emitter/presets.js +1 -1
  46. package/dist/particle-emitter.d.ts +3 -3
  47. package/dist/particle-emitter.js +2 -2
  48. package/dist/platformer-2d.d.ts +9 -1
  49. package/dist/platformer-2d.js +2 -2
  50. package/dist/platformer-3d.d.ts +9 -1
  51. package/dist/platformer-3d.js +2 -2
  52. package/dist/ricochet-2d.d.ts +1 -1
  53. package/dist/ricochet-2d.js +2 -2
  54. package/dist/ricochet-3d.d.ts +1 -1
  55. package/dist/ricochet-3d.js +2 -2
  56. package/dist/runtime-2d.d.ts +1 -1
  57. package/dist/screen-visibility.d.ts +1 -1
  58. package/dist/screen-wrap.d.ts +1 -1
  59. package/dist/shooter-2d.d.ts +1 -1
  60. package/dist/{spark-Dx3cJbTW.d.ts → spark-C4Tp-52_.d.ts} +4 -2
  61. package/dist/thruster.d.ts +1 -1
  62. package/dist/thruster.js +1 -1
  63. package/dist/top-down-movement.d.ts +1 -1
  64. package/dist/top-down-movement.js +2 -2
  65. package/dist/world-boundary-2d.d.ts +1 -1
  66. package/dist/world-boundary-2d.js +2 -2
  67. package/dist/world-boundary-3d.d.ts +1 -1
  68. package/dist/world-boundary-3d.js +2 -2
  69. package/package.json +159 -161
  70. package/dist/chunk-7JJEIADR.js.map +0 -1
  71. package/dist/chunk-E4X4YJZB.js.map +0 -1
  72. package/dist/chunk-VFDUKGRZ.js.map +0 -1
  73. package/dist/chunk-VT3H43QA.js.map +0 -1
  74. package/dist/chunk-W26PHBME.js.map +0 -1
  75. package/dist/chunk-ZRQWSURL.js.map +0 -1
  76. /package/dist/{chunk-5EBIIYZD.js.map → chunk-3QUECYMT.js.map} +0 -0
  77. /package/dist/{chunk-5NJGASUJ.js.map → chunk-B2ERQ6HD.js.map} +0 -0
  78. /package/dist/{chunk-KOWGILCN.js.map → chunk-D7N6SC4D.js.map} +0 -0
  79. /package/dist/{chunk-JGXRQUTC.js.map → chunk-DWVLGXMF.js.map} +0 -0
  80. /package/dist/{chunk-AEBDZWCP.js.map → chunk-GL5JGXPR.js.map} +0 -0
  81. /package/dist/{chunk-7JLWZXPA.js.map → chunk-GLXEJD2P.js.map} +0 -0
  82. /package/dist/{chunk-F6ESSHQK.js.map → chunk-JACX7ZMJ.js.map} +0 -0
  83. /package/dist/{chunk-5UMCWV5A.js.map → chunk-WQUPSOFV.js.map} +0 -0
  84. /package/dist/{chunk-GQAPBNGT.js.map → chunk-ZOYA3TZG.js.map} +0 -0
package/dist/core.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { _ as VelocityIntentMode, Y as TransformState, e as BehaviorRuntime, I as StagePose, l as StageBehaviorSnapshot, T as StageThrusterOptions, U as StageTopDownOptions, R as StageShooter2DOptions, Q as StageScreenWrapOptions, r as StageBoundaryDimValue, X as StageWorldBoundaryOptions, M as StageRicochetDimValue, N as StageRicochetOptions, H as StagePlatformer3DOptions, F as StagePlatformer2DOptions, z as StageFirstPersonOptions, y as StageFirstPersonInput, A as StageJumper2DOptions, E as StageJumper3DOptions, a0 as WasmStageRuntime, a1 as WasmStageRuntimeOptions, p as StageBodyKindValue, t as StageColliderShape, K as StageRenderSlot, J as StageRaycastHit, n as StageBodyInfo, u as StageDebugRender } from './behavior-system-CeJXzNvr.js';
2
- export { B as BaseBehaviorHandle, a as BehaviorDescriptor, b as BehaviorEntityLink, c as BehaviorHandle, d as BehaviorRef, f as BehaviorSystem, g as BehaviorSystemContext, h as BehaviorSystemFactory, C as CreateEntityFn, D as DefineBehaviorConfig, G as GameEntity, i as GameEntityOptions, S as STAGE_INPUT_BUTTON_JUMP, j as STAGE_INPUT_BUTTON_RUN, k as STAGE_INVALID_SLOT, m as StageBodyConfig, o as StageBodyKind, q as StageBoundaryDim, s as StageColliderConfig, v as StageEvent, w as StageEventType, x as StageEventTypeValue, L as StageRicochetDim, O as StageRicochetReflection, P as StageRicochetReflectionValue, V as StageTopDownPlane, W as StageTopDownPlaneValue, Z as VelocityIntent, $ as WasmSnapshotBackref, a2 as createTransformStore, a3 as createWasmStageRuntime, a4 as defineBehavior, a5 as readBehaviorSnapshot, a6 as readStageRenderSlot } from './behavior-system-CeJXzNvr.js';
3
- export { P as PhysicsBodyComponent, T as TransformComponent, c as createPhysicsBodyComponent, a as createTransformComponent, u as useBehavior } from './components-BANNjAZP.js';
4
- export { E as EntityWithBody, M as MoveableBodyLike, a as MoveableEntity, V as Vector, g as getPosition, b as getVelocity, m as makeMoveable, c as move, d as moveForwardXY, e as moveX, f as moveXY, h as moveXZ, i as moveY, j as moveZ, r as resetVelocity, s as setPosition, k as setPositionX, l as setPositionY, n as setPositionZ, w as wrapAround3D, o as wrapAroundXY } from './moveable-XhzWPAw5.js';
1
+ import { $ as VelocityIntentMode, Z as TransformState, e as BehaviorRuntime, J as StagePose, l as StageBehaviorSnapshot, U as StageThrusterOptions, V as StageTopDownOptions, T as StageShooter2DOptions, R as StageScreenWrapOptions, r as StageBoundaryDimValue, Y as StageWorldBoundaryOptions, N as StageRicochetDimValue, O as StageRicochetOptions, H as StagePlatformer3DOptions, F as StagePlatformer2DOptions, z as StageFirstPersonOptions, y as StageFirstPersonInput, A as StageJumper2DOptions, E as StageJumper3DOptions, a1 as WasmStageRuntime, a2 as WasmStageRuntimeOptions, p as StageBodyKindValue, t as StageColliderShape, L as StageRenderSlot, K as StageRaycastHit, n as StageBodyInfo, u as StageDebugRender } from './behavior-system-HEt67el5.js';
2
+ export { B as BaseBehaviorHandle, a as BehaviorDescriptor, b as BehaviorEntityLink, c as BehaviorHandle, d as BehaviorRef, f as BehaviorSystem, g as BehaviorSystemContext, h as BehaviorSystemFactory, C as CreateEntityFn, D as DefineBehaviorConfig, G as GameEntity, i as GameEntityOptions, S as STAGE_INPUT_BUTTON_JUMP, j as STAGE_INPUT_BUTTON_RUN, k as STAGE_INVALID_SLOT, m as StageBodyConfig, o as StageBodyKind, q as StageBoundaryDim, s as StageColliderConfig, v as StageEvent, w as StageEventType, x as StageEventTypeValue, I as StagePlatformerShapeSource, M as StageRicochetDim, P as StageRicochetReflection, Q as StageRicochetReflectionValue, W as StageTopDownPlane, X as StageTopDownPlaneValue, _ as VelocityIntent, a0 as WasmSnapshotBackref, a3 as createTransformStore, a4 as createWasmStageRuntime, a5 as defineBehavior, a6 as readBehaviorSnapshot, a7 as readStageRenderSlot } from './behavior-system-HEt67el5.js';
3
+ export { P as PhysicsBodyComponent, T as TransformComponent, c as createPhysicsBodyComponent, a as createTransformComponent, u as useBehavior } from './components-JZQoO2sU.js';
4
+ export { E as EntityWithBody, M as MoveableBodyLike, a as MoveableEntity, V as Vector, g as getPosition, b as getVelocity, m as makeMoveable, c as move, d as moveForwardXY, e as moveX, f as moveXY, h as moveXZ, i as moveY, j as moveZ, r as resetVelocity, s as setPosition, k as setPositionX, l as setPositionY, n as setPositionZ, w as wrapAround3D, o as wrapAroundXY } from './moveable-BdFmI3s1.js';
5
5
  export { V as VEC2_ONE, a as VEC2_ZERO, b as VEC3_ONE, c as VEC3_ZERO, d as Vec2, e as Vec2Components, f as Vec2Input, g as Vec3, h as Vec3Components, i as Vec3Input, j as isVec2Input, k as isVec3Input, n as normalizeVec2, l as normalizeVec3, t as toThreeVector2, m as toThreeVector3 } from './vector-DjhLUrak.js';
6
6
  export { S as SyncStateMachine } from './sync-state-machine-CZyspBpj.js';
7
7
  export { F as FirstPersonPerspective } from './first-person-perspective-C9Mptl0-.js';
@@ -78,7 +78,7 @@ declare class MockBehaviorRuntime implements BehaviorRuntime {
78
78
  kind: string;
79
79
  args: unknown[];
80
80
  }>;
81
- /** Last written batched-input state for a handle. */
81
+ /** Last written slot-indexed input state for a handle. */
82
82
  getBatchedInput(handle: number): MockSlotState['input'];
83
83
  reset(): void;
84
84
  setPosition(handle: number, x: number, y: number, z: number): boolean;
@@ -137,7 +137,7 @@ declare class MockBehaviorRuntime implements BehaviorRuntime {
137
137
  * Opaque, stable identifier for a simulation entity. `slot` is the raw
138
138
  * runtime slot index — treat it as an implementation detail owned by the
139
139
  * Simulation (it is only exposed so hosts can wire behavior systems, which
140
- * address the batched buffers by slot).
140
+ * address the slot-indexed buffers by slot).
141
141
  */
142
142
  interface EntityHandle {
143
143
  /** Monotonic public id, never reused within a Simulation. */
@@ -233,8 +233,20 @@ interface SimulationFrame {
233
233
  interface SimulationOptions extends WasmStageRuntimeOptions {
234
234
  /** Fixed physics timestep in seconds (default 1/60). */
235
235
  fixedTimestep?: number;
236
- /** Max fixed steps per `update()` to avoid death spirals (default 4). */
236
+ /** Max fixed steps per `update()` to avoid death spirals (default 2). */
237
237
  maxSubSteps?: number;
238
+ /**
239
+ * Rapier contact solver iterations (default 4; auto-drops to 2 when a
240
+ * stage has 512+ dynamic bodies). Lower = faster, less stable stacks.
241
+ */
242
+ solverIterations?: number;
243
+ /**
244
+ * Sleep activation overrides applied after create. Defaults match the
245
+ * aggressive canSleep policy on newly attached bodies.
246
+ */
247
+ sleepLinearThreshold?: number;
248
+ sleepAngularThreshold?: number;
249
+ timeUntilSleep?: number;
238
250
  }
239
251
  /**
240
252
  * The behavior world. Construct via {@link createSimulation}.
@@ -254,6 +266,7 @@ declare class Simulation {
254
266
  private idToHandle;
255
267
  private previousRender;
256
268
  private disposed;
269
+ private eventsEnabled;
257
270
  constructor(adapter: WasmStageRuntime, options?: SimulationOptions);
258
271
  /**
259
272
  * Create a runtime entity from a plain definition. Returns `null` when
@@ -263,6 +276,15 @@ declare class Simulation {
263
276
  despawn(handle: EntityHandle): boolean;
264
277
  /** Resolve a raw runtime slot back to its public handle, if alive. */
265
278
  handleForSlot(slot: number): EntityHandle | null;
279
+ /**
280
+ * Toggle collision-event collection. When disabled the wasm stage skips
281
+ * per-step contact-pair hashing and `update()` skips event draining /
282
+ * translation entirely (`frame.events` stays empty). Re-enabling emits
283
+ * `collisionStarted` for every currently overlapping pair on the next
284
+ * step, so late listeners observe current state.
285
+ */
286
+ setEventsEnabled(enabled: boolean): void;
287
+ get areEventsEnabled(): boolean;
266
288
  get entityCount(): number;
267
289
  /**
268
290
  * Advance the simulation by `deltaTime` seconds using a fixed-timestep
@@ -284,6 +306,9 @@ declare class Simulation {
284
306
  readPreviousRenderSlot(handle: EntityHandle, out?: StageRenderSlot): StageRenderSlot | null;
285
307
  readSnapshot(handle: EntityHandle, out?: StageBehaviorSnapshot): StageBehaviorSnapshot | null;
286
308
  setGravity(x: number, y: number, z: number): void;
309
+ setSolverIterations(iterations: number): void;
310
+ setSleepThresholds(normalizedLinearThreshold: number, angularThreshold: number, timeUntilSleep: number): void;
311
+ awakeDynamicCount(): number;
287
312
  /** Physics raycast; the hit's slot is resolved to an entity handle. */
288
313
  castRay(origin: readonly [number, number, number], dir: readonly [number, number, number], maxDistance: number, solidOnly?: boolean): (Omit<StageRaycastHit, 'slot'> & {
289
314
  entity: EntityHandle | null;
package/dist/core.js CHANGED
@@ -30,6 +30,7 @@ import {
30
30
  StageBodyKind,
31
31
  StageBoundaryDim,
32
32
  StageEventType,
33
+ StagePlatformerShapeSource,
33
34
  StageRicochetDim,
34
35
  StageRicochetReflection,
35
36
  StageTopDownPlane,
@@ -37,14 +38,14 @@ import {
37
38
  createWasmStageRuntime,
38
39
  readBehaviorSnapshot,
39
40
  readStageRenderSlot
40
- } from "./chunk-E4X4YJZB.js";
41
+ } from "./chunk-4GW6DCYF.js";
41
42
  import {
42
43
  defineBehavior
43
44
  } from "./chunk-EZNCCO4L.js";
44
45
  import "./chunk-5WRI5ZAA.js";
45
46
 
46
47
  // src/lib/capabilities/transform-store.ts
47
- import { proxy } from "valtio";
48
+ import { proxy } from "valtio/vanilla";
48
49
  function createTransformStore(initial) {
49
50
  const defaultState = {
50
51
  position: { x: 0, y: 0, z: 0 },
@@ -270,7 +271,7 @@ var MockBehaviorRuntime = class {
270
271
  getInputCalls(handle) {
271
272
  return this.slots.get(handle)?.inputs ?? [];
272
273
  }
273
- /** Last written batched-input state for a handle. */
274
+ /** Last written slot-indexed input state for a handle. */
274
275
  getBatchedInput(handle) {
275
276
  return this.slot(handle).input;
276
277
  }
@@ -420,7 +421,7 @@ var MockBehaviorRuntime = class {
420
421
 
421
422
  // src/lib/runtime/simulation.ts
422
423
  var DEFAULT_FIXED_TIMESTEP = 1 / 60;
423
- var DEFAULT_MAX_SUB_STEPS = 4;
424
+ var DEFAULT_MAX_SUB_STEPS = 2;
424
425
  var Simulation = class {
425
426
  /**
426
427
  * The low-level wasm adapter. Behavior systems receive this as their
@@ -436,10 +437,21 @@ var Simulation = class {
436
437
  idToHandle = /* @__PURE__ */ new Map();
437
438
  previousRender = new Float32Array(0);
438
439
  disposed = false;
440
+ eventsEnabled = true;
439
441
  constructor(adapter, options = {}) {
440
442
  this.adapter = adapter;
441
443
  this.fixedTimestep = options.fixedTimestep ?? DEFAULT_FIXED_TIMESTEP;
442
444
  this.maxSubSteps = Math.max(1, options.maxSubSteps ?? DEFAULT_MAX_SUB_STEPS);
445
+ if (options.solverIterations !== void 0) {
446
+ this.adapter.setSolverIterations(options.solverIterations);
447
+ }
448
+ if (options.sleepLinearThreshold !== void 0 || options.sleepAngularThreshold !== void 0 || options.timeUntilSleep !== void 0) {
449
+ this.adapter.setSleepThresholds(
450
+ options.sleepLinearThreshold ?? 0.8,
451
+ options.sleepAngularThreshold ?? 1,
452
+ options.timeUntilSleep ?? 0.5
453
+ );
454
+ }
443
455
  }
444
456
  // ─── Entity lifecycle ───────────────────────────────────────────────
445
457
  /**
@@ -492,6 +504,21 @@ var Simulation = class {
492
504
  handleForSlot(slot) {
493
505
  return this.slotToHandle.get(slot) ?? null;
494
506
  }
507
+ /**
508
+ * Toggle collision-event collection. When disabled the wasm stage skips
509
+ * per-step contact-pair hashing and `update()` skips event draining /
510
+ * translation entirely (`frame.events` stays empty). Re-enabling emits
511
+ * `collisionStarted` for every currently overlapping pair on the next
512
+ * step, so late listeners observe current state.
513
+ */
514
+ setEventsEnabled(enabled) {
515
+ if (this.eventsEnabled === enabled) return;
516
+ this.eventsEnabled = enabled;
517
+ this.adapter.setEventsEnabled(enabled);
518
+ }
519
+ get areEventsEnabled() {
520
+ return this.eventsEnabled;
521
+ }
495
522
  get entityCount() {
496
523
  return this.idToHandle.size;
497
524
  }
@@ -508,7 +535,9 @@ var Simulation = class {
508
535
  while (this.accumulator >= this.fixedTimestep && steps < this.maxSubSteps) {
509
536
  this.capturePreviousRender();
510
537
  this.adapter.step(this.fixedTimestep);
511
- this.translateEvents(this.adapter.drainEvents(), events);
538
+ if (this.eventsEnabled) {
539
+ this.translateEvents(this.adapter.drainEvents(), events);
540
+ }
512
541
  this.accumulator -= this.fixedTimestep;
513
542
  steps++;
514
543
  }
@@ -526,6 +555,7 @@ var Simulation = class {
526
555
  };
527
556
  }
528
557
  capturePreviousRender() {
558
+ this.adapter.refreshViews();
529
559
  const current = this.adapter.render;
530
560
  if (this.previousRender.length !== current.length) {
531
561
  this.previousRender = new Float32Array(current.length);
@@ -614,6 +644,19 @@ var Simulation = class {
614
644
  setGravity(x, y, z) {
615
645
  this.adapter.setGravity(x, y, z);
616
646
  }
647
+ setSolverIterations(iterations) {
648
+ this.adapter.setSolverIterations(iterations);
649
+ }
650
+ setSleepThresholds(normalizedLinearThreshold, angularThreshold, timeUntilSleep) {
651
+ this.adapter.setSleepThresholds(
652
+ normalizedLinearThreshold,
653
+ angularThreshold,
654
+ timeUntilSleep
655
+ );
656
+ }
657
+ awakeDynamicCount() {
658
+ return this.adapter.awakeDynamicCount();
659
+ }
617
660
  /** Physics raycast; the hit's slot is resolved to an entity handle. */
618
661
  castRay(origin, dir, maxDistance, solidOnly = true) {
619
662
  const hit = this.adapter.castRay(origin, dir, maxDistance, solidOnly);
@@ -724,6 +767,7 @@ export {
724
767
  StageBodyKind,
725
768
  StageBoundaryDim,
726
769
  StageEventType,
770
+ StagePlatformerShapeSource,
727
771
  StageRicochetDim,
728
772
  StageRicochetReflection,
729
773
  StageTopDownPlane,
package/dist/core.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/capabilities/transform-store.ts","../src/lib/capabilities/velocity-intents.ts","../src/lib/capabilities/moveable.ts","../src/lib/runtime/mock-behavior-runtime.ts","../src/lib/runtime/simulation.ts","../src/lib/entities/entity.ts"],"sourcesContent":["import { proxy } from 'valtio';\n\nexport type VelocityIntentMode = 'replace' | 'add';\n\nexport interface VelocityIntent {\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\tmode: VelocityIntentMode;\n\tpriority?: number;\n}\n\n/**\n * Transform state managed by Valtio for batched physics updates.\n * \n * This store accumulates transformation intents during the frame,\n * then applies them all at once after onUpdate() callbacks complete.\n * \n * Design decisions:\n * - Position: Accumulated deltas (additive)\n * - Rotation: Last value wins (replacement)\n * - Velocity: Accumulated deltas (additive)\n * - Angular velocity: Accumulated deltas (additive)\n */\nexport interface TransformState {\n\t/** Position deltas to be applied (accumulated) */\n\tposition: { x: number; y: number; z: number };\n\t\n\t/** Rotation quaternion (last value wins) */\n\trotation: { x: number; y: number; z: number; w: number };\n\t\n\t/** Linear velocity (accumulated) */\n\tvelocity: { x: number; y: number; z: number };\n\t\n\t/** Angular velocity (accumulated) */\n\tangularVelocity: { x: number; y: number; z: number };\n\n\t/** Per-source velocity intents composed once per frame */\n\tvelocityChannels: Record<string, VelocityIntent>;\n\t\n\t/** Dirty flags to track what needs to be applied */\n\tdirty: {\n\t\tposition: boolean;\n\t\trotation: boolean;\n\t\tvelocityX: boolean;\n\t\tvelocityY: boolean;\n\t\tvelocityZ: boolean;\n\t\tvelocityChannels: boolean;\n\t\tangularVelocity: boolean;\n\t};\n}\n\n/**\n * Create a new transform store with optional initial values.\n * The store is a Valtio proxy, making it reactive for debugging/visualization.\n * \n * @param initial Optional initial state values\n * @returns Reactive transform state\n */\nexport function createTransformStore(initial?: Partial<TransformState>): TransformState {\n\tconst defaultState: TransformState = {\n\t\tposition: { x: 0, y: 0, z: 0 },\n\t\trotation: { x: 0, y: 0, z: 0, w: 1 },\n\t\tvelocity: { x: 0, y: 0, z: 0 },\n\t\tangularVelocity: { x: 0, y: 0, z: 0 },\n\t\tvelocityChannels: {},\n\t\tdirty: {\n\t\t\tposition: false,\n\t\t\trotation: false,\n\t\t\tvelocityX: false,\n\t\t\tvelocityY: false,\n\t\t\tvelocityZ: false,\n\t\t\tvelocityChannels: false,\n\t\t\tangularVelocity: false,\n\t\t},\n\t};\n\n\treturn proxy({\n\t\t...defaultState,\n\t\t...initial,\n\t\t// Ensure dirty flags are properly initialized even if partial initial state\n\t\tdirty: {\n\t\t\t...defaultState.dirty,\n\t\t\t...initial?.dirty,\n\t\t},\n\t});\n}\n\n","import { TransformState, VelocityIntentMode } from './transform-store';\n\nexport interface VelocityIntentOptions {\n\tmode?: VelocityIntentMode;\n\tpriority?: number;\n}\n\nexport interface VelocityIntentVector {\n\tx?: number;\n\ty?: number;\n\tz?: number;\n}\n\nexport function setVelocityIntent(\n\tstore: TransformState,\n\tsourceId: string,\n\tvector: VelocityIntentVector,\n\toptions: VelocityIntentOptions = {},\n): void {\n\tconst prev = store.velocityChannels[sourceId];\n\tconst mode = options.mode ?? prev?.mode ?? 'replace';\n\tconst priority = options.priority ?? prev?.priority ?? 0;\n\tconst isAdditiveMerge = mode === 'add' && prev?.mode === 'add';\n\n\tconst x =\n\t\tvector.x == null\n\t\t\t? prev?.x\n\t\t\t: isAdditiveMerge\n\t\t\t\t? (prev?.x ?? 0) + vector.x\n\t\t\t\t: vector.x;\n\tconst y =\n\t\tvector.y == null\n\t\t\t? prev?.y\n\t\t\t: isAdditiveMerge\n\t\t\t\t? (prev?.y ?? 0) + vector.y\n\t\t\t\t: vector.y;\n\tconst z =\n\t\tvector.z == null\n\t\t\t? prev?.z\n\t\t\t: isAdditiveMerge\n\t\t\t\t? (prev?.z ?? 0) + vector.z\n\t\t\t\t: vector.z;\n\n\tstore.velocityChannels[sourceId] = {\n\t\tx,\n\t\ty,\n\t\tz,\n\t\tmode,\n\t\tpriority,\n\t};\n\tstore.dirty.velocityChannels = true;\n}\n\nexport function clearVelocityIntent(store: TransformState, sourceId: string): void {\n\tif (!(sourceId in store.velocityChannels)) return;\n\tdelete store.velocityChannels[sourceId];\n\tstore.dirty.velocityChannels = true;\n}\n","import { Vector3 } from 'three';\nimport type { TransformState } from './transform-store';\nimport { createTransformStore } from './transform-store';\nimport { setVelocityIntent } from './velocity-intents';\n\n/** Plain `{ x, y, z }` vector returned by pose/velocity reads. */\nexport interface Vector {\n\tx: number;\n\ty: number;\n\tz: number;\n}\n\n/**\n * Structural slice of the host body reference used by the direct-body helpers\n * below (`getPosition`, `setPosition`, `resetVelocity`, ...). The host's\n * runtime-backed body proxy satisfies this shape.\n */\nexport interface MoveableBodyLike {\n\ttranslation(): Vector;\n\tlinvel(): Vector;\n\tsetTranslation(translation: Vector, wakeUp: boolean): void;\n\tsetLinvel(velocity: Vector, wakeUp: boolean): void;\n\tsetLinearDamping(damping: number): void;\n}\n\nexport interface EntityWithBody {\n\tbody: MoveableBodyLike | null;\n\ttransformStore?: TransformState;\n}\n\n/**\n * Move an entity along the X axis, preserving other velocities.\n */\nexport function moveX(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(entity.transformStore, 'actions', { x: delta }, { mode: 'replace' });\n}\n\n/**\n * Move an entity along the Y axis, preserving other velocities.\n */\nexport function moveY(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(entity.transformStore, 'actions', { y: delta }, { mode: 'replace' });\n}\n\n/**\n * Move an entity along the Z axis, preserving other velocities.\n */\nexport function moveZ(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(entity.transformStore, 'actions', { z: delta }, { mode: 'replace' });\n}\n\n/**\n * Move an entity along the X and Y axis, preserving Z velocity.\n */\nexport function moveXY(entity: EntityWithBody, deltaX: number, deltaY: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(\n\t\tentity.transformStore,\n\t\t'actions',\n\t\t{ x: deltaX, y: deltaY },\n\t\t{ mode: 'replace' },\n\t);\n}\n\n/**\n * Move an entity along the X and Z axis, preserving Y velocity.\n */\nexport function moveXZ(entity: EntityWithBody, deltaX: number, deltaZ: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(\n\t\tentity.transformStore,\n\t\t'actions',\n\t\t{ x: deltaX, z: deltaZ },\n\t\t{ mode: 'replace' },\n\t);\n}\n\n/**\n * Move entity based on a vector, adding to existing velocities.\n */\nexport function move(entity: EntityWithBody, vector: Vector3): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(\n\t\tentity.transformStore,\n\t\t'actions',\n\t\t{ x: vector.x, y: vector.y, z: vector.z },\n\t\t{ mode: 'add' },\n\t);\n}\n\n/**\n * Reset entity velocity\n */\nexport function resetVelocity(entity: EntityWithBody): void {\n\tif (!entity.body) return;\n\tentity.body.setLinvel(new Vector3(0, 0, 0), true);\n\tentity.body.setLinearDamping(5);\n}\n\n/**\n * Move entity forward in 2D space, preserving Z velocity\n */\nexport function moveForwardXY(entity: EntityWithBody, delta: number, rotation2DAngle: number): void {\n\tconst deltaX = Math.sin(-rotation2DAngle) * delta;\n\tconst deltaY = Math.cos(-rotation2DAngle) * delta;\n\tmoveXY(entity, deltaX, deltaY);\n}\n\n/**\n * Get entity position\n */\nexport function getPosition(entity: EntityWithBody): Vector | null {\n\tif (!entity.body) return null;\n\treturn entity.body.translation();\n}\n\n/**\n * Get entity velocity\n */\nexport function getVelocity(entity: EntityWithBody): Vector | null {\n\tif (!entity.body) return null;\n\treturn entity.body.linvel();\n}\n\n/**\n * Set entity position\n */\nexport function setPosition(entity: EntityWithBody, x: number, y: number, z: number): void {\n\tif (!entity.body) return;\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity X position\n */\nexport function setPositionX(entity: EntityWithBody, x: number): void {\n\tif (!entity.body) return;\n\tconst { y, z } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity Y position\n */\nexport function setPositionY(entity: EntityWithBody, y: number): void {\n\tif (!entity.body) return;\n\tconst { x, z } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity Z position\n */\nexport function setPositionZ(entity: EntityWithBody, z: number): void {\n\tif (!entity.body) return;\n\tconst { x, y } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Wrap entity around 2D bounds\n */\nexport function wrapAroundXY(entity: EntityWithBody, boundsX: number, boundsY: number): void {\n\tconst position = getPosition(entity);\n\tif (!position) return;\n\n\tconst { x, y } = position;\n\tconst newX = x > boundsX ? -boundsX : (x < -boundsX ? boundsX : x);\n\tconst newY = y > boundsY ? -boundsY : (y < -boundsY ? boundsY : y);\n\n\tif (newX !== x || newY !== y) {\n\t\tsetPosition(entity, newX, newY, 0);\n\t}\n}\n\n/**\n * Wrap entity around 3D bounds\n */\nexport function wrapAround3D(entity: EntityWithBody, boundsX: number, boundsY: number, boundsZ: number): void {\n\tconst position = getPosition(entity);\n\tif (!position) return;\n\n\tconst { x, y, z } = position;\n\tconst newX = x > boundsX ? -boundsX : (x < -boundsX ? boundsX : x);\n\tconst newY = y > boundsY ? -boundsY : (y < -boundsY ? boundsY : y);\n\tconst newZ = z > boundsZ ? -boundsZ : (z < -boundsZ ? boundsZ : z);\n\n\tif (newX !== x || newY !== y || newZ !== z) {\n\t\tsetPosition(entity, newX, newY, newZ);\n\t}\n}\n\n/**\n * Enhanced moveable entity with bound methods\n */\nexport interface MoveableEntity extends EntityWithBody {\n\tmoveX(delta: number): void;\n\tmoveY(delta: number): void;\n\tmoveZ(delta: number): void;\n\tmoveXY(deltaX: number, deltaY: number): void;\n\tmoveXZ(deltaX: number, deltaZ: number): void;\n\tmove(vector: Vector3): void;\n\tresetVelocity(): void;\n\tmoveForwardXY(delta: number, rotation2DAngle: number): void;\n\tgetPosition(): Vector | null;\n\tgetVelocity(): Vector | null;\n\tsetPosition(x: number, y: number, z: number): void;\n\tsetPositionX(x: number): void;\n\tsetPositionY(y: number): void;\n\tsetPositionZ(z: number): void;\n\twrapAroundXY(boundsX: number, boundsY: number): void;\n\twrapAround3D(boundsX: number, boundsY: number, boundsZ: number): void;\n}\n\n/**\n * Enhance an entity with additive movement methods.\n * Automatically creates a transform store if one doesn't exist.\n */\nexport function makeMoveable<T extends EntityWithBody>(entity: T): T & MoveableEntity {\n\tconst moveable = entity as T & MoveableEntity;\n\n\t// Create transform store if it doesn't exist\n\tif (!moveable.transformStore) {\n\t\tmoveable.transformStore = createTransformStore();\n\t}\n\n\tmoveable.moveX = (delta: number) => moveX(entity, delta);\n\tmoveable.moveY = (delta: number) => moveY(entity, delta);\n\tmoveable.moveZ = (delta: number) => moveZ(entity, delta);\n\tmoveable.moveXY = (deltaX: number, deltaY: number) => moveXY(entity, deltaX, deltaY);\n\tmoveable.moveXZ = (deltaX: number, deltaZ: number) => moveXZ(entity, deltaX, deltaZ);\n\tmoveable.move = (vector: Vector3) => move(entity, vector);\n\tmoveable.resetVelocity = () => resetVelocity(entity);\n\tmoveable.moveForwardXY = (delta: number, rotation2DAngle: number) => moveForwardXY(entity, delta, rotation2DAngle);\n\tmoveable.getPosition = () => getPosition(entity);\n\tmoveable.getVelocity = () => getVelocity(entity);\n\tmoveable.setPosition = (x: number, y: number, z: number) => setPosition(entity, x, y, z);\n\tmoveable.setPositionX = (x: number) => setPositionX(entity, x);\n\tmoveable.setPositionY = (y: number) => setPositionY(entity, y);\n\tmoveable.setPositionZ = (z: number) => setPositionZ(entity, z);\n\tmoveable.wrapAroundXY = (boundsX: number, boundsY: number) => wrapAroundXY(entity, boundsX, boundsY);\n\tmoveable.wrapAround3D = (boundsX: number, boundsY: number, boundsZ: number) => wrapAround3D(entity, boundsX, boundsY, boundsZ);\n\n\treturn moveable;\n}","/**\n * In-memory implementation of the {@link BehaviorRuntime} contract for unit\n * tests. Records every attach / input call per handle and lets tests seed\n * poses and behavior snapshots without instantiating the wasm runtime.\n */\n\nimport type {\n\tBehaviorRuntime,\n\tStageBehaviorSnapshot,\n\tStageBoundaryDimValue,\n\tStageFirstPersonInput,\n\tStageFirstPersonOptions,\n\tStageJumper2DOptions,\n\tStageJumper3DOptions,\n\tStagePlatformer2DOptions,\n\tStagePlatformer3DOptions,\n\tStagePose,\n\tStageRicochetDimValue,\n\tStageRicochetOptions,\n\tStageScreenWrapOptions,\n\tStageShooter2DOptions,\n\tStageThrusterOptions,\n\tStageTopDownOptions,\n\tStageWorldBoundaryOptions,\n} from './wasm-stage-runtime';\n\ninterface MockSlotState {\n\tpose: StagePose;\n\tsnapshot: StageBehaviorSnapshot | null;\n\tinput: {\n\t\taxisA: number;\n\t\taxisB: number;\n\t\tyawDelta: number;\n\t\tpitchDelta: number;\n\t\treservedA: number;\n\t\treservedB: number;\n\t\tbuttons: number;\n\t};\n\tattachments: Map<string, unknown>;\n\tinputs: Array<{ kind: string; args: unknown[] }>;\n\tscreenWrapQuery: { fsm: number; lastWrappedAxes: number } | null;\n\tworldBoundaryQuery: { hits: number; clamped: [number, number, number] } | null;\n}\n\nfunction freshSlot(): MockSlotState {\n\treturn {\n\t\tpose: { position: [0, 0, 0], rotation: [0, 0, 0, 1] },\n\t\tsnapshot: null,\n\t\tinput: { axisA: 0, axisB: 0, yawDelta: 0, pitchDelta: 0, reservedA: 0, reservedB: 0, buttons: 0 },\n\t\tattachments: new Map(),\n\t\tinputs: [],\n\t\tscreenWrapQuery: null,\n\t\tworldBoundaryQuery: null,\n\t};\n}\n\nexport class MockBehaviorRuntime implements BehaviorRuntime {\n\tprivate slots = new Map<number, MockSlotState>();\n\n\tprivate slot(handle: number): MockSlotState {\n\t\tlet state = this.slots.get(handle);\n\t\tif (!state) {\n\t\t\tstate = freshSlot();\n\t\t\tthis.slots.set(handle, state);\n\t\t}\n\t\treturn state;\n\t}\n\n\t// ─── Test seams ─────────────────────────────────────────────────────\n\n\t/** Seed the pose returned by {@link getPose} for a handle. */\n\tsetPose(handle: number, pose: StagePose): void {\n\t\tthis.slot(handle).pose = pose;\n\t}\n\n\t/** Seed the snapshot returned by {@link readSnapshot} for a handle. */\n\tsetSnapshot(handle: number, snapshot: StageBehaviorSnapshot | null): void {\n\t\tthis.slot(handle).snapshot = snapshot;\n\t}\n\n\t/** Seed {@link queryScreenWrap} results. */\n\tsetScreenWrapQuery(handle: number, value: { fsm: number; lastWrappedAxes: number } | null): void {\n\t\tthis.slot(handle).screenWrapQuery = value;\n\t}\n\n\t/** Seed {@link queryWorldBoundary} results. */\n\tsetWorldBoundaryQuery(\n\t\thandle: number,\n\t\tvalue: { hits: number; clamped: [number, number, number] } | null,\n\t): void {\n\t\tthis.slot(handle).worldBoundaryQuery = value;\n\t}\n\n\t/** Attachment options recorded for a handle, keyed by behavior name. */\n\tgetAttachment<T>(handle: number, kind: string): T | undefined {\n\t\treturn this.slots.get(handle)?.attachments.get(kind) as T | undefined;\n\t}\n\n\thasAttachment(handle: number, kind: string): boolean {\n\t\treturn this.slots.get(handle)?.attachments.has(kind) ?? false;\n\t}\n\n\t/** Every per-entity input call recorded for a handle, oldest first. */\n\tgetInputCalls(handle: number): Array<{ kind: string; args: unknown[] }> {\n\t\treturn this.slots.get(handle)?.inputs ?? [];\n\t}\n\n\t/** Last written batched-input state for a handle. */\n\tgetBatchedInput(handle: number): MockSlotState['input'] {\n\t\treturn this.slot(handle).input;\n\t}\n\n\treset(): void {\n\t\tthis.slots.clear();\n\t}\n\n\t// ─── BehaviorRuntime contract ───────────────────────────────────────\n\n\tsetPosition(handle: number, x: number, y: number, z: number): boolean {\n\t\tconst pose = this.slot(handle).pose;\n\t\tpose.position[0] = x;\n\t\tpose.position[1] = y;\n\t\tpose.position[2] = z;\n\t\treturn true;\n\t}\n\n\tsetRotation(handle: number, x: number, y: number, z: number, w: number): boolean {\n\t\tconst pose = this.slot(handle).pose;\n\t\tpose.rotation[0] = x;\n\t\tpose.rotation[1] = y;\n\t\tpose.rotation[2] = z;\n\t\tpose.rotation[3] = w;\n\t\treturn true;\n\t}\n\n\tgetPose(handle: number, out?: StagePose): StagePose | null {\n\t\tconst state = this.slots.get(handle);\n\t\tif (!state) return null;\n\t\tconst result = out ?? { position: [0, 0, 0], rotation: [0, 0, 0, 1] } as StagePose;\n\t\tresult.position[0] = state.pose.position[0];\n\t\tresult.position[1] = state.pose.position[1];\n\t\tresult.position[2] = state.pose.position[2];\n\t\tresult.rotation[0] = state.pose.rotation[0];\n\t\tresult.rotation[1] = state.pose.rotation[1];\n\t\tresult.rotation[2] = state.pose.rotation[2];\n\t\tresult.rotation[3] = state.pose.rotation[3];\n\t\treturn result;\n\t}\n\n\twriteInputAxes(handle: number, axisA: number, axisB: number): boolean {\n\t\tconst input = this.slot(handle).input;\n\t\tinput.axisA = axisA;\n\t\tinput.axisB = axisB;\n\t\treturn true;\n\t}\n\n\twriteInputLook(handle: number, yawDelta: number, pitchDelta: number): boolean {\n\t\tconst input = this.slot(handle).input;\n\t\tinput.yawDelta = yawDelta;\n\t\tinput.pitchDelta = pitchDelta;\n\t\treturn true;\n\t}\n\n\twriteInputReserved(handle: number, reservedA: number, reservedB: number): boolean {\n\t\tconst input = this.slot(handle).input;\n\t\tinput.reservedA = reservedA;\n\t\tinput.reservedB = reservedB;\n\t\treturn true;\n\t}\n\n\twriteInputButton(handle: number, buttonMask: number, pressed: boolean): boolean {\n\t\tconst input = this.slot(handle).input;\n\t\tinput.buttons = pressed ? (input.buttons | buttonMask) : (input.buttons & ~buttonMask);\n\t\treturn true;\n\t}\n\n\treadSnapshot(handle: number, out?: StageBehaviorSnapshot): StageBehaviorSnapshot | null {\n\t\tconst snapshot = this.slots.get(handle)?.snapshot ?? null;\n\t\tif (!snapshot) return null;\n\t\tif (!out) return { ...snapshot };\n\t\tObject.assign(out, snapshot);\n\t\treturn out;\n\t}\n\n\tattachThruster(handle: number, opts: StageThrusterOptions): boolean {\n\t\tthis.slot(handle).attachments.set('thruster', opts);\n\t\treturn true;\n\t}\n\n\tsetThrusterInput(\n\t\thandle: number,\n\t\tthrust: number,\n\t\trotate: number,\n\t\tvectorX = 0,\n\t\tvectorY = 0,\n\t): void {\n\t\tthis.slot(handle).inputs.push({\n\t\t\tkind: 'thruster',\n\t\t\targs: [thrust, rotate, vectorX, vectorY],\n\t\t});\n\t}\n\n\tattachTopDown(handle: number, opts: StageTopDownOptions): boolean {\n\t\tthis.slot(handle).attachments.set('topDown', opts);\n\t\treturn true;\n\t}\n\n\tsetTopDownInput(handle: number, moveX: number, moveY: number): void {\n\t\tthis.slot(handle).inputs.push({ kind: 'topDown', args: [moveX, moveY] });\n\t}\n\n\tattachShooter2D(handle: number, opts: StageShooter2DOptions): boolean {\n\t\tthis.slot(handle).attachments.set('shooter2d', opts);\n\t\treturn true;\n\t}\n\n\tattachScreenWrap(handle: number, opts: StageScreenWrapOptions): boolean {\n\t\tthis.slot(handle).attachments.set('screenWrap', opts);\n\t\treturn true;\n\t}\n\n\tqueryScreenWrap(handle: number): { fsm: number; lastWrappedAxes: number } | null {\n\t\treturn this.slots.get(handle)?.screenWrapQuery ?? null;\n\t}\n\n\tattachWorldBoundary(\n\t\thandle: number,\n\t\tdim: StageBoundaryDimValue,\n\t\topts: StageWorldBoundaryOptions,\n\t): boolean {\n\t\tthis.slot(handle).attachments.set('worldBoundary', { dim, ...opts });\n\t\treturn true;\n\t}\n\n\tqueryWorldBoundary(handle: number): { hits: number; clamped: [number, number, number] } | null {\n\t\treturn this.slots.get(handle)?.worldBoundaryQuery ?? null;\n\t}\n\n\tattachRicochet(handle: number, dim: StageRicochetDimValue, opts: StageRicochetOptions): boolean {\n\t\tthis.slot(handle).attachments.set('ricochet', { dim, ...opts });\n\t\treturn true;\n\t}\n\n\tattachPlatformer3D(handle: number, opts: StagePlatformer3DOptions): boolean {\n\t\tthis.slot(handle).attachments.set('platformer3d', opts);\n\t\treturn true;\n\t}\n\n\tsetPlatformer3DInputAxes(handle: number, moveX: number, moveZ: number): void {\n\t\tthis.slot(handle).inputs.push({ kind: 'platformer3dAxes', args: [moveX, moveZ] });\n\t}\n\n\tsetPlatformer3DInputButtons(handle: number, jump: boolean, run: boolean): void {\n\t\tthis.slot(handle).inputs.push({ kind: 'platformer3dButtons', args: [jump, run] });\n\t}\n\n\tattachPlatformer2D(handle: number, opts: StagePlatformer2DOptions): boolean {\n\t\tthis.slot(handle).attachments.set('platformer2d', opts);\n\t\treturn true;\n\t}\n\n\tsetPlatformer2DInputAxes(handle: number, moveX: number): void {\n\t\tthis.slot(handle).inputs.push({ kind: 'platformer2dAxes', args: [moveX] });\n\t}\n\n\tsetPlatformer2DInputButtons(handle: number, jump: boolean, run: boolean): void {\n\t\tthis.slot(handle).inputs.push({ kind: 'platformer2dButtons', args: [jump, run] });\n\t}\n\n\tattachFirstPerson(handle: number, opts: StageFirstPersonOptions): boolean {\n\t\tthis.slot(handle).attachments.set('firstPerson', opts);\n\t\treturn true;\n\t}\n\n\tsetFirstPersonInput(handle: number, input: StageFirstPersonInput): void {\n\t\tthis.slot(handle).inputs.push({ kind: 'firstPerson', args: [input] });\n\t}\n\n\tattachJumper2D(handle: number, opts: StageJumper2DOptions): boolean {\n\t\tthis.slot(handle).attachments.set('jumper2d', opts);\n\t\treturn true;\n\t}\n\n\tsetJumper2DInput(handle: number, jumpPressed: boolean): void {\n\t\tthis.slot(handle).inputs.push({ kind: 'jumper2d', args: [jumpPressed] });\n\t}\n\n\tattachJumper3D(handle: number, opts: StageJumper3DOptions): boolean {\n\t\tthis.slot(handle).attachments.set('jumper3d', opts);\n\t\treturn true;\n\t}\n\n\tsetJumper3DInput(handle: number, jumpPressed: boolean): void {\n\t\tthis.slot(handle).inputs.push({ kind: 'jumper3d', args: [jumpPressed] });\n\t}\n}\n","/**\n * `Simulation` (a.k.a. `BehaviorWorld`) — the primary public abstraction of\n * `@zylem/behaviors`. It owns the wasm runtime lifecycle (one\n * `WebAssembly.Instance` of `@zylem/runtime` per simulation), the fixed\n * timestep accumulator, an entity registry mapping opaque\n * {@link EntityHandle}s to runtime slots, and per-step event translation\n * from raw stage events into typed {@link SimulationEvent}s.\n *\n * Hosts (e.g. `@zylem/game-lib`) call {@link createSimulation} once per\n * stage, `spawn()`/`despawn()` entities, call `update(delta)` once per\n * render frame, and read poses for rendering from the returned\n * {@link SimulationFrame}.\n */\n\nimport {\n\tWasmStageRuntime,\n\tcreateWasmStageRuntime,\n\tStageBodyKind,\n\tStageEventType,\n\tSTAGE_RENDER_STRIDE,\n\treadStageRenderSlot,\n\ttype StageBehaviorSnapshot,\n\ttype StageBodyConfig,\n\ttype StageBodyKindValue,\n\ttype StageColliderConfig,\n\ttype StageColliderShape,\n\ttype StageDebugRender,\n\ttype StageBodyInfo,\n\ttype StageEvent,\n\ttype StagePose,\n\ttype StageRaycastHit,\n\ttype StageRenderSlot,\n\ttype WasmStageRuntimeOptions,\n} from './wasm-stage-runtime';\n\n/**\n * Opaque, stable identifier for a simulation entity. `slot` is the raw\n * runtime slot index — treat it as an implementation detail owned by the\n * Simulation (it is only exposed so hosts can wire behavior systems, which\n * address the batched buffers by slot).\n */\nexport interface EntityHandle {\n\t/** Monotonic public id, never reused within a Simulation. */\n\treadonly id: number;\n\t/** Raw runtime slot index. Internal — may be reused after despawn. */\n\treadonly slot: number;\n}\n\n/** Partial body description; unspecified fields use sensible defaults. */\nexport interface SimulationBodyDefinition {\n\tkind?: StageBodyKindValue;\n\tposition?: readonly [number, number, number];\n\trotation?: readonly [number, number, number, number];\n\tlinearDamping?: number;\n\tangularDamping?: number;\n\tgravityScale?: number;\n\tcanSleep?: boolean;\n\tccdEnabled?: boolean;\n\tlockRotation?: readonly [boolean, boolean, boolean];\n\tlockTranslation?: readonly [boolean, boolean, boolean];\n}\n\n/** Partial collider description; unspecified fields use sensible defaults. */\nexport interface SimulationColliderDefinition {\n\tshape: StageColliderShape;\n\toffset?: readonly [number, number, number];\n\tfriction?: number;\n\trestitution?: number;\n\tsensor?: boolean;\n\tcollisionGroups?: number;\n}\n\n/** Everything needed to materialize one entity inside the runtime. */\nexport interface EntityDefinition {\n\tbody?: SimulationBodyDefinition;\n\tcolliders?: SimulationColliderDefinition[];\n}\n\n/** Typed, handle-resolved simulation event. */\nexport type SimulationEvent =\n\t| {\n\t\ttype: 'collisionStarted' | 'collisionStopped';\n\t\ta: EntityHandle | null;\n\t\tb: EntityHandle | null;\n\t\t/** True when either collider in the pair is a sensor (zone overlap). */\n\t\tsensor: boolean;\n\t\t/** Best-effort contact normal (x, y); zero for sensor pairs / stops. */\n\t\tnormal: [number, number];\n\t}\n\t| { type: 'boundaryHit'; entity: EntityHandle | null; axes: number; signs: number }\n\t| { type: 'ricochet'; entity: EntityHandle | null; kind: number }\n\t| { type: 'regionEntered'; entity: EntityHandle | null; triggerId: number }\n\t| { type: 'jumpStarted'; entity: EntityHandle | null; jumpCount: number }\n\t| { type: 'landed'; entity: EntityHandle | null }\n\t| { type: 'wrapped'; entity: EntityHandle | null; axes: number }\n\t| { type: 'cooldownFired'; entity: EntityHandle | null; cooldownId: number };\n\n/**\n * Snapshot of one `update()` call: how many fixed steps ran, the live render\n * buffer view, the previous-step render copy + interpolation alpha for\n * smooth rendering, and the translated events from every step taken.\n */\nexport interface SimulationFrame {\n\t/** Wall-clock delta handed to `update()`. */\n\tdeltaTime: number;\n\t/** Number of fixed steps executed (0 when accumulating). */\n\tstepsTaken: number;\n\t/** Interpolation alpha in [0, 1): fraction of a fixed step accumulated. */\n\talpha: number;\n\t/** Live render buffer (post-step poses), {@link STAGE_RENDER_STRIDE} floats per slot. */\n\trender: Float32Array;\n\t/** Copy of the render buffer as of the step before the last one. */\n\tpreviousRender: Float32Array;\n\trenderStride: number;\n\t/** Typed events from all steps taken this update, oldest first. */\n\tevents: SimulationEvent[];\n}\n\nexport interface SimulationOptions extends WasmStageRuntimeOptions {\n\t/** Fixed physics timestep in seconds (default 1/60). */\n\tfixedTimestep?: number;\n\t/** Max fixed steps per `update()` to avoid death spirals (default 4). */\n\tmaxSubSteps?: number;\n}\n\nconst DEFAULT_FIXED_TIMESTEP = 1 / 60;\nconst DEFAULT_MAX_SUB_STEPS = 4;\n\n/**\n * The behavior world. Construct via {@link createSimulation}.\n */\nexport class Simulation {\n\t/**\n\t * The low-level wasm adapter. Behavior systems receive this as their\n\t * `wasmStage` context so descriptors can attach/query behaviors by slot;\n\t * hosts should prefer the handle-based methods on the Simulation itself.\n\t */\n\treadonly adapter: WasmStageRuntime;\n\n\treadonly fixedTimestep: number;\n\tprivate readonly maxSubSteps: number;\n\n\tprivate accumulator = 0;\n\tprivate nextEntityId = 1;\n\tprivate slotToHandle = new Map<number, EntityHandle>();\n\tprivate idToHandle = new Map<number, EntityHandle>();\n\tprivate previousRender: Float32Array = new Float32Array(0);\n\tprivate disposed = false;\n\n\tconstructor(adapter: WasmStageRuntime, options: SimulationOptions = {}) {\n\t\tthis.adapter = adapter;\n\t\tthis.fixedTimestep = options.fixedTimestep ?? DEFAULT_FIXED_TIMESTEP;\n\t\tthis.maxSubSteps = Math.max(1, options.maxSubSteps ?? DEFAULT_MAX_SUB_STEPS);\n\t}\n\n\t// ─── Entity lifecycle ───────────────────────────────────────────────\n\n\t/**\n\t * Create a runtime entity from a plain definition. Returns `null` when\n\t * the runtime rejects the allocation.\n\t */\n\tspawn(definition: EntityDefinition = {}): EntityHandle | null {\n\t\tconst slot = this.adapter.createEntity();\n\t\tif (slot === 0xffffffff) return null;\n\n\t\tconst body = definition.body;\n\t\tconst bodyConfig: StageBodyConfig = {\n\t\t\tkind: body?.kind ?? StageBodyKind.Dynamic,\n\t\t\tposition: body?.position ?? [0, 0, 0],\n\t\t\trotation: body?.rotation ?? [0, 0, 0, 1],\n\t\t\tlinearDamping: body?.linearDamping ?? 0,\n\t\t\tangularDamping: body?.angularDamping ?? 0,\n\t\t\tgravityScale: body?.gravityScale ?? 1,\n\t\t\tcanSleep: body?.canSleep ?? false,\n\t\t\tccdEnabled: body?.ccdEnabled ?? true,\n\t\t\tlockRotation: body?.lockRotation ?? [false, false, false],\n\t\t\tlockTranslation: body?.lockTranslation ?? [false, false, false],\n\t\t};\n\t\tthis.adapter.attachBody(slot, bodyConfig);\n\n\t\tfor (const collider of definition.colliders ?? []) {\n\t\t\tconst config: StageColliderConfig = {\n\t\t\t\tshape: collider.shape,\n\t\t\t\toffset: collider.offset ?? [0, 0, 0],\n\t\t\t\tfriction: collider.friction ?? 0.5,\n\t\t\t\trestitution: collider.restitution ?? 0,\n\t\t\t\tsensor: collider.sensor ?? false,\n\t\t\t\tcollisionGroups: collider.collisionGroups ?? 0xffffffff,\n\t\t\t};\n\t\t\tthis.adapter.addCollider(slot, config);\n\t\t}\n\n\t\tconst handle: EntityHandle = { id: this.nextEntityId++, slot };\n\t\tthis.slotToHandle.set(slot, handle);\n\t\tthis.idToHandle.set(handle.id, handle);\n\t\treturn handle;\n\t}\n\n\tdespawn(handle: EntityHandle): boolean {\n\t\tconst registered = this.idToHandle.get(handle.id);\n\t\tif (!registered) return false;\n\t\tthis.idToHandle.delete(handle.id);\n\t\tif (this.slotToHandle.get(registered.slot) === registered) {\n\t\t\tthis.slotToHandle.delete(registered.slot);\n\t\t}\n\t\treturn this.adapter.destroyEntity(registered.slot);\n\t}\n\n\t/** Resolve a raw runtime slot back to its public handle, if alive. */\n\thandleForSlot(slot: number): EntityHandle | null {\n\t\treturn this.slotToHandle.get(slot) ?? null;\n\t}\n\n\tget entityCount(): number {\n\t\treturn this.idToHandle.size;\n\t}\n\n\t// ─── Per-frame update ───────────────────────────────────────────────\n\n\t/**\n\t * Advance the simulation by `deltaTime` seconds using a fixed-timestep\n\t * accumulator. Runs zero or more fixed steps and returns a\n\t * {@link SimulationFrame} with translated events and interpolation data.\n\t */\n\tupdate(deltaTime: number): SimulationFrame {\n\t\tconst events: SimulationEvent[] = [];\n\t\tthis.accumulator += Math.max(0, deltaTime);\n\t\tlet steps = 0;\n\n\t\twhile (this.accumulator >= this.fixedTimestep && steps < this.maxSubSteps) {\n\t\t\tthis.capturePreviousRender();\n\t\t\tthis.adapter.step(this.fixedTimestep);\n\t\t\tthis.translateEvents(this.adapter.drainEvents(), events);\n\t\t\tthis.accumulator -= this.fixedTimestep;\n\t\t\tsteps++;\n\t\t}\n\t\t// Drop leftover time we couldn't consume (death-spiral guard).\n\t\tif (steps === this.maxSubSteps && this.accumulator >= this.fixedTimestep) {\n\t\t\tthis.accumulator = this.accumulator % this.fixedTimestep;\n\t\t}\n\n\t\treturn {\n\t\t\tdeltaTime,\n\t\t\tstepsTaken: steps,\n\t\t\talpha: this.fixedTimestep > 0 ? this.accumulator / this.fixedTimestep : 0,\n\t\t\trender: this.adapter.render,\n\t\t\tpreviousRender: this.previousRender,\n\t\t\trenderStride: STAGE_RENDER_STRIDE,\n\t\t\tevents,\n\t\t};\n\t}\n\n\tprivate capturePreviousRender(): void {\n\t\tconst current = this.adapter.render;\n\t\tif (this.previousRender.length !== current.length) {\n\t\t\tthis.previousRender = new Float32Array(current.length);\n\t\t}\n\t\tthis.previousRender.set(current);\n\t}\n\n\tprivate translateEvents(raw: StageEvent[], out: SimulationEvent[]): void {\n\t\tfor (const event of raw) {\n\t\t\tconst primary = event.primarySlot !== null ? this.handleForSlot(event.primarySlot) : null;\n\t\t\tconst secondary = event.secondarySlot !== null ? this.handleForSlot(event.secondarySlot) : null;\n\t\t\tswitch (event.type) {\n\t\t\t\tcase StageEventType.CollisionStarted:\n\t\t\t\tcase StageEventType.CollisionStopped:\n\t\t\t\t\tout.push({\n\t\t\t\t\t\ttype: event.type === StageEventType.CollisionStarted\n\t\t\t\t\t\t\t? 'collisionStarted'\n\t\t\t\t\t\t\t: 'collisionStopped',\n\t\t\t\t\t\ta: primary,\n\t\t\t\t\t\tb: secondary,\n\t\t\t\t\t\tsensor: event.payload[0] !== 0,\n\t\t\t\t\t\tnormal: [event.payload[1], event.payload[2]],\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase StageEventType.BoundaryHit:\n\t\t\t\t\tout.push({\n\t\t\t\t\t\ttype: 'boundaryHit',\n\t\t\t\t\t\tentity: primary,\n\t\t\t\t\t\taxes: event.payload[0] | 0,\n\t\t\t\t\t\tsigns: event.payload[1] | 0,\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase StageEventType.Ricochet:\n\t\t\t\t\tout.push({ type: 'ricochet', entity: primary, kind: event.payload[0] | 0 });\n\t\t\t\t\tbreak;\n\t\t\t\tcase StageEventType.RegionEntered:\n\t\t\t\t\tout.push({ type: 'regionEntered', entity: primary, triggerId: event.payload[0] | 0 });\n\t\t\t\t\tbreak;\n\t\t\t\tcase StageEventType.JumpStarted:\n\t\t\t\t\tout.push({ type: 'jumpStarted', entity: primary, jumpCount: event.payload[0] | 0 });\n\t\t\t\t\tbreak;\n\t\t\t\tcase StageEventType.Landed:\n\t\t\t\t\tout.push({ type: 'landed', entity: primary });\n\t\t\t\t\tbreak;\n\t\t\t\tcase StageEventType.Wrapped:\n\t\t\t\t\tout.push({ type: 'wrapped', entity: primary, axes: event.payload[0] | 0 });\n\t\t\t\t\tbreak;\n\t\t\t\tcase StageEventType.CooldownFired:\n\t\t\t\t\tout.push({ type: 'cooldownFired', entity: primary, cooldownId: event.payload[0] | 0 });\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// ─── Handle-based reads / writes ────────────────────────────────────\n\n\tgetPose(handle: EntityHandle, out?: StagePose): StagePose | null {\n\t\treturn this.adapter.getPose(handle.slot, out);\n\t}\n\n\tsetPosition(handle: EntityHandle, x: number, y: number, z: number): boolean {\n\t\treturn this.adapter.setPosition(handle.slot, x, y, z);\n\t}\n\n\tsetRotation(handle: EntityHandle, x: number, y: number, z: number, w: number): boolean {\n\t\treturn this.adapter.setRotation(handle.slot, x, y, z, w);\n\t}\n\n\tsetLinearVelocity(handle: EntityHandle, x: number, y: number, z: number): boolean {\n\t\treturn this.adapter.setLinearVelocity(handle.slot, x, y, z);\n\t}\n\n\tgetLinearVelocity(handle: EntityHandle): [number, number, number] | null {\n\t\treturn this.adapter.getLinearVelocity(handle.slot);\n\t}\n\n\tsetAngularVelocity(handle: EntityHandle, x: number, y: number, z: number): boolean {\n\t\treturn this.adapter.setAngularVelocity(handle.slot, x, y, z);\n\t}\n\n\tapplyImpulse(handle: EntityHandle, x: number, y: number, z: number): boolean {\n\t\treturn this.adapter.applyImpulse(handle.slot, x, y, z);\n\t}\n\n\treadRenderSlot(handle: EntityHandle, out?: StageRenderSlot): StageRenderSlot | null {\n\t\treturn readStageRenderSlot(this.adapter.render, handle.slot, out);\n\t}\n\n\t/** Decode a handle's pose from the previous-step render copy. */\n\treadPreviousRenderSlot(handle: EntityHandle, out?: StageRenderSlot): StageRenderSlot | null {\n\t\treturn readStageRenderSlot(this.previousRender, handle.slot, out);\n\t}\n\n\treadSnapshot(handle: EntityHandle, out?: StageBehaviorSnapshot): StageBehaviorSnapshot | null {\n\t\treturn this.adapter.readSnapshot(handle.slot, out);\n\t}\n\n\t// ─── World-level controls / diagnostics ─────────────────────────────\n\n\tsetGravity(x: number, y: number, z: number): void {\n\t\tthis.adapter.setGravity(x, y, z);\n\t}\n\n\t/** Physics raycast; the hit's slot is resolved to an entity handle. */\n\tcastRay(\n\t\torigin: readonly [number, number, number],\n\t\tdir: readonly [number, number, number],\n\t\tmaxDistance: number,\n\t\tsolidOnly = true,\n\t): (Omit<StageRaycastHit, 'slot'> & { entity: EntityHandle | null }) | null {\n\t\tconst hit = this.adapter.castRay(origin, dir, maxDistance, solidOnly);\n\t\tif (!hit) return null;\n\t\treturn {\n\t\t\tdistance: hit.distance,\n\t\t\tnormal: hit.normal,\n\t\t\tentity: this.handleForSlot(hit.slot),\n\t\t};\n\t}\n\n\tgetBodyInfo(handle: EntityHandle): StageBodyInfo | null {\n\t\treturn this.adapter.getBodyInfo(handle.slot);\n\t}\n\n\tgetDebugRender(): StageDebugRender | null {\n\t\treturn this.adapter.getDebugRender();\n\t}\n\n\tget isDisposed(): boolean {\n\t\treturn this.disposed;\n\t}\n\n\t/** Destroy the wasm stage. The Simulation must not be used afterwards. */\n\tdispose(): void {\n\t\tif (this.disposed) return;\n\t\tthis.disposed = true;\n\t\tthis.slotToHandle.clear();\n\t\tthis.idToHandle.clear();\n\t\tthis.adapter.dispose();\n\t}\n}\n\n/** Alias matching the architecture doc's naming. */\nexport type BehaviorWorld = Simulation;\n\n/**\n * Load and instantiate the `@zylem/runtime` wasm module and wrap it in a\n * {@link Simulation}. One call per logical stage/world.\n */\nexport async function createSimulation(options: SimulationOptions = {}): Promise<Simulation> {\n\tconst adapter = await createWasmStageRuntime(options);\n\treturn new Simulation(adapter, options);\n}\n","import type {\n\tBehaviorDescriptor,\n\tBehaviorHandle,\n\tBehaviorRef,\n} from '../behaviors/behavior-descriptor';\nimport type { TransformState } from '../capabilities/transform-store';\n\n/**\n * Minimal, runtime-agnostic entity options contract.\n *\n * The full engine entity (in `@zylem/game-lib`) provides a richer options type,\n * but behaviors only rely on this loose shape.\n */\nexport interface GameEntityOptions {\n\t[key: string]: any;\n\tname?: string;\n}\n\n/**\n * Structural stand-in for the engine `GameEntity`.\n *\n * Behaviors annotate against this loose contract so that `@zylem/behaviors`\n * (and its `@zylem/behaviors/core` surface) never has to depend on the concrete\n * `@zylem/game-lib` entity implementation. The real engine entity is\n * structurally assignable to this type.\n */\nexport class GameEntity<TOptions = unknown> {\n\t[key: string]: any;\n\n\tuuid!: string;\n\tname!: string;\n\ttype!: string;\n\toptions?: TOptions & Record<string, unknown>;\n\tgroup: any = null;\n\tmesh?: any;\n\tmaterials?: any[];\n\t/** Opaque host-owned physics references (never inspected by behaviors). */\n\tbody: unknown | null = null;\n\tcollider: unknown | null = null;\n\tcolliderDesc?: any;\n\tcolliderDescs: any[] = [];\n\tbodyDesc?: any;\n\tphysicsAttached = false;\n\truntimeHandle?: number;\n\ttransformStore?: TransformState;\n\tnodeDestroy?: any;\n\tisInstanced?: boolean;\n\n\tprivate __behaviorRefs: BehaviorRef<any>[] = [];\n\n\tcreate(): this {\n\t\treturn this;\n\t}\n\n\tonCleanup(callback: () => void): this {\n\t\tvoid callback;\n\t\treturn this;\n\t}\n\n\tsetPosition(_x: number, _y: number, _z: number): void {}\n\tsetRotation(_x: number, _y: number, _z: number): void {}\n\tsetRotationZ(_z: number): void {}\n\tsetScale(_x: number, _y: number, _z: number): void {}\n\n\t/**\n\t * Attach a behavior to this entity. The real engine entity does substantially\n\t * more, but this functional stub stores the merged ref and builds the handle\n\t * so descriptor/handle logic (and tests that drive behaviors directly) work\n\t * without the full engine.\n\t */\n\tuse<\n\t\tO extends Record<string, any>,\n\t\tH extends Record<string, any> = Record<string, never>,\n\t>(\n\t\tdescriptor: BehaviorDescriptor<O, H>,\n\t\toptions?: Partial<O>,\n\t): BehaviorHandle<O, H> {\n\t\tconst mergedOptions = {\n\t\t\t...(descriptor.defaultOptions as O),\n\t\t\t...(options ?? {}),\n\t\t} as O;\n\t\tconst ref: BehaviorRef<O> = { descriptor, options: mergedOptions };\n\t\tthis.__behaviorRefs.push(ref as BehaviorRef<any>);\n\n\t\tconst baseHandle = {\n\t\t\tgetFSM: () => ref.fsm ?? null,\n\t\t\tgetOptions: () => ref.options,\n\t\t\tref,\n\t\t};\n\t\tconst extra = descriptor.createHandle\n\t\t\t? descriptor.createHandle(ref)\n\t\t\t: ({} as H);\n\t\treturn { ...baseHandle, ...extra } as BehaviorHandle<O, H>;\n\t}\n\n\t/** Live behavior refs attached via {@link use}. */\n\tgetBehaviorRefs(): BehaviorRef<any>[] {\n\t\treturn this.__behaviorRefs;\n\t}\n}\n\n/**\n * Factory contract injected into behavior systems via\n * {@link BehaviorSystemContext.createEntity}. The host engine supplies the real\n * entity factory at stage-construction time.\n */\nexport type CreateEntityFn = (\n\toptions?: Partial<GameEntityOptions>,\n) => GameEntity<GameEntityOptions>;\n"],"mappings":"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","names":["moveX","moveY","moveZ"]}
1
+ {"version":3,"sources":["../src/lib/capabilities/transform-store.ts","../src/lib/capabilities/velocity-intents.ts","../src/lib/capabilities/moveable.ts","../src/lib/runtime/mock-behavior-runtime.ts","../src/lib/runtime/simulation.ts","../src/lib/entities/entity.ts"],"sourcesContent":["import { proxy } from 'valtio/vanilla';\n\nexport type VelocityIntentMode = 'replace' | 'add';\n\nexport interface VelocityIntent {\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\tmode: VelocityIntentMode;\n\tpriority?: number;\n}\n\n/**\n * Transform state managed by Valtio for per-frame physics intent accumulation.\n * \n * This store accumulates transformation intents during the frame,\n * then applies them all at once after onUpdate() callbacks complete.\n * \n * Design decisions:\n * - Position: Accumulated deltas (additive)\n * - Rotation: Last value wins (replacement)\n * - Velocity: Accumulated deltas (additive)\n * - Angular velocity: Accumulated deltas (additive)\n */\nexport interface TransformState {\n\t/** Position deltas to be applied (accumulated) */\n\tposition: { x: number; y: number; z: number };\n\t\n\t/** Rotation quaternion (last value wins) */\n\trotation: { x: number; y: number; z: number; w: number };\n\t\n\t/** Linear velocity (accumulated) */\n\tvelocity: { x: number; y: number; z: number };\n\t\n\t/** Angular velocity (accumulated) */\n\tangularVelocity: { x: number; y: number; z: number };\n\n\t/** Per-source velocity intents composed once per frame */\n\tvelocityChannels: Record<string, VelocityIntent>;\n\t\n\t/** Dirty flags to track what needs to be applied */\n\tdirty: {\n\t\tposition: boolean;\n\t\trotation: boolean;\n\t\tvelocityX: boolean;\n\t\tvelocityY: boolean;\n\t\tvelocityZ: boolean;\n\t\tvelocityChannels: boolean;\n\t\tangularVelocity: boolean;\n\t};\n}\n\n/**\n * Create a new transform store with optional initial values.\n * The store is a Valtio proxy, making it reactive for debugging/visualization.\n * \n * @param initial Optional initial state values\n * @returns Reactive transform state\n */\nexport function createTransformStore(initial?: Partial<TransformState>): TransformState {\n\tconst defaultState: TransformState = {\n\t\tposition: { x: 0, y: 0, z: 0 },\n\t\trotation: { x: 0, y: 0, z: 0, w: 1 },\n\t\tvelocity: { x: 0, y: 0, z: 0 },\n\t\tangularVelocity: { x: 0, y: 0, z: 0 },\n\t\tvelocityChannels: {},\n\t\tdirty: {\n\t\t\tposition: false,\n\t\t\trotation: false,\n\t\t\tvelocityX: false,\n\t\t\tvelocityY: false,\n\t\t\tvelocityZ: false,\n\t\t\tvelocityChannels: false,\n\t\t\tangularVelocity: false,\n\t\t},\n\t};\n\n\treturn proxy({\n\t\t...defaultState,\n\t\t...initial,\n\t\t// Ensure dirty flags are properly initialized even if partial initial state\n\t\tdirty: {\n\t\t\t...defaultState.dirty,\n\t\t\t...initial?.dirty,\n\t\t},\n\t});\n}\n\n","import { TransformState, VelocityIntentMode } from './transform-store';\n\nexport interface VelocityIntentOptions {\n\tmode?: VelocityIntentMode;\n\tpriority?: number;\n}\n\nexport interface VelocityIntentVector {\n\tx?: number;\n\ty?: number;\n\tz?: number;\n}\n\nexport function setVelocityIntent(\n\tstore: TransformState,\n\tsourceId: string,\n\tvector: VelocityIntentVector,\n\toptions: VelocityIntentOptions = {},\n): void {\n\tconst prev = store.velocityChannels[sourceId];\n\tconst mode = options.mode ?? prev?.mode ?? 'replace';\n\tconst priority = options.priority ?? prev?.priority ?? 0;\n\tconst isAdditiveMerge = mode === 'add' && prev?.mode === 'add';\n\n\tconst x =\n\t\tvector.x == null\n\t\t\t? prev?.x\n\t\t\t: isAdditiveMerge\n\t\t\t\t? (prev?.x ?? 0) + vector.x\n\t\t\t\t: vector.x;\n\tconst y =\n\t\tvector.y == null\n\t\t\t? prev?.y\n\t\t\t: isAdditiveMerge\n\t\t\t\t? (prev?.y ?? 0) + vector.y\n\t\t\t\t: vector.y;\n\tconst z =\n\t\tvector.z == null\n\t\t\t? prev?.z\n\t\t\t: isAdditiveMerge\n\t\t\t\t? (prev?.z ?? 0) + vector.z\n\t\t\t\t: vector.z;\n\n\tstore.velocityChannels[sourceId] = {\n\t\tx,\n\t\ty,\n\t\tz,\n\t\tmode,\n\t\tpriority,\n\t};\n\tstore.dirty.velocityChannels = true;\n}\n\nexport function clearVelocityIntent(store: TransformState, sourceId: string): void {\n\tif (!(sourceId in store.velocityChannels)) return;\n\tdelete store.velocityChannels[sourceId];\n\tstore.dirty.velocityChannels = true;\n}\n","import { Vector3 } from 'three';\nimport type { TransformState } from './transform-store';\nimport { createTransformStore } from './transform-store';\nimport { setVelocityIntent } from './velocity-intents';\n\n/** Plain `{ x, y, z }` vector returned by pose/velocity reads. */\nexport interface Vector {\n\tx: number;\n\ty: number;\n\tz: number;\n}\n\n/**\n * Structural slice of the host body reference used by the direct-body helpers\n * below (`getPosition`, `setPosition`, `resetVelocity`, ...). The host's\n * runtime-backed body proxy satisfies this shape.\n */\nexport interface MoveableBodyLike {\n\ttranslation(): Vector;\n\tlinvel(): Vector;\n\tsetTranslation(translation: Vector, wakeUp: boolean): void;\n\tsetLinvel(velocity: Vector, wakeUp: boolean): void;\n\tsetLinearDamping(damping: number): void;\n}\n\nexport interface EntityWithBody {\n\tbody: MoveableBodyLike | null;\n\ttransformStore?: TransformState;\n}\n\n/**\n * Move an entity along the X axis, preserving other velocities.\n */\nexport function moveX(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(entity.transformStore, 'actions', { x: delta }, { mode: 'replace' });\n}\n\n/**\n * Move an entity along the Y axis, preserving other velocities.\n */\nexport function moveY(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(entity.transformStore, 'actions', { y: delta }, { mode: 'replace' });\n}\n\n/**\n * Move an entity along the Z axis, preserving other velocities.\n */\nexport function moveZ(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(entity.transformStore, 'actions', { z: delta }, { mode: 'replace' });\n}\n\n/**\n * Move an entity along the X and Y axis, preserving Z velocity.\n */\nexport function moveXY(entity: EntityWithBody, deltaX: number, deltaY: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(\n\t\tentity.transformStore,\n\t\t'actions',\n\t\t{ x: deltaX, y: deltaY },\n\t\t{ mode: 'replace' },\n\t);\n}\n\n/**\n * Move an entity along the X and Z axis, preserving Y velocity.\n */\nexport function moveXZ(entity: EntityWithBody, deltaX: number, deltaZ: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(\n\t\tentity.transformStore,\n\t\t'actions',\n\t\t{ x: deltaX, z: deltaZ },\n\t\t{ mode: 'replace' },\n\t);\n}\n\n/**\n * Move entity based on a vector, adding to existing velocities.\n */\nexport function move(entity: EntityWithBody, vector: Vector3): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(\n\t\tentity.transformStore,\n\t\t'actions',\n\t\t{ x: vector.x, y: vector.y, z: vector.z },\n\t\t{ mode: 'add' },\n\t);\n}\n\n/**\n * Reset entity velocity\n */\nexport function resetVelocity(entity: EntityWithBody): void {\n\tif (!entity.body) return;\n\tentity.body.setLinvel(new Vector3(0, 0, 0), true);\n\tentity.body.setLinearDamping(5);\n}\n\n/**\n * Move entity forward in 2D space, preserving Z velocity\n */\nexport function moveForwardXY(entity: EntityWithBody, delta: number, rotation2DAngle: number): void {\n\tconst deltaX = Math.sin(-rotation2DAngle) * delta;\n\tconst deltaY = Math.cos(-rotation2DAngle) * delta;\n\tmoveXY(entity, deltaX, deltaY);\n}\n\n/**\n * Get entity position\n */\nexport function getPosition(entity: EntityWithBody): Vector | null {\n\tif (!entity.body) return null;\n\treturn entity.body.translation();\n}\n\n/**\n * Get entity velocity\n */\nexport function getVelocity(entity: EntityWithBody): Vector | null {\n\tif (!entity.body) return null;\n\treturn entity.body.linvel();\n}\n\n/**\n * Set entity position\n */\nexport function setPosition(entity: EntityWithBody, x: number, y: number, z: number): void {\n\tif (!entity.body) return;\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity X position\n */\nexport function setPositionX(entity: EntityWithBody, x: number): void {\n\tif (!entity.body) return;\n\tconst { y, z } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity Y position\n */\nexport function setPositionY(entity: EntityWithBody, y: number): void {\n\tif (!entity.body) return;\n\tconst { x, z } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity Z position\n */\nexport function setPositionZ(entity: EntityWithBody, z: number): void {\n\tif (!entity.body) return;\n\tconst { x, y } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Wrap entity around 2D bounds\n */\nexport function wrapAroundXY(entity: EntityWithBody, boundsX: number, boundsY: number): void {\n\tconst position = getPosition(entity);\n\tif (!position) return;\n\n\tconst { x, y } = position;\n\tconst newX = x > boundsX ? -boundsX : (x < -boundsX ? boundsX : x);\n\tconst newY = y > boundsY ? -boundsY : (y < -boundsY ? boundsY : y);\n\n\tif (newX !== x || newY !== y) {\n\t\tsetPosition(entity, newX, newY, 0);\n\t}\n}\n\n/**\n * Wrap entity around 3D bounds\n */\nexport function wrapAround3D(entity: EntityWithBody, boundsX: number, boundsY: number, boundsZ: number): void {\n\tconst position = getPosition(entity);\n\tif (!position) return;\n\n\tconst { x, y, z } = position;\n\tconst newX = x > boundsX ? -boundsX : (x < -boundsX ? boundsX : x);\n\tconst newY = y > boundsY ? -boundsY : (y < -boundsY ? boundsY : y);\n\tconst newZ = z > boundsZ ? -boundsZ : (z < -boundsZ ? boundsZ : z);\n\n\tif (newX !== x || newY !== y || newZ !== z) {\n\t\tsetPosition(entity, newX, newY, newZ);\n\t}\n}\n\n/**\n * Enhanced moveable entity with bound methods\n */\nexport interface MoveableEntity extends EntityWithBody {\n\tmoveX(delta: number): void;\n\tmoveY(delta: number): void;\n\tmoveZ(delta: number): void;\n\tmoveXY(deltaX: number, deltaY: number): void;\n\tmoveXZ(deltaX: number, deltaZ: number): void;\n\tmove(vector: Vector3): void;\n\tresetVelocity(): void;\n\tmoveForwardXY(delta: number, rotation2DAngle: number): void;\n\tgetPosition(): Vector | null;\n\tgetVelocity(): Vector | null;\n\tsetPosition(x: number, y: number, z: number): void;\n\tsetPositionX(x: number): void;\n\tsetPositionY(y: number): void;\n\tsetPositionZ(z: number): void;\n\twrapAroundXY(boundsX: number, boundsY: number): void;\n\twrapAround3D(boundsX: number, boundsY: number, boundsZ: number): void;\n}\n\n/**\n * Enhance an entity with additive movement methods.\n * Automatically creates a transform store if one doesn't exist.\n */\nexport function makeMoveable<T extends EntityWithBody>(entity: T): T & MoveableEntity {\n\tconst moveable = entity as T & MoveableEntity;\n\n\t// Create transform store if it doesn't exist\n\tif (!moveable.transformStore) {\n\t\tmoveable.transformStore = createTransformStore();\n\t}\n\n\tmoveable.moveX = (delta: number) => moveX(entity, delta);\n\tmoveable.moveY = (delta: number) => moveY(entity, delta);\n\tmoveable.moveZ = (delta: number) => moveZ(entity, delta);\n\tmoveable.moveXY = (deltaX: number, deltaY: number) => moveXY(entity, deltaX, deltaY);\n\tmoveable.moveXZ = (deltaX: number, deltaZ: number) => moveXZ(entity, deltaX, deltaZ);\n\tmoveable.move = (vector: Vector3) => move(entity, vector);\n\tmoveable.resetVelocity = () => resetVelocity(entity);\n\tmoveable.moveForwardXY = (delta: number, rotation2DAngle: number) => moveForwardXY(entity, delta, rotation2DAngle);\n\tmoveable.getPosition = () => getPosition(entity);\n\tmoveable.getVelocity = () => getVelocity(entity);\n\tmoveable.setPosition = (x: number, y: number, z: number) => setPosition(entity, x, y, z);\n\tmoveable.setPositionX = (x: number) => setPositionX(entity, x);\n\tmoveable.setPositionY = (y: number) => setPositionY(entity, y);\n\tmoveable.setPositionZ = (z: number) => setPositionZ(entity, z);\n\tmoveable.wrapAroundXY = (boundsX: number, boundsY: number) => wrapAroundXY(entity, boundsX, boundsY);\n\tmoveable.wrapAround3D = (boundsX: number, boundsY: number, boundsZ: number) => wrapAround3D(entity, boundsX, boundsY, boundsZ);\n\n\treturn moveable;\n}","/**\n * In-memory implementation of the {@link BehaviorRuntime} contract for unit\n * tests. Records every attach / input call per handle and lets tests seed\n * poses and behavior snapshots without instantiating the wasm runtime.\n */\n\nimport type {\n\tBehaviorRuntime,\n\tStageBehaviorSnapshot,\n\tStageBoundaryDimValue,\n\tStageFirstPersonInput,\n\tStageFirstPersonOptions,\n\tStageJumper2DOptions,\n\tStageJumper3DOptions,\n\tStagePlatformer2DOptions,\n\tStagePlatformer3DOptions,\n\tStagePose,\n\tStageRicochetDimValue,\n\tStageRicochetOptions,\n\tStageScreenWrapOptions,\n\tStageShooter2DOptions,\n\tStageThrusterOptions,\n\tStageTopDownOptions,\n\tStageWorldBoundaryOptions,\n} from './wasm-stage-runtime';\n\ninterface MockSlotState {\n\tpose: StagePose;\n\tsnapshot: StageBehaviorSnapshot | null;\n\tinput: {\n\t\taxisA: number;\n\t\taxisB: number;\n\t\tyawDelta: number;\n\t\tpitchDelta: number;\n\t\treservedA: number;\n\t\treservedB: number;\n\t\tbuttons: number;\n\t};\n\tattachments: Map<string, unknown>;\n\tinputs: Array<{ kind: string; args: unknown[] }>;\n\tscreenWrapQuery: { fsm: number; lastWrappedAxes: number } | null;\n\tworldBoundaryQuery: { hits: number; clamped: [number, number, number] } | null;\n}\n\nfunction freshSlot(): MockSlotState {\n\treturn {\n\t\tpose: { position: [0, 0, 0], rotation: [0, 0, 0, 1] },\n\t\tsnapshot: null,\n\t\tinput: { axisA: 0, axisB: 0, yawDelta: 0, pitchDelta: 0, reservedA: 0, reservedB: 0, buttons: 0 },\n\t\tattachments: new Map(),\n\t\tinputs: [],\n\t\tscreenWrapQuery: null,\n\t\tworldBoundaryQuery: null,\n\t};\n}\n\nexport class MockBehaviorRuntime implements BehaviorRuntime {\n\tprivate slots = new Map<number, MockSlotState>();\n\n\tprivate slot(handle: number): MockSlotState {\n\t\tlet state = this.slots.get(handle);\n\t\tif (!state) {\n\t\t\tstate = freshSlot();\n\t\t\tthis.slots.set(handle, state);\n\t\t}\n\t\treturn state;\n\t}\n\n\t// ─── Test seams ─────────────────────────────────────────────────────\n\n\t/** Seed the pose returned by {@link getPose} for a handle. */\n\tsetPose(handle: number, pose: StagePose): void {\n\t\tthis.slot(handle).pose = pose;\n\t}\n\n\t/** Seed the snapshot returned by {@link readSnapshot} for a handle. */\n\tsetSnapshot(handle: number, snapshot: StageBehaviorSnapshot | null): void {\n\t\tthis.slot(handle).snapshot = snapshot;\n\t}\n\n\t/** Seed {@link queryScreenWrap} results. */\n\tsetScreenWrapQuery(handle: number, value: { fsm: number; lastWrappedAxes: number } | null): void {\n\t\tthis.slot(handle).screenWrapQuery = value;\n\t}\n\n\t/** Seed {@link queryWorldBoundary} results. */\n\tsetWorldBoundaryQuery(\n\t\thandle: number,\n\t\tvalue: { hits: number; clamped: [number, number, number] } | null,\n\t): void {\n\t\tthis.slot(handle).worldBoundaryQuery = value;\n\t}\n\n\t/** Attachment options recorded for a handle, keyed by behavior name. */\n\tgetAttachment<T>(handle: number, kind: string): T | undefined {\n\t\treturn this.slots.get(handle)?.attachments.get(kind) as T | undefined;\n\t}\n\n\thasAttachment(handle: number, kind: string): boolean {\n\t\treturn this.slots.get(handle)?.attachments.has(kind) ?? false;\n\t}\n\n\t/** Every per-entity input call recorded for a handle, oldest first. */\n\tgetInputCalls(handle: number): Array<{ kind: string; args: unknown[] }> {\n\t\treturn this.slots.get(handle)?.inputs ?? [];\n\t}\n\n\t/** Last written slot-indexed input state for a handle. */\n\tgetBatchedInput(handle: number): MockSlotState['input'] {\n\t\treturn this.slot(handle).input;\n\t}\n\n\treset(): void {\n\t\tthis.slots.clear();\n\t}\n\n\t// ─── BehaviorRuntime contract ───────────────────────────────────────\n\n\tsetPosition(handle: number, x: number, y: number, z: number): boolean {\n\t\tconst pose = this.slot(handle).pose;\n\t\tpose.position[0] = x;\n\t\tpose.position[1] = y;\n\t\tpose.position[2] = z;\n\t\treturn true;\n\t}\n\n\tsetRotation(handle: number, x: number, y: number, z: number, w: number): boolean {\n\t\tconst pose = this.slot(handle).pose;\n\t\tpose.rotation[0] = x;\n\t\tpose.rotation[1] = y;\n\t\tpose.rotation[2] = z;\n\t\tpose.rotation[3] = w;\n\t\treturn true;\n\t}\n\n\tgetPose(handle: number, out?: StagePose): StagePose | null {\n\t\tconst state = this.slots.get(handle);\n\t\tif (!state) return null;\n\t\tconst result = out ?? { position: [0, 0, 0], rotation: [0, 0, 0, 1] } as StagePose;\n\t\tresult.position[0] = state.pose.position[0];\n\t\tresult.position[1] = state.pose.position[1];\n\t\tresult.position[2] = state.pose.position[2];\n\t\tresult.rotation[0] = state.pose.rotation[0];\n\t\tresult.rotation[1] = state.pose.rotation[1];\n\t\tresult.rotation[2] = state.pose.rotation[2];\n\t\tresult.rotation[3] = state.pose.rotation[3];\n\t\treturn result;\n\t}\n\n\twriteInputAxes(handle: number, axisA: number, axisB: number): boolean {\n\t\tconst input = this.slot(handle).input;\n\t\tinput.axisA = axisA;\n\t\tinput.axisB = axisB;\n\t\treturn true;\n\t}\n\n\twriteInputLook(handle: number, yawDelta: number, pitchDelta: number): boolean {\n\t\tconst input = this.slot(handle).input;\n\t\tinput.yawDelta = yawDelta;\n\t\tinput.pitchDelta = pitchDelta;\n\t\treturn true;\n\t}\n\n\twriteInputReserved(handle: number, reservedA: number, reservedB: number): boolean {\n\t\tconst input = this.slot(handle).input;\n\t\tinput.reservedA = reservedA;\n\t\tinput.reservedB = reservedB;\n\t\treturn true;\n\t}\n\n\twriteInputButton(handle: number, buttonMask: number, pressed: boolean): boolean {\n\t\tconst input = this.slot(handle).input;\n\t\tinput.buttons = pressed ? (input.buttons | buttonMask) : (input.buttons & ~buttonMask);\n\t\treturn true;\n\t}\n\n\treadSnapshot(handle: number, out?: StageBehaviorSnapshot): StageBehaviorSnapshot | null {\n\t\tconst snapshot = this.slots.get(handle)?.snapshot ?? null;\n\t\tif (!snapshot) return null;\n\t\tif (!out) return { ...snapshot };\n\t\tObject.assign(out, snapshot);\n\t\treturn out;\n\t}\n\n\tattachThruster(handle: number, opts: StageThrusterOptions): boolean {\n\t\tthis.slot(handle).attachments.set('thruster', opts);\n\t\treturn true;\n\t}\n\n\tsetThrusterInput(\n\t\thandle: number,\n\t\tthrust: number,\n\t\trotate: number,\n\t\tvectorX = 0,\n\t\tvectorY = 0,\n\t): void {\n\t\tthis.slot(handle).inputs.push({\n\t\t\tkind: 'thruster',\n\t\t\targs: [thrust, rotate, vectorX, vectorY],\n\t\t});\n\t}\n\n\tattachTopDown(handle: number, opts: StageTopDownOptions): boolean {\n\t\tthis.slot(handle).attachments.set('topDown', opts);\n\t\treturn true;\n\t}\n\n\tsetTopDownInput(handle: number, moveX: number, moveY: number): void {\n\t\tthis.slot(handle).inputs.push({ kind: 'topDown', args: [moveX, moveY] });\n\t}\n\n\tattachShooter2D(handle: number, opts: StageShooter2DOptions): boolean {\n\t\tthis.slot(handle).attachments.set('shooter2d', opts);\n\t\treturn true;\n\t}\n\n\tattachScreenWrap(handle: number, opts: StageScreenWrapOptions): boolean {\n\t\tthis.slot(handle).attachments.set('screenWrap', opts);\n\t\treturn true;\n\t}\n\n\tqueryScreenWrap(handle: number): { fsm: number; lastWrappedAxes: number } | null {\n\t\treturn this.slots.get(handle)?.screenWrapQuery ?? null;\n\t}\n\n\tattachWorldBoundary(\n\t\thandle: number,\n\t\tdim: StageBoundaryDimValue,\n\t\topts: StageWorldBoundaryOptions,\n\t): boolean {\n\t\tthis.slot(handle).attachments.set('worldBoundary', { dim, ...opts });\n\t\treturn true;\n\t}\n\n\tqueryWorldBoundary(handle: number): { hits: number; clamped: [number, number, number] } | null {\n\t\treturn this.slots.get(handle)?.worldBoundaryQuery ?? null;\n\t}\n\n\tattachRicochet(handle: number, dim: StageRicochetDimValue, opts: StageRicochetOptions): boolean {\n\t\tthis.slot(handle).attachments.set('ricochet', { dim, ...opts });\n\t\treturn true;\n\t}\n\n\tattachPlatformer3D(handle: number, opts: StagePlatformer3DOptions): boolean {\n\t\tthis.slot(handle).attachments.set('platformer3d', opts);\n\t\treturn true;\n\t}\n\n\tsetPlatformer3DInputAxes(handle: number, moveX: number, moveZ: number): void {\n\t\tthis.slot(handle).inputs.push({ kind: 'platformer3dAxes', args: [moveX, moveZ] });\n\t}\n\n\tsetPlatformer3DInputButtons(handle: number, jump: boolean, run: boolean): void {\n\t\tthis.slot(handle).inputs.push({ kind: 'platformer3dButtons', args: [jump, run] });\n\t}\n\n\tattachPlatformer2D(handle: number, opts: StagePlatformer2DOptions): boolean {\n\t\tthis.slot(handle).attachments.set('platformer2d', opts);\n\t\treturn true;\n\t}\n\n\tsetPlatformer2DInputAxes(handle: number, moveX: number): void {\n\t\tthis.slot(handle).inputs.push({ kind: 'platformer2dAxes', args: [moveX] });\n\t}\n\n\tsetPlatformer2DInputButtons(handle: number, jump: boolean, run: boolean): void {\n\t\tthis.slot(handle).inputs.push({ kind: 'platformer2dButtons', args: [jump, run] });\n\t}\n\n\tattachFirstPerson(handle: number, opts: StageFirstPersonOptions): boolean {\n\t\tthis.slot(handle).attachments.set('firstPerson', opts);\n\t\treturn true;\n\t}\n\n\tsetFirstPersonInput(handle: number, input: StageFirstPersonInput): void {\n\t\tthis.slot(handle).inputs.push({ kind: 'firstPerson', args: [input] });\n\t}\n\n\tattachJumper2D(handle: number, opts: StageJumper2DOptions): boolean {\n\t\tthis.slot(handle).attachments.set('jumper2d', opts);\n\t\treturn true;\n\t}\n\n\tsetJumper2DInput(handle: number, jumpPressed: boolean): void {\n\t\tthis.slot(handle).inputs.push({ kind: 'jumper2d', args: [jumpPressed] });\n\t}\n\n\tattachJumper3D(handle: number, opts: StageJumper3DOptions): boolean {\n\t\tthis.slot(handle).attachments.set('jumper3d', opts);\n\t\treturn true;\n\t}\n\n\tsetJumper3DInput(handle: number, jumpPressed: boolean): void {\n\t\tthis.slot(handle).inputs.push({ kind: 'jumper3d', args: [jumpPressed] });\n\t}\n}\n","/**\n * `Simulation` (a.k.a. `BehaviorWorld`) — the primary public abstraction of\n * `@zylem/behaviors`. It owns the wasm runtime lifecycle (one\n * `WebAssembly.Instance` of `@zylem/runtime` per simulation), the fixed\n * timestep accumulator, an entity registry mapping opaque\n * {@link EntityHandle}s to runtime slots, and per-step event translation\n * from raw stage events into typed {@link SimulationEvent}s.\n *\n * Hosts (e.g. `@zylem/game-lib`) call {@link createSimulation} once per\n * stage, `spawn()`/`despawn()` entities, call `update(delta)` once per\n * render frame, and read poses for rendering from the returned\n * {@link SimulationFrame}.\n */\n\nimport {\n\tWasmStageRuntime,\n\tcreateWasmStageRuntime,\n\tStageBodyKind,\n\tStageEventType,\n\tSTAGE_RENDER_STRIDE,\n\treadStageRenderSlot,\n\ttype StageBehaviorSnapshot,\n\ttype StageBodyConfig,\n\ttype StageBodyKindValue,\n\ttype StageColliderConfig,\n\ttype StageColliderShape,\n\ttype StageDebugRender,\n\ttype StageBodyInfo,\n\ttype StageEvent,\n\ttype StagePose,\n\ttype StageRaycastHit,\n\ttype StageRenderSlot,\n\ttype WasmStageRuntimeOptions,\n} from './wasm-stage-runtime';\n\n/**\n * Opaque, stable identifier for a simulation entity. `slot` is the raw\n * runtime slot index — treat it as an implementation detail owned by the\n * Simulation (it is only exposed so hosts can wire behavior systems, which\n * address the slot-indexed buffers by slot).\n */\nexport interface EntityHandle {\n\t/** Monotonic public id, never reused within a Simulation. */\n\treadonly id: number;\n\t/** Raw runtime slot index. Internal — may be reused after despawn. */\n\treadonly slot: number;\n}\n\n/** Partial body description; unspecified fields use sensible defaults. */\nexport interface SimulationBodyDefinition {\n\tkind?: StageBodyKindValue;\n\tposition?: readonly [number, number, number];\n\trotation?: readonly [number, number, number, number];\n\tlinearDamping?: number;\n\tangularDamping?: number;\n\tgravityScale?: number;\n\tcanSleep?: boolean;\n\tccdEnabled?: boolean;\n\tlockRotation?: readonly [boolean, boolean, boolean];\n\tlockTranslation?: readonly [boolean, boolean, boolean];\n}\n\n/** Partial collider description; unspecified fields use sensible defaults. */\nexport interface SimulationColliderDefinition {\n\tshape: StageColliderShape;\n\toffset?: readonly [number, number, number];\n\tfriction?: number;\n\trestitution?: number;\n\tsensor?: boolean;\n\tcollisionGroups?: number;\n}\n\n/** Everything needed to materialize one entity inside the runtime. */\nexport interface EntityDefinition {\n\tbody?: SimulationBodyDefinition;\n\tcolliders?: SimulationColliderDefinition[];\n}\n\n/** Typed, handle-resolved simulation event. */\nexport type SimulationEvent =\n\t| {\n\t\ttype: 'collisionStarted' | 'collisionStopped';\n\t\ta: EntityHandle | null;\n\t\tb: EntityHandle | null;\n\t\t/** True when either collider in the pair is a sensor (zone overlap). */\n\t\tsensor: boolean;\n\t\t/** Best-effort contact normal (x, y); zero for sensor pairs / stops. */\n\t\tnormal: [number, number];\n\t}\n\t| { type: 'boundaryHit'; entity: EntityHandle | null; axes: number; signs: number }\n\t| { type: 'ricochet'; entity: EntityHandle | null; kind: number }\n\t| { type: 'regionEntered'; entity: EntityHandle | null; triggerId: number }\n\t| { type: 'jumpStarted'; entity: EntityHandle | null; jumpCount: number }\n\t| { type: 'landed'; entity: EntityHandle | null }\n\t| { type: 'wrapped'; entity: EntityHandle | null; axes: number }\n\t| { type: 'cooldownFired'; entity: EntityHandle | null; cooldownId: number };\n\n/**\n * Snapshot of one `update()` call: how many fixed steps ran, the live render\n * buffer view, the previous-step render copy + interpolation alpha for\n * smooth rendering, and the translated events from every step taken.\n */\nexport interface SimulationFrame {\n\t/** Wall-clock delta handed to `update()`. */\n\tdeltaTime: number;\n\t/** Number of fixed steps executed (0 when accumulating). */\n\tstepsTaken: number;\n\t/** Interpolation alpha in [0, 1): fraction of a fixed step accumulated. */\n\talpha: number;\n\t/** Live render buffer (post-step poses), {@link STAGE_RENDER_STRIDE} floats per slot. */\n\trender: Float32Array;\n\t/** Copy of the render buffer as of the step before the last one. */\n\tpreviousRender: Float32Array;\n\trenderStride: number;\n\t/** Typed events from all steps taken this update, oldest first. */\n\tevents: SimulationEvent[];\n}\n\nexport interface SimulationOptions extends WasmStageRuntimeOptions {\n\t/** Fixed physics timestep in seconds (default 1/60). */\n\tfixedTimestep?: number;\n\t/** Max fixed steps per `update()` to avoid death spirals (default 2). */\n\tmaxSubSteps?: number;\n\t/**\n\t * Rapier contact solver iterations (default 4; auto-drops to 2 when a\n\t * stage has 512+ dynamic bodies). Lower = faster, less stable stacks.\n\t */\n\tsolverIterations?: number;\n\t/**\n\t * Sleep activation overrides applied after create. Defaults match the\n\t * aggressive canSleep policy on newly attached bodies.\n\t */\n\tsleepLinearThreshold?: number;\n\tsleepAngularThreshold?: number;\n\ttimeUntilSleep?: number;\n}\n\nconst DEFAULT_FIXED_TIMESTEP = 1 / 60;\n// Hosts clamp frame delta to 1/30s, so more than 2 substeps of 1/60 per\n// frame is wasted work that amplifies slow steps into a death spiral.\nconst DEFAULT_MAX_SUB_STEPS = 2;\n\n/**\n * The behavior world. Construct via {@link createSimulation}.\n */\nexport class Simulation {\n\t/**\n\t * The low-level wasm adapter. Behavior systems receive this as their\n\t * `wasmStage` context so descriptors can attach/query behaviors by slot;\n\t * hosts should prefer the handle-based methods on the Simulation itself.\n\t */\n\treadonly adapter: WasmStageRuntime;\n\n\treadonly fixedTimestep: number;\n\tprivate readonly maxSubSteps: number;\n\n\tprivate accumulator = 0;\n\tprivate nextEntityId = 1;\n\tprivate slotToHandle = new Map<number, EntityHandle>();\n\tprivate idToHandle = new Map<number, EntityHandle>();\n\tprivate previousRender: Float32Array = new Float32Array(0);\n\tprivate disposed = false;\n\tprivate eventsEnabled = true;\n\n\tconstructor(adapter: WasmStageRuntime, options: SimulationOptions = {}) {\n\t\tthis.adapter = adapter;\n\t\tthis.fixedTimestep = options.fixedTimestep ?? DEFAULT_FIXED_TIMESTEP;\n\t\tthis.maxSubSteps = Math.max(1, options.maxSubSteps ?? DEFAULT_MAX_SUB_STEPS);\n\t\tif (options.solverIterations !== undefined) {\n\t\t\tthis.adapter.setSolverIterations(options.solverIterations);\n\t\t}\n\t\tif (\n\t\t\toptions.sleepLinearThreshold !== undefined ||\n\t\t\toptions.sleepAngularThreshold !== undefined ||\n\t\t\toptions.timeUntilSleep !== undefined\n\t\t) {\n\t\t\tthis.adapter.setSleepThresholds(\n\t\t\t\toptions.sleepLinearThreshold ?? 0.8,\n\t\t\t\toptions.sleepAngularThreshold ?? 1.0,\n\t\t\t\toptions.timeUntilSleep ?? 0.5,\n\t\t\t);\n\t\t}\n\t}\n\n\t// ─── Entity lifecycle ───────────────────────────────────────────────\n\n\t/**\n\t * Create a runtime entity from a plain definition. Returns `null` when\n\t * the runtime rejects the allocation.\n\t */\n\tspawn(definition: EntityDefinition = {}): EntityHandle | null {\n\t\tconst slot = this.adapter.createEntity();\n\t\tif (slot === 0xffffffff) return null;\n\n\t\tconst body = definition.body;\n\t\tconst bodyConfig: StageBodyConfig = {\n\t\t\tkind: body?.kind ?? StageBodyKind.Dynamic,\n\t\t\tposition: body?.position ?? [0, 0, 0],\n\t\t\trotation: body?.rotation ?? [0, 0, 0, 1],\n\t\t\tlinearDamping: body?.linearDamping ?? 0,\n\t\t\tangularDamping: body?.angularDamping ?? 0,\n\t\t\tgravityScale: body?.gravityScale ?? 1,\n\t\t\tcanSleep: body?.canSleep ?? false,\n\t\t\tccdEnabled: body?.ccdEnabled ?? true,\n\t\t\tlockRotation: body?.lockRotation ?? [false, false, false],\n\t\t\tlockTranslation: body?.lockTranslation ?? [false, false, false],\n\t\t};\n\t\tthis.adapter.attachBody(slot, bodyConfig);\n\n\t\tfor (const collider of definition.colliders ?? []) {\n\t\t\tconst config: StageColliderConfig = {\n\t\t\t\tshape: collider.shape,\n\t\t\t\toffset: collider.offset ?? [0, 0, 0],\n\t\t\t\tfriction: collider.friction ?? 0.5,\n\t\t\t\trestitution: collider.restitution ?? 0,\n\t\t\t\tsensor: collider.sensor ?? false,\n\t\t\t\tcollisionGroups: collider.collisionGroups ?? 0xffffffff,\n\t\t\t};\n\t\t\tthis.adapter.addCollider(slot, config);\n\t\t}\n\n\t\tconst handle: EntityHandle = { id: this.nextEntityId++, slot };\n\t\tthis.slotToHandle.set(slot, handle);\n\t\tthis.idToHandle.set(handle.id, handle);\n\t\treturn handle;\n\t}\n\n\tdespawn(handle: EntityHandle): boolean {\n\t\tconst registered = this.idToHandle.get(handle.id);\n\t\tif (!registered) return false;\n\t\tthis.idToHandle.delete(handle.id);\n\t\tif (this.slotToHandle.get(registered.slot) === registered) {\n\t\t\tthis.slotToHandle.delete(registered.slot);\n\t\t}\n\t\treturn this.adapter.destroyEntity(registered.slot);\n\t}\n\n\t/** Resolve a raw runtime slot back to its public handle, if alive. */\n\thandleForSlot(slot: number): EntityHandle | null {\n\t\treturn this.slotToHandle.get(slot) ?? null;\n\t}\n\n\t/**\n\t * Toggle collision-event collection. When disabled the wasm stage skips\n\t * per-step contact-pair hashing and `update()` skips event draining /\n\t * translation entirely (`frame.events` stays empty). Re-enabling emits\n\t * `collisionStarted` for every currently overlapping pair on the next\n\t * step, so late listeners observe current state.\n\t */\n\tsetEventsEnabled(enabled: boolean): void {\n\t\tif (this.eventsEnabled === enabled) return;\n\t\tthis.eventsEnabled = enabled;\n\t\tthis.adapter.setEventsEnabled(enabled);\n\t}\n\n\tget areEventsEnabled(): boolean {\n\t\treturn this.eventsEnabled;\n\t}\n\n\tget entityCount(): number {\n\t\treturn this.idToHandle.size;\n\t}\n\n\t// ─── Per-frame update ───────────────────────────────────────────────\n\n\t/**\n\t * Advance the simulation by `deltaTime` seconds using a fixed-timestep\n\t * accumulator. Runs zero or more fixed steps and returns a\n\t * {@link SimulationFrame} with translated events and interpolation data.\n\t */\n\tupdate(deltaTime: number): SimulationFrame {\n\t\tconst events: SimulationEvent[] = [];\n\t\tthis.accumulator += Math.max(0, deltaTime);\n\t\tlet steps = 0;\n\n\t\twhile (this.accumulator >= this.fixedTimestep && steps < this.maxSubSteps) {\n\t\t\tthis.capturePreviousRender();\n\t\t\tthis.adapter.step(this.fixedTimestep);\n\t\t\tif (this.eventsEnabled) {\n\t\t\t\tthis.translateEvents(this.adapter.drainEvents(), events);\n\t\t\t}\n\t\t\tthis.accumulator -= this.fixedTimestep;\n\t\t\tsteps++;\n\t\t}\n\t\t// Drop leftover time we couldn't consume (death-spiral guard).\n\t\tif (steps === this.maxSubSteps && this.accumulator >= this.fixedTimestep) {\n\t\t\tthis.accumulator = this.accumulator % this.fixedTimestep;\n\t\t}\n\n\t\treturn {\n\t\t\tdeltaTime,\n\t\t\tstepsTaken: steps,\n\t\t\talpha: this.fixedTimestep > 0 ? this.accumulator / this.fixedTimestep : 0,\n\t\t\trender: this.adapter.render,\n\t\t\tpreviousRender: this.previousRender,\n\t\t\trenderStride: STAGE_RENDER_STRIDE,\n\t\t\tevents,\n\t\t};\n\t}\n\n\tprivate capturePreviousRender(): void {\n\t\tthis.adapter.refreshViews();\n\t\tconst current = this.adapter.render;\n\t\tif (this.previousRender.length !== current.length) {\n\t\t\tthis.previousRender = new Float32Array(current.length);\n\t\t}\n\t\tthis.previousRender.set(current);\n\t}\n\n\tprivate translateEvents(raw: StageEvent[], out: SimulationEvent[]): void {\n\t\tfor (const event of raw) {\n\t\t\tconst primary = event.primarySlot !== null ? this.handleForSlot(event.primarySlot) : null;\n\t\t\tconst secondary = event.secondarySlot !== null ? this.handleForSlot(event.secondarySlot) : null;\n\t\t\tswitch (event.type) {\n\t\t\t\tcase StageEventType.CollisionStarted:\n\t\t\t\tcase StageEventType.CollisionStopped:\n\t\t\t\t\tout.push({\n\t\t\t\t\t\ttype: event.type === StageEventType.CollisionStarted\n\t\t\t\t\t\t\t? 'collisionStarted'\n\t\t\t\t\t\t\t: 'collisionStopped',\n\t\t\t\t\t\ta: primary,\n\t\t\t\t\t\tb: secondary,\n\t\t\t\t\t\tsensor: event.payload[0] !== 0,\n\t\t\t\t\t\tnormal: [event.payload[1], event.payload[2]],\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase StageEventType.BoundaryHit:\n\t\t\t\t\tout.push({\n\t\t\t\t\t\ttype: 'boundaryHit',\n\t\t\t\t\t\tentity: primary,\n\t\t\t\t\t\taxes: event.payload[0] | 0,\n\t\t\t\t\t\tsigns: event.payload[1] | 0,\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase StageEventType.Ricochet:\n\t\t\t\t\tout.push({ type: 'ricochet', entity: primary, kind: event.payload[0] | 0 });\n\t\t\t\t\tbreak;\n\t\t\t\tcase StageEventType.RegionEntered:\n\t\t\t\t\tout.push({ type: 'regionEntered', entity: primary, triggerId: event.payload[0] | 0 });\n\t\t\t\t\tbreak;\n\t\t\t\tcase StageEventType.JumpStarted:\n\t\t\t\t\tout.push({ type: 'jumpStarted', entity: primary, jumpCount: event.payload[0] | 0 });\n\t\t\t\t\tbreak;\n\t\t\t\tcase StageEventType.Landed:\n\t\t\t\t\tout.push({ type: 'landed', entity: primary });\n\t\t\t\t\tbreak;\n\t\t\t\tcase StageEventType.Wrapped:\n\t\t\t\t\tout.push({ type: 'wrapped', entity: primary, axes: event.payload[0] | 0 });\n\t\t\t\t\tbreak;\n\t\t\t\tcase StageEventType.CooldownFired:\n\t\t\t\t\tout.push({ type: 'cooldownFired', entity: primary, cooldownId: event.payload[0] | 0 });\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// ─── Handle-based reads / writes ────────────────────────────────────\n\n\tgetPose(handle: EntityHandle, out?: StagePose): StagePose | null {\n\t\treturn this.adapter.getPose(handle.slot, out);\n\t}\n\n\tsetPosition(handle: EntityHandle, x: number, y: number, z: number): boolean {\n\t\treturn this.adapter.setPosition(handle.slot, x, y, z);\n\t}\n\n\tsetRotation(handle: EntityHandle, x: number, y: number, z: number, w: number): boolean {\n\t\treturn this.adapter.setRotation(handle.slot, x, y, z, w);\n\t}\n\n\tsetLinearVelocity(handle: EntityHandle, x: number, y: number, z: number): boolean {\n\t\treturn this.adapter.setLinearVelocity(handle.slot, x, y, z);\n\t}\n\n\tgetLinearVelocity(handle: EntityHandle): [number, number, number] | null {\n\t\treturn this.adapter.getLinearVelocity(handle.slot);\n\t}\n\n\tsetAngularVelocity(handle: EntityHandle, x: number, y: number, z: number): boolean {\n\t\treturn this.adapter.setAngularVelocity(handle.slot, x, y, z);\n\t}\n\n\tapplyImpulse(handle: EntityHandle, x: number, y: number, z: number): boolean {\n\t\treturn this.adapter.applyImpulse(handle.slot, x, y, z);\n\t}\n\n\treadRenderSlot(handle: EntityHandle, out?: StageRenderSlot): StageRenderSlot | null {\n\t\treturn readStageRenderSlot(this.adapter.render, handle.slot, out);\n\t}\n\n\t/** Decode a handle's pose from the previous-step render copy. */\n\treadPreviousRenderSlot(handle: EntityHandle, out?: StageRenderSlot): StageRenderSlot | null {\n\t\treturn readStageRenderSlot(this.previousRender, handle.slot, out);\n\t}\n\n\treadSnapshot(handle: EntityHandle, out?: StageBehaviorSnapshot): StageBehaviorSnapshot | null {\n\t\treturn this.adapter.readSnapshot(handle.slot, out);\n\t}\n\n\t// ─── World-level controls / diagnostics ─────────────────────────────\n\n\tsetGravity(x: number, y: number, z: number): void {\n\t\tthis.adapter.setGravity(x, y, z);\n\t}\n\n\tsetSolverIterations(iterations: number): void {\n\t\tthis.adapter.setSolverIterations(iterations);\n\t}\n\n\tsetSleepThresholds(\n\t\tnormalizedLinearThreshold: number,\n\t\tangularThreshold: number,\n\t\ttimeUntilSleep: number,\n\t): void {\n\t\tthis.adapter.setSleepThresholds(\n\t\t\tnormalizedLinearThreshold,\n\t\t\tangularThreshold,\n\t\t\ttimeUntilSleep,\n\t\t);\n\t}\n\n\tawakeDynamicCount(): number {\n\t\treturn this.adapter.awakeDynamicCount();\n\t}\n\n\t/** Physics raycast; the hit's slot is resolved to an entity handle. */\n\tcastRay(\n\t\torigin: readonly [number, number, number],\n\t\tdir: readonly [number, number, number],\n\t\tmaxDistance: number,\n\t\tsolidOnly = true,\n\t): (Omit<StageRaycastHit, 'slot'> & { entity: EntityHandle | null }) | null {\n\t\tconst hit = this.adapter.castRay(origin, dir, maxDistance, solidOnly);\n\t\tif (!hit) return null;\n\t\treturn {\n\t\t\tdistance: hit.distance,\n\t\t\tnormal: hit.normal,\n\t\t\tentity: this.handleForSlot(hit.slot),\n\t\t};\n\t}\n\n\tgetBodyInfo(handle: EntityHandle): StageBodyInfo | null {\n\t\treturn this.adapter.getBodyInfo(handle.slot);\n\t}\n\n\tgetDebugRender(): StageDebugRender | null {\n\t\treturn this.adapter.getDebugRender();\n\t}\n\n\tget isDisposed(): boolean {\n\t\treturn this.disposed;\n\t}\n\n\t/** Destroy the wasm stage. The Simulation must not be used afterwards. */\n\tdispose(): void {\n\t\tif (this.disposed) return;\n\t\tthis.disposed = true;\n\t\tthis.slotToHandle.clear();\n\t\tthis.idToHandle.clear();\n\t\tthis.adapter.dispose();\n\t}\n}\n\n/** Alias matching the architecture doc's naming. */\nexport type BehaviorWorld = Simulation;\n\n/**\n * Load and instantiate the `@zylem/runtime` wasm module and wrap it in a\n * {@link Simulation}. One call per logical stage/world.\n */\nexport async function createSimulation(options: SimulationOptions = {}): Promise<Simulation> {\n\tconst adapter = await createWasmStageRuntime(options);\n\treturn new Simulation(adapter, options);\n}\n","import type {\n\tBehaviorDescriptor,\n\tBehaviorHandle,\n\tBehaviorRef,\n} from '../behaviors/behavior-descriptor';\nimport type { TransformState } from '../capabilities/transform-store';\n\n/**\n * Minimal, runtime-agnostic entity options contract.\n *\n * The full engine entity (in `@zylem/game-lib`) provides a richer options type,\n * but behaviors only rely on this loose shape.\n */\nexport interface GameEntityOptions {\n\t[key: string]: any;\n\tname?: string;\n}\n\n/**\n * Structural stand-in for the engine `GameEntity`.\n *\n * Behaviors annotate against this loose contract so that `@zylem/behaviors`\n * (and its `@zylem/behaviors/core` surface) never has to depend on the concrete\n * `@zylem/game-lib` entity implementation. The real engine entity is\n * structurally assignable to this type.\n */\nexport class GameEntity<TOptions = unknown> {\n\t[key: string]: any;\n\n\tuuid!: string;\n\tname!: string;\n\ttype!: string;\n\toptions?: TOptions & Record<string, unknown>;\n\tgroup: any = null;\n\tmesh?: any;\n\tmaterials?: any[];\n\t/** Opaque host-owned physics references (never inspected by behaviors). */\n\tbody: unknown | null = null;\n\tcollider: unknown | null = null;\n\tcolliderDesc?: any;\n\tcolliderDescs: any[] = [];\n\tbodyDesc?: any;\n\tphysicsAttached = false;\n\truntimeHandle?: number;\n\ttransformStore?: TransformState;\n\tnodeDestroy?: any;\n\tisInstanced?: boolean;\n\n\tprivate __behaviorRefs: BehaviorRef<any>[] = [];\n\n\tcreate(): this {\n\t\treturn this;\n\t}\n\n\tonCleanup(callback: () => void): this {\n\t\tvoid callback;\n\t\treturn this;\n\t}\n\n\tsetPosition(_x: number, _y: number, _z: number): void {}\n\tsetRotation(_x: number, _y: number, _z: number): void {}\n\tsetRotationZ(_z: number): void {}\n\tsetScale(_x: number, _y: number, _z: number): void {}\n\n\t/**\n\t * Attach a behavior to this entity. The real engine entity does substantially\n\t * more, but this functional stub stores the merged ref and builds the handle\n\t * so descriptor/handle logic (and tests that drive behaviors directly) work\n\t * without the full engine.\n\t */\n\tuse<\n\t\tO extends Record<string, any>,\n\t\tH extends Record<string, any> = Record<string, never>,\n\t>(\n\t\tdescriptor: BehaviorDescriptor<O, H>,\n\t\toptions?: Partial<O>,\n\t): BehaviorHandle<O, H> {\n\t\tconst mergedOptions = {\n\t\t\t...(descriptor.defaultOptions as O),\n\t\t\t...(options ?? {}),\n\t\t} as O;\n\t\tconst ref: BehaviorRef<O> = { descriptor, options: mergedOptions };\n\t\tthis.__behaviorRefs.push(ref as BehaviorRef<any>);\n\n\t\tconst baseHandle = {\n\t\t\tgetFSM: () => ref.fsm ?? null,\n\t\t\tgetOptions: () => ref.options,\n\t\t\tref,\n\t\t};\n\t\tconst extra = descriptor.createHandle\n\t\t\t? descriptor.createHandle(ref)\n\t\t\t: ({} as H);\n\t\treturn { ...baseHandle, ...extra } as BehaviorHandle<O, H>;\n\t}\n\n\t/** Live behavior refs attached via {@link use}. */\n\tgetBehaviorRefs(): BehaviorRef<any>[] {\n\t\treturn this.__behaviorRefs;\n\t}\n}\n\n/**\n * Factory contract injected into behavior systems via\n * {@link BehaviorSystemContext.createEntity}. The host engine supplies the real\n * entity factory at stage-construction time.\n */\nexport type CreateEntityFn = (\n\toptions?: Partial<GameEntityOptions>,\n) => GameEntity<GameEntityOptions>;\n"],"mappings":"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","names":["moveX","moveY","moveZ"]}
@@ -1,4 +1,4 @@
1
- import { a as BehaviorDescriptor } from './behavior-system-CeJXzNvr.js';
1
+ import { a as BehaviorDescriptor } from './behavior-system-HEt67el5.js';
2
2
  import { Material } from 'three';
3
3
  import { FractureOptions, DestructibleMesh } from '@dgreenheck/three-pinata';
4
4
  export { DestructibleMesh, FractureOptions, VoronoiOptions } from '@dgreenheck/three-pinata';
@@ -3,7 +3,7 @@ export { c as createFirstPersonInputComponent, d as createFirstPersonMovementCom
3
3
  import { S as SyncStateMachine } from './sync-state-machine-CZyspBpj.js';
4
4
  import { Vector3, Euler } from 'three';
5
5
  import { F as FirstPersonPerspective } from './first-person-perspective-C9Mptl0-.js';
6
- import { Y as TransformState, e as BehaviorRuntime, a as BehaviorDescriptor } from './behavior-system-CeJXzNvr.js';
6
+ import { Z as TransformState, e as BehaviorRuntime, a as BehaviorDescriptor } from './behavior-system-HEt67el5.js';
7
7
  import { i as Vec3Input } from './vector-DjhLUrak.js';
8
8
  import 'typescript-fsm';
9
9
  import '@zylem/runtime';
@@ -4,7 +4,7 @@ import {
4
4
  FirstPersonFSM,
5
5
  FirstPersonPresentation,
6
6
  FirstPersonState
7
- } from "./chunk-5NJGASUJ.js";
7
+ } from "./chunk-B2ERQ6HD.js";
8
8
  import {
9
9
  createFirstPersonInputComponent,
10
10
  createFirstPersonMovementComponent,
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-QVCMJ4Q2.js";
13
13
  import "./chunk-M3QDKKDF.js";
14
14
  import "./chunk-AS3HR7AS.js";
15
- import "./chunk-E4X4YJZB.js";
15
+ import "./chunk-4GW6DCYF.js";
16
16
  import "./chunk-EZNCCO4L.js";
17
17
  import "./chunk-5WRI5ZAA.js";
18
18
  export {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { a as BehaviorDescriptor, c as BehaviorHandle, d as BehaviorRef, f as BehaviorSystem, h as BehaviorSystemFactory, D as DefineBehaviorConfig, a4 as defineBehavior } from './behavior-system-CeJXzNvr.js';
2
- export { P as PhysicsBodyComponent, T as TransformComponent, c as createPhysicsBodyComponent, a as createTransformComponent, u as useBehavior } from './components-BANNjAZP.js';
1
+ export { a as BehaviorDescriptor, c as BehaviorHandle, d as BehaviorRef, f as BehaviorSystem, h as BehaviorSystemFactory, D as DefineBehaviorConfig, a5 as defineBehavior } from './behavior-system-HEt67el5.js';
2
+ export { P as PhysicsBodyComponent, T as TransformComponent, c as createPhysicsBodyComponent, a as createTransformComponent, u as useBehavior } from './components-JZQoO2sU.js';
3
3
  export { T as ThrusterInputComponent, a as ThrusterMovementComponent, b as ThrusterStateComponent, c as createThrusterInputComponent, d as createThrusterMovementComponent, e as createThrusterStateComponent } from './components-B29WHGQN.js';
4
4
  export { PlayerInput, ThrusterBehavior, ThrusterBehaviorOptions, ThrusterEntity, ThrusterEvent, ThrusterFSM, ThrusterFSMContext, ThrusterState } from './thruster.js';
5
5
  export { T as TopDownMovementComponent, a as TopDownMovementInputComponent, b as TopDownMovementStateComponent, c as createTopDownMovementComponent, d as createTopDownMovementInputComponent, e as createTopDownMovementStateComponent } from './components-XCpL6IYt.js';
@@ -29,7 +29,7 @@ export { FirstPersonShooterCoordinator, FirstPersonShooterEntity, FirstPersonSho
29
29
  export { TopDownShooterCoordinator, TopDownShooterEntity, TopDownShooterInput } from './coordinators/top-down-shooter.js';
30
30
  export { MultidirectionalSpaceShooterCoordinator, MultidirectionalSpaceShooterEntity, MultidirectionalSpaceShooterInput } from './coordinators/multidirectional-space-shooter.js';
31
31
  export { F as FacingAngle2DEntity, R as ResolvedAim2D, S as Shooter2DAimFireInput, f as fireShooter2DIfRequested, g as getEntityFacingAngle2D, r as resolveAim2D } from './shooter-fire-DGripl0z.js';
32
- export { P as ParticleEffectDefinition, a as ParticleMagicAgency, b as ParticleMagicAlignment, c as ParticleMagicModifierInput, d as ParticleMagicModifierOptions, e as ParticleMagicOrder, f as ParticleMagicRealityEffect, g as ParticleMagicTemperament, h as ParticlePresetMaterialOptions, S as SemanticParticlePresetOptions, v as particleEffect } from './spark-Dx3cJbTW.js';
32
+ export { P as ParticleEffectDefinition, a as ParticleMagicAgency, b as ParticleMagicAlignment, c as ParticleMagicModifierInput, d as ParticleMagicModifierOptions, e as ParticleMagicOrder, f as ParticleMagicRealityEffect, g as ParticleMagicTemperament, h as ParticlePresetMaterialOptions, S as SemanticParticlePresetOptions, v as particleEffect } from './spark-C4Tp-52_.js';
33
33
  import '@zylem/runtime';
34
34
  import 'three';
35
35
  import './sync-state-machine-CZyspBpj.js';
@@ -37,7 +37,7 @@ import 'typescript-fsm';
37
37
  import './vector-DjhLUrak.js';
38
38
  import './entity-types-DhfsZbSK.js';
39
39
  import './first-person-perspective-C9Mptl0-.js';
40
- import './moveable-XhzWPAw5.js';
40
+ import './moveable-BdFmI3s1.js';
41
41
  import 'three/webgpu';
42
42
 
43
43
  /**