@zylem/behaviors 0.8.9 → 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 (168) 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-CTSYM56P.js → chunk-2QCCLHJC.js} +10 -6
  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-LLDLVVG4.js → chunk-7HGDADLB.js} +25 -9
  25. package/dist/chunk-7IOQEXYR.js +92 -0
  26. package/dist/{chunk-OU2SW4U5.js → chunk-APAM55J3.js} +10 -6
  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-OBF6BIA2.js → chunk-CBQSC6W3.js} +2 -2
  32. package/dist/chunk-DDLZLJ7W.js +8 -0
  33. package/dist/chunk-DRIXFB4C.js +132 -0
  34. package/dist/{chunk-7CE6OHLW.js → chunk-DTLUKSX2.js} +6 -2
  35. package/dist/{chunk-TK3AXXXI.js → chunk-EMEA45JQ.js} +10 -6
  36. package/dist/chunk-EQFLPRF7.js +130 -0
  37. package/dist/{chunk-M25QJBDN.js → chunk-GNRMH7D3.js} +18 -6
  38. package/dist/chunk-GYEKT5AY.js +102 -0
  39. package/dist/{chunk-SHZZ2QRV.js → chunk-HCWLIPXP.js} +5 -1
  40. package/dist/{chunk-WHKPWIQO.js → chunk-HMVEQB2T.js} +1 -0
  41. package/dist/chunk-HQ2UFI3S.js +116 -0
  42. package/dist/chunk-I52PC5IU.js +128 -0
  43. package/dist/{chunk-CB3C7CRD.js → chunk-IAIJG2PB.js} +10 -6
  44. package/dist/{chunk-NDJO56BB.js → chunk-IJILTFEL.js} +5 -1
  45. package/dist/{chunk-7GGR26YA.js → chunk-IRNU4JGV.js} +10 -6
  46. package/dist/chunk-IRPBFVAK.js +141 -0
  47. package/dist/chunk-JFBR4FNX.js +140 -0
  48. package/dist/{chunk-ERS6SNA5.js → chunk-K34N2CBL.js} +5 -1
  49. package/dist/chunk-LMMF7KXF.js +178 -0
  50. package/dist/chunk-LWGJ3QQZ.js +107 -0
  51. package/dist/chunk-MPNGQLHZ.js +132 -0
  52. package/dist/chunk-OH5LJAEJ.js +135 -0
  53. package/dist/{chunk-57GLKGEX.js → chunk-P6TMZSWF.js} +32 -7
  54. package/dist/chunk-PDHHOVVQ.js +126 -0
  55. package/dist/{chunk-7TIIRJKF.js → chunk-RUBKGAPS.js} +5 -1
  56. package/dist/chunk-S44ZHYE6.js +1912 -0
  57. package/dist/chunk-SFMJNAW3.js +128 -0
  58. package/dist/{chunk-E2MOFIDH.js → chunk-SKKVOH6D.js} +13 -7
  59. package/dist/{chunk-RR3XNDKG.js → chunk-T2LAQQDS.js} +1 -1
  60. package/dist/chunk-TSYXRRS4.js +125 -0
  61. package/dist/chunk-TZHO6P22.js +150 -0
  62. package/dist/chunk-V26L6MY6.js +127 -0
  63. package/dist/chunk-V4M46BF6.js +105 -0
  64. package/dist/chunk-VSFWETXS.js +127 -0
  65. package/dist/chunk-VU4LTE2X.js +147 -0
  66. package/dist/chunk-WF6HC5U3.js +8 -0
  67. package/dist/chunk-WG5NCDS4.js +99 -0
  68. package/dist/{chunk-7LHXAEOZ.js → chunk-WUYHS6JZ.js} +6 -2
  69. package/dist/chunk-XNRY6NOC.js +120 -0
  70. package/dist/{chunk-55CFXXZH.js → chunk-XT47QZQ6.js} +32 -7
  71. package/dist/chunk-Y5CCNMJI.js +58 -0
  72. package/dist/chunk-YVVB6YMG.js +133 -0
  73. package/dist/chunk-ZZXTGVGN.js +131 -0
  74. package/dist/combat-ai.d.ts +21 -0
  75. package/dist/combat-ai.js +41 -0
  76. package/dist/{components--RTwuT4S.d.ts → components-ClmBORMP.d.ts} +1 -1
  77. package/dist/cooldown.d.ts +2 -8
  78. package/dist/cooldown.js +3 -2
  79. package/dist/coordinators/boundary-ricochet-3d.d.ts +3 -2
  80. package/dist/coordinators/boundary-ricochet-3d.js +2 -2
  81. package/dist/coordinators/boundary-ricochet.d.ts +3 -2
  82. package/dist/coordinators/boundary-ricochet.js +2 -2
  83. package/dist/coordinators/multidirectional-space-shooter.d.ts +3 -2
  84. package/dist/coordinators/multidirectional-space-shooter.js +2 -2
  85. package/dist/coordinators/top-down-shooter.d.ts +3 -2
  86. package/dist/coordinators/top-down-shooter.js +2 -2
  87. package/dist/core.d.ts +387 -26
  88. package/dist/core.js +1583 -6
  89. package/dist/destructible-3d.d.ts +3 -2
  90. package/dist/destructible-3d.js +3 -2
  91. package/dist/destructible-prebake.d.ts +1 -1
  92. package/dist/environmental-locomotion.d.ts +23 -0
  93. package/dist/environmental-locomotion.js +35 -0
  94. package/dist/first-person.d.ts +3 -2
  95. package/dist/first-person.js +25 -4
  96. package/dist/golf-racket.d.ts +21 -0
  97. package/dist/golf-racket.js +37 -0
  98. package/dist/index.d.ts +28 -6
  99. package/dist/index.js +766 -82
  100. package/dist/jumper-2d.d.ts +2 -1
  101. package/dist/jumper-2d.js +25 -4
  102. package/dist/jumper-3d.d.ts +2 -1
  103. package/dist/jumper-3d.js +25 -4
  104. package/dist/lane-defense.d.ts +21 -0
  105. package/dist/lane-defense.js +39 -0
  106. package/dist/life-simulation.d.ts +21 -0
  107. package/dist/life-simulation.js +39 -0
  108. package/dist/matching-pinball.d.ts +21 -0
  109. package/dist/matching-pinball.js +39 -0
  110. package/dist/melee-combat.d.ts +22 -0
  111. package/dist/melee-combat.js +45 -0
  112. package/dist/{moveable-CFOHmblC.d.ts → moveable-CXK2wEZL.d.ts} +2 -2
  113. package/dist/particle-emitter/presets.d.ts +1 -1
  114. package/dist/particle-emitter.d.ts +5 -4
  115. package/dist/particle-emitter.js +3 -2
  116. package/dist/{payload-BQzu-oY_.d.ts → payload-WEzfgjSL.d.ts} +1 -1
  117. package/dist/platformer-2d.d.ts +2 -1
  118. package/dist/platformer-2d.js +25 -4
  119. package/dist/platformer-3d.d.ts +2 -1
  120. package/dist/platformer-3d.js +25 -4
  121. package/dist/racing-vehicles.d.ts +21 -0
  122. package/dist/racing-vehicles.js +37 -0
  123. package/dist/rhythm-performance.d.ts +21 -0
  124. package/dist/rhythm-performance.js +39 -0
  125. package/dist/ricochet-2d.d.ts +2 -1
  126. package/dist/ricochet-2d.js +25 -4
  127. package/dist/ricochet-3d.d.ts +2 -1
  128. package/dist/ricochet-3d.js +25 -4
  129. package/dist/runtime-2d.d.ts +2 -1
  130. package/dist/runtime-2d.js +10 -1
  131. package/dist/screen-visibility.d.ts +2 -1
  132. package/dist/screen-visibility.js +3 -2
  133. package/dist/screen-wrap.d.ts +2 -7
  134. package/dist/screen-wrap.js +4 -3
  135. package/dist/shooter-2d.d.ts +3 -2
  136. package/dist/shooter-2d.js +3 -2
  137. package/dist/skate-snowboard.d.ts +21 -0
  138. package/dist/skate-snowboard.js +37 -0
  139. package/dist/{spark-C4Tp-52_.d.ts → spark-VoQoemz_.d.ts} +1 -1
  140. package/dist/spatial-puzzles.d.ts +21 -0
  141. package/dist/spatial-puzzles.js +35 -0
  142. package/dist/squad-rts.d.ts +21 -0
  143. package/dist/squad-rts.js +39 -0
  144. package/dist/stealth-city.d.ts +21 -0
  145. package/dist/stealth-city.js +41 -0
  146. package/dist/survival-resources.d.ts +21 -0
  147. package/dist/survival-resources.js +37 -0
  148. package/dist/tactical-grid.d.ts +21 -0
  149. package/dist/tactical-grid.js +39 -0
  150. package/dist/thruster.d.ts +2 -1
  151. package/dist/thruster.js +4 -3
  152. package/dist/top-down-movement.d.ts +2 -1
  153. package/dist/top-down-movement.js +24 -3
  154. package/dist/turn-based-rpg.d.ts +21 -0
  155. package/dist/turn-based-rpg.js +39 -0
  156. package/dist/{vector-DjhLUrak.d.ts → vector-s7GbCrVn.d.ts} +1 -1
  157. package/dist/weapon-systems.d.ts +22 -0
  158. package/dist/weapon-systems.js +45 -0
  159. package/dist/world-boundary-2d.d.ts +2 -1
  160. package/dist/world-boundary-2d.js +25 -4
  161. package/dist/world-boundary-3d.d.ts +2 -1
  162. package/dist/world-boundary-3d.js +26 -5
  163. package/package.json +90 -5
  164. package/dist/behavior-system-DkFAwLb_.d.ts +0 -914
  165. package/dist/chunk-GZ3DQIIZ.js +0 -888
  166. package/dist/{chunk-OSPQFWQF.js → chunk-4K37UL53.js} +3 -3
  167. package/dist/{chunk-DD4U42FG.js → chunk-AQB246W5.js} +3 -3
  168. package/dist/{chunk-UKGBQTHL.js → chunk-CXDNR4R4.js} +3 -3
