@zylem/behaviors 0.8.8 → 0.8.10

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 (61) hide show
  1. package/dist/{behavior-system-DkFAwLb_.d.ts → behavior-descriptor-Dr8qmQ20.d.ts} +105 -105
  2. package/dist/{chunk-55CFXXZH.js → chunk-57JGBNCS.js} +23 -2
  3. package/dist/{chunk-7GGR26YA.js → chunk-6RIS4MGM.js} +1 -1
  4. package/dist/{chunk-OBF6BIA2.js → chunk-CBQSC6W3.js} +2 -2
  5. package/dist/{chunk-OU2SW4U5.js → chunk-G5S5U6WI.js} +1 -1
  6. package/dist/{chunk-WHKPWIQO.js → chunk-HMVEQB2T.js} +1 -0
  7. package/dist/{chunk-57GLKGEX.js → chunk-HZMC4LGW.js} +23 -2
  8. package/dist/{chunk-E2MOFIDH.js → chunk-IU7Y3L7Y.js} +8 -6
  9. package/dist/{chunk-LLDLVVG4.js → chunk-NZM5YQBW.js} +17 -5
  10. package/dist/{chunk-RR3XNDKG.js → chunk-T2LAQQDS.js} +1 -1
  11. package/dist/{chunk-CB3C7CRD.js → chunk-T7ST62OT.js} +1 -1
  12. package/dist/{chunk-7CE6OHLW.js → chunk-U2BSZJ3S.js} +1 -1
  13. package/dist/{chunk-TK3AXXXI.js → chunk-VB4GYWTE.js} +1 -1
  14. package/dist/{chunk-CTSYM56P.js → chunk-VNQLMRWC.js} +1 -1
  15. package/dist/{chunk-M25QJBDN.js → chunk-X45KOKUF.js} +10 -2
  16. package/dist/{components--RTwuT4S.d.ts → components-tct075-p.d.ts} +1 -1
  17. package/dist/cooldown.d.ts +1 -1
  18. package/dist/coordinators/boundary-ricochet-3d.d.ts +2 -2
  19. package/dist/coordinators/boundary-ricochet-3d.js +2 -2
  20. package/dist/coordinators/boundary-ricochet.d.ts +2 -2
  21. package/dist/coordinators/multidirectional-space-shooter.d.ts +2 -2
  22. package/dist/coordinators/top-down-shooter.d.ts +2 -2
  23. package/dist/core.d.ts +5 -5
  24. package/dist/core.js +1 -1
  25. package/dist/destructible-3d.d.ts +2 -2
  26. package/dist/destructible-prebake.d.ts +1 -1
  27. package/dist/first-person.d.ts +2 -2
  28. package/dist/first-person.js +2 -2
  29. package/dist/index.d.ts +6 -6
  30. package/dist/index.js +14 -14
  31. package/dist/jumper-2d.d.ts +1 -1
  32. package/dist/jumper-2d.js +2 -2
  33. package/dist/jumper-3d.d.ts +1 -1
  34. package/dist/jumper-3d.js +2 -2
  35. package/dist/{moveable-CFOHmblC.d.ts → moveable-tkFsn7mE.d.ts} +2 -2
  36. package/dist/particle-emitter/presets.d.ts +1 -1
  37. package/dist/particle-emitter.d.ts +4 -4
  38. package/dist/{payload-BQzu-oY_.d.ts → payload-WEzfgjSL.d.ts} +1 -1
  39. package/dist/platformer-2d.d.ts +1 -1
  40. package/dist/platformer-2d.js +2 -2
  41. package/dist/platformer-3d.d.ts +1 -1
  42. package/dist/platformer-3d.js +2 -2
  43. package/dist/ricochet-2d.d.ts +1 -1
  44. package/dist/ricochet-2d.js +2 -2
  45. package/dist/ricochet-3d.d.ts +1 -1
  46. package/dist/ricochet-3d.js +2 -2
  47. package/dist/runtime-2d.d.ts +1 -1
  48. package/dist/screen-visibility.d.ts +1 -1
  49. package/dist/screen-wrap.d.ts +1 -1
  50. package/dist/screen-wrap.js +2 -2
  51. package/dist/shooter-2d.d.ts +2 -2
  52. package/dist/{spark-C4Tp-52_.d.ts → spark-VoQoemz_.d.ts} +1 -1
  53. package/dist/thruster.d.ts +1 -1
  54. package/dist/thruster.js +2 -2
  55. package/dist/top-down-movement.d.ts +1 -1
  56. package/dist/{vector-DjhLUrak.d.ts → vector-s7GbCrVn.d.ts} +1 -1
  57. package/dist/world-boundary-2d.d.ts +1 -1
  58. package/dist/world-boundary-2d.js +2 -2
  59. package/dist/world-boundary-3d.d.ts +1 -1
  60. package/dist/world-boundary-3d.js +3 -3
  61. package/package.json +5 -4
@@ -1,109 +1,5 @@
1
1
  import { StageWasmExports } from '@zylem/runtime';
2
2
 
