@zylem/behaviors 0.3.1 → 0.4.1

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 (139) hide show
  1. package/dist/behavior-system-y8SGrGWy.d.ts +580 -0
  2. package/dist/{chunk-ARJWUNRE.js → chunk-27UPCP5B.js} +10 -10
  3. package/dist/{chunk-ARJWUNRE.js.map → chunk-27UPCP5B.js.map} +1 -1
  4. package/dist/{chunk-YUO6SKJD.js → chunk-4L36OPY2.js} +33 -23
  5. package/dist/chunk-4L36OPY2.js.map +1 -0
  6. package/dist/{chunk-DYLH6K7B.js → chunk-4WH2ZN7P.js} +1 -1
  7. package/dist/{chunk-DYLH6K7B.js.map → chunk-4WH2ZN7P.js.map} +1 -1
  8. package/dist/{chunk-ZPSAXX73.js → chunk-5SM5SH5O.js} +26 -26
  9. package/dist/chunk-5SM5SH5O.js.map +1 -0
  10. package/dist/{chunk-STCCNLPC.js → chunk-5XZWTFGF.js} +5 -3
  11. package/dist/chunk-5XZWTFGF.js.map +1 -0
  12. package/dist/{chunk-JAN34G6S.js → chunk-67XLJ26X.js} +152 -168
  13. package/dist/chunk-67XLJ26X.js.map +1 -0
  14. package/dist/{chunk-2CLT36VB.js → chunk-75FJIUIG.js} +22 -23
  15. package/dist/chunk-75FJIUIG.js.map +1 -0
  16. package/dist/{chunk-OYWFPIHF.js → chunk-A4CA35DQ.js} +20 -17
  17. package/dist/chunk-A4CA35DQ.js.map +1 -0
  18. package/dist/{chunk-SS7ELMJ7.js → chunk-F72WX4MH.js} +49 -33
  19. package/dist/chunk-F72WX4MH.js.map +1 -0
  20. package/dist/{chunk-RTRVBEIB.js → chunk-FTDZAKZW.js} +5 -18
  21. package/dist/chunk-FTDZAKZW.js.map +1 -0
  22. package/dist/{chunk-XIJNE67Y.js → chunk-GFARAJV2.js} +3 -5
  23. package/dist/{chunk-XIJNE67Y.js.map → chunk-GFARAJV2.js.map} +1 -1
  24. package/dist/{chunk-VAN4WW3F.js → chunk-H4TJ7X4O.js} +4 -7
  25. package/dist/chunk-H4TJ7X4O.js.map +1 -0
  26. package/dist/{chunk-KS72RZHX.js → chunk-IZJFUAXB.js} +1 -1
  27. package/dist/{chunk-KS72RZHX.js.map → chunk-IZJFUAXB.js.map} +1 -1
  28. package/dist/{chunk-SVLNF434.js → chunk-JXMF4NUI.js} +51 -3
  29. package/dist/chunk-JXMF4NUI.js.map +1 -0
  30. package/dist/chunk-KFFETUAL.js +40 -0
  31. package/dist/chunk-KFFETUAL.js.map +1 -0
  32. package/dist/chunk-LL4FLHIY.js +12 -0
  33. package/dist/chunk-LL4FLHIY.js.map +1 -0
  34. package/dist/{chunk-RTVRUNYR.js → chunk-OTLSUYQQ.js} +2 -2
  35. package/dist/chunk-OTLSUYQQ.js.map +1 -0
  36. package/dist/{chunk-Y6UJOUE5.js → chunk-Q75LKHDF.js} +14 -2
  37. package/dist/chunk-Q75LKHDF.js.map +1 -0
  38. package/dist/{chunk-KOZUNIIE.js → chunk-QDCJLJUV.js} +10 -10
  39. package/dist/{chunk-KOZUNIIE.js.map → chunk-QDCJLJUV.js.map} +1 -1
  40. package/dist/{chunk-LD5SMIB3.js → chunk-QVCMJ4Q2.js} +1 -1
  41. package/dist/{chunk-LD5SMIB3.js.map → chunk-QVCMJ4Q2.js.map} +1 -1
  42. package/dist/{chunk-F3KRX2V4.js → chunk-RDHSHEZM.js} +46 -24
  43. package/dist/chunk-RDHSHEZM.js.map +1 -0
  44. package/dist/chunk-UIG7MWS2.js +518 -0
  45. package/dist/chunk-UIG7MWS2.js.map +1 -0
  46. package/dist/{chunk-6C6NXNEW.js → chunk-UL6Q5HDP.js} +25 -3
  47. package/dist/chunk-UL6Q5HDP.js.map +1 -0
  48. package/dist/{chunk-XG2YMCJW.js → chunk-VMQHNJJI.js} +6 -8
  49. package/dist/{chunk-XG2YMCJW.js.map → chunk-VMQHNJJI.js.map} +1 -1
  50. package/dist/{chunk-GCNRXAKH.js → chunk-XP3ASVGJ.js} +13 -10
  51. package/dist/chunk-XP3ASVGJ.js.map +1 -0
  52. package/dist/{chunk-ID5QJYF5.js → chunk-Y7YIAWPW.js} +11 -1
  53. package/dist/chunk-Y7YIAWPW.js.map +1 -0
  54. package/dist/{chunk-4I6E6DGV.js → chunk-Z72F2ENM.js} +6 -8
  55. package/dist/{chunk-4I6E6DGV.js.map → chunk-Z72F2ENM.js.map} +1 -1
  56. package/dist/{chunk-FPTWVCPN.js → chunk-ZA43LPRM.js} +4 -24
  57. package/dist/chunk-ZA43LPRM.js.map +1 -0
  58. package/dist/{chunk-K3UNLQ7W.js → chunk-ZRQWSURL.js} +2 -2
  59. package/dist/chunk-ZRQWSURL.js.map +1 -0
  60. package/dist/cooldown.d.ts +2 -1
  61. package/dist/cooldown.js +1 -1
  62. package/dist/coordinators/boundary-ricochet-3d.d.ts +12 -5
  63. package/dist/coordinators/boundary-ricochet-3d.js +2 -1
  64. package/dist/coordinators/boundary-ricochet.d.ts +9 -7
  65. package/dist/coordinators/boundary-ricochet.js +2 -1
  66. package/dist/coordinators/first-person-shooter.d.ts +9 -8
  67. package/dist/coordinators/first-person-shooter.js +3 -3
  68. package/dist/coordinators/multidirectional-space-shooter.d.ts +12 -9
  69. package/dist/coordinators/multidirectional-space-shooter.js +4 -4
  70. package/dist/coordinators/top-down-shooter.d.ts +9 -8
  71. package/dist/coordinators/top-down-shooter.js +3 -3
  72. package/dist/core.d.ts +4 -4
  73. package/dist/core.js +17 -39
  74. package/dist/core.js.map +1 -1
  75. package/dist/destructible-3d.d.ts +2 -1
  76. package/dist/first-person.d.ts +12 -12
  77. package/dist/first-person.js +9 -8
  78. package/dist/index.d.ts +37 -14
  79. package/dist/index.js +73 -44
  80. package/dist/jumper-2d.d.ts +7 -6
  81. package/dist/jumper-2d.js +6 -5
  82. package/dist/jumper-3d.d.ts +12 -11
  83. package/dist/jumper-3d.js +7 -6
  84. package/dist/{moveable-BCRpjAQb.d.ts → moveable-Cl9h-_w7.d.ts} +2 -78
  85. package/dist/particle-emitter.d.ts +1 -1
  86. package/dist/particle-emitter.js +1 -1
  87. package/dist/platformer-2d.d.ts +306 -0
  88. package/dist/platformer-2d.js +24 -0
  89. package/dist/platformer-3d.d.ts +74 -87
  90. package/dist/platformer-3d.js +5 -4
  91. package/dist/ricochet-2d.d.ts +1 -1
  92. package/dist/ricochet-2d.js +2 -2
  93. package/dist/ricochet-3d.d.ts +1 -1
  94. package/dist/ricochet-3d.js +2 -2
  95. package/dist/runtime-2d.d.ts +93 -2
  96. package/dist/runtime-2d.js +145 -22
  97. package/dist/runtime-2d.js.map +1 -1
  98. package/dist/screen-visibility.d.ts +2 -1
  99. package/dist/screen-wrap.d.ts +2 -1
  100. package/dist/screen-wrap.js +1 -1
  101. package/dist/shooter-2d.d.ts +5 -3
  102. package/dist/shooter-2d.js +2 -2
  103. package/dist/shooter-fire-DGripl0z.d.ts +55 -0
  104. package/dist/thruster.d.ts +8 -18
  105. package/dist/thruster.js +6 -6
  106. package/dist/top-down-movement.d.ts +7 -4
  107. package/dist/top-down-movement.js +5 -5
  108. package/dist/{use-behavior-D_82jAL3.d.ts → use-behavior-B85d5u7-.d.ts} +1 -1
  109. package/dist/world-boundary-2d.d.ts +2 -1
  110. package/dist/world-boundary-2d.js +2 -2
  111. package/dist/world-boundary-3d.d.ts +2 -1
  112. package/dist/world-boundary-3d.js +2 -2
  113. package/package.json +7 -5
  114. package/dist/behavior-system-DYbx-x_-.d.ts +0 -307
  115. package/dist/chunk-2C3Z5GE7.js +0 -176
  116. package/dist/chunk-2C3Z5GE7.js.map +0 -1
  117. package/dist/chunk-2CLT36VB.js.map +0 -1
  118. package/dist/chunk-3PYGRHAL.js +0 -35
  119. package/dist/chunk-3PYGRHAL.js.map +0 -1
  120. package/dist/chunk-6C6NXNEW.js.map +0 -1
  121. package/dist/chunk-F3KRX2V4.js.map +0 -1
  122. package/dist/chunk-FPTWVCPN.js.map +0 -1
  123. package/dist/chunk-GCNRXAKH.js.map +0 -1
  124. package/dist/chunk-ID5QJYF5.js.map +0 -1
  125. package/dist/chunk-JAN34G6S.js.map +0 -1
  126. package/dist/chunk-K3UNLQ7W.js.map +0 -1
  127. package/dist/chunk-OYWFPIHF.js.map +0 -1
  128. package/dist/chunk-RTRVBEIB.js.map +0 -1
  129. package/dist/chunk-RTVRUNYR.js.map +0 -1
  130. package/dist/chunk-SS7ELMJ7.js.map +0 -1
  131. package/dist/chunk-STCCNLPC.js.map +0 -1
  132. package/dist/chunk-SVLNF434.js.map +0 -1
  133. package/dist/chunk-VAN4WW3F.js.map +0 -1
  134. package/dist/chunk-Y6UJOUE5.js.map +0 -1
  135. package/dist/chunk-YUO6SKJD.js.map +0 -1
  136. package/dist/chunk-ZPSAXX73.js.map +0 -1
  137. package/dist/runtime-pong.d.ts +0 -92
  138. package/dist/runtime-pong.js +0 -38
  139. /package/dist/{runtime-pong.js.map → platformer-2d.js.map} +0 -0
