@zylem/behaviors 0.8.10 → 0.8.11

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 (159) hide show
  1. package/dist/acrobatics-2d.d.ts +25 -0
  2. package/dist/acrobatics-2d.js +37 -0
  3. package/dist/action-rpg.d.ts +21 -0
  4. package/dist/action-rpg.js +39 -0
  5. package/dist/adventure-tools.d.ts +22 -0
  6. package/dist/adventure-tools.js +39 -0
  7. package/dist/behavior-descriptor-NS_qnzzp.d.ts +4527 -0
  8. package/dist/behavior-metadata-Drm1zxI2.d.ts +13 -0
  9. package/dist/catalog.d.ts +2143 -0
  10. package/dist/catalog.js +9 -0
  11. package/dist/chunk-2BE5BW7D.js +130 -0
  12. package/dist/{chunk-VNQLMRWC.js → chunk-2QCCLHJC.js} +9 -5
  13. package/dist/chunk-2UGT4MIF.js +94 -0
  14. package/dist/chunk-3J3ISPFQ.js +99 -0
  15. package/dist/chunk-3LBGEWT6.js +124 -0
  16. package/dist/{chunk-UUMH3DC3.js → chunk-3QBNWT7B.js} +5 -1
  17. package/dist/chunk-3T44EDXU.js +114 -0
  18. package/dist/chunk-5AJJ44QK.js +129 -0
  19. package/dist/{chunk-YDLO5M7S.js → chunk-5SMXQ6AU.js} +1 -0
  20. package/dist/chunk-5VJIP535.js +71 -0
  21. package/dist/chunk-6DTIJB7B.js +166 -0
  22. package/dist/chunk-73MHJY6R.js +78 -0
  23. package/dist/chunk-73YASAYS.js +137 -0
  24. package/dist/{chunk-NZM5YQBW.js → chunk-7HGDADLB.js} +8 -4
  25. package/dist/chunk-7IOQEXYR.js +92 -0
  26. package/dist/{chunk-G5S5U6WI.js → chunk-APAM55J3.js} +9 -5
  27. package/dist/chunk-BLTBZJPG.js +126 -0
  28. package/dist/chunk-BN6QZDR5.js +90 -0
  29. package/dist/chunk-BR33KT4Z.js +3186 -0
  30. package/dist/chunk-C5AYL42A.js +138 -0
  31. package/dist/chunk-DDLZLJ7W.js +8 -0
  32. package/dist/chunk-DRIXFB4C.js +132 -0
  33. package/dist/{chunk-U2BSZJ3S.js → chunk-DTLUKSX2.js} +5 -1
  34. package/dist/{chunk-VB4GYWTE.js → chunk-EMEA45JQ.js} +9 -5
  35. package/dist/chunk-EQFLPRF7.js +130 -0
  36. package/dist/{chunk-X45KOKUF.js → chunk-GNRMH7D3.js} +8 -4
  37. package/dist/chunk-GYEKT5AY.js +102 -0
  38. package/dist/{chunk-SHZZ2QRV.js → chunk-HCWLIPXP.js} +5 -1
  39. package/dist/chunk-HQ2UFI3S.js +116 -0
  40. package/dist/chunk-I52PC5IU.js +128 -0
  41. package/dist/{chunk-T7ST62OT.js → chunk-IAIJG2PB.js} +9 -5
  42. package/dist/{chunk-NDJO56BB.js → chunk-IJILTFEL.js} +5 -1
  43. package/dist/{chunk-6RIS4MGM.js → chunk-IRNU4JGV.js} +9 -5
  44. package/dist/chunk-IRPBFVAK.js +141 -0
  45. package/dist/chunk-JFBR4FNX.js +140 -0
  46. package/dist/{chunk-ERS6SNA5.js → chunk-K34N2CBL.js} +5 -1
  47. package/dist/chunk-LMMF7KXF.js +178 -0
  48. package/dist/chunk-LWGJ3QQZ.js +107 -0
  49. package/dist/chunk-MPNGQLHZ.js +132 -0
  50. package/dist/chunk-OH5LJAEJ.js +135 -0
  51. package/dist/{chunk-HZMC4LGW.js → chunk-P6TMZSWF.js} +10 -6
  52. package/dist/chunk-PDHHOVVQ.js +126 -0
  53. package/dist/{chunk-7TIIRJKF.js → chunk-RUBKGAPS.js} +5 -1
  54. package/dist/chunk-S44ZHYE6.js +1912 -0
  55. package/dist/chunk-SFMJNAW3.js +128 -0
  56. package/dist/{chunk-IU7Y3L7Y.js → chunk-SKKVOH6D.js} +5 -1
  57. package/dist/chunk-TSYXRRS4.js +125 -0
  58. package/dist/chunk-TZHO6P22.js +150 -0
  59. package/dist/chunk-V26L6MY6.js +127 -0
  60. package/dist/chunk-V4M46BF6.js +105 -0
  61. package/dist/chunk-VSFWETXS.js +127 -0
  62. package/dist/chunk-VU4LTE2X.js +147 -0
  63. package/dist/chunk-WF6HC5U3.js +8 -0
  64. package/dist/chunk-WG5NCDS4.js +99 -0
  65. package/dist/{chunk-7LHXAEOZ.js → chunk-WUYHS6JZ.js} +6 -2
  66. package/dist/chunk-XNRY6NOC.js +120 -0
  67. package/dist/{chunk-57JGBNCS.js → chunk-XT47QZQ6.js} +10 -6
  68. package/dist/chunk-Y5CCNMJI.js +58 -0
  69. package/dist/chunk-YVVB6YMG.js +133 -0
  70. package/dist/chunk-ZZXTGVGN.js +131 -0
  71. package/dist/combat-ai.d.ts +21 -0
  72. package/dist/combat-ai.js +41 -0
  73. package/dist/{components-tct075-p.d.ts → components-ClmBORMP.d.ts} +1 -1
  74. package/dist/cooldown.d.ts +2 -8
  75. package/dist/cooldown.js +3 -2
  76. package/dist/coordinators/boundary-ricochet-3d.d.ts +3 -2
  77. package/dist/coordinators/boundary-ricochet.d.ts +3 -2
  78. package/dist/coordinators/boundary-ricochet.js +2 -2
  79. package/dist/coordinators/multidirectional-space-shooter.d.ts +2 -1
  80. package/dist/coordinators/multidirectional-space-shooter.js +2 -2
  81. package/dist/coordinators/top-down-shooter.d.ts +2 -1
  82. package/dist/coordinators/top-down-shooter.js +2 -2
  83. package/dist/core.d.ts +386 -25
  84. package/dist/core.js +1583 -6
  85. package/dist/destructible-3d.d.ts +2 -1
  86. package/dist/destructible-3d.js +3 -2
  87. package/dist/environmental-locomotion.d.ts +23 -0
  88. package/dist/environmental-locomotion.js +35 -0
  89. package/dist/first-person.d.ts +2 -1
  90. package/dist/first-person.js +24 -3
  91. package/dist/golf-racket.d.ts +21 -0
  92. package/dist/golf-racket.js +37 -0
  93. package/dist/index.d.ts +25 -3
  94. package/dist/index.js +763 -79
  95. package/dist/jumper-2d.d.ts +2 -1
  96. package/dist/jumper-2d.js +24 -3
  97. package/dist/jumper-3d.d.ts +2 -1
  98. package/dist/jumper-3d.js +24 -3
  99. package/dist/lane-defense.d.ts +21 -0
  100. package/dist/lane-defense.js +39 -0
  101. package/dist/life-simulation.d.ts +21 -0
  102. package/dist/life-simulation.js +39 -0
  103. package/dist/matching-pinball.d.ts +21 -0
  104. package/dist/matching-pinball.js +39 -0
  105. package/dist/melee-combat.d.ts +22 -0
  106. package/dist/melee-combat.js +45 -0
  107. package/dist/{moveable-tkFsn7mE.d.ts → moveable-CXK2wEZL.d.ts} +1 -1
  108. package/dist/particle-emitter.d.ts +2 -1
  109. package/dist/particle-emitter.js +3 -2
  110. package/dist/platformer-2d.d.ts +2 -1
  111. package/dist/platformer-2d.js +24 -3
  112. package/dist/platformer-3d.d.ts +2 -1
  113. package/dist/platformer-3d.js +24 -3
  114. package/dist/racing-vehicles.d.ts +21 -0
  115. package/dist/racing-vehicles.js +37 -0
  116. package/dist/rhythm-performance.d.ts +21 -0
  117. package/dist/rhythm-performance.js +39 -0
  118. package/dist/ricochet-2d.d.ts +2 -1
  119. package/dist/ricochet-2d.js +24 -3
  120. package/dist/ricochet-3d.d.ts +2 -1
  121. package/dist/ricochet-3d.js +24 -3
  122. package/dist/runtime-2d.d.ts +2 -1
  123. package/dist/runtime-2d.js +10 -1
  124. package/dist/screen-visibility.d.ts +2 -1
  125. package/dist/screen-visibility.js +3 -2
  126. package/dist/screen-wrap.d.ts +2 -7
  127. package/dist/screen-wrap.js +3 -2
  128. package/dist/shooter-2d.d.ts +2 -1
  129. package/dist/shooter-2d.js +3 -2
  130. package/dist/skate-snowboard.d.ts +21 -0
  131. package/dist/skate-snowboard.js +37 -0
  132. package/dist/spatial-puzzles.d.ts +21 -0
  133. package/dist/spatial-puzzles.js +35 -0
  134. package/dist/squad-rts.d.ts +21 -0
  135. package/dist/squad-rts.js +39 -0
  136. package/dist/stealth-city.d.ts +21 -0
  137. package/dist/stealth-city.js +41 -0
  138. package/dist/survival-resources.d.ts +21 -0
  139. package/dist/survival-resources.js +37 -0
  140. package/dist/tactical-grid.d.ts +21 -0
  141. package/dist/tactical-grid.js +39 -0
  142. package/dist/thruster.d.ts +2 -1
  143. package/dist/thruster.js +3 -2
  144. package/dist/top-down-movement.d.ts +2 -1
  145. package/dist/top-down-movement.js +24 -3
  146. package/dist/turn-based-rpg.d.ts +21 -0
  147. package/dist/turn-based-rpg.js +39 -0
  148. package/dist/weapon-systems.d.ts +22 -0
  149. package/dist/weapon-systems.js +45 -0
  150. package/dist/world-boundary-2d.d.ts +2 -1
  151. package/dist/world-boundary-2d.js +24 -3
  152. package/dist/world-boundary-3d.d.ts +2 -1
  153. package/dist/world-boundary-3d.js +24 -3
  154. package/package.json +87 -3
  155. package/dist/behavior-descriptor-Dr8qmQ20.d.ts +0 -914
  156. package/dist/chunk-GZ3DQIIZ.js +0 -888
  157. package/dist/{chunk-OSPQFWQF.js → chunk-4K37UL53.js} +3 -3
  158. package/dist/{chunk-DD4U42FG.js → chunk-AQB246W5.js} +3 -3
  159. package/dist/{chunk-UKGBQTHL.js → chunk-CXDNR4R4.js} +3 -3