3
- /**
4
- * BehaviorDescriptor
5
- *
6
- * Type-safe behavior descriptors that provide options inference.
7
- * Used with entity.use() to declaratively attach behaviors to entities.
8
- *
9
- * Each behavior can define its own handle type via `createHandle`,
10
- * providing behavior-specific methods with full type safety.
11
- */
12
-
13
- /**
14
- * Base handle returned by entity.use() for lazy access to behavior runtime.
15
- * FSM is null until entity is spawned and components are initialized.
16
- */
17
- interface BaseBehaviorHandle<O extends Record<string, any> = Record<string, any>> {
18
- /** Get the FSM instance (null until entity is spawned) */
19
- getFSM(): any | null;
20
- /** Get the current options */
21
- getOptions(): O;
22
- /** Access the underlying behavior ref */
23
- readonly ref: BehaviorRef<O>;
24
- }
25
- /**
26
- * Reference to a behavior stored on an entity
27
- */
28
- interface BehaviorRef<O extends Record<string, any> = Record<string, any>> {
29
- /** The behavior descriptor */
30
- descriptor: BehaviorDescriptor<O, any>;
31
- /** Merged options (defaults + overrides) */
32
- options: O;
33
- /** Optional FSM instance - set lazily when entity is spawned */
34
- fsm?: any;
35
- }
36
- /**
37
- * A typed behavior descriptor that associates a symbol key with:
38
- * - Default options (providing type inference)
39
- * - A system factory to create the behavior system
40
- * - An optional handle factory for behavior-specific methods
41
- */
42
- interface BehaviorDescriptor<O extends Record<string, any> = Record<string, any>, H extends Record<string, any> = Record<string, never>, I = unknown> {
43
- /** Unique symbol identifying this behavior */
44
- readonly key: symbol;
45
- /** Default options (used for type inference) */
46
- readonly defaultOptions: O;
47
- /** Factory to create the behavior system */
48
- readonly systemFactory: any;
49
- /**
50
- * Optional factory to create behavior-specific handle methods.
51
- * These methods are merged into the handle returned by entity.use().
52
- */
53
- readonly createHandle?: (ref: any) => H;
54
- }
55
- /**
56
- * The full handle type returned by entity.use().
57
- * Combines base handle with behavior-specific methods.
58
- */
59
- type BehaviorHandle<O extends Record<string, any> = Record<string, any>, H extends Record<string, any> = Record<string, never>> = BaseBehaviorHandle<O> & H;
60
- /**
61
- * Configuration for defining a new behavior
62
- */
63
- interface DefineBehaviorConfig<O extends Record<string, any>, H extends Record<string, any> = Record<string, never>, I = unknown> {
64
- /** Human-readable name for debugging */
65
- name: string;
66
- /** Default options - these define the type */
67
- defaultOptions: O;
68
- /** Factory function to create the system */
69
- systemFactory: BehaviorSystemFactory;
70
- /**
71
- * Optional factory to create behavior-specific handle methods.
72
- * The returned object is merged into the handle returned by entity.use().
73
- *
74
- * @example
75
- * ```typescript
76
- * createHandle: (ref) => ({
77
- * getLastHits: () => ref.fsm?.getLastHits() ?? null,
78
- * getMovement: (moveX, moveY) => ref.fsm?.getMovement(moveX, moveY) ?? { moveX, moveY },
79
- * }),
80
- * ```
81
- */
82
- createHandle?: (ref: BehaviorRef<O>) => H;
83
- }
84
- /**
85
- * Define a typed behavior descriptor.
86
- *
87
- * @example
88
- * ```typescript
89
- * export const WorldBoundary2DBehavior = defineBehavior({
90
- * name: 'world-boundary-2d',
91
- * defaultOptions: { boundaries: { top: 0, bottom: 0, left: 0, right: 0 } },
92
- * systemFactory: (ctx) => new WorldBoundary2DSystem(ctx.world),
93
- * createHandle: (ref) => ({
94
- * getLastHits: () => ref.fsm?.getLastHits() ?? null,
95
- * getMovement: (moveX: number, moveY: number) =>
96
- * ref.fsm?.getMovement(moveX, moveY) ?? { moveX, moveY },
97
- * }),
98
- * });
99
- *
100
- * // Usage - handle has getLastHits and getMovement with full types
101
- * const boundary = ship.use(WorldBoundary2DBehavior, { ... });
102
- * const hits = boundary.getLastHits(); // Fully typed!
103
- * ```
104
- */
105
- declare function defineBehavior<O extends Record<string, any>, H extends Record<string, any> = Record<string, never>, I = unknown>(config: DefineBehaviorConfig<O, H, I>): BehaviorDescriptor<O, H, I>;
106
-
107
3
  type VelocityIntentMode = 'replace' | 'add';
