@zylem/behaviors 0.3.1 → 0.4.0

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 (138) hide show
  1. package/dist/{behavior-system-DYbx-x_-.d.ts → behavior-system-DSNek0W9.d.ts} +205 -29
  2. package/dist/{chunk-Y6UJOUE5.js → chunk-4V7TIRO2.js} +1 -1
  3. package/dist/chunk-4V7TIRO2.js.map +1 -0
  4. package/dist/{chunk-DYLH6K7B.js → chunk-4WH2ZN7P.js} +1 -1
  5. package/dist/{chunk-DYLH6K7B.js.map → chunk-4WH2ZN7P.js.map} +1 -1
  6. package/dist/{chunk-ZPSAXX73.js → chunk-5SM5SH5O.js} +26 -26
  7. package/dist/chunk-5SM5SH5O.js.map +1 -0
  8. package/dist/{chunk-STCCNLPC.js → chunk-5XZWTFGF.js} +5 -3
  9. package/dist/chunk-5XZWTFGF.js.map +1 -0
  10. package/dist/{chunk-OYWFPIHF.js → chunk-64HKCSXD.js} +19 -16
  11. package/dist/chunk-64HKCSXD.js.map +1 -0
  12. package/dist/{chunk-JAN34G6S.js → chunk-FRJDQM23.js} +108 -154
  13. package/dist/chunk-FRJDQM23.js.map +1 -0
  14. package/dist/{chunk-RTRVBEIB.js → chunk-FTDZAKZW.js} +5 -18
  15. package/dist/chunk-FTDZAKZW.js.map +1 -0
  16. package/dist/{chunk-XIJNE67Y.js → chunk-GFARAJV2.js} +3 -5
  17. package/dist/{chunk-XIJNE67Y.js.map → chunk-GFARAJV2.js.map} +1 -1
  18. package/dist/{chunk-SS7ELMJ7.js → chunk-GTLA6LOJ.js} +16 -22
  19. package/dist/chunk-GTLA6LOJ.js.map +1 -0
  20. package/dist/{chunk-VAN4WW3F.js → chunk-H4TJ7X4O.js} +4 -7
  21. package/dist/chunk-H4TJ7X4O.js.map +1 -0
  22. package/dist/{chunk-4I6E6DGV.js → chunk-HNESASBB.js} +4 -6
  23. package/dist/{chunk-4I6E6DGV.js.map → chunk-HNESASBB.js.map} +1 -1
  24. package/dist/{chunk-KS72RZHX.js → chunk-IZJFUAXB.js} +1 -1
  25. package/dist/{chunk-KS72RZHX.js.map → chunk-IZJFUAXB.js.map} +1 -1
  26. package/dist/{chunk-SVLNF434.js → chunk-JXMF4NUI.js} +51 -3
  27. package/dist/chunk-JXMF4NUI.js.map +1 -0
  28. package/dist/chunk-KFFETUAL.js +40 -0
  29. package/dist/chunk-KFFETUAL.js.map +1 -0
  30. package/dist/chunk-LL4FLHIY.js +12 -0
  31. package/dist/chunk-LL4FLHIY.js.map +1 -0
  32. package/dist/{chunk-2CLT36VB.js → chunk-MJFMNRMZ.js} +13 -14
  33. package/dist/chunk-MJFMNRMZ.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-XG2YMCJW.js → chunk-PWF757B6.js} +4 -6
  37. package/dist/{chunk-XG2YMCJW.js.map → chunk-PWF757B6.js.map} +1 -1
  38. package/dist/{chunk-LD5SMIB3.js → chunk-QVCMJ4Q2.js} +1 -1
  39. package/dist/{chunk-LD5SMIB3.js.map → chunk-QVCMJ4Q2.js.map} +1 -1
  40. package/dist/{chunk-F3KRX2V4.js → chunk-RONH2KDI.js} +10 -12
  41. package/dist/chunk-RONH2KDI.js.map +1 -0
  42. package/dist/chunk-RTRFJVCZ.js +454 -0
  43. package/dist/chunk-RTRFJVCZ.js.map +1 -0
  44. package/dist/{chunk-6C6NXNEW.js → chunk-UL6Q5HDP.js} +25 -3
  45. package/dist/chunk-UL6Q5HDP.js.map +1 -0
  46. package/dist/{chunk-KOZUNIIE.js → chunk-V74N7D6Q.js} +7 -7
  47. package/dist/{chunk-KOZUNIIE.js.map → chunk-V74N7D6Q.js.map} +1 -1
  48. package/dist/{chunk-YUO6SKJD.js → chunk-WXXXJ22R.js} +11 -13
  49. package/dist/chunk-WXXXJ22R.js.map +1 -0
  50. package/dist/{chunk-ARJWUNRE.js → chunk-XLUJDKCT.js} +7 -7
  51. package/dist/{chunk-ARJWUNRE.js.map → chunk-XLUJDKCT.js.map} +1 -1
  52. package/dist/{chunk-GCNRXAKH.js → chunk-XP3ASVGJ.js} +13 -10
  53. package/dist/chunk-XP3ASVGJ.js.map +1 -0
  54. package/dist/{chunk-ID5QJYF5.js → chunk-Y7YIAWPW.js} +11 -1
  55. package/dist/chunk-Y7YIAWPW.js.map +1 -0
  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 +4 -32
  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 +8 -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 +5 -5
  82. package/dist/jumper-3d.d.ts +12 -11
  83. package/dist/jumper-3d.js +6 -6
  84. package/dist/{moveable-BCRpjAQb.d.ts → moveable-BLTHO7Jq.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 +23 -0
  89. package/dist/platformer-3d.d.ts +74 -87
  90. package/dist/platformer-3d.js +4 -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-h9-T5FSv.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 +5 -5
  114. package/dist/chunk-2C3Z5GE7.js +0 -176
  115. package/dist/chunk-2C3Z5GE7.js.map +0 -1
  116. package/dist/chunk-2CLT36VB.js.map +0 -1
  117. package/dist/chunk-3PYGRHAL.js +0 -35
  118. package/dist/chunk-3PYGRHAL.js.map +0 -1
  119. package/dist/chunk-6C6NXNEW.js.map +0 -1
  120. package/dist/chunk-F3KRX2V4.js.map +0 -1
  121. package/dist/chunk-FPTWVCPN.js.map +0 -1
  122. package/dist/chunk-GCNRXAKH.js.map +0 -1
  123. package/dist/chunk-ID5QJYF5.js.map +0 -1
  124. package/dist/chunk-JAN34G6S.js.map +0 -1
  125. package/dist/chunk-K3UNLQ7W.js.map +0 -1
  126. package/dist/chunk-OYWFPIHF.js.map +0 -1
  127. package/dist/chunk-RTRVBEIB.js.map +0 -1
  128. package/dist/chunk-RTVRUNYR.js.map +0 -1
  129. package/dist/chunk-SS7ELMJ7.js.map +0 -1
  130. package/dist/chunk-STCCNLPC.js.map +0 -1
  131. package/dist/chunk-SVLNF434.js.map +0 -1
  132. package/dist/chunk-VAN4WW3F.js.map +0 -1
  133. package/dist/chunk-Y6UJOUE5.js.map +0 -1
  134. package/dist/chunk-YUO6SKJD.js.map +0 -1
  135. package/dist/chunk-ZPSAXX73.js.map +0 -1
  136. package/dist/runtime-pong.d.ts +0 -92
  137. package/dist/runtime-pong.js +0 -38
  138. /package/dist/{runtime-pong.js.map → platformer-2d.js.map} +0 -0
@@ -0,0 +1,306 @@
1
+ import { S as SyncStateMachine } from './sync-state-machine-CZyspBpj.js';
2
+ import { RigidBody, Collider } from '@dimforge/rapier3d-compat';
3
+ import { Z as ZylemWorld, a as BehaviorDescriptor } from './behavior-system-DSNek0W9.js';
4
+ import 'typescript-fsm';
5
+
6
+ /**
7
+ * Platformer 2D Components
8
+ *
9
+ * Components for 2D platformer movement on the X/Y plane: walking/running on
10
+ * X, jumping with multi-jump support, and falling/landing states.
11
+ */
12
+ interface Platformer2DMovementComponent {
13
+ /** Base walking speed */
14
+ walkSpeed: number;
15
+ /** Sprint/run speed */
16
+ runSpeed: number;
17
+ /** Initial jump force/velocity */
18
+ jumpForce: number;
19
+ /** Maximum number of jumps (1 = single jump, 2 = double jump, etc.) */
20
+ maxJumps: number;
21
+ /** Gravity force */
22
+ gravity: number;
23
+ /** Coyote time in seconds (grace period after leaving ground) */
24
+ coyoteTime: number;
25
+ /** Jump buffer time in seconds (queue jump input before landing) */
26
+ jumpBufferTime: number;
27
+ /** Velocity multiplier when releasing jump button early (0-1) */
28
+ jumpCutMultiplier: number;
29
+ /** Time in seconds before multi-jump becomes available (0 = after button release) */
30
+ multiJumpWindowTime: number;
31
+ /** Maximum slope angle (degrees) the character can walk up */
32
+ slopeClimbAngle: number;
33
+ /** Slope angle (degrees) past which the character slides down */
34
+ slopeSlideAngle: number;
35
+ /** Autostep configuration for SNES-style step-ups, or false to disable */
36
+ autostep: {
37
+ maxHeight: number;
38
+ minWidth: number;
39
+ } | false;
40
+ /** Snap-to-ground distance (keeps the character glued going downhill) */
41
+ snapToGroundDistance: number;
42
+ /** Character controller offset (small gap kept between collider and environment) */
43
+ characterOffset: number;
44
+ }
45
+ declare function createPlatformer2DMovementComponent(options?: Partial<Platformer2DMovementComponent>): Platformer2DMovementComponent;
46
+ interface Platformer2DInputComponent {
47
+ /** Horizontal movement input (-1 to 1) */
48
+ moveX: number;
49
+ /** Jump button pressed */
50
+ jump: boolean;
51
+ /** Run/sprint button held */
52
+ run: boolean;
53
+ }
54
+ declare function createPlatformer2DInputComponent(): Platformer2DInputComponent;
55
+ interface Platformer2DStateComponent {
56
+ /** Is the entity on the ground */
57
+ grounded: boolean;
58
+ /** Is currently in a jump arc */
59
+ jumping: boolean;
60
+ /** Is falling (not jumping) */
61
+ falling: boolean;
62
+ /** Current jump count (for multi-jump) */
63
+ jumpCount: number;
64
+ /** Y position when jump started */
65
+ jumpStartHeight: number;
66
+ /** Current movement speed being applied */
67
+ currentSpeed: number;
68
+ /** Last known ground Y position */
69
+ lastGroundedY: number;
70
+ /** Was jump button pressed last frame (for edge detection) */
71
+ jumpPressedLastFrame: boolean;
72
+ /** Time in seconds since last grounded */
73
+ timeSinceGrounded: number;
74
+ /** Is a jump allowed due to buffer? */
75
+ jumpBuffered: boolean;
76
+ /** Time remaining in jump buffer */
77
+ jumpBufferTimer: number;
78
+ /** Is jump button currently held */
79
+ jumpHeld: boolean;
80
+ /** Has the jump cut been applied for this jump? */
81
+ jumpCutApplied: boolean;
82
+ /** Has jump button been released since last jump (required for multi-jump) */
83
+ jumpReleasedSinceLastJump: boolean;
84
+ /** Time since current jump started (for multi-jump window) */
85
+ timeSinceJump: number;
86
+ /** True for the single frame on which a jump impulse was applied; prevents gravity from clobbering jump velocity. */
87
+ jumpedThisFrame: boolean;
88
+ /** Remaining seconds of jump-cut velocity ramp; while > 0, verticalVelocity lerps toward verticalVelocity * jumpCutMultiplier. */
89
+ jumpCutRampTimer: number;
90
+ /**
91
+ * Controller-owned vertical velocity (units/second).
92
+ * The body is kinematic, so `linvel()` is meaningless — this field is the
93
+ * single source of truth for jump/gravity motion on the Y axis.
94
+ */
95
+ verticalVelocity: number;
96
+ }
97
+ declare function createPlatformer2DStateComponent(): Platformer2DStateComponent;
98
+
99
+ /**
100
+ * Platformer 2D Finite State Machine
101
+ *
102
+ * Manages state transitions for 2D platformer movement:
103
+ * - Idle: Standing still on ground
104
+ * - Walking: Moving on ground (slow)
105
+ * - Running: Moving on ground (fast)
106
+ * - Jumping: Ascending from jump
107
+ * - Falling: Descending (gravity)
108
+ * - Landing: Just touched ground
109
+ */
110
+
111
+ /**
112
+ * Simplified collision context (normal in the X/Y plane).
113
+ */
114
+ interface Platformer2DCollisionContext {
115
+ contact: {
116
+ normal: {
117
+ x: number;
118
+ y: number;
119
+ };
120
+ };
121
+ }
122
+ declare enum Platformer2DState {
123
+ Idle = "idle",
124
+ Walking = "walking",
125
+ Running = "running",
126
+ Jumping = "jumping",
127
+ Falling = "falling",
128
+ Landing = "landing"
129
+ }
130
+ declare enum Platformer2DEvent {
131
+ Walk = "walk",
132
+ Run = "run",
133
+ Jump = "jump",
134
+ Fall = "fall",
135
+ Land = "land",
136
+ Stop = "stop"
137
+ }
138
+ interface Platformer2DContext {
139
+ input: Platformer2DInputComponent;
140
+ state: Platformer2DStateComponent;
141
+ }
142
+ declare class Platformer2DFSM {
143
+ private ctx;
144
+ machine: SyncStateMachine<Platformer2DState, Platformer2DEvent, never>;
145
+ constructor(ctx: Platformer2DContext);
146
+ getState(): Platformer2DState;
147
+ dispatch(event: Platformer2DEvent): void;
148
+ isGrounded(): boolean;
149
+ getJumpCount(): number;
150
+ /**
151
+ * Update FSM based on current component state.
152
+ */
153
+ update(input: Platformer2DInputComponent, state: Platformer2DStateComponent): void;
154
+ }
155
+
156
+ /**
157
+ * Platformer 2D System
158
+ *
159
+ * Kinematic character controller (SNES-style) on the X/Y plane: the
160
+ * controller owns all motion and physics is only a collision database.
161
+ *
162
+ * - The entity's body is converted to `KinematicPositionBased` on first
163
+ * update; Rapier never applies forces to it.
164
+ * - Each tick, desired displacement (X input + integrated vertical velocity,
165
+ * z locked to 0) is run through Rapier's `KinematicCharacterController`
166
+ * (collide-and-slide with autostep, slope limits, and snap-to-ground) and
167
+ * the corrected movement is applied via `setNextKinematicTranslation`. The
168
+ * z coordinate is re-pinned to its first-seen value every tick so slide
169
+ * resolution can never drift the entity off the 2D plane.
170
+ * - Grounded comes from `controller.computedGrounded()` — no contact-pair or
171
+ * raycast probing.
172
+ * - Vertical velocity lives in `state.verticalVelocity` (`linvel()` is
173
+ * meaningless on kinematic bodies). Jump buffering, coyote time,
174
+ * multi-jump, and the jump-cut ramp all operate on that field.
175
+ */
176
+
177
+ /**
178
+ * Entity with 2D platformer components
179
+ */
180
+ interface Platformer2DEntity {
181
+ uuid: string;
182
+ body: RigidBody;
183
+ collider?: Collider | null;
184
+ platformer2D: Platformer2DMovementComponent;
185
+ $platformer2D: Platformer2DInputComponent;
186
+ platformer2DState: Platformer2DStateComponent;
187
+ }
188
+ /**
189
+ * Platformer 2D movement system.
190
+ *
191
+ * Core kinematic controller for 2D platformer movement. Requires a live
192
+ * `ZylemWorld` with the raw Rapier `World` exposed on `.world` — without it
193
+ * the system is a no-op.
194
+ */
195
+ declare class Platformer2DSystem {
196
+ private world;
197
+ /** Per-entity character controllers, keyed by entity uuid. */
198
+ private controllers;
199
+ /** Spawn-time z per entity; re-pinned every tick to hold the 2D plane. */
200
+ private planeZ;
201
+ constructor(world: ZylemWorld | null);
202
+ /**
203
+ * One-time per-entity physics setup: convert the body to a
204
+ * position-based kinematic body, record the plane z, and create the
205
+ * entity's character controller. Done lazily on the first update because
206
+ * the body isn't always available at construction time.
207
+ */
208
+ private ensurePhysicsConfigured;
209
+ /**
210
+ * Handle jump logic with multi-jump, coyote time, buffering, and jump-cut
211
+ * ramp. All vertical motion is written to `state.verticalVelocity`.
212
+ */
213
+ private handleJump;
214
+ /**
215
+ * Integrate gravity into `state.verticalVelocity`.
216
+ *
217
+ * While grounded (and not on the jump frame) vertical velocity is held at
218
+ * a small constant downward speed so the controller stays pressed into
219
+ * the ground. Skipped entirely on the frame a jump was applied — the
220
+ * grounded flag is still stale-true then and would clobber the jump.
221
+ */
222
+ private applyGravity;
223
+ /**
224
+ * Update entity state from the controller's grounded result.
225
+ */
226
+ private updateState;
227
+ /**
228
+ * Update one platformer entity. Invoked per linked entity by the
229
+ * Platformer2DBehaviorSystem adapter.
230
+ */
231
+ updateEntity(entity: Platformer2DEntity, delta: number): void;
232
+ destroy(): void;
233
+ }
234
+
235
+ /**
236
+ * Platformer 2D behavior options (typed for entity.use() autocomplete)
237
+ */
238
+ interface Platformer2DBehaviorOptions {
239
+ /** Base walking speed (default: 8) */
240
+ walkSpeed?: number;
241
+ /** Sprint/run speed (default: 14) */
242
+ runSpeed?: number;
243
+ /** Initial jump force (default: 12) */
244
+ jumpForce?: number;
245
+ /** Maximum number of jumps (default: 1) */
246
+ maxJumps?: number;
247
+ /** Gravity force (default: 20) */
248
+ gravity?: number;
249
+ /** Coyote time in seconds (default: 0.1) */
250
+ coyoteTime?: number;
251
+ /** Jump buffer time in seconds (default: 0.1) */
252
+ jumpBufferTime?: number;
253
+ /** Velocity multiplier when releasing jump early (default: 0.5) */
254
+ jumpCutMultiplier?: number;
255
+ /** Maximum slope angle in degrees the character can walk up (default: 50) */
256
+ slopeClimbAngle?: number;
257
+ /** Slope angle in degrees past which the character slides (default: 40) */
258
+ slopeSlideAngle?: number;
259
+ /** Autostep over small step-ups, or false to disable (default: { maxHeight: 0.25, minWidth: 0.05 }) */
260
+ autostep?: {
261
+ maxHeight: number;
262
+ minWidth: number;
263
+ } | false;
264
+ /** Snap-to-ground distance for downhill/step-down stability (default: 0.2) */
265
+ snapToGroundDistance?: number;
266
+ /** Character controller collision offset (default: 0.05) */
267
+ characterOffset?: number;
268
+ }
269
+ /**
270
+ * Platformer2DBehavior - typed descriptor for 2D platformer movement
271
+ *
272
+ * Provides complete 2D platformer physics on the X/Y plane including:
273
+ * - Walking and running on X
274
+ * - Jumping with buffer, coyote time, multi-jump, and jump-cut
275
+ * - Gravity ownership and falling
276
+ * - Kinematic character controller (collide-and-slide, autostep, snap-to-ground)
277
+ *
278
+ * @example
279
+ * ```typescript
280
+ * import { Platformer2DBehavior } from "@zylem/behaviors/platformer-2d";
281
+ *
282
+ * const platformer = player.use(Platformer2DBehavior, {
283
+ * walkSpeed: 8,
284
+ * runSpeed: 14,
285
+ * jumpForce: 12,
286
+ * maxJumps: 2, // Double jump!
287
+ * });
288
+ *
289
+ * // In update loop
290
+ * player.onUpdate(({ inputs }) => {
291
+ * player.$platformer2D.moveX = inputs.p1.axes.Horizontal.value;
292
+ * player.$platformer2D.jump = inputs.p1.buttons.A.held > 0;
293
+ * player.$platformer2D.run = inputs.p1.shoulders.LTrigger.held > 0;
294
+ *
295
+ * const state = platformer.getState();
296
+ * const grounded = platformer.isGrounded();
297
+ * });
298
+ * ```
299
+ */
300
+ declare const Platformer2DBehavior: BehaviorDescriptor<Platformer2DBehaviorOptions, {
301
+ getState: () => Platformer2DState;
302
+ isGrounded: () => boolean;
303
+ getJumpCount: () => number;
304
+ }, Platformer2DEntity>;
305
+
306
+ export { Platformer2DBehavior, type Platformer2DBehaviorOptions, type Platformer2DCollisionContext, type Platformer2DContext, type Platformer2DEntity, Platformer2DEvent, Platformer2DFSM, type Platformer2DInputComponent, type Platformer2DMovementComponent, Platformer2DState, type Platformer2DStateComponent, Platformer2DSystem, createPlatformer2DInputComponent, createPlatformer2DMovementComponent, createPlatformer2DStateComponent };
@@ -0,0 +1,23 @@
1
+ import {
2
+ Platformer2DBehavior,
3
+ Platformer2DEvent,
4
+ Platformer2DFSM,
5
+ Platformer2DState,
6
+ Platformer2DSystem,
7
+ createPlatformer2DInputComponent,
8
+ createPlatformer2DMovementComponent,
9
+ createPlatformer2DStateComponent
10
+ } from "./chunk-RTRFJVCZ.js";
11
+ import "./chunk-4URF65BR.js";
12
+ import "./chunk-EZNCCO4L.js";
13
+ export {
14
+ Platformer2DBehavior,
15
+ Platformer2DEvent,
16
+ Platformer2DFSM,
17
+ Platformer2DState,
18
+ Platformer2DSystem,
19
+ createPlatformer2DInputComponent,
20
+ createPlatformer2DMovementComponent,
21
+ createPlatformer2DStateComponent
22
+ };
23
+ //# sourceMappingURL=platformer-2d.js.map
@@ -1,5 +1,6 @@
1
1
  import { S as SyncStateMachine } from './sync-state-machine-CZyspBpj.js';
2
- import { a as BehaviorDescriptor } from './behavior-system-DYbx-x_-.js';
2
+ import { RigidBody, Collider } from '@dimforge/rapier3d-compat';
3
+ import { Z as ZylemWorld, a as BehaviorDescriptor } from './behavior-system-DSNek0W9.js';
3
4
  import 'typescript-fsm';
4
5
 
5
6
  /**
@@ -19,8 +20,6 @@ interface Platformer3DMovementComponent {
19
20
  maxJumps: number;
20
21
  /** Gravity force (optional override) */
21
22
  gravity: number;
22
- /** Ray length for ground detection */
23
- groundRayLength: number;
24
23
  /** Coyote time in seconds (grace period after leaving ground) */
25
24
  coyoteTime: number;
26
25
  /** Jump buffer time in seconds (queue jump input before landing) */
@@ -29,8 +28,19 @@ interface Platformer3DMovementComponent {
29
28
  jumpCutMultiplier: number;
30
29
  /** Time in seconds before multi-jump becomes available (0 = after button release) */
31
30
  multiJumpWindowTime: number;
32
- /** Enable ground-ray debug visualization */
33
- debugGroundProbe: boolean;
31
+ /** Maximum slope angle (degrees) the character can walk up */
32
+ slopeClimbAngle: number;
33
+ /** Slope angle (degrees) past which the character slides down */
34
+ slopeSlideAngle: number;
35
+ /** Autostep configuration for small ledges, or false to disable */
36
+ autostep: {
37
+ maxHeight: number;
38
+ minWidth: number;
39
+ } | false;
40
+ /** Snap-to-ground distance (keeps the character glued going downhill) */
41
+ snapToGroundDistance: number;
42
+ /** Character controller offset (small gap kept between collider and environment) */
43
+ characterOffset: number;
34
44
  }
35
45
  declare function createPlatformer3DMovementComponent(options?: Partial<Platformer3DMovementComponent>): Platformer3DMovementComponent;
36
46
  interface Platformer3DInputComponent {
@@ -81,10 +91,14 @@ interface Platformer3DStateComponent {
81
91
  timeSinceJump: number;
82
92
  /** True for the single frame on which a jump impulse was applied; prevents gravity from clobbering jump velocity. */
83
93
  jumpedThisFrame: boolean;
84
- /** Remaining seconds of jump-cut velocity ramp; while > 0, velocity.y lerps toward velocity.y * jumpCutMultiplier. */
94
+ /** Remaining seconds of jump-cut velocity ramp; while > 0, verticalVelocity lerps toward verticalVelocity * jumpCutMultiplier. */
85
95
  jumpCutRampTimer: number;
86
- /** Remaining seconds of grounded-hysteresis grace (keeps `grounded` true briefly after ground probe misses, to absorb edge/ray flicker). */
87
- groundedGraceTimer: number;
96
+ /**
97
+ * Controller-owned vertical velocity (units/second).
98
+ * The body is kinematic, so `linvel()` is meaningless — this field is the
99
+ * single source of truth for jump/gravity motion on the Y axis.
100
+ */
101
+ verticalVelocity: number;
88
102
  }
89
103
  declare function createPlatformer3DStateComponent(): Platformer3DStateComponent;
90
104
 
@@ -175,18 +189,22 @@ declare class Platformer3DFSM {
175
189
  }
176
190
 
177
191
  /**
178
- * Platformer 3D Behavior System
192
+ * Platformer 3D System
179
193
  *
180
- * Handles 3D platformer physics including:
181
- * - Contact-based ground detection (uses the actual capsule collider — no
182
- * raycast/shapecast probe). The bottom of the body's collider is the
183
- * single source of truth for "is grounded".
184
- * - Horizontal movement (walk/run)
185
- * - Jumping with multi-jump support
186
- * - Gravity application (Rapier's internal gravity is disabled per-body so
187
- * `movement.gravity` is the only fall acceleration — previously the two
188
- * stacked, doubling the airborne fall rate).
189
- * - State synchronization with FSM
194
+ * Kinematic character controller (N64-style): the controller owns all motion
195
+ * and physics is only a collision database.
196
+ *
197
+ * - The entity's body is converted to `KinematicPositionBased` on first
198
+ * update; Rapier never applies forces to it.
199
+ * - Each tick, desired displacement (horizontal input + integrated vertical
200
+ * velocity) is run through Rapier's `KinematicCharacterController`
201
+ * (collide-and-slide with autostep, slope limits, and snap-to-ground) and
202
+ * the corrected movement is applied via `setNextKinematicTranslation`.
203
+ * - Grounded comes from `controller.computedGrounded()` — no contact-pair or
204
+ * raycast probing.
205
+ * - Vertical velocity lives in `state.verticalVelocity` (`linvel()` is
206
+ * meaningless on kinematic bodies). Jump buffering, coyote time,
207
+ * multi-jump, and the jump-cut ramp all operate on that field.
190
208
  */
191
209
 
192
210
  /**
@@ -194,94 +212,54 @@ declare class Platformer3DFSM {
194
212
  */
195
213
  interface Platformer3DEntity {
196
214
  uuid: string;
197
- body: any;
215
+ body: RigidBody;
216
+ collider?: Collider | null;
198
217
  platformer: Platformer3DMovementComponent;
199
218
  $platformer: Platformer3DInputComponent;
200
219
  platformerState: Platformer3DStateComponent;
201
- transformStore?: any;
202
220
  }
203
221
  /**
204
- * Platformer 3D Movement Behavior
222
+ * Platformer 3D movement system.
205
223
  *
206
- * Core physics system for 3D platformer movement.
207
- *
208
- * Ground detection uses Rapier's narrow-phase contacts on the entity's
209
- * collider (`world.contactsWith` + `contactPair`). This eliminates the old
210
- * shape/ray probe and aligns "grounded" with the same surface the body
211
- * physically rests on, which removes the jitter that happened on heightmap
212
- * terrain (the probe and the contact resolver could disagree by a frame).
224
+ * Core kinematic controller for 3D platformer movement. Requires a live
225
+ * `ZylemWorld` with the raw Rapier `World` exposed on `.world` — without it
226
+ * the system is a no-op (the WASM fast path handles that case upstream).
213
227
  */
214
- declare class Platformer3DBehavior$1 {
228
+ declare class Platformer3DSystem {
215
229
  private world;
216
- private scene;
217
- /**
218
- * Tracks entities whose Rapier `gravityScale` has been zeroed so that
219
- * `applyGravity` is the sole writer of vertical velocity. We do this
220
- * lazily on the first update because the body isn't always available at
221
- * construction time.
222
- */
223
- private gravityConfiguredUUIDs;
224
- constructor(world: any, scene: any);
230
+ /** Per-entity character controllers, keyed by entity uuid. */
231
+ private controllers;
232
+ constructor(world: ZylemWorld | null);
225
233
  /**
226
- * Detect "grounded" using the actual capsule collider's contact pairs.
227
- *
228
- * A contact is treated as ground when its solver point lies below the
229
- * body center (i.e., it sits on the bottom hemisphere/cylinder). We
230
- * deliberately don't filter by normal direction: the contact point's
231
- * position alone is robust against the various normal-flip conventions
232
- * Rapier uses for `flipped` manifolds and against rolling-bottom edges
233
- * on heightmap terrain.
234
- */
235
- private detectGroundedFromContacts;
236
- /**
237
- * One-time per-entity physics setup: take over gravity from Rapier's
238
- * world so that `applyGravity` controls the entire airborne fall curve.
239
- * Without this, gravity was effectively doubled (Rapier's world gravity
240
- * + this behavior's explicit gravity were both pulling the body down).
234
+ * One-time per-entity physics setup: convert the body to a
235
+ * position-based kinematic body and create its character controller.
236
+ * Done lazily on the first update because the body isn't always
237
+ * available at construction time.
241
238
  */
242
239
  private ensurePhysicsConfigured;
243
240
  /**
244
- * Apply horizontal movement based on input.
245
- *
246
- * Only writes X/Z axes — Y is left untouched so Rapier's contact resolution
247
- * can damp vertical motion correctly while grounded. Jump and gravity are
248
- * the sole writers of Y velocity (see handleJump / applyGravity).
249
- */
250
- private applyMovement;
251
- /**
252
- * Handle jump logic with multi-jump, coyote time, buffering, and jump-cut ramp.
241
+ * Handle jump logic with multi-jump, coyote time, buffering, and jump-cut
242
+ * ramp. All vertical motion is written to `state.verticalVelocity`.
253
243
  */
254
244
  private handleJump;
255
245
  /**
256
- * Apply gravity when not grounded.
246
+ * Integrate gravity into `state.verticalVelocity`.
257
247
  *
258
- * Skipped on the single frame immediately after a jump impulse is applied
259
- * (tracked via `state.jumpedThisFrame`) so gravity never overwrites a
260
- * just-applied jump velocity. The flag is cleared here regardless, so it
261
- * only suppresses exactly one gravity step — independent of frame rate.
248
+ * While grounded (and not on the jump frame) vertical velocity is held at
249
+ * a small constant downward speed so the controller stays pressed into
250
+ * the ground. Skipped entirely on the frame a jump was applied — the
251
+ * grounded flag is still stale-true then and would clobber the jump.
262
252
  */
263
253
  private applyGravity;
264
254
  /**
265
- * Update entity state based on physics.
266
- *
267
- * Grounded is determined purely by Rapier's contact pairs on the entity's
268
- * collider. This removes a whole class of slope/heightmap jitter caused
269
- * by the previous shape probe disagreeing with the contact resolver — the
270
- * probe could report grounded while a contact impulse had just nudged the
271
- * body off the ground, producing visible micro-bouncing.
272
- *
273
- * While grounded, vertical velocity is held at 0 each frame. This stops
274
- * residual upward kicks from slope-contact resolution from accumulating
275
- * across frames (which previously caused the character to "ride up"
276
- * slopes and lose contact briefly, then fall back, then re-contact, in a
277
- * tight oscillation).
255
+ * Update entity state from the controller's grounded result.
278
256
  */
279
257
  private updateState;
280
258
  /**
281
259
  * Update one platformer entity. Invoked per linked entity by the
282
260
  * Platformer3DBehaviorSystem adapter.
283
261
  */
284
- updateEntity(entity: any, delta: number): void;
262
+ updateEntity(entity: Platformer3DEntity, delta: number): void;
285
263
  destroy(): void;
286
264
  }
287
265
 
@@ -299,10 +277,19 @@ interface Platformer3DBehaviorOptions {
299
277
  maxJumps?: number;
300
278
  /** Gravity force (default: 9.82) */
301
279
  gravity?: number;
302
- /** Ray length for ground detection (default: 1.0) */
303
- groundRayLength?: number;
304
- /** Enable debug visualization for ground probe rays (default: false) */
305
- debugGroundProbe?: boolean;
280
+ /** Maximum slope angle in degrees the character can walk up (default: 50) */
281
+ slopeClimbAngle?: number;
282
+ /** Slope angle in degrees past which the character slides (default: 40) */
283
+ slopeSlideAngle?: number;
284
+ /** Autostep over small ledges, or false to disable (default: { maxHeight: 0.3, minWidth: 0.1 }) */
285
+ autostep?: {
286
+ maxHeight: number;
287
+ minWidth: number;
288
+ } | false;
289
+ /** Snap-to-ground distance for downhill/step-down stability (default: 0.3) */
290
+ snapToGroundDistance?: number;
291
+ /** Character controller collision offset (default: 0.05) */
292
+ characterOffset?: number;
306
293
  }
307
294
  /**
308
295
  * Platformer3DBehavior - typed descriptor for 3D platformer movement
@@ -344,4 +331,4 @@ declare const Platformer3DBehavior: BehaviorDescriptor<Platformer3DBehaviorOptio
344
331
  onPlatformCollision: (ctx: PlatformerCollisionContext) => void;
345
332
  }, Platformer3DEntity>;
346
333
 
347
- export { Platformer3DBehavior, type Platformer3DBehaviorOptions, type Platformer3DContext, type Platformer3DEntity, Platformer3DEvent, Platformer3DFSM, type Platformer3DInputComponent, Platformer3DBehavior$1 as Platformer3DMovementBehavior, type Platformer3DMovementComponent, Platformer3DState, type Platformer3DStateComponent, type PlatformerCollisionContext, createPlatformer3DInputComponent, createPlatformer3DMovementComponent, createPlatformer3DStateComponent };
334
+ export { Platformer3DBehavior, type Platformer3DBehaviorOptions, type Platformer3DContext, type Platformer3DEntity, Platformer3DEvent, Platformer3DFSM, type Platformer3DInputComponent, type Platformer3DMovementComponent, Platformer3DState, type Platformer3DStateComponent, Platformer3DSystem, type PlatformerCollisionContext, createPlatformer3DInputComponent, createPlatformer3DMovementComponent, createPlatformer3DStateComponent };
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  Platformer3DBehavior,
3
- Platformer3DBehavior2,
4
3
  Platformer3DEvent,
5
4
  Platformer3DFSM,
6
5
  Platformer3DState,
6
+ Platformer3DSystem,
7
7
  createPlatformer3DInputComponent,
8
8
  createPlatformer3DMovementComponent,
9
9
  createPlatformer3DStateComponent
10
- } from "./chunk-JAN34G6S.js";
10
+ } from "./chunk-FRJDQM23.js";
11
11
  import "./chunk-4URF65BR.js";
12
12
  import "./chunk-EZNCCO4L.js";
13
13
  export {
14
- Platformer3DBehavior2 as Platformer3DBehavior,
14
+ Platformer3DBehavior,
15
15
  Platformer3DEvent,
16
16
  Platformer3DFSM,
17
- Platformer3DBehavior as Platformer3DMovementBehavior,
18
17
  Platformer3DState,
18
+ Platformer3DSystem,
19
19
  createPlatformer3DInputComponent,
20
20
  createPlatformer3DMovementComponent,
21
21
  createPlatformer3DStateComponent
@@ -1,6 +1,6 @@
1
1
  import { B as BaseEntityInterface } from './entity-types-CmtQ-IBp.js';
2
2
  import { S as SyncStateMachine } from './sync-state-machine-CZyspBpj.js';
3
- import { a as BehaviorDescriptor } from './behavior-system-DYbx-x_-.js';
3
+ import { a as BehaviorDescriptor } from './behavior-system-DSNek0W9.js';
4
4
  import 'three';
5
5
  import '@dimforge/rapier3d-compat';
6
6
  import 'typescript-fsm';
@@ -3,8 +3,8 @@ import {
3
3
  Ricochet2DEvent,
4
4
  Ricochet2DFSM,
5
5
  Ricochet2DState
6
- } from "./chunk-KOZUNIIE.js";
7
- import "./chunk-Y6UJOUE5.js";
6
+ } from "./chunk-V74N7D6Q.js";
7
+ import "./chunk-4V7TIRO2.js";
8
8
  import "./chunk-4URF65BR.js";
9
9
  import "./chunk-EZNCCO4L.js";
10
10
  export {
@@ -1,6 +1,6 @@
1
1
  import { S as SyncStateMachine } from './sync-state-machine-CZyspBpj.js';
2
2
  import { B as BaseEntityInterface } from './entity-types-CmtQ-IBp.js';
3
- import { a as BehaviorDescriptor } from './behavior-system-DYbx-x_-.js';
3
+ import { a as BehaviorDescriptor } from './behavior-system-DSNek0W9.js';
4
4
  import 'typescript-fsm';
5
5
  import 'three';
6
6
  import '@dimforge/rapier3d-compat';
@@ -3,8 +3,8 @@ import {
3
3
  Ricochet3DEvent,
4
4
  Ricochet3DFSM,
5
5
  Ricochet3DState
6
- } from "./chunk-ARJWUNRE.js";
7
- import "./chunk-Y6UJOUE5.js";
6
+ } from "./chunk-XLUJDKCT.js";
7
+ import "./chunk-4V7TIRO2.js";
8
8
  import "./chunk-4URF65BR.js";
9
9
  import "./chunk-EZNCCO4L.js";
10
10
  export {