@@ -1,914 +0,0 @@
1
- import { StageWasmExports } from '@zylem/runtime';
2
-
3
- type VelocityIntentMode = 'replace' | 'add';
4
- interface VelocityIntent {
5
- x?: number;
6
- y?: number;
7
- z?: number;
8
- mode: VelocityIntentMode;
9
- priority?: number;
10
- }
11
- /**
12
- * Transform state managed by Valtio for per-frame physics intent accumulation.
13
- *
14
- * This store accumulates transformation intents during the frame,
15
- * then applies them all at once after onUpdate() callbacks complete.
16
- *
17
- * Design decisions:
18
- * - Position: Accumulated deltas (additive)
19
- * - Rotation: Last value wins (replacement)
20
- * - Velocity: Accumulated deltas (additive)
21
- * - Angular velocity: Accumulated deltas (additive)
22
- */
23
- interface TransformState {
24
- /** Position deltas to be applied (accumulated) */
25
- position: {
26
- x: number;
27
- y: number;
28
- z: number;
29
- };
30
- /** Rotation quaternion (last value wins) */
31
- rotation: {
32
- x: number;
33
- y: number;
34
- z: number;
35
- w: number;
36
- };
37
- /** Linear velocity (accumulated) */
38
- velocity: {
39
- x: number;
40
- y: number;
41
- z: number;
42
- };
43
- /** Angular velocity (accumulated) */
44
- angularVelocity: {
45
- x: number;
46
- y: number;
47
- z: number;
48
- };
49
- /** Per-source velocity intents composed once per frame */
50
- velocityChannels: Record<string, VelocityIntent>;
51
- /** Dirty flags to track what needs to be applied */
52
- dirty: {
53
- position: boolean;
54
- rotation: boolean;
55
- velocityX: boolean;
56
- velocityY: boolean;
57
- velocityZ: boolean;
58
- velocityChannels: boolean;
59
- angularVelocity: boolean;
60
- };
61
- }
62
- /**
63
- * Create a new transform store with optional initial values.
64
- * The store is a Valtio proxy, making it reactive for debugging/visualization.
65
- *
66
- * @param initial Optional initial state values
67
- * @returns Reactive transform state
68
- */
69
- declare function createTransformStore(initial?: Partial<TransformState>): TransformState;
70
-
71
- /**
72
- * Minimal, runtime-agnostic entity options contract.
73
- *
74
- * The full engine entity (in `@zylem/game-lib`) provides a richer options type,
75
- * but behaviors only rely on this loose shape.
76
- */
77
- interface GameEntityOptions {
78
- [key: string]: any;
79
- name?: string;
80
- }
81
- /**
82
- * Structural stand-in for the engine `GameEntity`.
83
- *
84
- * Behaviors annotate against this loose contract so that `@zylem/behaviors`
85
- * (and its `@zylem/behaviors/core` surface) never has to depend on the concrete
86
- * `@zylem/game-lib` entity implementation. The real engine entity is
87
- * structurally assignable to this type.
88
- */
89
- declare class GameEntity<TOptions = unknown> {
90
- [key: string]: any;
91
- uuid: string;
92
- name: string;
93
- type: string;
94
- options?: TOptions & Record<string, unknown>;
95
- group: any;
96
- mesh?: any;
97
- materials?: any[];
98
- /** Opaque host-owned physics references (never inspected by behaviors). */
99
- body: unknown | null;
100
- collider: unknown | null;
101
- colliderDesc?: any;
102
- colliderDescs: any[];
103
- bodyDesc?: any;
104
- physicsAttached: boolean;
105
- runtimeHandle?: number;
106
- transformStore?: TransformState;
107
- nodeDestroy?: any;
108
- isInstanced?: boolean;
109
- private __behaviorRefs;
110
- create(): this;
111
- onCleanup(callback: () => void): this;
112
- setPosition(_x: number, _y: number, _z: number): void;
113
- setRotation(_x: number, _y: number, _z: number): void;
114
- setRotationZ(_z: number): void;
115
- setScale(_x: number, _y: number, _z: number): void;
116
- /**
117
- * Attach a behavior to this entity. The real engine entity does substantially
118
- * more, but this functional stub stores the merged ref and builds the handle
119
- * so descriptor/handle logic (and tests that drive behaviors directly) work
120
- * without the full engine.
121
- */
122
- use<O extends Record<string, any>, H extends Record<string, any> = Record<string, never>>(descriptor: BehaviorDescriptor<O, H>, options?: Partial<O>): BehaviorHandle<O, H>;
123
- /** Live behavior refs attached via {@link use}. */
124
- getBehaviorRefs(): BehaviorRef<any>[];
125
- }
126
- /**
127
- * Factory contract injected into behavior systems via
128
- * {@link BehaviorSystemContext.createEntity}. The host engine supplies the real
129
- * entity factory at stage-construction time.
130
- */
131
- type CreateEntityFn = (options?: Partial<GameEntityOptions>) => GameEntity<GameEntityOptions>;
132
-
133
- /**
134
- * `WasmStageRuntime` — owns one wasm `WebAssembly.Instance` of
135
- * `@zylem/runtime` and exposes the unified-Stage FFI as typed TypeScript
136
- * methods. This is the single simulation adapter for the whole framework:
137
- * behavior systems talk to it through the {@link BehaviorRuntime} contract,
138
- * and hosts (e.g. `@zylem/game-lib`) drive it through
139
- * {@link createSimulation} in `./simulation`.
140
- */
141
-
142
- /** Sentinel handle for "no entity / failed allocation". Mirrors `INVALID_SLOT` in Rust. */
143
- declare const STAGE_INVALID_SLOT = 4294967295;
144
- declare const StageBodyKind: {
145
- readonly Dynamic: 0;
146
- readonly Static: 1;
147
- readonly KinematicPosition: 2;
148
- readonly KinematicVelocity: 3;
149
- };
150
- type StageBodyKindValue = (typeof StageBodyKind)[keyof typeof StageBodyKind];
151
- declare const StageBoundaryDim: {
152
- readonly Two: 2;
153
- readonly Three: 3;
154
- };
155
- declare const StageRicochetDim: {
156
- readonly Two: 2;
157
- readonly Three: 3;
158
- };
159
- declare const StageRicochetReflection: {
160
- readonly Mirror: 0;
161
- readonly Angled: 1;
162
- };
163
- declare const StageTopDownPlane: {
164
- readonly Xy: 0;
165
- readonly Xz: 1;
166
- };
167
- declare const StageEventType: {
168
- readonly CollisionStarted: 1;
169
- readonly CollisionStopped: 2;
170
- readonly BoundaryHit: 3;
171
- readonly Ricochet: 4;
172
- readonly RegionEntered: 5;
173
- readonly JumpStarted: 6;
174
- readonly Landed: 7;
175
- readonly Wrapped: 8;
176
- readonly CooldownFired: 9;
177
- };
178
- type StageBoundaryDimValue = (typeof StageBoundaryDim)[keyof typeof StageBoundaryDim];
179
- type StageRicochetDimValue = (typeof StageRicochetDim)[keyof typeof StageRicochetDim];
180
- type StageRicochetReflectionValue = (typeof StageRicochetReflection)[keyof typeof StageRicochetReflection];
181
- type StageTopDownPlaneValue = (typeof StageTopDownPlane)[keyof typeof StageTopDownPlane];
182
- /** Position + rotation snapshot for one runtime slot. */
183
- interface StagePose {
184
- position: [number, number, number];
185
- rotation: [number, number, number, number];
186
- }
187
- interface StageWorldBoundaryOptions {
188
- top: number;
189
- bottom: number;
190
- left: number;
191
- right: number;
192
- front?: number;
193
- back?: number;
194
- padding?: number;
195
- }
196
- interface StageScreenWrapOptions {
197
- width: number;
198
- height: number;
199
- centerX?: number;
200
- centerY?: number;
201
- edgeThreshold?: number;
202
- }
203
- interface StageRicochetOptions {
204
- minSpeed: number;
205
- maxSpeed: number;
206
- speedMultiplier: number;
207
- maxAngleDeg: number;
208
- reflectionMode: StageRicochetReflectionValue;
209
- }
210
- interface StageThrusterOptions {
211
- maxSpeed: number;
212
- acceleration: number;
213
- turnRateRadPerSec: number;
214
- linearDamping: number;
215
- }
216
- interface StageTopDownOptions {
217
- plane: StageTopDownPlaneValue;
218
- speed: number;
219
- faceMovement?: boolean;
220
- }
221
- interface StageShooter2DOptions {
222
- fireRateHz: number;
223
- muzzleOffsetX: number;
224
- muzzleOffsetY: number;
225
- muzzleSpeed: number;
226
- }
227
- interface StageJumper2DOptions {
228
- jumpForce: number;
229
- maxJumps: number;
230
- jumpBufferTime: number;
231
- coyoteTime: number;
232
- gravity: number;
233
- }
234
- interface StageJumper3DOptions {
235
- jumpForce: number;
236
- maxJumps: number;
237
- gravity: number;
238
- /** Coyote time in seconds (default 0.1). */
239
- coyoteTime?: number;
240
- /** Jump buffer window in seconds (default 0.08). */
241
- jumpBufferTime?: number;
242
- }
243
- interface StagePlatformer3DOptions {
244
- halfHeight: number;
245
- radius: number;
246
- walkSpeed: number;
247
- runSpeed: number;
248
- jumpForce: number;
249
- maxJumps: number;
250
- gravity: number;
251
- /** Coyote time in seconds (default 0.1). */
252
- coyoteTime?: number;
253
- /** Jump buffer window in seconds (default 0.1). */
254
- jumpBufferTime?: number;
255
- /** Velocity multiplier applied on early jump release (default 0.5). */
256
- jumpCutMultiplier?: number;
257
- /** Seconds before a multi-jump becomes available (default 0.15). */
258
- multiJumpWindow?: number;
259
- /** Max slope angle in degrees the KCC can climb (default 50). */
260
- slopeClimbAngle?: number;
261
- /** Slope angle in degrees past which the character slides (default 40). */
262
- slopeSlideAngle?: number;
263
- /** Autostep max height in world units; 0 disables (default 0.3). */
264
- autostepHeight?: number;
265
- /** Minimum unobstructed width for an autostep (default 0.1). */
266
- autostepMinWidth?: number;
267
- /** Snap-to-ground distance in world units; 0 disables (default 0.3). */
268
- snapToGroundDistance?: number;
269
- /** KCC collision offset between collider and environment (default 0.05). */
270
- characterOffset?: number;
271
- /** Collider local offset X (fallback / override). */
272
- offsetX?: number;
273
- /** Collider local offset Y (fallback / override). */
274
- offsetY?: number;
275
- /** Collider local offset Z (fallback / override). */
276
- offsetZ?: number;
277
- /** 0 = auto-read attached collider; 1 = use stored shape fields. */
278
- shapeSource?: number;
279
- }
280
- declare const StagePlatformerShapeSource: {
281
- readonly Auto: 0;
282
- readonly Override: 1;
283
- };
284
- interface StagePlatformer2DOptions {
285
- halfHeight: number;
286
- radius: number;
287
- walkSpeed: number;
288
- runSpeed: number;
289
- jumpForce: number;
290
- maxJumps: number;
291
- gravity: number;
292
- /** Coyote time in seconds (default 0.1). */
293
- coyoteTime?: number;
294
- /** Jump buffer window in seconds (default 0.1). */
295
- jumpBufferTime?: number;
296
- /** Velocity multiplier applied on early jump release (default 0.5). */
297
- jumpCutMultiplier?: number;
298
- /** Seconds before a multi-jump becomes available (default 0.15). */
299
- multiJumpWindow?: number;
300
- /** Max slope angle in degrees the KCC can climb (default 50). */
301
- slopeClimbAngle?: number;
302
- /** Slope angle in degrees past which the character slides (default 40). */
303
- slopeSlideAngle?: number;
304
- /** Autostep max height in world units; 0 disables (default 0.25). */
305
- autostepHeight?: number;
306
- /** Minimum unobstructed width for an autostep (default 0.05). */
307
- autostepMinWidth?: number;
308
- /** Snap-to-ground distance in world units; 0 disables (default 0.2). */
309
- snapToGroundDistance?: number;
310
- /** KCC collision offset between collider and environment (default 0.05). */
311
- characterOffset?: number;
312
- /** Collider local offset X (fallback / override). */
313
- offsetX?: number;
314
- /** Collider local offset Y (fallback / override). */
315
- offsetY?: number;
316
- /** Collider local offset Z (fallback / override). */
317
- offsetZ?: number;
318
- /** 0 = auto-read attached collider; 1 = use stored shape fields. */
319
- shapeSource?: number;
320
- }
321
- interface StageFirstPersonOptions {
322
- walkSpeed: number;
323
- runSpeed: number;
324
- eyeHeight: number;
325
- lookSensitivity: number;
326
- }
327
- interface StageFirstPersonInput {
328
- moveX: number;
329
- moveZ: number;
330
- lookYawDelta: number;
331
- lookPitchDelta: number;
332
- run: boolean;
333
- }
334
- /** Button bits for the slot-indexed input buffer's bitmask field. */
335
- declare const STAGE_INPUT_BUTTON_JUMP = 1;
336
- declare const STAGE_INPUT_BUTTON_RUN = 2;
337
- /**
338
- * Decoded per-slot behavior snapshot written by the runtime after every
339
- * step: movement fields come from whichever character behavior the entity
340
- * has (platformer 3D/2D, jumper 3D/2D); first-person fills yaw/pitch.
341
- * Values reflect the end of the previous `step()` (one-frame read lag).
342
- */
343
- interface StageBehaviorSnapshot {
344
- grounded: boolean;
345
- fsmState: number;
346
- jumpCount: number;
347
- verticalVelocity: number;
348
- speed: number;
349
- yaw: number;
350
- pitch: number;
351
- }
352
- /**
353
- * Wasm fast-path backrefs a behavior system stores on its `BehaviorRef` every
354
- * frame so descriptor handles can read the runtime snapshot buffer instead of
355
- * a duplicate TS FSM (or hardcoded defaults).
356
- */
357
- interface WasmSnapshotBackref {
358
- __wasmStage?: BehaviorRuntime | null;
359
- __entity?: {
360
- runtimeHandle?: number;
361
- } | null;
362
- }
363
- /**
364
- * Read the behavior snapshot for the entity a `BehaviorRef` is linked to.
365
- * Returns `null` off the wasm fast path (no stage runtime / no
366
- * `runtimeHandle` / no snapshot yet), in which case handles should fall back
367
- * to their TS FSM.
368
- */
369
- declare function readBehaviorSnapshot(ref: object): StageBehaviorSnapshot | null;
370
- /**
371
- * Runtime surface behavior systems rely on. `WasmStageRuntime` is the real
372
- * wasm-backed implementation; `MockBehaviorRuntime` (see
373
- * `./mock-behavior-runtime`) implements the same contract for unit tests, so
374
- * descriptors stay runtime-agnostic.
375
- */
376
- interface BehaviorRuntime {
377
- getPose(handle: number, out?: StagePose): StagePose | null;
378
- setPosition(handle: number, x: number, y: number, z: number): boolean;
379
- setRotation(handle: number, x: number, y: number, z: number, w: number): boolean;
380
- writeInputAxes(handle: number, axisA: number, axisB: number): boolean;
381
- writeInputLook(handle: number, yawDelta: number, pitchDelta: number): boolean;
382
- /** Write reserved input slots (thruster world-space vector X/Y). */
383
- writeInputReserved(handle: number, reservedA: number, reservedB: number): boolean;
384
- writeInputButton(handle: number, buttonMask: number, pressed: boolean): boolean;
385
- /** Read the per-slot behavior snapshot written at the end of the previous step. */
386
- readSnapshot(handle: number, out?: StageBehaviorSnapshot): StageBehaviorSnapshot | null;
387
- attachThruster(handle: number, opts: StageThrusterOptions): boolean;
388
- setThrusterInput(handle: number, thrust: number, rotate: number, vectorX?: number, vectorY?: number): void;
389
- attachTopDown(handle: number, opts: StageTopDownOptions): boolean;
390
- setTopDownInput(handle: number, moveX: number, moveY: number): void;
391
- attachShooter2D(handle: number, opts: StageShooter2DOptions): boolean;
392
- attachScreenWrap(handle: number, opts: StageScreenWrapOptions): boolean;
393
- queryScreenWrap(handle: number): {
394
- fsm: number;
395
- lastWrappedAxes: number;
396
- } | null;
397
- attachWorldBoundary(handle: number, dim: StageBoundaryDimValue, opts: StageWorldBoundaryOptions): boolean;
398
- queryWorldBoundary(handle: number): {
399
- hits: number;
400
- clamped: [number, number, number];
401
- } | null;
402
- attachRicochet(handle: number, dim: StageRicochetDimValue, opts: StageRicochetOptions): boolean;
403
- attachPlatformer3D(handle: number, opts: StagePlatformer3DOptions): boolean;
404
- setPlatformer3DInputAxes(handle: number, moveX: number, moveZ: number): void;
405
- setPlatformer3DInputButtons(handle: number, jump: boolean, run: boolean): void;
406
- attachPlatformer2D(handle: number, opts: StagePlatformer2DOptions): boolean;
407
- setPlatformer2DInputAxes(handle: number, moveX: number): void;
408
- setPlatformer2DInputButtons(handle: number, jump: boolean, run: boolean): void;
409
- attachFirstPerson(handle: number, opts: StageFirstPersonOptions): boolean;
410
- setFirstPersonInput(handle: number, input: StageFirstPersonInput): void;
411
- attachJumper2D(handle: number, opts: StageJumper2DOptions): boolean;
412
- setJumper2DInput(handle: number, jumpPressed: boolean): void;
413
- attachJumper3D(handle: number, opts: StageJumper3DOptions): boolean;
414
- setJumper3DInput(handle: number, jumpPressed: boolean): void;
415
- }
416
- /** Default options used when constructing a wasm-backed Stage runtime. */
417
- interface WasmStageRuntimeOptions {
418
- initialCapacity?: number;
419
- gravity?: readonly [number, number, number];
420
- imports?: WebAssembly.Imports;
421
- /**
422
- * Custom wasm source. Defaults to the `zylem_runtime.wasm` bundled with
423
- * `@zylem/runtime`.
424
- */
425
- source?: RequestInfo | URL | ArrayBuffer | Uint8Array;
426
- }
427
- type StageEventTypeValue = (typeof StageEventType)[keyof typeof StageEventType];
428
- /** One decoded event drained from the runtime's per-step event buffer. */
429
- interface StageEvent {
430
- type: StageEventTypeValue;
431
- primarySlot: number | null;
432
- secondarySlot: number | null;
433
- payload: [number, number, number];
434
- }
435
- /**
436
- * Decoded view of one entity's slot in the unified render buffer.
437
- *
438
- * Mirrors the `STAGE_RENDER_STRIDE` (12-float) packing documented in
439
- * `runtime/stage/render.rs`:
440
- * `[0..3]` position, `[3..7]` rotation xyzw, `[7]` uniform scale,
441
- * `[8..11]` custom0..custom2 (shading hints), `[11]` custom3 sleeping flag
442
- * (1.0 = sleeping).
443
- */
444
- interface StageRenderSlot {
445
- position: [number, number, number];
446
- rotation: [number, number, number, number];
447
- scale: number;
448
- custom: [number, number, number, number];
449
- /** True when custom[3] indicates the body is sleeping. */
450
- isSleeping: boolean;
451
- }
452
- /**
453
- * Read a single entity slot out of a unified-Stage render buffer view.
454
- *
455
- * @param view The `Float32Array` over wasm memory (e.g. `WasmStageRuntime.render`).
456
- * @param slot The entity's wasm slot id (its `runtimeHandle`).
457
- * @param out Optional target object to write into (avoids per-call allocation).
458
- * @returns The decoded slot, or `null` when the slot is out of range.
459
- */
460
- declare function readStageRenderSlot(view: Float32Array, slot: number, out?: StageRenderSlot): StageRenderSlot | null;
461
- interface StageBodyConfig {
462
- kind: StageBodyKindValue;
463
- position: readonly [number, number, number];
464
- rotation: readonly [number, number, number, number];
465
- linearDamping: number;
466
- angularDamping: number;
467
- gravityScale: number;
468
- canSleep: boolean;
469
- ccdEnabled: boolean;
470
- lockRotation: readonly [boolean, boolean, boolean];
471
- lockTranslation: readonly [boolean, boolean, boolean];
472
- }
473
- type StageColliderShape = {
474
- type: 'box';
475
- halfExtents: readonly [number, number, number];
476
- } | {
477
- type: 'sphere';
478
- radius: number;
479
- } | {
480
- type: 'capsule';
481
- halfHeight: number;
482
- radius: number;
483
- } | {
484
- type: 'cylinder';
485
- halfHeight: number;
486
- radius: number;
487
- } | {
488
- type: 'cone';
489
- halfHeight: number;
490
- radius: number;
491
- } | {
492
- type: 'convexHull';
493
- vertices: Float32Array;
494
- } | {
495
- type: 'trimesh';
496
- vertices: Float32Array;
497
- indices: Uint32Array;
498
- } | {
499
- type: 'heightfield';
500
- rows: number;
501
- cols: number;
502
- scale: readonly [number, number, number];
503
- heights: Float32Array;
504
- };
505
- interface StageColliderConfig {
506
- shape: StageColliderShape;
507
- offset: readonly [number, number, number];
508
- friction: number;
509
- restitution: number;
510
- sensor: boolean;
511
- /** Packed interaction-groups: high 16 bits = membership, low 16 bits = filter. */
512
- collisionGroups: number;
513
- }
514
- /** Result of a physics raycast against the stage. */
515
- interface StageRaycastHit {
516
- slot: number;
517
- distance: number;
518
- normal: [number, number, number];
519
- }
520
- /** Body introspection payload for debug tooling. */
521
- interface StageBodyInfo {
522
- bodyType: number;
523
- mass: number;
524
- isSleeping: boolean;
525
- isEnabled: boolean;
526
- linearVelocity: [number, number, number];
527
- }
528
- /** Line-list wireframe for physics debug rendering. */
529
- interface StageDebugRender {
530
- /** `[x, y, z]` per vertex, two vertices per line. */
531
- vertices: Float32Array;
532
- /** RGBA per vertex. */
533
- colors: Float32Array;
534
- }
535
- /**
536
- * Owns the wasm instance plus the live float-views over its render / event /
537
- * pose / scratch buffers. One instance per logical stage; each stage gets
538
- * its own `WebAssembly.Instance` so the singleton inside `stage_ffi.rs`
539
- * stays single-stage scoped (today's `thread_local!` contract).
540
- */
541
- declare class WasmStageRuntime implements BehaviorRuntime {
542
- readonly exports: StageWasmExports;
543
- private readonly memory;
544
- private renderView;
545
- private inputView;
546
- private snapshotView;
547
- private eventView;
548
- private poseView;
549
- private vec3View;
550
- private queryView;
551
- private scratchView;
552
- constructor(exports: StageWasmExports, options?: WasmStageRuntimeOptions);
553
- /** Recreate typed views over wasm memory. Call after step() or whenever memory may have grown. */
554
- refreshViews(): void;
555
- /** Step the simulation by `dt` seconds. Refreshes views afterwards. */
556
- step(dt: number): number;
557
- dispose(): void;
558
- get tickCount(): number;
559
- get activeCount(): number;
560
- setGravity(x: number, y: number, z: number): void;
561
- /**
562
- * Toggle per-step collision-event collection in the wasm stage. Hosts
563
- * with no collision listeners should disable it — with thousands of
564
- * touching bodies the per-step contact-pair hashing is a significant
565
- * fraction of `step()`.
566
- */
567
- setEventsEnabled(enabled: boolean): void;
568
- /** Cap Rapier contact solver iterations (default 4). */
569
- setSolverIterations(iterations: number): void;
570
- /**
571
- * Override sleep activation thresholds for sleep-capable dynamic bodies.
572
- * Higher velocity thresholds / lower `timeUntilSleep` put piles to sleep
573
- * sooner.
574
- */
575
- setSleepThresholds(normalizedLinearThreshold: number, angularThreshold: number, timeUntilSleep: number): void;
576
- /** Number of awake (non-sleeping) dynamic rigid bodies. */
577
- awakeDynamicCount(): number;
578
- createEntity(): number;
579
- destroyEntity(slot: number): boolean;
580
- attachBody(slot: number, config: StageBodyConfig): boolean;
581
- addCollider(slot: number, config: StageColliderConfig): boolean;
582
- private stageScratch;
583
- private stageScratchIndices;
584
- getPose(slot: number, out?: StagePose): StagePose | null;
585
- setPosition(slot: number, x: number, y: number, z: number): boolean;
586
- setRotation(slot: number, x: number, y: number, z: number, w: number): boolean;
587
- setLinearVelocity(slot: number, x: number, y: number, z: number): boolean;
588
- getLinearVelocity(slot: number, out?: [number, number, number]): [number, number, number] | null;
589
- setAngularVelocity(slot: number, x: number, y: number, z: number): boolean;
590
- getAngularVelocity(slot: number, out?: [number, number, number]): [number, number, number] | null;
591
- applyImpulse(slot: number, x: number, y: number, z: number): boolean;
592
- /** Cast a ray against the physics world. Returns the closest hit or `null`. */
593
- castRay(origin: readonly [number, number, number], dir: readonly [number, number, number], maxDistance: number, solidOnly?: boolean): StageRaycastHit | null;
594
- /** Body introspection for debug tooling. */
595
- getBodyInfo(slot: number): StageBodyInfo | null;
596
- /** Wireframe debug render of every collider (all shapes). */
597
- getDebugRender(): StageDebugRender | null;
598
- /** Read-only view over the render buffer; one slot occupies {@link STAGE_RENDER_STRIDE} floats. */
599
- get render(): Float32Array;
600
- get renderStride(): number;
601
- /**
602
- * Decode a single entity slot from the live render buffer. Convenience
603
- * wrapper over {@link readStageRenderSlot} bound to this runtime's view.
604
- */
605
- readRenderSlot(slot: number, out?: StageRenderSlot): StageRenderSlot | null;
606
- /** Drain the wasm event buffer into a fresh array of typed events. */
607
- drainEvents(): StageEvent[];
608
- /** Writable view over the slot-indexed input buffer ({@link STAGE_INPUT_STRIDE} floats/slot). */
609
- get input(): Float32Array;
610
- get inputStride(): number;
611
- /** Read-only view over the per-slot behavior snapshot buffer ({@link STAGE_SNAPSHOT_STRIDE} floats/slot). */
612
- get snapshot(): Float32Array;
613
- get snapshotStride(): number;
614
- /**
615
- * Write the primary movement axes for a slot into the slot-indexed input
616
- * buffer and mark the slot dirty. Field-scoped (doesn't touch look
617
- * deltas or buttons) so multiple behaviors composed on one entity can
618
- * each write their part.
619
- */
620
- writeInputAxes(slot: number, axisA: number, axisB: number): boolean;
621
- /** Write the look deltas (first-person yaw/pitch) for a slot. */
622
- writeInputLook(slot: number, yawDelta: number, pitchDelta: number): boolean;
623
- /** Write reserved input slots (thruster world-space vector X/Y). */
624
- writeInputReserved(slot: number, reservedA: number, reservedB: number): boolean;
625
- /**
626
- * Set or clear one button bit ({@link STAGE_INPUT_BUTTON_JUMP} /
627
- * {@link STAGE_INPUT_BUTTON_RUN}) in a slot's input bitmask.
628
- */
629
- writeInputButton(slot: number, buttonMask: number, pressed: boolean): boolean;
630
- /**
631
- * Decode a slot's behavior snapshot from the buffer written at the end of
632
- * the previous step. Returns `null` when the slot has no behavior data.
633
- */
634
- readSnapshot(slot: number, out?: StageBehaviorSnapshot): StageBehaviorSnapshot | null;
635
- get queryScratch(): Float32Array;
636
- attachCooldown(slot: number): boolean;
637
- registerCooldown(slot: number, id: number, durationSeconds: number, immediate?: boolean): boolean;
638
- fireCooldown(slot: number, id: number): boolean;
639
- resetCooldown(slot: number, id: number): boolean;
640
- cooldownRemaining(slot: number, id: number): number;
641
- attachWorldBoundary(slot: number, dim: StageBoundaryDimValue, bounds: StageWorldBoundaryOptions): boolean;
642
- queryWorldBoundary(slot: number): {
643
- hits: number;
644
- clamped: [number, number, number];
645
- } | null;
646
- attachScreenWrap(slot: number, opts: StageScreenWrapOptions): boolean;
647
- queryScreenWrap(slot: number): {
648
- fsm: number;
649
- lastWrappedAxes: number;
650
- } | null;
651
- attachRicochet(slot: number, dim: StageRicochetDimValue, opts: StageRicochetOptions): boolean;
652
- queryRicochet(slot: number): {
653
- bounces: number;
654
- lastKind: number;
655
- } | null;
656
- attachThruster(slot: number, opts: StageThrusterOptions): boolean;
657
- setThrusterInput(slot: number, thrust: number, turn: number, vectorX?: number, vectorY?: number): void;
658
- queryThruster(slot: number): {
659
- headingRad: number;
660
- speed: number;
661
- } | null;
662
- attachTopDown(slot: number, opts: StageTopDownOptions): boolean;
663
- setTopDownInput(slot: number, axisA: number, axisB: number): void;
664
- attachJumper2D(slot: number, opts: StageJumper2DOptions): boolean;
665
- setJumper2DInput(slot: number, jumpPressed: boolean): void;
666
- queryJumper2D(slot: number): {
667
- grounded: boolean;
668
- jumpCount: number;
669
- coyote: number;
670
- jumpBuffer: number;
671
- } | null;
672
- attachJumper3D(slot: number, opts: StageJumper3DOptions): boolean;
673
- setJumper3DInput(slot: number, jump: boolean): void;
674
- queryJumper3D(slot: number): {
675
- grounded: boolean;
676
- jumpCount: number;
677
- verticalVelocity: number;
678
- } | null;
679
- attachShooter2D(slot: number, opts: StageShooter2DOptions): boolean;
680
- fireShooter2D(slot: number, x: number, y: number, z: number, yaw: number): boolean;
681
- queryShooter2D(slot: number): {
682
- cooldown: number;
683
- firedCount: number;
684
- } | null;
685
- attachPlatformer3D(slot: number, opts: StagePlatformer3DOptions): boolean;
686
- setPlatformer3DInputAxes(slot: number, moveX: number, moveZ: number): void;
687
- setPlatformer3DInputButtons(slot: number, jump: boolean, run: boolean): void;
688
- queryPlatformer3D(slot: number): {
689
- grounded: boolean;
690
- jumpCount: number;
691
- fsmState: number;
692
- speed: number;
693
- } | null;
694
- attachPlatformer2D(slot: number, opts: StagePlatformer2DOptions): boolean;
695
- setPlatformer2DInputAxes(slot: number, moveX: number): void;
696
- setPlatformer2DInputButtons(slot: number, jump: boolean, run: boolean): void;
697
- queryPlatformer2D(slot: number): {
698
- grounded: boolean;
699
- jumpCount: number;
700
- fsmState: number;
701
- verticalVelocity: number;
702
- } | null;
703
- attachFirstPerson(slot: number, opts: StageFirstPersonOptions): boolean;
704
- setFirstPersonInput(slot: number, input: StageFirstPersonInput): void;
705
- queryFirstPerson(slot: number): {
706
- yaw: number;
707
- pitch: number;
708
- speed: number;
709
- eyeHeight: number;
710
- } | null;
711
- }
712
- /**
713
- * Load the bundled `@zylem/runtime` wasm (or a custom `source`), instantiate
714
- * it, and construct a `WasmStageRuntime` around the exports.
715
- */
716
- declare function createWasmStageRuntime(options?: WasmStageRuntimeOptions): Promise<WasmStageRuntime>;
717
-
718
- /**
719
- * Structural stand-in for the engine world wrapper. The engine's world
720
- * delegate exposes an entity lookup map; behaviors only rely on this slice.
721
- *
722
- * The map value is intentionally `unknown` (not the `GameEntity` stub class):
723
- * the engine's concrete entity class is a different nominal type, and systems
724
- * that iterate the map narrow entities themselves.
725
- */
726
- interface ZylemWorld {
727
- collisionMap?: Map<string, unknown>;
728
- }
729
-
730
- /**
731
- * BehaviorSystem Interface
732
- *
733
- * Legacy behavior systems reserved the first `update` argument for an ECS world
734
- * handle; it is always `undefined` now.
735
- */
736
- /**
737
- * A behavior system that processes entities with specific components.
738
- *
739
- * @example
740
- * ```typescript
741
- * class ThrusterSystem implements BehaviorSystem {
742
- * update(_ecs: unknown, delta: number): void {
743
- * // Iterate behavior links, push intent into wasm runtime, etc.
744
- * }
745
- * }
746
- * ```
747
- */
748
- interface BehaviorSystem {
749
- /** Optional eager initialization when a behavior link is registered on a live entity */
750
- attach?(link: BehaviorEntityLink): void;
751
- /** Called once per frame. The first argument is always `undefined` (reserved legacy slot). */
752
- update(ecs: unknown, delta: number): void;
753
- /**
754
- * Called once per frame after the simulation has stepped and before the
755
- * host syncs render poses. Systems that need this frame's post-step state
756
- * (e.g. wasm-side teleports) run here instead of in `update`.
757
- */
758
- postUpdate?(ecs: unknown, delta: number): void;
759
- /** Optional cleanup when a behavior link is detached from a live entity */
760
- detach?(link: BehaviorEntityLink): void;
761
- /** Optional cleanup when stage is destroyed */
762
- destroy?(ecs?: unknown): void;
763
- }
764
- /**
765
- * Runtime link between a spawned entity and one of its behavior refs.
766
- * Systems can iterate these links to avoid scanning all world entities.
767
- */
768
- interface BehaviorEntityLink {
769
- entity: any;
770
- ref: any;
771
- }
772
- /**
773
- * Context provided to behavior-system factories.
774
- *
775
- * After the runtime-only stage migration, `wasmStage` is the source of
776
- * truth — descriptors should call `wasmStage.attach<X>(handle, opts)` /
777
- * `wasmStage.query<X>(handle)` from inside the system instead of touching
778
- * `entity.body` directly. The legacy `world` / `scene` fields remain for
779
- * unmigrated descriptors.
780
- */
781
- interface BehaviorSystemContext {
782
- world: ZylemWorld | null;
783
- /** Host scene wrapper (engine-specific); behaviors only call `add`/`remove`-style methods on it. */
784
- scene: any;
785
- /** Wasm-driven Stage runtime; omitted when the stage has no wasm module. */
786
- wasmStage?: BehaviorRuntime | null;
787
- /**
788
- * Returns live behavior links for a descriptor key.
789
- * O(1) lookup into a pre-built stage index.
790
- */
791
- getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>;
792
- /**
793
- * Host-injected entity factory. Behaviors that spawn entities at runtime
794
- * (e.g. destructible-3d fragments) use this instead of importing the engine
795
- * entity factory directly, keeping the behavior layer decoupled.
796
- */
797
- createEntity?: CreateEntityFn;
798
- /**
799
- * Host-injected accessor for the global game-state bag, passed to entity
800
- * lifecycle hooks (e.g. `nodeDestroy`).
801
- */
802
- getGlobals?: () => any;
803
- }
804
- /**
805
- * Factory function that creates a BehaviorSystem.
806
- * Receives the stage for access to world, scene, etc.
807
- */
808
- type BehaviorSystemFactory<T extends BehaviorSystem = BehaviorSystem> = (stage: BehaviorSystemContext) => T;
809
-
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 };