@@ -1,888 +0,0 @@
1
- // src/lib/runtime/wasm-stage-runtime.ts
2
- import {
3
- loadStageFfi,
4
- STAGE_RENDER_STRIDE,
5
- STAGE_INPUT_STRIDE,
6
- STAGE_SNAPSHOT_STRIDE,
7
- STAGE_EVENT_STRIDE
8
- } from "@zylem/runtime";
9
- var STAGE_INVALID_SLOT = 4294967295;
10
- var StageBodyKind = {
11
- Dynamic: 0,
12
- Static: 1,
13
- KinematicPosition: 2,
14
- KinematicVelocity: 3
15
- };
16
- var StageBoundaryDim = {
17
- Two: 2,
18
- Three: 3
19
- };
20
- var StageRicochetDim = {
21
- Two: 2,
22
- Three: 3
23
- };
24
- var StageRicochetReflection = {
25
- Mirror: 0,
26
- Angled: 1
27
- };
28
- var StageTopDownPlane = {
29
- Xy: 0,
30
- Xz: 1
31
- };
32
- var StageEventType = {
33
- CollisionStarted: 1,
34
- CollisionStopped: 2,
35
- BoundaryHit: 3,
36
- Ricochet: 4,
37
- RegionEntered: 5,
38
- JumpStarted: 6,
39
- Landed: 7,
40
- Wrapped: 8,
41
- CooldownFired: 9
42
- };
43
- var StagePlatformerShapeSource = {
44
- Auto: 0,
45
- Override: 1
46
- };
47
- var STAGE_INPUT_BUTTON_JUMP = 1;
48
- var STAGE_INPUT_BUTTON_RUN = 2;
49
- function readBehaviorSnapshot(ref) {
50
- const backref = ref;
51
- const wasmStage = backref.__wasmStage;
52
- const handle = backref.__entity?.runtimeHandle ?? -1;
53
- if (!wasmStage || handle < 0) return null;
54
- return wasmStage.readSnapshot(handle);
55
- }
56
- function readStageRenderSlot(view, slot, out) {
57
- const base = slot * STAGE_RENDER_STRIDE;
58
- if (slot < 0 || base + STAGE_RENDER_STRIDE > view.length) {
59
- return null;
60
- }
61
- const result = out ?? {
62
- position: [0, 0, 0],
63
- rotation: [0, 0, 0, 1],
64
- scale: 1,
65
- custom: [0, 0, 0, 0],
66
- isSleeping: false
67
- };
68
- result.position[0] = view[base];
69
- result.position[1] = view[base + 1];
70
- result.position[2] = view[base + 2];
71
- result.rotation[0] = view[base + 3];
72
- result.rotation[1] = view[base + 4];
73
- result.rotation[2] = view[base + 5];
74
- result.rotation[3] = view[base + 6];
75
- const scale = view[base + 7];
76
- result.scale = scale === 0 ? 1 : scale;
77
- result.custom[0] = view[base + 8];
78
- result.custom[1] = view[base + 9];
79
- result.custom[2] = view[base + 10];
80
- result.custom[3] = view[base + 11];
81
- result.isSleeping = result.custom[3] > 0.5;
82
- return result;
83
- }
84
- var WasmStageRuntime = class {
85
- exports;
86
- memory;
87
- renderView = new Float32Array(0);
88
- inputView = new Float32Array(0);
89
- snapshotView = new Float32Array(0);
90
- eventView = new Float32Array(0);
91
- poseView = new Float32Array(0);
92
- vec3View = new Float32Array(0);
93
- queryView = new Float32Array(0);
94
- scratchView = new Float32Array(0);
95
- constructor(exports, options = {}) {
96
- this.exports = exports;
97
- this.memory = exports.memory;
98
- const capacity = Math.max(options.initialCapacity ?? 64, 8);
99
- exports.zylem_stage_create(capacity);
100
- if (options.gravity) {
101
- exports.zylem_stage_set_gravity(
102
- options.gravity[0],
103
- options.gravity[1],
104
- options.gravity[2]
105
- );
106
- }
107
- this.refreshViews();
108
- }
109
- /** Recreate typed views over wasm memory. Call after step() or whenever memory may have grown. */
110
- refreshViews() {
111
- const buffer = this.memory.buffer;
112
- const renderPtr = this.exports.zylem_stage_render_ptr();
113
- const renderLen = this.exports.zylem_stage_render_len();
114
- const inputPtr = this.exports.zylem_stage_input_ptr();
115
- const inputLen = this.exports.zylem_stage_input_len();
116
- const snapshotPtr = this.exports.zylem_stage_snapshot_ptr();
117
- const snapshotLen = this.exports.zylem_stage_snapshot_len();
118
- const eventPtr = this.exports.zylem_stage_event_ptr();
119
- const eventLen = this.exports.zylem_stage_event_len();
120
- const posePtr = this.exports.zylem_stage_pose_ptr();
121
- const poseLen = this.exports.zylem_stage_pose_len();
122
- const vec3Ptr = this.exports.zylem_stage_vec3_ptr();
123
- const queryPtr = this.exports.zylem_stage_query_ptr();
124
- const queryLen = this.exports.zylem_stage_query_len();
125
- const scratchPtr = this.exports.zylem_stage_scratch_ptr();
126
- const scratchCap = this.exports.zylem_stage_scratch_capacity();
127
- this.renderView = renderLen > 0 ? new Float32Array(buffer, renderPtr, renderLen) : new Float32Array(0);
128
- this.inputView = inputLen > 0 ? new Float32Array(buffer, inputPtr, inputLen) : new Float32Array(0);
129
- this.snapshotView = snapshotLen > 0 ? new Float32Array(buffer, snapshotPtr, snapshotLen) : new Float32Array(0);
130
- this.eventView = eventLen > 0 ? new Float32Array(buffer, eventPtr, eventLen) : new Float32Array(0);
131
- this.poseView = poseLen > 0 ? new Float32Array(buffer, posePtr, poseLen) : new Float32Array(0);
132
- this.vec3View = vec3Ptr !== 0 ? new Float32Array(buffer, vec3Ptr, 3) : new Float32Array(0);
133
- this.queryView = queryLen > 0 ? new Float32Array(buffer, queryPtr, queryLen) : new Float32Array(0);
134
- this.scratchView = scratchCap > 0 ? new Float32Array(buffer, scratchPtr, scratchCap) : new Float32Array(0);
135
- }
136
- /** Step the simulation by `dt` seconds. Refreshes views afterwards. */
137
- step(dt) {
138
- const active = this.exports.zylem_stage_step(dt);
139
- this.refreshViews();
140
- return active;
141
- }
142
- dispose() {
143
- this.exports.zylem_stage_destroy();
144
- }
145
- get tickCount() {
146
- return this.exports.zylem_stage_tick_count() >>> 0;
147
- }
148
- get activeCount() {
149
- return this.exports.zylem_stage_active_count() >>> 0;
150
- }
151
- setGravity(x, y, z) {
152
- this.exports.zylem_stage_set_gravity(x, y, z);
153
- }
154
- /**
155
- * Toggle per-step collision-event collection in the wasm stage. Hosts
156
- * with no collision listeners should disable it — with thousands of
157
- * touching bodies the per-step contact-pair hashing is a significant
158
- * fraction of `step()`.
159
- */
160
- setEventsEnabled(enabled) {
161
- this.exports.zylem_stage_set_events_enabled(enabled ? 1 : 0);
162
- }
163
- /** Cap Rapier contact solver iterations (default 4). */
164
- setSolverIterations(iterations) {
165
- this.exports.zylem_stage_set_solver_iterations(Math.max(1, iterations | 0));
166
- }
167
- /**
168
- * Override sleep activation thresholds for sleep-capable dynamic bodies.
169
- * Higher velocity thresholds / lower `timeUntilSleep` put piles to sleep
170
- * sooner.
171
- */
172
- setSleepThresholds(normalizedLinearThreshold, angularThreshold, timeUntilSleep) {
173
- this.exports.zylem_stage_set_sleep_thresholds(
174
- normalizedLinearThreshold,
175
- angularThreshold,
176
- timeUntilSleep
177
- );
178
- }
179
- /** Number of awake (non-sleeping) dynamic rigid bodies. */
180
- awakeDynamicCount() {
181
- return this.exports.zylem_stage_awake_dynamic_count();
182
- }
183
- // ─── Entity lifecycle ───────────────────────────────────────────────
184
- createEntity() {
185
- const slot = this.exports.zylem_stage_create_entity() >>> 0;
186
- this.refreshViews();
187
- return slot;
188
- }
189
- destroyEntity(slot) {
190
- return this.exports.zylem_stage_destroy_entity(slot) !== 0;
191
- }
192
- // ─── Body / collider attach ────────────────────────────────────────
193
- attachBody(slot, config) {
194
- const ok = this.exports.zylem_stage_attach_body(
195
- slot,
196
- config.kind,
197
- config.position[0],
198
- config.position[1],
199
- config.position[2],
200
- config.rotation[0],
201
- config.rotation[1],
202
- config.rotation[2],
203
- config.rotation[3],
204
- config.linearDamping,
205
- config.angularDamping,
206
- config.gravityScale,
207
- config.canSleep ? 1 : 0,
208
- config.ccdEnabled ? 1 : 0,
209
- config.lockRotation[0] ? 1 : 0,
210
- config.lockRotation[1] ? 1 : 0,
211
- config.lockRotation[2] ? 1 : 0,
212
- config.lockTranslation[0] ? 1 : 0,
213
- config.lockTranslation[1] ? 1 : 0,
214
- config.lockTranslation[2] ? 1 : 0
215
- );
216
- return ok !== 0;
217
- }
218
- addCollider(slot, config) {
219
- const offset = config.offset;
220
- const sensor = config.sensor ? 1 : 0;
221
- const groups = config.collisionGroups >>> 0;
222
- const friction = config.friction;
223
- const restitution = config.restitution;
224
- switch (config.shape.type) {
225
- case "box": {
226
- const [hx, hy, hz] = config.shape.halfExtents;
227
- return this.exports.zylem_stage_add_collider_box(
228
- slot,
229
- hx,
230
- hy,
231
- hz,
232
- offset[0],
233
- offset[1],
234
- offset[2],
235
- friction,
236
- restitution,
237
- sensor,
238
- groups
239
- ) !== 0;
240
- }
241
- case "sphere": {
242
- return this.exports.zylem_stage_add_collider_sphere(
243
- slot,
244
- config.shape.radius,
245
- offset[0],
246
- offset[1],
247
- offset[2],
248
- friction,
249
- restitution,
250
- sensor,
251
- groups
252
- ) !== 0;
253
- }
254
- case "capsule": {
255
- return this.exports.zylem_stage_add_collider_capsule(
256
- slot,
257
- config.shape.halfHeight,
258
- config.shape.radius,
259
- offset[0],
260
- offset[1],
261
- offset[2],
262
- friction,
263
- restitution,
264
- sensor,
265
- groups
266
- ) !== 0;
267
- }
268
- case "cylinder": {
269
- return this.exports.zylem_stage_add_collider_cylinder(
270
- slot,
271
- config.shape.halfHeight,
272
- config.shape.radius,
273
- offset[0],
274
- offset[1],
275
- offset[2],
276
- friction,
277
- restitution,
278
- sensor,
279
- groups
280
- ) !== 0;
281
- }
282
- case "cone": {
283
- return this.exports.zylem_stage_add_collider_cone(
284
- slot,
285
- config.shape.halfHeight,
286
- config.shape.radius,
287
- offset[0],
288
- offset[1],
289
- offset[2],
290
- friction,
291
- restitution,
292
- sensor,
293
- groups
294
- ) !== 0;
295
- }
296
- case "convexHull": {
297
- const verts = config.shape.vertices;
298
- if (verts.length % 3 !== 0) return false;
299
- const offsetFloats = this.stageScratch(verts);
300
- return this.exports.zylem_stage_add_collider_convex_hull(
301
- slot,
302
- offsetFloats,
303
- verts.length / 3,
304
- offset[0],
305
- offset[1],
306
- offset[2],
307
- friction,
308
- restitution,
309
- sensor,
310
- groups
311
- ) !== 0;
312
- }
313
- case "trimesh": {
314
- const verts = config.shape.vertices;
315
- const indices = config.shape.indices;
316
- if (verts.length % 3 !== 0 || indices.length % 3 !== 0) return false;
317
- const vertOffset = this.stageScratch(verts);
318
- const indexOffset = this.stageScratchIndices(indices, vertOffset + verts.length);
319
- return this.exports.zylem_stage_add_collider_trimesh(
320
- slot,
321
- vertOffset,
322
- verts.length / 3,
323
- indexOffset,
324
- indices.length,
325
- offset[0],
326
- offset[1],
327
- offset[2],
328
- friction,
329
- restitution,
330
- sensor,
331
- groups
332
- ) !== 0;
333
- }
334
- case "heightfield": {
335
- const heights = config.shape.heights;
336
- const heightOffset = this.stageScratch(heights);
337
- return this.exports.zylem_stage_add_collider_heightfield(
338
- slot,
339
- config.shape.rows,
340
- config.shape.cols,
341
- config.shape.scale[0],
342
- config.shape.scale[1],
343
- config.shape.scale[2],
344
- heightOffset,
345
- offset[0],
346
- offset[1],
347
- offset[2],
348
- friction,
349
- restitution,
350
- sensor,
351
- groups
352
- ) !== 0;
353
- }
354
- default: {
355
- const _exhaustive = config.shape;
356
- void _exhaustive;
357
- return false;
358
- }
359
- }
360
- }
361
- stageScratch(values, baseOffset = 0) {
362
- this.scratchView.set(values, baseOffset);
363
- return baseOffset;
364
- }
365
- stageScratchIndices(indices, baseOffset) {
366
- for (let i = 0; i < indices.length; i++) {
367
- this.scratchView[baseOffset + i] = indices[i];
368
- }
369
- return baseOffset;
370
- }
371
- // ─── Pose / velocity ───────────────────────────────────────────────
372
- getPose(slot, out) {
373
- const ok = this.exports.zylem_stage_get_pose(slot) !== 0;
374
- if (!ok) return null;
375
- const v = this.poseView;
376
- const result = out ?? {
377
- position: [0, 0, 0],
378
- rotation: [0, 0, 0, 1]
379
- };
380
- result.position[0] = v[0];
381
- result.position[1] = v[1];
382
- result.position[2] = v[2];
383
- result.rotation[0] = v[3];
384
- result.rotation[1] = v[4];
385
- result.rotation[2] = v[5];
386
- result.rotation[3] = v[6];
387
- return result;
388
- }
389
- setPosition(slot, x, y, z) {
390
- return this.exports.zylem_stage_set_position(slot, x, y, z) !== 0;
391
- }
392
- setRotation(slot, x, y, z, w) {
393
- return this.exports.zylem_stage_set_rotation(slot, x, y, z, w) !== 0;
394
- }
395
- setLinearVelocity(slot, x, y, z) {
396
- return this.exports.zylem_stage_set_linvel(slot, x, y, z) !== 0;
397
- }
398
- getLinearVelocity(slot, out) {
399
- if (this.exports.zylem_stage_get_linvel(slot) === 0) return null;
400
- const v = this.vec3View;
401
- const result = out ?? [0, 0, 0];
402
- result[0] = v[0];
403
- result[1] = v[1];
404
- result[2] = v[2];
405
- return result;
406
- }
407
- setAngularVelocity(slot, x, y, z) {
408
- return this.exports.zylem_stage_set_angvel(slot, x, y, z) !== 0;
409
- }
410
- getAngularVelocity(slot, out) {
411
- if (this.exports.zylem_stage_get_angvel(slot) === 0) return null;
412
- const v = this.vec3View;
413
- const result = out ?? [0, 0, 0];
414
- result[0] = v[0];
415
- result[1] = v[1];
416
- result[2] = v[2];
417
- return result;
418
- }
419
- applyImpulse(slot, x, y, z) {
420
- return this.exports.zylem_stage_apply_impulse(slot, x, y, z) !== 0;
421
- }
422
- // ─── Queries / diagnostics ─────────────────────────────────────────
423
- /** Cast a ray against the physics world. Returns the closest hit or `null`. */
424
- castRay(origin, dir, maxDistance, solidOnly = true) {
425
- const hit = this.exports.zylem_stage_cast_ray(
426
- origin[0],
427
- origin[1],
428
- origin[2],
429
- dir[0],
430
- dir[1],
431
- dir[2],
432
- maxDistance,
433
- solidOnly ? 1 : 0
434
- );
435
- if (hit === 0) return null;
436
- const v = this.queryView;
437
- return {
438
- slot: v[0] >>> 0,
439
- distance: v[1],
440
- normal: [v[2], v[3], v[4]]
441
- };
442
- }
443
- /** Body introspection for debug tooling. */
444
- getBodyInfo(slot) {
445
- if (this.exports.zylem_stage_body_info(slot) === 0) return null;
446
- const v = this.queryView;
447
- return {
448
- bodyType: v[0] | 0,
449
- mass: v[1],
450
- isSleeping: v[2] > 0.5,
451
- isEnabled: v[3] > 0.5,
452
- linearVelocity: [v[4], v[5], v[6]]
453
- };
454
- }
455
- /** Wireframe debug render of every collider (all shapes). */
456
- getDebugRender() {
457
- const vertexCount = this.exports.zylem_stage_debug_render() >>> 0;
458
- this.refreshViews();
459
- if (vertexCount === 0) return null;
460
- const buffer = this.memory.buffer;
461
- const vertices = new Float32Array(
462
- buffer,
463
- this.exports.zylem_stage_debug_vertices_ptr(),
464
- this.exports.zylem_stage_debug_vertices_len()
465
- );
466
- const colors = new Float32Array(
467
- buffer,
468
- this.exports.zylem_stage_debug_colors_ptr(),
469
- this.exports.zylem_stage_debug_colors_len()
470
- );
471
- return {
472
- vertices: new Float32Array(vertices),
473
- colors: new Float32Array(colors)
474
- };
475
- }
476
- // ─── Render / event reads ──────────────────────────────────────────
477
- /** Read-only view over the render buffer; one slot occupies {@link STAGE_RENDER_STRIDE} floats. */
478
- get render() {
479
- return this.renderView;
480
- }
481
- get renderStride() {
482
- return STAGE_RENDER_STRIDE;
483
- }
484
- /**
485
- * Decode a single entity slot from the live render buffer. Convenience
486
- * wrapper over {@link readStageRenderSlot} bound to this runtime's view.
487
- */
488
- readRenderSlot(slot, out) {
489
- return readStageRenderSlot(this.renderView, slot, out);
490
- }
491
- /** Drain the wasm event buffer into a fresh array of typed events. */
492
- drainEvents() {
493
- const count = this.exports.zylem_stage_event_count() >>> 0;
494
- if (count === 0) return [];
495
- const view = this.eventView;
496
- const events = new Array(count);
497
- for (let i = 0; i < count; i++) {
498
- const base = i * STAGE_EVENT_STRIDE;
499
- const primaryRaw = view[base + 1];
500
- const secondaryRaw = view[base + 2];
501
- events[i] = {
502
- type: view[base] | 0,
503
- primarySlot: Number.isNaN(primaryRaw) ? null : primaryRaw >>> 0,
504
- secondarySlot: Number.isNaN(secondaryRaw) ? null : secondaryRaw >>> 0,
505
- payload: [view[base + 3], view[base + 4], view[base + 5]]
506
- };
507
- }
508
- return events;
509
- }
510
- // ─── Batched input / snapshot buffers ─────────────────────────────
511
- /** Writable view over the slot-indexed input buffer ({@link STAGE_INPUT_STRIDE} floats/slot). */
512
- get input() {
513
- return this.inputView;
514
- }
515
- get inputStride() {
516
- return STAGE_INPUT_STRIDE;
517
- }
518
- /** Read-only view over the per-slot behavior snapshot buffer ({@link STAGE_SNAPSHOT_STRIDE} floats/slot). */
519
- get snapshot() {
520
- return this.snapshotView;
521
- }
522
- get snapshotStride() {
523
- return STAGE_SNAPSHOT_STRIDE;
524
- }
525
- /**
526
- * Write the primary movement axes for a slot into the slot-indexed input
527
- * buffer and mark the slot dirty. Field-scoped (doesn't touch look
528
- * deltas or buttons) so multiple behaviors composed on one entity can
529
- * each write their part.
530
- */
531
- writeInputAxes(slot, axisA, axisB) {
532
- const base = slot * STAGE_INPUT_STRIDE;
533
- const view = this.inputView;
534
- if (slot < 0 || base + STAGE_INPUT_STRIDE > view.length) return false;
535
- view[base] = axisA;
536
- view[base + 1] = axisB;
537
- view[base + 7] = 1;
538
- return true;
539
- }
540
- /** Write the look deltas (first-person yaw/pitch) for a slot. */
541
- writeInputLook(slot, yawDelta, pitchDelta) {
542
- const base = slot * STAGE_INPUT_STRIDE;
543
- const view = this.inputView;
544
- if (slot < 0 || base + STAGE_INPUT_STRIDE > view.length) return false;
545
- view[base + 2] = yawDelta;
546
- view[base + 3] = pitchDelta;
547
- view[base + 7] = 1;
548
- return true;
549
- }
550
- /** Write reserved input slots (thruster world-space vector X/Y). */
551
- writeInputReserved(slot, reservedA, reservedB) {
552
- const base = slot * STAGE_INPUT_STRIDE;
553
- const view = this.inputView;
554
- if (slot < 0 || base + STAGE_INPUT_STRIDE > view.length) return false;
555
- view[base + 5] = reservedA;
556
- view[base + 6] = reservedB;
557
- view[base + 7] = 1;
558
- return true;
559
- }
560
- /**
561
- * Set or clear one button bit ({@link STAGE_INPUT_BUTTON_JUMP} /
562
- * {@link STAGE_INPUT_BUTTON_RUN}) in a slot's input bitmask.
563
- */
564
- writeInputButton(slot, buttonMask, pressed) {
565
- const base = slot * STAGE_INPUT_STRIDE;
566
- const view = this.inputView;
567
- if (slot < 0 || base + STAGE_INPUT_STRIDE > view.length) return false;
568
- const current = view[base + 4] | 0;
569
- view[base + 4] = pressed ? current | buttonMask : current & ~buttonMask;
570
- view[base + 7] = 1;
571
- return true;
572
- }
573
- /**
574
- * Decode a slot's behavior snapshot from the buffer written at the end of
575
- * the previous step. Returns `null` when the slot has no behavior data.
576
- */
577
- readSnapshot(slot, out) {
578
- const base = slot * STAGE_SNAPSHOT_STRIDE;
579
- const view = this.snapshotView;
580
- if (slot < 0 || base + STAGE_SNAPSHOT_STRIDE > view.length) return null;
581
- if (view[base + 7] === 0) return null;
582
- const result = out ?? {
583
- grounded: false,
584
- fsmState: 0,
585
- jumpCount: 0,
586
- verticalVelocity: 0,
587
- speed: 0,
588
- yaw: 0,
589
- pitch: 0
590
- };
591
- result.grounded = view[base] > 0.5;
592
- result.fsmState = view[base + 1] | 0;
593
- result.jumpCount = view[base + 2] | 0;
594
- result.verticalVelocity = view[base + 3];
595
- result.speed = view[base + 4];
596
- result.yaw = view[base + 5];
597
- result.pitch = view[base + 6];
598
- return result;
599
- }
600
- // ─── Behavior helpers ─────────────────────────────────────────────
601
- get queryScratch() {
602
- return this.queryView;
603
- }
604
- attachCooldown(slot) {
605
- return this.exports.zylem_stage_attach_cooldown(slot) !== 0;
606
- }
607
- registerCooldown(slot, id, durationSeconds, immediate = false) {
608
- return this.exports.zylem_stage_cooldown_register(slot, id >>> 0, durationSeconds, immediate ? 1 : 0) !== 0;
609
- }
610
- fireCooldown(slot, id) {
611
- return this.exports.zylem_stage_cooldown_fire(slot, id >>> 0) !== 0;
612
- }
613
- resetCooldown(slot, id) {
614
- return this.exports.zylem_stage_cooldown_reset(slot, id >>> 0) !== 0;
615
- }
616
- cooldownRemaining(slot, id) {
617
- return this.exports.zylem_stage_cooldown_remaining(slot, id >>> 0);
618
- }
619
- attachWorldBoundary(slot, dim, bounds) {
620
- return this.exports.zylem_stage_attach_world_boundary(
621
- slot,
622
- dim,
623
- bounds.top,
624
- bounds.bottom,
625
- bounds.left,
626
- bounds.right,
627
- bounds.front ?? 0,
628
- bounds.back ?? 0,
629
- bounds.padding ?? 0
630
- ) !== 0;
631
- }
632
- queryWorldBoundary(slot) {
633
- if (this.exports.zylem_stage_query_world_boundary(slot) === 0) return null;
634
- const v = this.queryView;
635
- return {
636
- hits: v[0] | 0,
637
- clamped: [v[1], v[2], v[3]]
638
- };
639
- }
640
- attachScreenWrap(slot, opts) {
641
- return this.exports.zylem_stage_attach_screen_wrap(
642
- slot,
643
- opts.width,
644
- opts.height,
645
- opts.centerX ?? 0,
646
- opts.centerY ?? 0,
647
- opts.edgeThreshold ?? 0
648
- ) !== 0;
649
- }
650
- queryScreenWrap(slot) {
651
- if (this.exports.zylem_stage_query_screen_wrap(slot) === 0) return null;
652
- const v = this.queryView;
653
- return { fsm: v[0] | 0, lastWrappedAxes: v[1] | 0 };
654
- }
655
- attachRicochet(slot, dim, opts) {
656
- return this.exports.zylem_stage_attach_ricochet(
657
- slot,
658
- dim,
659
- opts.minSpeed,
660
- opts.maxSpeed,
661
- opts.speedMultiplier,
662
- opts.maxAngleDeg,
663
- opts.reflectionMode
664
- ) !== 0;
665
- }
666
- queryRicochet(slot) {
667
- if (this.exports.zylem_stage_query_ricochet(slot) === 0) return null;
668
- const v = this.queryView;
669
- return { bounces: v[0] | 0, lastKind: v[1] | 0 };
670
- }
671
- attachThruster(slot, opts) {
672
- return this.exports.zylem_stage_attach_thruster(
673
- slot,
674
- opts.maxSpeed,
675
- opts.acceleration,
676
- opts.turnRateRadPerSec,
677
- opts.linearDamping
678
- ) !== 0;
679
- }
680
- setThrusterInput(slot, thrust, turn, vectorX = 0, vectorY = 0) {
681
- this.exports.zylem_stage_set_thruster_input(slot, thrust, turn, vectorX, vectorY);
682
- }
683
- queryThruster(slot) {
684
- if (this.exports.zylem_stage_query_thruster(slot) === 0) return null;
685
- const v = this.queryView;
686
- return { headingRad: v[0], speed: v[1] };
687
- }
688
- attachTopDown(slot, opts) {
689
- return this.exports.zylem_stage_attach_top_down(slot, opts.plane, opts.speed, opts.faceMovement ? 1 : 0) !== 0;
690
- }
691
- setTopDownInput(slot, axisA, axisB) {
692
- this.exports.zylem_stage_set_top_down_input(slot, axisA, axisB);
693
- }
694
- attachJumper2D(slot, opts) {
695
- return this.exports.zylem_stage_attach_jumper_2d(
696
- slot,
697
- opts.jumpForce,
698
- opts.maxJumps >>> 0,
699
- opts.jumpBufferTime,
700
- opts.coyoteTime,
701
- opts.gravity
702
- ) !== 0;
703
- }
704
- setJumper2DInput(slot, jumpPressed) {
705
- this.exports.zylem_stage_set_jumper_2d_input(slot, jumpPressed ? 1 : 0);
706
- }
707
- queryJumper2D(slot) {
708
- if (this.exports.zylem_stage_query_jumper_2d(slot) === 0) return null;
709
- const v = this.queryView;
710
- return {
711
- grounded: v[0] > 0.5,
712
- jumpCount: v[1] | 0,
713
- coyote: v[2],
714
- jumpBuffer: v[3]
715
- };
716
- }
717
- attachJumper3D(slot, opts) {
718
- return this.exports.zylem_stage_attach_jumper_3d(
719
- slot,
720
- opts.jumpForce,
721
- opts.maxJumps >>> 0,
722
- opts.gravity,
723
- opts.coyoteTime ?? 0.1,
724
- opts.jumpBufferTime ?? 0.08
725
- ) !== 0;
726
- }
727
- setJumper3DInput(slot, jump) {
728
- this.exports.zylem_stage_set_jumper_3d_input(slot, jump ? 1 : 0);
729
- }
730
- queryJumper3D(slot) {
731
- if (this.exports.zylem_stage_query_jumper_3d(slot) === 0) return null;
732
- const v = this.queryView;
733
- return { grounded: v[0] > 0.5, jumpCount: v[1] | 0, verticalVelocity: v[2] };
734
- }
735
- attachShooter2D(slot, opts) {
736
- return this.exports.zylem_stage_attach_shooter_2d(
737
- slot,
738
- opts.fireRateHz,
739
- opts.muzzleOffsetX,
740
- opts.muzzleOffsetY,
741
- opts.muzzleSpeed
742
- ) !== 0;
743
- }
744
- fireShooter2D(slot, x, y, z, yaw) {
745
- return this.exports.zylem_stage_shooter_2d_fire(slot, x, y, z, yaw) !== 0;
746
- }
747
- queryShooter2D(slot) {
748
- if (this.exports.zylem_stage_query_shooter_2d(slot) === 0) return null;
749
- const v = this.queryView;
750
- return { cooldown: v[0], firedCount: v[1] | 0 };
751
- }
752
- attachPlatformer3D(slot, opts) {
753
- return this.exports.zylem_stage_attach_platformer_3d(
754
- slot,
755
- opts.halfHeight,
756
- opts.radius,
757
- opts.walkSpeed,
758
- opts.runSpeed,
759
- opts.jumpForce,
760
- opts.maxJumps >>> 0,
761
- opts.gravity,
762
- opts.coyoteTime ?? 0.1,
763
- opts.jumpBufferTime ?? 0.1,
764
- opts.jumpCutMultiplier ?? 0.5,
765
- opts.multiJumpWindow ?? 0.15,
766
- opts.slopeClimbAngle ?? 50,
767
- opts.slopeSlideAngle ?? 40,
768
- opts.autostepHeight ?? 0.3,
769
- opts.autostepMinWidth ?? 0.1,
770
- opts.snapToGroundDistance ?? 0.3,
771
- opts.characterOffset ?? 0.05,
772
- opts.offsetX ?? 0,
773
- opts.offsetY ?? 0,
774
- opts.offsetZ ?? 0,
775
- opts.shapeSource ?? StagePlatformerShapeSource.Auto
776
- ) !== 0;
777
- }
778
- setPlatformer3DInputAxes(slot, moveX, moveZ) {
779
- this.exports.zylem_stage_set_platformer_3d_input_axes(slot, moveX, moveZ);
780
- }
781
- setPlatformer3DInputButtons(slot, jump, run) {
782
- this.exports.zylem_stage_set_platformer_3d_input_buttons(slot, jump ? 1 : 0, run ? 1 : 0);
783
- }
784
- queryPlatformer3D(slot) {
785
- if (this.exports.zylem_stage_query_platformer_3d(slot) === 0) return null;
786
- const v = this.queryView;
787
- return {
788
- grounded: v[0] > 0.5,
789
- jumpCount: v[1] | 0,
790
- fsmState: v[2] | 0,
791
- speed: v[3]
792
- };
793
- }
794
- attachPlatformer2D(slot, opts) {
795
- return this.exports.zylem_stage_attach_platformer_2d(
796
- slot,
797
- opts.halfHeight,
798
- opts.radius,
799
- opts.walkSpeed,
800
- opts.runSpeed,
801
- opts.jumpForce,
802
- opts.maxJumps >>> 0,
803
- opts.gravity,
804
- opts.coyoteTime ?? 0.1,
805
- opts.jumpBufferTime ?? 0.1,
806
- opts.jumpCutMultiplier ?? 0.5,
807
- opts.multiJumpWindow ?? 0.15,
808
- opts.slopeClimbAngle ?? 50,
809
- opts.slopeSlideAngle ?? 40,
810
- opts.autostepHeight ?? 0.25,
811
- opts.autostepMinWidth ?? 0.05,
812
- opts.snapToGroundDistance ?? 0.2,
813
- opts.characterOffset ?? 0.05,
814
- opts.offsetX ?? 0,
815
- opts.offsetY ?? 0,
816
- opts.offsetZ ?? 0,
817
- opts.shapeSource ?? StagePlatformerShapeSource.Auto
818
- ) !== 0;
819
- }
820
- setPlatformer2DInputAxes(slot, moveX) {
821
- this.exports.zylem_stage_set_platformer_2d_input_axes(slot, moveX);
822
- }
823
- setPlatformer2DInputButtons(slot, jump, run) {
824
- this.exports.zylem_stage_set_platformer_2d_input_buttons(slot, jump ? 1 : 0, run ? 1 : 0);
825
- }
826
- queryPlatformer2D(slot) {
827
- if (this.exports.zylem_stage_query_platformer_2d(slot) === 0) return null;
828
- const v = this.queryView;
829
- return {
830
- grounded: v[0] > 0.5,
831
- jumpCount: v[1] | 0,
832
- fsmState: v[2] | 0,
833
- verticalVelocity: v[3]
834
- };
835
- }
836
- attachFirstPerson(slot, opts) {
837
- return this.exports.zylem_stage_attach_first_person(
838
- slot,
839
- opts.walkSpeed,
840
- opts.runSpeed,
841
- opts.eyeHeight,
842
- opts.lookSensitivity
843
- ) !== 0;
844
- }
845
- setFirstPersonInput(slot, input) {
846
- this.exports.zylem_stage_set_first_person_input(
847
- slot,
848
- input.moveX,
849
- input.moveZ,
850
- input.lookYawDelta,
851
- input.lookPitchDelta,
852
- input.run ? 1 : 0
853
- );
854
- }
855
- queryFirstPerson(slot) {
856
- if (this.exports.zylem_stage_query_first_person(slot) === 0) return null;
857
- const v = this.queryView;
858
- return { yaw: v[0], pitch: v[1], speed: v[2], eyeHeight: v[3] };
859
- }
860
- };
861
- async function createWasmStageRuntime(options = {}) {
862
- const { exports } = await loadStageFfi({
863
- source: options.source,
864
- imports: options.imports
865
- });
866
- return new WasmStageRuntime(exports, options);
867
- }
868
-
869
- export {
870
- STAGE_RENDER_STRIDE,
871
- STAGE_INPUT_STRIDE,
872
- STAGE_SNAPSHOT_STRIDE,
873
- STAGE_EVENT_STRIDE,
874
- STAGE_INVALID_SLOT,
875
- StageBodyKind,
876
- StageBoundaryDim,
877
- StageRicochetDim,
878
- StageRicochetReflection,
879
- StageTopDownPlane,
880
- StageEventType,
881
- StagePlatformerShapeSource,
882
- STAGE_INPUT_BUTTON_JUMP,
883
- STAGE_INPUT_BUTTON_RUN,
884
- readBehaviorSnapshot,
885
- readStageRenderSlot,
886
- WasmStageRuntime,
887
- createWasmStageRuntime
888
- };