108
4
  interface VelocityIntent {
109
5
  x?: number;
@@ -911,4 +807,108 @@ interface BehaviorSystemContext {
911
807
  */
912
808
  type BehaviorSystemFactory<T extends BehaviorSystem = BehaviorSystem> = (stage: BehaviorSystemContext) => T;
913
809
 
914
- export { type VelocityIntentMode as $, type StageJumper2DOptions as A, type BaseBehaviorHandle as B, type CreateEntityFn as C, type DefineBehaviorConfig as D, type StageJumper3DOptions as E, type StagePlatformer2DOptions as F, GameEntity as G, type StagePlatformer3DOptions as H, StagePlatformerShapeSource as I, type StagePose as J, type StageRaycastHit as K, type StageRenderSlot as L, StageRicochetDim as M, type StageRicochetDimValue as N, type StageRicochetOptions as O, StageRicochetReflection as P, type StageRicochetReflectionValue as Q, type StageScreenWrapOptions as R, STAGE_INPUT_BUTTON_JUMP as S, type StageShooter2DOptions as T, type StageThrusterOptions as U, type StageTopDownOptions as V, StageTopDownPlane as W, type StageTopDownPlaneValue as X, type StageWorldBoundaryOptions as Y, type TransformState as Z, type VelocityIntent as _, type BehaviorDescriptor as a, type WasmSnapshotBackref as a0, WasmStageRuntime as a1, type WasmStageRuntimeOptions as a2, createTransformStore as a3, createWasmStageRuntime as a4, defineBehavior as a5, readBehaviorSnapshot as a6, readStageRenderSlot as a7, type BehaviorEntityLink as b, type BehaviorHandle as c, type BehaviorRef as d, type BehaviorRuntime as e, type BehaviorSystem as f, type BehaviorSystemContext as g, type BehaviorSystemFactory as h, type GameEntityOptions as i, STAGE_INPUT_BUTTON_RUN as j, STAGE_INVALID_SLOT as k, type StageBehaviorSnapshot as l, type StageBodyConfig as m, type StageBodyInfo as n, StageBodyKind as o, type StageBodyKindValue as p, StageBoundaryDim as q, type StageBoundaryDimValue as r, type StageColliderConfig as s, type StageColliderShape as t, type StageDebugRender as u, type StageEvent as v, StageEventType as w, type StageEventTypeValue as x, type StageFirstPersonInput as y, type StageFirstPersonOptions as z };
810
+ /**
811
+ * BehaviorDescriptor
812
+ *
813
+ * Type-safe behavior descriptors that provide options inference.
814
+ * Used with entity.use() to declaratively attach behaviors to entities.
815
+ *
816
+ * Each behavior can define its own handle type via `createHandle`,
817
+ * providing behavior-specific methods with full type safety.
818
+ */
819
+
820
+ /**
821
+ * Base handle returned by entity.use() for lazy access to behavior runtime.
822
+ * FSM is null until entity is spawned and components are initialized.
823
+ */
824
+ interface BaseBehaviorHandle<O extends Record<string, any> = Record<string, any>> {
825
+ /** Get the FSM instance (null until entity is spawned) */
826
+ getFSM(): any | null;
827
+ /** Get the current options */
828
+ getOptions(): O;
829
+ /** Access the underlying behavior ref */
830
+ readonly ref: BehaviorRef<O>;
831
+ }
832
+ /**
833
+ * Reference to a behavior stored on an entity
834
+ */
835
+ interface BehaviorRef<O extends Record<string, any> = Record<string, any>> {
836
+ /** The behavior descriptor */
837
+ descriptor: BehaviorDescriptor<O, any>;
838
+ /** Merged options (defaults + overrides) */
839
+ options: O;
840
+ /** Optional FSM instance - set lazily when entity is spawned */
841
+ fsm?: any;
842
+ }
843
+ /**
844
+ * A typed behavior descriptor that associates a symbol key with:
845
+ * - Default options (providing type inference)
846
+ * - A system factory to create the behavior system
847
+ * - An optional handle factory for behavior-specific methods
848
+ */
849
+ interface BehaviorDescriptor<O extends Record<string, any> = Record<string, any>, H extends Record<string, any> = Record<string, never>, I = unknown> {
850
+ /** Unique symbol identifying this behavior */
851
+ readonly key: symbol;
852
+ /** Default options (used for type inference) */
853
+ readonly defaultOptions: O;
854
+ /** Factory to create the behavior system */
855
+ readonly systemFactory: any;
856
+ /**
857
+ * Optional factory to create behavior-specific handle methods.
858
+ * These methods are merged into the handle returned by entity.use().
859
+ */
860
+ readonly createHandle?: (ref: any) => H;
861
+ }
862
+ /**
863
+ * The full handle type returned by entity.use().
864
+ * Combines base handle with behavior-specific methods.
865
+ */
866
+ type BehaviorHandle<O extends Record<string, any> = Record<string, any>, H extends Record<string, any> = Record<string, never>> = BaseBehaviorHandle<O> & H;
867
+ /**
868
+ * Configuration for defining a new behavior
869
+ */
870
+ interface DefineBehaviorConfig<O extends Record<string, any>, H extends Record<string, any> = Record<string, never>, I = unknown> {
871
+ /** Human-readable name for debugging */
872
+ name: string;
873
+ /** Default options - these define the type */
874
+ defaultOptions: O;
875
+ /** Factory function to create the system */
876
+ systemFactory: BehaviorSystemFactory;
877
+ /**
878
+ * Optional factory to create behavior-specific handle methods.
879
+ * The returned object is merged into the handle returned by entity.use().
880
+ *
881
+ * @example
882
+ * ```typescript
883
+ * createHandle: (ref) => ({
884
+ * getLastHits: () => ref.fsm?.getLastHits() ?? null,
885
+ * getMovement: (moveX, moveY) => ref.fsm?.getMovement(moveX, moveY) ?? { moveX, moveY },
886
+ * }),
887
+ * ```
888
+ */
889
+ createHandle?: (ref: BehaviorRef<O>) => H;
890
+ }
891
+ /**
892
+ * Define a typed behavior descriptor.
893
+ *
894
+ * @example
895
+ * ```typescript
896
+ * export const WorldBoundary2DBehavior = defineBehavior({
897
+ * name: 'world-boundary-2d',
898
+ * defaultOptions: { boundaries: { top: 0, bottom: 0, left: 0, right: 0 } },
899
+ * systemFactory: (ctx) => new WorldBoundary2DSystem(ctx.world),
900
+ * createHandle: (ref) => ({
901
+ * getLastHits: () => ref.fsm?.getLastHits() ?? null,
902
+ * getMovement: (moveX: number, moveY: number) =>
903
+ * ref.fsm?.getMovement(moveX, moveY) ?? { moveX, moveY },
904
+ * }),
905
+ * });
906
+ *
907
+ * // Usage - handle has getLastHits and getMovement with full types
908
+ * const boundary = ship.use(WorldBoundary2DBehavior, { ... });
909
+ * const hits = boundary.getLastHits(); // Fully typed!
910
+ * ```
911
+ */
912
+ declare function defineBehavior<O extends Record<string, any>, H extends Record<string, any> = Record<string, never>, I = unknown>(config: DefineBehaviorConfig<O, H, I>): BehaviorDescriptor<O, H, I>;
913
+
914
+ export { type StageRicochetReflectionValue as $, type StageBodyInfo as A, type BehaviorDescriptor as B, type StageDebugRender as C, type DefineBehaviorConfig as D, type BaseBehaviorHandle as E, type BehaviorEntityLink as F, GameEntity as G, type BehaviorSystemContext as H, type CreateEntityFn as I, type GameEntityOptions as J, STAGE_INPUT_BUTTON_JUMP as K, STAGE_INPUT_BUTTON_RUN as L, STAGE_INVALID_SLOT as M, type StageBodyConfig as N, StageBodyKind as O, StageBoundaryDim as P, type StageColliderConfig as Q, type StageEvent as R, type StagePose as S, type TransformState as T, StageEventType as U, type VelocityIntentMode as V, WasmStageRuntime as W, type StageEventTypeValue as X, StagePlatformerShapeSource as Y, StageRicochetDim as Z, StageRicochetReflection as _, type BehaviorHandle as a, StageTopDownPlane as a0, type StageTopDownPlaneValue as a1, type VelocityIntent as a2, type WasmSnapshotBackref as a3, createTransformStore as a4, createWasmStageRuntime as a5, readBehaviorSnapshot as a6, readStageRenderSlot as a7, type BehaviorRef as b, type BehaviorSystem as c, type BehaviorSystemFactory as d, defineBehavior as e, type BehaviorRuntime as f, type StageBehaviorSnapshot as g, type StageThrusterOptions as h, type StageTopDownOptions as i, type StageShooter2DOptions as j, type StageScreenWrapOptions as k, type StageBoundaryDimValue as l, type StageWorldBoundaryOptions as m, type StageRicochetDimValue as n, type StageRicochetOptions as o, type StagePlatformer3DOptions as p, type StagePlatformer2DOptions as q, type StageFirstPersonOptions as r, type StageFirstPersonInput as s, type StageJumper2DOptions as t, type StageJumper3DOptions as u, type WasmStageRuntimeOptions as v, type StageBodyKindValue as w, type StageColliderShape as x, type StageRenderSlot as y, type StageRaycastHit as z };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SyncStateMachine,
3
3
  import_typescript_fsm
4
- } from "./chunk-OBF6BIA2.js";
4
+ } from "./chunk-CBQSC6W3.js";
5
5
  import {
6
6
  STAGE_INPUT_BUTTON_JUMP,
7
7
  STAGE_INPUT_BUTTON_RUN,
@@ -168,7 +168,8 @@ var Platformer3DFSM = class {
168
168
  const currentState = this.getState();
169
169
  const hasInput = Math.abs(input.moveX) > 0.1 || Math.abs(input.moveZ) > 0.1;
170
170
  const isRunning = input.run;
171
- if (currentState === "falling" /* Falling */ && state.grounded) {
171
+ const airborne = currentState === "falling" /* Falling */ || currentState === "jumping" /* Jumping */;
172
+ if (airborne && state.grounded) {
172
173
  this.dispatch("land" /* Land */);
173
174
  }
174
175
  if (state.grounded) {
@@ -201,6 +202,15 @@ var FSM_STATE_BY_INDEX = [
201
202
  "falling" /* Falling */,
202
203
  "landing" /* Landing */
203
204
  ];
205
+ function syncStateFromSnapshot(state, snapshot) {
206
+ const fsmState = FSM_STATE_BY_INDEX[snapshot.fsmState];
207
+ state.grounded = snapshot.grounded;
208
+ state.jumping = fsmState === "jumping" /* Jumping */;
209
+ state.falling = fsmState === "falling" /* Falling */;
210
+ state.jumpCount = snapshot.jumpCount;
211
+ state.currentSpeed = snapshot.speed;
212
+ state.verticalVelocity = snapshot.verticalVelocity;
213
+ }
204
214
  var defaultOptions = {
205
215
  walkSpeed: 12,
206
216
  runSpeed: 24,
@@ -256,6 +266,15 @@ var Platformer3DBehaviorSystem = class {
256
266
  wasmStage;
257
267
  getBehaviorLinks;
258
268
  attachedRuntimeSlots = /* @__PURE__ */ new Set();
269
+ snapshot = {
270
+ grounded: false,
271
+ fsmState: 0,
272
+ jumpCount: 0,
273
+ verticalVelocity: 0,
274
+ speed: 0,
275
+ yaw: 0,
276
+ pitch: 0
277
+ };
259
278
  update(_ecs, _delta) {
260
279
  const links = this.getBehaviorLinks?.(PLATFORMER_BEHAVIOR_KEY);
261
280
  if (!links) return;
@@ -283,6 +302,8 @@ var Platformer3DBehaviorSystem = class {
283
302
  this.wasmStage.writeInputButton(handle, STAGE_INPUT_BUTTON_JUMP, !!input.jump);
284
303
  this.wasmStage.writeInputButton(handle, STAGE_INPUT_BUTTON_RUN, !!input.run);
285
304
  }
305
+ const snapshot = this.wasmStage.readSnapshot(handle, this.snapshot);
306
+ if (snapshot) syncStateFromSnapshot(gameEntity.platformerState, snapshot);
286
307
  }
287
308
  }
288
309
  ensureWasmAttached(handle, options, gameEntity) {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SyncStateMachine,
3
3
  import_typescript_fsm
4
- } from "./chunk-OBF6BIA2.js";
4
+ } from "./chunk-CBQSC6W3.js";
5
5
  import {
6
6
  StageRicochetDim,
7
7
  StageRicochetReflection
@@ -3,9 +3,9 @@ import {
3
3
  __toESM
4
4
  } from "./chunk-JSBRDJBE.js";
5
5
 
6
- // node_modules/.pnpm/typescript-fsm@1.6.0/node_modules/typescript-fsm/dist/stateMachine.js
6
+ // ../../node_modules/.pnpm/typescript-fsm@1.6.0/node_modules/typescript-fsm/dist/stateMachine.js
7
7
  var require_stateMachine = __commonJS({
8
- "node_modules/.pnpm/typescript-fsm@1.6.0/node_modules/typescript-fsm/dist/stateMachine.js"(exports) {
8
+ "../../node_modules/.pnpm/typescript-fsm@1.6.0/node_modules/typescript-fsm/dist/stateMachine.js"(exports) {
9
9
  "use strict";
10
10
  Object.defineProperty(exports, "__esModule", { value: true });
11
11
  exports.SyncStateMachine = exports.StateMachine = void 0;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SyncStateMachine,
3
3
  import_typescript_fsm
4
- } from "./chunk-OBF6BIA2.js";
4
+ } from "./chunk-CBQSC6W3.js";
5
5
  import {
6
6
  STAGE_INPUT_BUTTON_JUMP,
7
7
  readBehaviorSnapshot
@@ -76,6 +76,7 @@ function getBounds3DNormalFromHits(hits) {
76
76
  }
77
77
 
78
78
  export {
79
+ normalizeBounds3DPadding,
79
80
  insetBounds3D,
80
81
  computeBounds3DHits,
81
82
  hasAnyBounds3DHit,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SyncStateMachine,
3
3
  import_typescript_fsm
4
- } from "./chunk-OBF6BIA2.js";
4
+ } from "./chunk-CBQSC6W3.js";
5
5
  import {
6
6
  STAGE_INPUT_BUTTON_JUMP,
7
7
  STAGE_INPUT_BUTTON_RUN,
@@ -145,7 +145,8 @@ var Platformer2DFSM = class {
145
145
  const currentState = this.getState();
146
146
  const hasInput = Math.abs(input.moveX) > 0.1;
147
147
  const isRunning = input.run;
148
- if (currentState === "falling" /* Falling */ && state.grounded) {
148
+ const airborne = currentState === "falling" /* Falling */ || currentState === "jumping" /* Jumping */;
149
+ if (airborne && state.grounded) {
149
150
  this.dispatch("land" /* Land */);
150
151
  }
151
152
  if (state.grounded) {
@@ -176,6 +177,15 @@ var FSM_STATE_BY_INDEX = [
176
177
  "falling" /* Falling */,
177
178
  "landing" /* Landing */
178
179
  ];
180
+ function syncStateFromSnapshot(state, snapshot) {
181
+ const fsmState = FSM_STATE_BY_INDEX[snapshot.fsmState];
182
+ state.grounded = snapshot.grounded;
183
+ state.jumping = fsmState === "jumping" /* Jumping */;
184
+ state.falling = fsmState === "falling" /* Falling */;
185
+ state.jumpCount = snapshot.jumpCount;
186
+ state.currentSpeed = snapshot.speed;
187
+ state.verticalVelocity = snapshot.verticalVelocity;
188
+ }
179
189
  var defaultOptions = {
180
190
  walkSpeed: 8,
181
191
  runSpeed: 14,
@@ -234,6 +244,15 @@ var Platformer2DBehaviorSystem = class {
234
244
  wasmStage;
235
245
  getBehaviorLinks;
236
246
  attachedRuntimeSlots = /* @__PURE__ */ new Set();
247
+ snapshot = {
248
+ grounded: false,
249
+ fsmState: 0,
250
+ jumpCount: 0,
251
+ verticalVelocity: 0,
252
+ speed: 0,
253
+ yaw: 0,
254
+ pitch: 0
255
+ };
237
256
  update(_ecs, _delta) {
238
257
  const links = this.getBehaviorLinks?.(PLATFORMER_2D_BEHAVIOR_KEY);
239
258
  if (!links) return;
@@ -261,6 +280,8 @@ var Platformer2DBehaviorSystem = class {
261
280
  this.wasmStage.writeInputButton(handle, STAGE_INPUT_BUTTON_JUMP, !!input.jump);
262
281
  this.wasmStage.writeInputButton(handle, STAGE_INPUT_BUTTON_RUN, !!input.run);
263
282
  }
283
+ const snapshot = this.wasmStage.readSnapshot(handle, this.snapshot);
284
+ if (snapshot) syncStateFromSnapshot(gameEntity.platformer2DState, snapshot);
264
285
  }
265
286
  }
266
287
  ensureWasmAttached(handle, options, gameEntity) {
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  SyncStateMachine,
7
7
  import_typescript_fsm
8
- } from "./chunk-OBF6BIA2.js";
8
+ } from "./chunk-CBQSC6W3.js";
9
9
  import {
10
10
  defineBehavior
11
11
  } from "./chunk-YDLO5M7S.js";
@@ -116,14 +116,16 @@ var ThrusterBehaviorSystem = class {
116
116
  if (!gameEntity.$thruster) {
117
117
  gameEntity.$thruster = createThrusterInputComponent();
118
118
  }
119
+ const input = gameEntity.$thruster;
120
+ if (!thrusterRef.fsm) {
121
+ thrusterRef.fsm = new ThrusterFSM({ input });
122
+ }
123
+ thrusterRef.fsm.update(input);
119
124
  const handle = gameEntity.runtimeHandle ?? -1;
120
125
  if (!this.wasmStage || handle < 0) continue;
121
126
  this.ensureWasmAttached(handle, options);
122
- const input = gameEntity.$thruster;
123
- if (input) {
124
- this.wasmStage.writeInputAxes(handle, input.thrust, input.rotate);
125
- this.wasmStage.writeInputReserved(handle, input.thrustX, input.thrustY);
126
- }
127
+ this.wasmStage.writeInputAxes(handle, input.thrust, input.rotate);
128
+ this.wasmStage.writeInputReserved(handle, input.thrustX, input.thrustY);
127
129
  }
128
130
  }
129
131
  ensureWasmAttached(handle, options) {
@@ -3,12 +3,13 @@ import {
3
3
  computeBounds3DHits,
4
4
  constrainMovementToBounds3D,
5
5
  hasAnyBounds3DHit,
6
- insetBounds3D
7
- } from "./chunk-WHKPWIQO.js";
6
+ insetBounds3D,
7
+ normalizeBounds3DPadding
8
+ } from "./chunk-HMVEQB2T.js";
8
9
  import {
9
10
  SyncStateMachine,
10
11
  import_typescript_fsm
11
- } from "./chunk-OBF6BIA2.js";
12
+ } from "./chunk-CBQSC6W3.js";
12
13
  import {
13
14
  StageBoundaryDim
14
15
  } from "./chunk-GZ3DQIIZ.js";
@@ -134,6 +135,18 @@ function createWorldBoundary3DHandle(ref) {
134
135
  }
135
136
  };
136
137
  }
138
+ function paddedRuntimeBounds(bounds, padding) {
139
+ const f32 = Math.fround;
140
+ const pad = normalizeBounds3DPadding(padding);
141
+ return {
142
+ left: f32(f32(bounds.left) + f32(pad.x)),
143
+ right: f32(f32(bounds.right) - f32(pad.x)),
144
+ bottom: f32(f32(bounds.bottom) + f32(pad.y)),
145
+ top: f32(f32(bounds.top) - f32(pad.y)),
146
+ back: f32(f32(bounds.back) + f32(pad.z)),
147
+ front: f32(f32(bounds.front) - f32(pad.z))
148
+ };
149
+ }
137
150
  var WorldBoundary3DSystem = class {
138
151
  constructor(wasmStage, getBehaviorLinks) {
139
152
  this.wasmStage = wasmStage;
@@ -159,8 +172,7 @@ var WorldBoundary3DSystem = class {
159
172
  if (query) {
160
173
  boundaryRef.fsm.update(
161
174
  { x: query.clamped[0], y: query.clamped[1], z: query.clamped[2] },
162
- options.boundaries,
163
- options.padding
175
+ paddedRuntimeBounds(options.boundaries, options.padding)
164
176
  );
165
177
  }
166
178
  }
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getBounds3DNormalFromHits
3
- } from "./chunk-WHKPWIQO.js";
3
+ } from "./chunk-HMVEQB2T.js";
4
4
  import {
5
5
  updateBoundaryRicochet
6
6
  } from "./chunk-2YF7J3H4.js";
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  SyncStateMachine,
6
6
  import_typescript_fsm
7
- } from "./chunk-OBF6BIA2.js";
7
+ } from "./chunk-CBQSC6W3.js";
8
8
  import {
9
9
  STAGE_INPUT_BUTTON_JUMP,
10
10
  readBehaviorSnapshot
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  SyncStateMachine,
6
6
  import_typescript_fsm
7
- } from "./chunk-OBF6BIA2.js";
7
+ } from "./chunk-CBQSC6W3.js";
8
8
  import {
9
9
  defineBehavior
10
10
  } from "./chunk-YDLO5M7S.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SyncStateMachine,
3
3
  import_typescript_fsm
4
- } from "./chunk-OBF6BIA2.js";
4
+ } from "./chunk-CBQSC6W3.js";
5
5
  import {
6
6
  StageRicochetDim,
7
7
  StageRicochetReflection
@@ -10,7 +10,7 @@ import {
10
10
  import {
11
11
  SyncStateMachine,
12
12
  import_typescript_fsm
13
- } from "./chunk-OBF6BIA2.js";
13
+ } from "./chunk-CBQSC6W3.js";
14
14
  import {
15
15
  STAGE_INPUT_BUTTON_RUN,
16
16
  readBehaviorSnapshot
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  SyncStateMachine,
8
8
  import_typescript_fsm
9
- } from "./chunk-OBF6BIA2.js";
9
+ } from "./chunk-CBQSC6W3.js";
10
10
  import {
11
11
  StageBoundaryDim
12
12
  } from "./chunk-GZ3DQIIZ.js";
@@ -129,6 +129,14 @@ function createWorldBoundary2DHandle(ref) {
129
129
  }
130
130
  };
131
131
  }