@@ -0,0 +1,580 @@
1
+ import { RigidBody, Collider, World } from '@dimforge/rapier3d-compat';
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
+ type VelocityIntentMode = 'replace' | 'add';
108
+ interface VelocityIntent {
109
+ x?: number;
110
+ y?: number;
111
+ z?: number;
112
+ mode: VelocityIntentMode;
113
+ priority?: number;
114
+ }
115
+ /**
116
+ * Transform state managed by Valtio for batched physics updates.
117
+ *
118
+ * This store accumulates transformation intents during the frame,
119
+ * then applies them all at once after onUpdate() callbacks complete.
120
+ *
121
+ * Design decisions:
122
+ * - Position: Accumulated deltas (additive)
123
+ * - Rotation: Last value wins (replacement)
124
+ * - Velocity: Accumulated deltas (additive)
125
+ * - Angular velocity: Accumulated deltas (additive)
126
+ */
127
+ interface TransformState {
128
+ /** Position deltas to be applied (accumulated) */
129
+ position: {
130
+ x: number;
131
+ y: number;
132
+ z: number;
133
+ };
134
+ /** Rotation quaternion (last value wins) */
135
+ rotation: {
136
+ x: number;
137
+ y: number;
138
+ z: number;
139
+ w: number;
140
+ };
141
+ /** Linear velocity (accumulated) */
142
+ velocity: {
143
+ x: number;
144
+ y: number;
145
+ z: number;
146
+ };
147
+ /** Angular velocity (accumulated) */
148
+ angularVelocity: {
149
+ x: number;
150
+ y: number;
151
+ z: number;
152
+ };
153
+ /** Per-source velocity intents composed once per frame */
154
+ velocityChannels: Record<string, VelocityIntent>;
155
+ /** Dirty flags to track what needs to be applied */
156
+ dirty: {
157
+ position: boolean;
158
+ rotation: boolean;
159
+ velocityX: boolean;
160
+ velocityY: boolean;
161
+ velocityZ: boolean;
162
+ velocityChannels: boolean;
163
+ angularVelocity: boolean;
164
+ };
165
+ }
166
+ /**
167
+ * Create a new transform store with optional initial values.
168
+ * The store is a Valtio proxy, making it reactive for debugging/visualization.
169
+ *
170
+ * @param initial Optional initial state values
171
+ * @returns Reactive transform state
172
+ */
173
+ declare function createTransformStore(initial?: Partial<TransformState>): TransformState;
174
+
175
+ /**
176
+ * Minimal, runtime-agnostic entity options contract.
177
+ *
178
+ * The full engine entity (in `@zylem/game-lib`) provides a richer options type,
179
+ * but behaviors only rely on this loose shape.
180
+ */
181
+ interface GameEntityOptions {
182
+ [key: string]: any;
183
+ name?: string;
184
+ }
185
+ /**
186
+ * Structural stand-in for the engine `GameEntity`.
187
+ *
188
+ * Behaviors annotate against this loose contract so that `@zylem/behaviors`
189
+ * (and its `@zylem/behaviors/core` surface) never has to depend on the concrete
190
+ * `@zylem/game-lib` entity implementation. The real engine entity is
191
+ * structurally assignable to this type.
192
+ */
193
+ declare class GameEntity<TOptions = unknown> {
194
+ [key: string]: any;
195
+ uuid: string;
196
+ name: string;
197
+ type: string;
198
+ options?: TOptions & Record<string, unknown>;
199
+ group: any;
200
+ mesh?: any;
201
+ materials?: any[];
202
+ body: RigidBody | null;
203
+ collider: Collider | null;
204
+ colliderDesc?: any;
205
+ colliderDescs: any[];
206
+ bodyDesc?: any;
207
+ physicsAttached: boolean;
208
+ runtimeHandle?: number;
209
+ transformStore?: TransformState;
210
+ nodeDestroy?: any;
211
+ isInstanced?: boolean;
212
+ private __behaviorRefs;
213
+ create(): this;
214
+ onCleanup(callback: () => void): this;
215
+ setPosition(_x: number, _y: number, _z: number): void;
216
+ setRotation(_x: number, _y: number, _z: number): void;
217
+ setRotationZ(_z: number): void;
218
+ setScale(_x: number, _y: number, _z: number): void;
219
+ /**
220
+ * Attach a behavior to this entity. The real engine entity does substantially
221
+ * more, but this functional stub stores the merged ref and builds the handle
222
+ * so descriptor/handle logic (and tests that drive behaviors directly) work
223
+ * without the full engine.
224
+ */
225
+ use<O extends Record<string, any>, H extends Record<string, any> = Record<string, never>>(descriptor: BehaviorDescriptor<O, H>, options?: Partial<O>): BehaviorHandle<O, H>;
226
+ /** Live behavior refs attached via {@link use}. */
227
+ getBehaviorRefs(): BehaviorRef<any>[];
228
+ }
229
+ /**
230
+ * Factory contract injected into behavior systems via
231
+ * {@link BehaviorSystemContext.createEntity}. The host engine supplies the real
232
+ * entity factory at stage-construction time.
233
+ */
234
+ type CreateEntityFn = (options?: Partial<GameEntityOptions>) => GameEntity<GameEntityOptions>;
235
+
236
+ declare const StageBodyKind: {
237
+ readonly Dynamic: 0;
238
+ readonly Static: 1;
239
+ readonly KinematicPosition: 2;
240
+ readonly KinematicVelocity: 3;
241
+ };
242
+ declare const StageBoundaryDim: {
243
+ readonly Two: 2;
244
+ readonly Three: 3;
245
+ };
246
+ declare const StageRicochetDim: {
247
+ readonly Two: 2;
248
+ readonly Three: 3;
249
+ };
250
+ declare const StageRicochetReflection: {
251
+ readonly Mirror: 0;
252
+ readonly Angled: 1;
253
+ };
254
+ declare const StageTopDownPlane: {
255
+ readonly Xy: 0;
256
+ readonly Xz: 1;
257
+ };
258
+ declare const StageEventType: {
259
+ readonly CollisionStarted: 1;
260
+ readonly CollisionStopped: 2;
261
+ readonly BoundaryHit: 3;
262
+ readonly Ricochet: 4;
263
+ readonly RegionEntered: 5;
264
+ readonly JumpStarted: 6;
265
+ readonly Landed: 7;
266
+ readonly Wrapped: 8;
267
+ readonly CooldownFired: 9;
268
+ };
269
+ type StageBoundaryDimValue = (typeof StageBoundaryDim)[keyof typeof StageBoundaryDim];
270
+ type StageRicochetDimValue = (typeof StageRicochetDim)[keyof typeof StageRicochetDim];
271
+ type StageRicochetReflectionValue = (typeof StageRicochetReflection)[keyof typeof StageRicochetReflection];
272
+ type StageTopDownPlaneValue = (typeof StageTopDownPlane)[keyof typeof StageTopDownPlane];
273
+ /** Position + rotation snapshot for one runtime slot. */
274
+ interface StagePose {
275
+ position: [number, number, number];
276
+ rotation: [number, number, number, number];
277
+ }
278
+ interface StageWorldBoundaryOptions {
279
+ top: number;
280
+ bottom: number;
281
+ left: number;
282
+ right: number;
283
+ front?: number;
284
+ back?: number;
285
+ padding?: number;
286
+ }
287
+ interface StageScreenWrapOptions {
288
+ width: number;
289
+ height: number;
290
+ centerX?: number;
291
+ centerY?: number;
292
+ edgeThreshold?: number;
293
+ }
294
+ interface StageRicochetOptions {
295
+ minSpeed: number;
296
+ maxSpeed: number;
297
+ speedMultiplier: number;
298
+ maxAngleDeg: number;
299
+ reflectionMode: StageRicochetReflectionValue;
300
+ }
301
+ interface StageThrusterOptions {
302
+ maxSpeed: number;
303
+ acceleration: number;
304
+ turnRateRadPerSec: number;
305
+ linearDamping: number;
306
+ }
307
+ interface StageTopDownOptions {
308
+ plane: StageTopDownPlaneValue;
309
+ speed: number;
310
+ faceMovement?: boolean;
311
+ }
312
+ interface StageShooter2DOptions {
313
+ fireRateHz: number;
314
+ muzzleOffsetX: number;
315
+ muzzleOffsetY: number;
316
+ muzzleSpeed: number;
317
+ }
318
+ interface StageJumper2DOptions {
319
+ jumpForce: number;
320
+ maxJumps: number;
321
+ jumpBufferTime: number;
322
+ coyoteTime: number;
323
+ gravity: number;
324
+ }
325
+ interface StageJumper3DOptions {
326
+ jumpForce: number;
327
+ maxJumps: number;
328
+ gravity: number;
329
+ /** Coyote time in seconds (default 0.1). */
330
+ coyoteTime?: number;
331
+ /** Jump buffer window in seconds (default 0.08). */
332
+ jumpBufferTime?: number;
333
+ }
334
+ interface StagePlatformer3DOptions {
335
+ halfHeight: number;
336
+ radius: number;
337
+ walkSpeed: number;
338
+ runSpeed: number;
339
+ jumpForce: number;
340
+ maxJumps: number;
341
+ gravity: number;
342
+ /** Coyote time in seconds (default 0.1). */
343
+ coyoteTime?: number;
344
+ /** Jump buffer window in seconds (default 0.1). */
345
+ jumpBufferTime?: number;
346
+ /** Velocity multiplier applied on early jump release (default 0.5). */
347
+ jumpCutMultiplier?: number;
348
+ /** Seconds before a multi-jump becomes available (default 0.15). */
349
+ multiJumpWindow?: number;
350
+ /** Max slope angle in degrees the KCC can climb (default 50). */
351
+ slopeClimbAngle?: number;
352
+ /** Slope angle in degrees past which the character slides (default 40). */
353
+ slopeSlideAngle?: number;
354
+ /** Autostep max height in world units; 0 disables (default 0.3). */
355
+ autostepHeight?: number;
356
+ /** Minimum unobstructed width for an autostep (default 0.1). */
357
+ autostepMinWidth?: number;
358
+ /** Snap-to-ground distance in world units; 0 disables (default 0.3). */
359
+ snapToGroundDistance?: number;
360
+ /** KCC collision offset between collider and environment (default 0.05). */
361
+ characterOffset?: number;
362
+ }
363
+ interface StagePlatformer2DOptions {
364
+ halfHeight: number;
365
+ radius: number;
366
+ walkSpeed: number;
367
+ runSpeed: number;
368
+ jumpForce: number;
369
+ maxJumps: number;
370
+ gravity: number;
371
+ /** Coyote time in seconds (default 0.1). */
372
+ coyoteTime?: number;
373
+ /** Jump buffer window in seconds (default 0.1). */
374
+ jumpBufferTime?: number;
375
+ /** Velocity multiplier applied on early jump release (default 0.5). */
376
+ jumpCutMultiplier?: number;
377
+ /** Seconds before a multi-jump becomes available (default 0.15). */
378
+ multiJumpWindow?: number;
379
+ /** Max slope angle in degrees the KCC can climb (default 50). */
380
+ slopeClimbAngle?: number;
381
+ /** Slope angle in degrees past which the character slides (default 40). */
382
+ slopeSlideAngle?: number;
383
+ /** Autostep max height in world units; 0 disables (default 0.25). */
384
+ autostepHeight?: number;
385
+ /** Minimum unobstructed width for an autostep (default 0.05). */
386
+ autostepMinWidth?: number;
387
+ /** Snap-to-ground distance in world units; 0 disables (default 0.2). */
388
+ snapToGroundDistance?: number;
389
+ /** KCC collision offset between collider and environment (default 0.05). */
390
+ characterOffset?: number;
391
+ }
392
+ interface StageFirstPersonOptions {
393
+ walkSpeed: number;
394
+ runSpeed: number;
395
+ eyeHeight: number;
396
+ lookSensitivity: number;
397
+ }
398
+ interface StageFirstPersonInput {
399
+ moveX: number;
400
+ moveZ: number;
401
+ lookYawDelta: number;
402
+ lookPitchDelta: number;
403
+ run: boolean;
404
+ }
405
+ /** Button bits for the batched input buffer's bitmask field. */
406
+ declare const STAGE_INPUT_BUTTON_JUMP = 1;
407
+ declare const STAGE_INPUT_BUTTON_RUN = 2;
408
+ /**
409
+ * Decoded per-slot behavior snapshot written by the runtime after every
410
+ * step: movement fields come from whichever character behavior the entity
411
+ * has (platformer 3D/2D, jumper 3D/2D); first-person fills yaw/pitch.
412
+ * Values reflect the end of the previous `step()` (one-frame read lag).
413
+ */
414
+ interface StageBehaviorSnapshot {
415
+ grounded: boolean;
416
+ fsmState: number;
417
+ jumpCount: number;
418
+ verticalVelocity: number;
419
+ speed: number;
420
+ yaw: number;
421
+ pitch: number;
422
+ }
423
+ /**
424
+ * Wasm fast-path backrefs a behavior system stores on its `BehaviorRef` every
425
+ * frame so descriptor handles can read the runtime snapshot buffer instead of
426
+ * a duplicate TS FSM (or hardcoded defaults).
427
+ */
428
+ interface WasmSnapshotBackref {
429
+ __wasmStage?: WasmStageRuntime | null;
430
+ __entity?: {
431
+ runtimeHandle?: number;
432
+ } | null;
433
+ }
434
+ /**
435
+ * Read the behavior snapshot for the entity a `BehaviorRef` is linked to.
436
+ * Returns `null` off the wasm fast path (no stage runtime / no
437
+ * `runtimeHandle` / no snapshot yet), in which case handles should fall back
438
+ * to their TS FSM.
439
+ */
440
+ declare function readBehaviorSnapshot(ref: object): StageBehaviorSnapshot | null;
441
+ /**
442
+ * Typed FFI surface of the wasm unified Stage runtime that behaviors rely on.
443
+ *
444
+ * The concrete implementation lives in `@zylem/game-lib`
445
+ * (`wasm-stage-runtime.ts`); this contract mirrors the slice of its methods
446
+ * that behavior systems call so descriptors stay runtime-agnostic.
447
+ */
448
+ interface WasmStageRuntime {
449
+ getPose(handle: number, out?: StagePose): StagePose | null;
450
+ writeInputAxes(handle: number, axisA: number, axisB: number): boolean;
451
+ writeInputLook(handle: number, yawDelta: number, pitchDelta: number): boolean;
452
+ writeInputButton(handle: number, buttonMask: number, pressed: boolean): boolean;
453
+ /** Read the per-slot behavior snapshot written at the end of the previous step. */
454
+ readSnapshot(handle: number, out?: StageBehaviorSnapshot): StageBehaviorSnapshot | null;
455
+ attachThruster(handle: number, opts: StageThrusterOptions): boolean;
456
+ setThrusterInput(handle: number, thrust: number, rotate: number): void;
457
+ attachTopDown(handle: number, opts: StageTopDownOptions): boolean;
458
+ setTopDownInput(handle: number, moveX: number, moveY: number): void;
459
+ attachShooter2D(handle: number, opts: StageShooter2DOptions): boolean;
460
+ attachScreenWrap(handle: number, opts: StageScreenWrapOptions): boolean;
461
+ queryScreenWrap(handle: number): {
462
+ fsm: number;
463
+ lastWrappedAxes: number;
464
+ } | null;
465
+ attachWorldBoundary(handle: number, dim: StageBoundaryDimValue, opts: StageWorldBoundaryOptions): boolean;
466
+ queryWorldBoundary(handle: number): {
467
+ hits: number;
468
+ clamped: [number, number, number];
469
+ } | null;
470
+ attachRicochet(handle: number, dim: StageRicochetDimValue, opts: StageRicochetOptions): boolean;
471
+ attachPlatformer3D(handle: number, opts: StagePlatformer3DOptions): boolean;
472
+ setPlatformer3DInputAxes(handle: number, moveX: number, moveZ: number): void;
473
+ setPlatformer3DInputButtons(handle: number, jump: boolean, run: boolean): void;
474
+ attachPlatformer2D(handle: number, opts: StagePlatformer2DOptions): boolean;
475
+ setPlatformer2DInputAxes(handle: number, moveX: number): void;
476
+ setPlatformer2DInputButtons(handle: number, jump: boolean, run: boolean): void;
477
+ attachFirstPerson(handle: number, opts: StageFirstPersonOptions): boolean;
478
+ setFirstPersonInput(handle: number, input: StageFirstPersonInput): void;
479
+ attachJumper2D(handle: number, opts: StageJumper2DOptions): boolean;
480
+ setJumper2DInput(handle: number, jumpPressed: boolean): void;
481
+ attachJumper3D(handle: number, opts: StageJumper3DOptions): boolean;
482
+ setJumper3DInput(handle: number, jumpPressed: boolean): void;
483
+ }
484
+ /** Default options used when constructing a wasm-backed Stage runtime. */
485
+ interface WasmStageRuntimeOptions {
486
+ initialCapacity?: number;
487
+ gravity?: readonly [number, number, number];
488
+ imports?: WebAssembly.Imports;
489
+ }
490
+
491
+ /**
492
+ * Structural stand-in for the engine world wrapper. The engine's world
493
+ * delegate exposes the raw Rapier world plus an entity lookup map; behaviors
494
+ * only rely on this slice.
495
+ *
496
+ * The map value is intentionally `unknown` (not the `GameEntity` stub class):
497
+ * the engine's concrete entity class is a different nominal type, and systems
498
+ * that iterate the map narrow entities themselves.
499
+ */
500
+ interface ZylemWorld {
501
+ /** Raw Rapier physics world (present when the Rapier path is active). */
502
+ world?: World;
503
+ collisionMap?: Map<string, unknown>;
504
+ }
505
+
506
+ /**
507
+ * BehaviorSystem Interface
508
+ *
509
+ * Legacy behavior systems reserved the first `update` argument for an ECS world
510
+ * handle; it is always `undefined` now.
511
+ */
512
+ /**
513
+ * A behavior system that processes entities with specific components.
514
+ *
515
+ * @example
516
+ * ```typescript
517
+ * class ThrusterSystem implements BehaviorSystem {
518
+ * update(_ecs: unknown, delta: number): void {
519
+ * // Iterate behavior links, push intent into wasm runtime, etc.
520
+ * }
521
+ * }
522
+ * ```
523
+ */
524
+ interface BehaviorSystem {
525
+ /** Optional eager initialization when a behavior link is registered on a live entity */
526
+ attach?(link: BehaviorEntityLink): void;
527
+ /** Called once per frame. The first argument is always `undefined` (reserved legacy slot). */
528
+ update(ecs: unknown, delta: number): void;
529
+ /** Optional cleanup when a behavior link is detached from a live entity */
530
+ detach?(link: BehaviorEntityLink): void;
531
+ /** Optional cleanup when stage is destroyed */
532
+ destroy?(ecs?: unknown): void;
533
+ }
534
+ /**
535
+ * Runtime link between a spawned entity and one of its behavior refs.
536
+ * Systems can iterate these links to avoid scanning all world entities.
537
+ */
538
+ interface BehaviorEntityLink {
539
+ entity: any;
540
+ ref: any;
541
+ }
542
+ /**
543
+ * Context provided to behavior-system factories.
544
+ *
545
+ * After the runtime-only stage migration, `wasmStage` is the source of
546
+ * truth — descriptors should call `wasmStage.attach<X>(handle, opts)` /
547
+ * `wasmStage.query<X>(handle)` from inside the system instead of touching
548
+ * `entity.body` directly. The legacy `world` / `scene` fields remain for
549
+ * unmigrated descriptors.
550
+ */
551
+ interface BehaviorSystemContext {
552
+ world: ZylemWorld | null;
553
+ /** Host scene wrapper (engine-specific); behaviors only call `add`/`remove`-style methods on it. */
554
+ scene: any;
555
+ /** Wasm-driven Stage runtime; omitted when the stage has no wasm module. */
556
+ wasmStage?: WasmStageRuntime | null;
557
+ /**
558
+ * Returns live behavior links for a descriptor key.
559
+ * O(1) lookup into a pre-built stage index.
560
+ */
561
+ getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>;
562
+ /**
563
+ * Host-injected entity factory. Behaviors that spawn entities at runtime
564
+ * (e.g. destructible-3d fragments) use this instead of importing the engine
565
+ * entity factory directly, keeping the behavior layer decoupled.
566
+ */
567
+ createEntity?: CreateEntityFn;
568
+ /**
569
+ * Host-injected accessor for the global game-state bag, passed to entity
570
+ * lifecycle hooks (e.g. `nodeDestroy`).
571
+ */
572
+ getGlobals?: () => any;
573
+ }
574
+ /**
575
+ * Factory function that creates a BehaviorSystem.
576
+ * Receives the stage for access to world, scene, etc.
577
+ */
578
+ type BehaviorSystemFactory<T extends BehaviorSystem = BehaviorSystem> = (stage: BehaviorSystemContext) => T;
579
+
580
+ export { type StageScreenWrapOptions as A, type BaseBehaviorHandle as B, type CreateEntityFn as C, type DefineBehaviorConfig as D, type StageShooter2DOptions as E, type StageThrusterOptions as F, GameEntity as G, type StageTopDownOptions as H, StageTopDownPlane as I, type StageTopDownPlaneValue as J, type StageWorldBoundaryOptions as K, type VelocityIntentMode as L, type WasmStageRuntime as M, type WasmStageRuntimeOptions as N, createTransformStore as O, defineBehavior as P, readBehaviorSnapshot as Q, STAGE_INPUT_BUTTON_JUMP as S, type TransformState as T, type VelocityIntent as V, type WasmSnapshotBackref as W, type ZylemWorld as Z, type BehaviorDescriptor as a, type BehaviorEntityLink as b, type BehaviorHandle as c, type BehaviorRef as d, type BehaviorSystem as e, type BehaviorSystemContext as f, type BehaviorSystemFactory as g, type GameEntityOptions as h, STAGE_INPUT_BUTTON_RUN as i, type StageBehaviorSnapshot as j, StageBodyKind as k, StageBoundaryDim as l, type StageBoundaryDimValue as m, StageEventType as n, type StageFirstPersonInput as o, type StageFirstPersonOptions as p, type StageJumper2DOptions as q, type StageJumper3DOptions as r, type StagePlatformer2DOptions as s, type StagePlatformer3DOptions as t, type StagePose as u, StageRicochetDim as v, type StageRicochetDimValue as w, type StageRicochetOptions as x, StageRicochetReflection as y, type StageRicochetReflectionValue as z };
@@ -1,11 +1,11 @@
1
- import {
2
- StageRicochetDim,
3
- StageRicochetReflection
4
- } from "./chunk-Y6UJOUE5.js";
5
1
  import {
6
2
  SyncStateMachine,
7
3
  t
8
4
  } from "./chunk-4URF65BR.js";