132
+ function runtimeBounds(bounds) {
133
+ return {
134
+ top: Math.fround(bounds.top),
135
+ bottom: Math.fround(bounds.bottom),
136
+ left: Math.fround(bounds.left),
137
+ right: Math.fround(bounds.right)
138
+ };
139
+ }
132
140
  var WorldBoundary2DSystem = class {
133
141
  constructor(wasmStage, getBehaviorLinks) {
134
142
  this.wasmStage = wasmStage;
@@ -154,7 +162,7 @@ var WorldBoundary2DSystem = class {
154
162
  if (query) {
155
163
  boundaryRef.fsm.update(
156
164
  { x: query.clamped[0], y: query.clamped[1] },
157
- options.boundaries
165
+ runtimeBounds(options.boundaries)
158
166
  );
159
167
  }
160
168
  }
@@ -1,4 +1,4 @@
1
- import { G as GameEntity, a as BehaviorDescriptor } from './behavior-system-DkFAwLb_.js';
1
+ import { G as GameEntity, B as BehaviorDescriptor } from './behavior-descriptor-Dr8qmQ20.js';
2
2
  import { Vector3, Quaternion } from 'three';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { a as BehaviorDescriptor } from './behavior-system-DkFAwLb_.js';
1
+ import { B as BehaviorDescriptor } from './behavior-descriptor-Dr8qmQ20.js';
2
2
  import '@zylem/runtime';
3
3
 
4
4
  /**
@@ -1,9 +1,9 @@
1
- import { a as MoveableEntity } from '../moveable-CFOHmblC.js';
1
+ import { M as MoveableEntity } from '../moveable-tkFsn7mE.js';
2
2
  import { B as BaseEntityInterface } from '../entity-types-DhfsZbSK.js';
3
3
  import { Ricochet3DHandle } from '../ricochet-3d.js';
4
4
  import { WorldBoundary3DHandle } from '../world-boundary-3d.js';
5
5
  import 'three';
6
- import '../behavior-system-DkFAwLb_.js';
6
+ import '../behavior-descriptor-Dr8qmQ20.js';
7
7
  import '@zylem/runtime';
8
8
  import '../sync-state-machine-CZyspBpj.js';
9
9
  import 'typescript-fsm';
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  BoundaryRicochet3DCoordinator
3
- } from "../chunk-RR3XNDKG.js";
4
- import "../chunk-WHKPWIQO.js";
3
+ } from "../chunk-T2LAQQDS.js";
4
+ import "../chunk-HMVEQB2T.js";
5
5
  import "../chunk-2YF7J3H4.js";
6
6
  import "../chunk-JSBRDJBE.js";
7
7
  export {
@@ -1,10 +1,10 @@
1
1
  import { Ricochet2DHandle } from '../ricochet-2d.js';
2
2
  import { WorldBoundary2DHandle } from '../world-boundary-2d.js';
3
- import { a as MoveableEntity } from '../moveable-CFOHmblC.js';
3
+ import { M as MoveableEntity } from '../moveable-tkFsn7mE.js';
4
4
  import { B as BaseEntityInterface } from '../entity-types-DhfsZbSK.js';
5
5
  import '../sync-state-machine-CZyspBpj.js';
6
6
  import 'typescript-fsm';
7
- import '../behavior-system-DkFAwLb_.js';
7
+ import '../behavior-descriptor-Dr8qmQ20.js';
8
8
  import '@zylem/runtime';
9
9
  import 'three';
10
10
 
@@ -1,9 +1,9 @@
1
1
  import { T as ThrusterInputComponent } from '../components-B29WHGQN.js';
2
2
  import { Shooter2DSourceEntity, Shooter2DHandle, Shooter2DStageLike } from '../shooter-2d.js';
3
3
  import { S as Shooter2DAimFireInput } from '../shooter-fire-DGripl0z.js';
4
- import '../behavior-system-DkFAwLb_.js';
4
+ import '../behavior-descriptor-Dr8qmQ20.js';
5
5
  import '@zylem/runtime';
6
- import '../vector-DjhLUrak.js';
6
+ import '../vector-s7GbCrVn.js';
7
7
  import 'three';
8
8
 
9
9
  interface MultidirectionalSpaceShooterInput extends Shooter2DAimFireInput {
@@ -1,9 +1,9 @@
1
1
  import { a as TopDownMovementInputComponent } from '../components-XCpL6IYt.js';
2
2
  import { Shooter2DSourceEntity, Shooter2DHandle, Shooter2DStageLike } from '../shooter-2d.js';
3
3
  import { S as Shooter2DAimFireInput } from '../shooter-fire-DGripl0z.js';
4
- import '../behavior-system-DkFAwLb_.js';
4
+ import '../behavior-descriptor-Dr8qmQ20.js';
5
5
  import '@zylem/runtime';
6
- import '../vector-DjhLUrak.js';
6
+ import '../vector-s7GbCrVn.js';
7
7
  import 'three';
8
8
 
9
9
  interface TopDownShooterInput extends Shooter2DAimFireInput {
package/dist/core.d.ts CHANGED
@@ -1,8 +1,8 @@
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-DkFAwLb_.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-DkFAwLb_.js';
3
- export { P as PhysicsBodyComponent, T as TransformComponent, c as createPhysicsBodyComponent, a as createTransformComponent, u as useBehavior } from './components--RTwuT4S.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-CFOHmblC.js';
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';
1
+ import { V as VelocityIntentMode, T as TransformState, f as BehaviorRuntime, S as StagePose, g as StageBehaviorSnapshot, h as StageThrusterOptions, i as StageTopDownOptions, j as StageShooter2DOptions, k as StageScreenWrapOptions, l as StageBoundaryDimValue, m as StageWorldBoundaryOptions, n as StageRicochetDimValue, o as StageRicochetOptions, p as StagePlatformer3DOptions, q as StagePlatformer2DOptions, r as StageFirstPersonOptions, s as StageFirstPersonInput, t as StageJumper2DOptions, u as StageJumper3DOptions, W as WasmStageRuntime, v as WasmStageRuntimeOptions, w as StageBodyKindValue, x as StageColliderShape, y as StageRenderSlot, z as StageRaycastHit, A as StageBodyInfo, C as StageDebugRender } from './behavior-descriptor-Dr8qmQ20.js';
2
+ export { E as BaseBehaviorHandle, B as BehaviorDescriptor, F as BehaviorEntityLink, a as BehaviorHandle, b as BehaviorRef, c as BehaviorSystem, H as BehaviorSystemContext, d as BehaviorSystemFactory, I as CreateEntityFn, D as DefineBehaviorConfig, G as GameEntity, J as GameEntityOptions, K as STAGE_INPUT_BUTTON_JUMP, L as STAGE_INPUT_BUTTON_RUN, M as STAGE_INVALID_SLOT, N as StageBodyConfig, O as StageBodyKind, P as StageBoundaryDim, Q as StageColliderConfig, R as StageEvent, U as StageEventType, X as StageEventTypeValue, Y as StagePlatformerShapeSource, Z as StageRicochetDim, _ as StageRicochetReflection, $ as StageRicochetReflectionValue, a0 as StageTopDownPlane, a1 as StageTopDownPlaneValue, a2 as VelocityIntent, a3 as WasmSnapshotBackref, a4 as createTransformStore, a5 as createWasmStageRuntime, e as defineBehavior, a6 as readBehaviorSnapshot, a7 as readStageRenderSlot } from './behavior-descriptor-Dr8qmQ20.js';
3
+ export { P as PhysicsBodyComponent, T as TransformComponent, c as createPhysicsBodyComponent, a as createTransformComponent, u as useBehavior } from './components-tct075-p.js';
4
+ export { E as EntityWithBody, a as MoveableBodyLike, M 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-tkFsn7mE.js';
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-s7GbCrVn.js';
6
6
  export { S as SyncStateMachine } from './sync-state-machine-CZyspBpj.js';
7
7
  export { F as FirstPersonPerspective } from './first-person-perspective-BxFHgFln.js';
8
8
  export { ILogger, ITransition, SyncCallback, t } from 'typescript-fsm';
package/dist/core.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  import {
19
19
  SyncStateMachine,
20
20
  import_typescript_fsm
21
- } from "./chunk-OBF6BIA2.js";
21
+ } from "./chunk-CBQSC6W3.js";
22
22
  import {
23
23
  STAGE_EVENT_STRIDE,
24
24
  STAGE_INPUT_BUTTON_JUMP,