5
+ import {
6
+ StageRicochetDim,
7
+ StageRicochetReflection
8
+ } from "./chunk-Q75LKHDF.js";
9
9
  import {
10
10
  defineBehavior
11
11
  } from "./chunk-EZNCCO4L.js";
@@ -332,7 +332,9 @@ function createRicochet3DHandle(ref) {
332
332
  entity.transformStore.velocity.x = result.velocity.x;
333
333
  entity.transformStore.velocity.y = result.velocity.y;
334
334
  entity.transformStore.velocity.z = result.velocity.z;
335
- entity.transformStore.dirty.velocity = true;
335
+ entity.transformStore.dirty.velocityX = true;
336
+ entity.transformStore.dirty.velocityY = true;
337
+ entity.transformStore.dirty.velocityZ = true;
336
338
  }
337
339
  return true;
338
340
  },
@@ -358,12 +360,10 @@ function createRicochet3DHandle(ref) {
358
360
  };
359
361
  }
360
362
  var Ricochet3DSystem = class {
361
- constructor(world, wasmStage, getBehaviorLinks) {
362
- this.world = world;
363
+ constructor(wasmStage, getBehaviorLinks) {
363
364
  this.wasmStage = wasmStage;
364
365
  this.getBehaviorLinks = getBehaviorLinks;
365
366
  }
366
- world;
367
367
  wasmStage;
368
368
  getBehaviorLinks;
369
369
  elapsedMs = 0;
@@ -418,7 +418,7 @@ var Ricochet3DSystem = class {
418
418
  var Ricochet3DBehavior = defineBehavior({
419
419
  name: "ricochet-3d",
420
420
  defaultOptions,
421
- systemFactory: (ctx) => new Ricochet3DSystem(ctx.world, ctx.wasmStage ?? null, ctx.getBehaviorLinks),
421
+ systemFactory: (ctx) => new Ricochet3DSystem(ctx.wasmStage ?? null, ctx.getBehaviorLinks),
422
422
  createHandle: createRicochet3DHandle
423
423
  });
424
424
 
@@ -428,4 +428,4 @@ export {
428
428
  Ricochet3DFSM,
429
429
  Ricochet3DBehavior
430
430
  };
431
- //# sourceMappingURL=chunk-ARJWUNRE.js.map
431
+ //# sourceMappingURL=chunk-27UPCP5B.js.map