@zylem/game-lib 0.6.3 → 0.7.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 (97) hide show
  1. package/README.md +3 -1
  2. package/dist/actions.d.ts +255 -8
  3. package/dist/actions.js +1 -772
  4. package/dist/audio.d.ts +13 -0
  5. package/dist/audio.js +1 -0
  6. package/dist/base-node-life-cycle-CnJ-7zX-.d.ts +143 -0
  7. package/dist/behavior.d.ts +3 -0
  8. package/dist/behavior.js +1 -0
  9. package/dist/chunk-4QLJUQSJ.js +1 -0
  10. package/dist/chunk-73VZQZUL.js +1 -0
  11. package/dist/chunk-A34ZG3L4.js +1 -0
  12. package/dist/chunk-CDPY4VOQ.js +1 -0
  13. package/dist/chunk-DR6XXZE7.js +19 -0
  14. package/dist/chunk-FM5TBEPO.js +1 -0
  15. package/dist/chunk-G2IIMSUH.js +1 -0
  16. package/dist/chunk-MSC2BEO5.js +1 -0
  17. package/dist/chunk-NIH5CONO.js +1 -0
  18. package/dist/chunk-ONWXGBWB.js +1 -0
  19. package/dist/chunk-QEDQDR27.js +1 -0
  20. package/dist/chunk-QXVH6POE.js +1 -0
  21. package/dist/chunk-RXDTAWI2.js +29 -0
  22. package/dist/chunk-WKHW2QO2.js +1 -0
  23. package/dist/chunk-XRP4JJXL.js +1 -0
  24. package/dist/chunk-YHEWKN7N.js +1 -0
  25. package/dist/chunk-YHKXQ2ZN.js +1 -0
  26. package/dist/core.d.ts +206 -13
  27. package/dist/core.js +24 -9160
  28. package/dist/debug.d.ts +24 -0
  29. package/dist/debug.js +1 -0
  30. package/dist/default-controls-BGc61yYl.d.ts +111 -0
  31. package/dist/entity-DNkYKfdp.d.ts +1043 -0
  32. package/dist/entity-type-map-C94h2TDW.d.ts +781 -0
  33. package/dist/entity.d.ts +265 -0
  34. package/dist/entity.js +1 -0
  35. package/dist/events.d.ts +172 -0
  36. package/dist/events.js +1 -0
  37. package/dist/game-Cuj5gy7U.d.ts +1590 -0
  38. package/dist/game-default-PZLLHYL7.js +1 -0
  39. package/dist/game-interfaces-tfpM5NBk.d.ts +90 -0
  40. package/dist/globals.d.ts +104 -0
  41. package/dist/globals.js +1 -0
  42. package/dist/graphics.d.ts +83 -0
  43. package/dist/graphics.js +1 -0
  44. package/dist/input-ui.d.ts +34 -0
  45. package/dist/input-ui.js +1 -0
  46. package/dist/input.d.ts +72 -0
  47. package/dist/input.js +1 -0
  48. package/dist/material-Wz83vTTp.d.ts +151 -0
  49. package/dist/runtime.d.ts +433 -0
  50. package/dist/runtime.js +1 -0
  51. package/dist/web-components.d.ts +67 -0
  52. package/dist/web-components.js +9 -0
  53. package/dist/world-C9zdyl5d.d.ts +103 -0
  54. package/dist/zylem-stage-runtime-Cs-UDEVU.d.ts +777 -0
  55. package/package.json +54 -41
  56. package/dist/actions.js.map +0 -1
  57. package/dist/behavior/platformer-3d.d.ts +0 -296
  58. package/dist/behavior/platformer-3d.js +0 -518
  59. package/dist/behavior/platformer-3d.js.map +0 -1
  60. package/dist/behavior/ricochet-2d.d.ts +0 -274
  61. package/dist/behavior/ricochet-2d.js +0 -394
  62. package/dist/behavior/ricochet-2d.js.map +0 -1
  63. package/dist/behavior/screen-wrap.d.ts +0 -86
  64. package/dist/behavior/screen-wrap.js +0 -195
  65. package/dist/behavior/screen-wrap.js.map +0 -1
  66. package/dist/behavior/thruster.d.ts +0 -10
  67. package/dist/behavior/thruster.js +0 -234
  68. package/dist/behavior/thruster.js.map +0 -1
  69. package/dist/behavior/world-boundary-2d.d.ts +0 -141
  70. package/dist/behavior/world-boundary-2d.js +0 -181
  71. package/dist/behavior/world-boundary-2d.js.map +0 -1
  72. package/dist/behavior-descriptor-BWNWmIjv.d.ts +0 -142
  73. package/dist/blueprints-BWGz8fII.d.ts +0 -26
  74. package/dist/camera-B5e4c78l.d.ts +0 -468
  75. package/dist/camera.d.ts +0 -6
  76. package/dist/camera.js +0 -1406
  77. package/dist/camera.js.map +0 -1
  78. package/dist/composition-DrzFrbqI.d.ts +0 -218
  79. package/dist/core-DAkskq6Y.d.ts +0 -498
  80. package/dist/core.js.map +0 -1
  81. package/dist/entities-DC9ce_vx.d.ts +0 -416
  82. package/dist/entities.d.ts +0 -9
  83. package/dist/entities.js +0 -4069
  84. package/dist/entities.js.map +0 -1
  85. package/dist/entity-BpbZqg19.d.ts +0 -1100
  86. package/dist/entity-Bq_eNEDI.d.ts +0 -28
  87. package/dist/entity-types-DAu8sGJH.d.ts +0 -26
  88. package/dist/global-change-Dc8uCKi2.d.ts +0 -25
  89. package/dist/main.d.ts +0 -654
  90. package/dist/main.js +0 -13355
  91. package/dist/main.js.map +0 -1
  92. package/dist/stage-types-BFsm3qsZ.d.ts +0 -567
  93. package/dist/stage.d.ts +0 -51
  94. package/dist/stage.js +0 -5738
  95. package/dist/stage.js.map +0 -1
  96. package/dist/thruster-DhRaJnoL.d.ts +0 -172
  97. package/dist/world-Be5m1XC1.d.ts +0 -31
@@ -0,0 +1,1043 @@
1
+ import { BufferGeometry, Material, Mesh, Group, Vector3, Color, ShaderMaterial } from 'three';
2
+ import { RigidBodyDesc, ColliderDesc, RigidBody, Collider, Vector } from '@dimforge/rapier3d-compat';
3
+ import { a as Vec3Input, c as Vec3, s as MaterialBuilder, M as MaterialOptions, b as Vec2Input } from './material-Wz83vTTp.js';
4
+ import { S as SetupContext, f as UpdateContext, D as DestroyContext, h as SetupFunction, i as LoadedFunction, U as UpdateFunction, j as DestroyFunction, k as CleanupFunction, L as LoadedContext, C as CleanupContext } from './base-node-life-cycle-CnJ-7zX-.js';
5
+ import { EventEmitterDelegate, EntityEvents } from './events.js';
6
+ import { TransformState, MoveableEntity, BehaviorDescriptor, BehaviorHandle, BehaviorRef } from '@zylem/behaviors/core';
7
+
8
+ interface NodeInterface {
9
+ uuid: string;
10
+ name: string;
11
+ markedForRemoval: boolean;
12
+ nodeSetup(params: SetupContext<any>): void;
13
+ nodeUpdate(params: UpdateContext<any>): void;
14
+ nodeDestroy(params: DestroyContext<any>): void;
15
+ setParent(parent: NodeInterface | null): void;
16
+ getParent(): NodeInterface | null;
17
+ }
18
+
19
+ type BaseNodeOptions<T = any> = BaseNode | Partial<T>;
20
+ /**
21
+ * Lifecycle callback arrays - each lifecycle event can have multiple callbacks
22
+ * that execute in order.
23
+ */
24
+ interface LifecycleCallbacks<T> {
25
+ setup: Array<SetupFunction<T>>;
26
+ loaded: Array<LoadedFunction<T>>;
27
+ update: Array<UpdateFunction<T>>;
28
+ destroy: Array<DestroyFunction<T>>;
29
+ cleanup: Array<CleanupFunction<T>>;
30
+ }
31
+ declare abstract class BaseNode<Options = any, T = any> implements NodeInterface {
32
+ protected parent: NodeInterface | null;
33
+ protected children: NodeInterface[];
34
+ options: Options;
35
+ uuid: string;
36
+ name: string;
37
+ markedForRemoval: boolean;
38
+ /**
39
+ * Lifecycle callback arrays - use onSetup(), onUpdate(), etc. to add callbacks
40
+ * Uses `any` for the type parameter to avoid invariance issues when subclasses
41
+ * are assigned to BaseNode references. Type safety is enforced by the public
42
+ * onSetup/onUpdate/etc. methods which are typed with `this`.
43
+ */
44
+ protected lifecycleCallbacks: LifecycleCallbacks<any>;
45
+ private trackLifecycleRegistrations;
46
+ private userLifecycleRegistrations;
47
+ constructor(args?: BaseNodeOptions[]);
48
+ /**
49
+ * Add setup callbacks to be executed in order during nodeSetup
50
+ */
51
+ onSetup(...callbacks: Array<SetupFunction<this>>): this;
52
+ /**
53
+ * Add loaded callbacks to be executed in order during nodeLoaded
54
+ */
55
+ onLoaded(...callbacks: Array<LoadedFunction<this>>): this;
56
+ /**
57
+ * Add update callbacks to be executed in order during nodeUpdate
58
+ */
59
+ onUpdate(...callbacks: Array<UpdateFunction<this>>): this;
60
+ /**
61
+ * Add destroy callbacks to be executed in order during nodeDestroy
62
+ */
63
+ onDestroy(...callbacks: Array<DestroyFunction<this>>): this;
64
+ /**
65
+ * Add cleanup callbacks to be executed in order during nodeCleanup
66
+ */
67
+ onCleanup(...callbacks: Array<CleanupFunction<this>>): this;
68
+ /**
69
+ * Prepend setup callbacks (run before existing ones)
70
+ */
71
+ prependSetup(...callbacks: Array<SetupFunction<this>>): this;
72
+ /**
73
+ * Prepend update callbacks (run before existing ones)
74
+ */
75
+ prependUpdate(...callbacks: Array<UpdateFunction<this>>): this;
76
+ setParent(parent: NodeInterface | null): void;
77
+ getParent(): NodeInterface | null;
78
+ add(baseNode: NodeInterface): void;
79
+ remove(baseNode: NodeInterface): void;
80
+ getChildren(): NodeInterface[];
81
+ isComposite(): boolean;
82
+ enableUserLifecycleTracking(): void;
83
+ protected replayUserLifecycleRegistrationsTo(target: BaseNode<any, any>, wrap?: <T extends Function>(callback: T) => T): void;
84
+ protected cloneChildrenInto(target: BaseNode<any, any>): void;
85
+ abstract create(): T;
86
+ protected abstract _setup(params: SetupContext<this>): void;
87
+ protected abstract _loaded(params: LoadedContext<this>): Promise<void>;
88
+ protected abstract _update(params: UpdateContext<this>): void;
89
+ protected abstract _destroy(params: DestroyContext<this>): void;
90
+ protected abstract _cleanup(params: CleanupContext<this>): void;
91
+ nodeSetup(params: SetupContext<this>): void;
92
+ nodeUpdate(params: UpdateContext<this>): void;
93
+ nodeDestroy(params: DestroyContext<this>): void;
94
+ nodeLoaded(params: LoadedContext<this>): Promise<void>;
95
+ nodeCleanup(params: CleanupContext<this>): void;
96
+ getOptions(): Options;
97
+ setOptions(options: Partial<Options>): void;
98
+ private recordLifecycleRegistration;
99
+ }
100
+
101
+ /**
102
+ * `WasmStageRuntime` — owns one wasm `WebAssembly.Instance` of `@zylem/runtime`
103
+ * and exposes the unified-Stage FFI as a set of typed TypeScript methods.
104
+ * Replaces the legacy {@link ZylemRuntimeStageAdapter} + {@link ZylemWorld}
105
+ * pair; every `ZylemStage` instantiates exactly one `WasmStageRuntime`.
106
+ *
107
+ * The runtime is the single source of truth for per-frame physics state.
108
+ * TS-side behaviors and visual layers (destructible-3d, particle-emitter,
109
+ * screen-visibility) read transforms from the render buffer; sim-only
110
+ * behaviors push their attach/query payload through the per-behavior
111
+ * helpers exposed here.
112
+ */
113
+ /** Sentinel handle for "no entity / failed allocation". Mirrors `INVALID_SLOT` in Rust. */
114
+ declare const STAGE_INVALID_SLOT = 4294967295;
115
+ /** Fixed render-buffer stride in floats. Must match `STAGE_RENDER_STRIDE` in Rust. */
116
+ declare const STAGE_RENDER_STRIDE = 12;
117
+ /** Fixed event-buffer stride in floats. Must match `STAGE_EVENT_STRIDE` in Rust. */
118
+ declare const STAGE_EVENT_STRIDE = 6;
119
+ /** Fixed pose-scratch stride in floats. Must match `POSE_SCRATCH_LEN` in Rust. */
120
+ declare const STAGE_POSE_LEN = 7;
121
+ declare const enum StageBodyKind {
122
+ Dynamic = 0,
123
+ Static = 1,
124
+ KinematicPosition = 2,
125
+ KinematicVelocity = 3
126
+ }
127
+ declare const enum StageBoundaryDim {
128
+ Two = 2,
129
+ Three = 3
130
+ }
131
+ declare const enum StageRicochetDim {
132
+ Two = 2,
133
+ Three = 3
134
+ }
135
+ declare const enum StageRicochetReflection {
136
+ Mirror = 0,
137
+ Angled = 1
138
+ }
139
+ declare const enum StageTopDownPlane {
140
+ Xy = 0,
141
+ Xz = 1
142
+ }
143
+ declare const enum StageEventType {
144
+ CollisionStarted = 1,
145
+ CollisionStopped = 2,
146
+ BoundaryHit = 3,
147
+ Ricochet = 4,
148
+ RegionEntered = 5,
149
+ JumpStarted = 6,
150
+ Landed = 7,
151
+ Wrapped = 8,
152
+ CooldownFired = 9
153
+ }
154
+ interface StageEvent {
155
+ type: StageEventType;
156
+ primarySlot: number | null;
157
+ secondarySlot: number | null;
158
+ payload: [number, number, number];
159
+ }
160
+ interface StagePose {
161
+ position: [number, number, number];
162
+ rotation: [number, number, number, number];
163
+ }
164
+ interface StageBodyConfig {
165
+ kind: StageBodyKind;
166
+ position: readonly [number, number, number];
167
+ rotation: readonly [number, number, number, number];
168
+ linearDamping: number;
169
+ angularDamping: number;
170
+ gravityScale: number;
171
+ canSleep: boolean;
172
+ ccdEnabled: boolean;
173
+ lockRotation: readonly [boolean, boolean, boolean];
174
+ lockTranslation: readonly [boolean, boolean, boolean];
175
+ }
176
+ type StageColliderShape = {
177
+ type: 'box';
178
+ halfExtents: readonly [number, number, number];
179
+ } | {
180
+ type: 'sphere';
181
+ radius: number;
182
+ } | {
183
+ type: 'capsule';
184
+ halfHeight: number;
185
+ radius: number;
186
+ } | {
187
+ type: 'cylinder';
188
+ halfHeight: number;
189
+ radius: number;
190
+ } | {
191
+ type: 'convexHull';
192
+ vertices: Float32Array;
193
+ } | {
194
+ type: 'trimesh';
195
+ vertices: Float32Array;
196
+ indices: Uint32Array;
197
+ } | {
198
+ type: 'heightfield';
199
+ rows: number;
200
+ cols: number;
201
+ scale: readonly [number, number, number];
202
+ heights: Float32Array;
203
+ };
204
+ interface StageColliderConfig {
205
+ shape: StageColliderShape;
206
+ offset: readonly [number, number, number];
207
+ friction: number;
208
+ restitution: number;
209
+ sensor: boolean;
210
+ /** Packed Rapier interaction-groups: high 16 bits = membership, low 16 bits = filter. */
211
+ collisionGroups: number;
212
+ }
213
+ /** Minimal exports surface used by `WasmStageRuntime`. Mirrors `stage_ffi.rs`. */
214
+ interface StageWasmExports {
215
+ readonly memory: WebAssembly.Memory;
216
+ zylem_stage_create(initialCapacity: number): number;
217
+ zylem_stage_destroy(): void;
218
+ zylem_stage_set_gravity(x: number, y: number, z: number): void;
219
+ zylem_stage_step(dt: number): number;
220
+ zylem_stage_active_count(): number;
221
+ zylem_stage_capacity(): number;
222
+ zylem_stage_tick_count(): number;
223
+ zylem_stage_create_entity(): number;
224
+ zylem_stage_destroy_entity(slot: number): number;
225
+ zylem_stage_attach_body(slot: number, kind: number, px: number, py: number, pz: number, rx: number, ry: number, rz: number, rw: number, linearDamping: number, angularDamping: number, gravityScale: number, canSleep: number, ccdEnabled: number, lockRotX: number, lockRotY: number, lockRotZ: number, lockTransX: number, lockTransY: number, lockTransZ: number): number;
226
+ zylem_stage_add_collider_box(slot: number, hx: number, hy: number, hz: number, ox: number, oy: number, oz: number, friction: number, restitution: number, sensor: number, collisionGroups: number): number;
227
+ zylem_stage_add_collider_sphere(slot: number, radius: number, ox: number, oy: number, oz: number, friction: number, restitution: number, sensor: number, collisionGroups: number): number;
228
+ zylem_stage_add_collider_capsule(slot: number, halfHeight: number, radius: number, ox: number, oy: number, oz: number, friction: number, restitution: number, sensor: number, collisionGroups: number): number;
229
+ zylem_stage_add_collider_cylinder(slot: number, halfHeight: number, radius: number, ox: number, oy: number, oz: number, friction: number, restitution: number, sensor: number, collisionGroups: number): number;
230
+ zylem_stage_add_collider_convex_hull(slot: number, vertexOffset: number, vertexCount: number, ox: number, oy: number, oz: number, friction: number, restitution: number, sensor: number, collisionGroups: number): number;
231
+ zylem_stage_add_collider_trimesh(slot: number, vertexOffset: number, vertexCount: number, indexOffset: number, indexCount: number, ox: number, oy: number, oz: number, friction: number, restitution: number, sensor: number, collisionGroups: number): number;
232
+ zylem_stage_add_collider_heightfield(slot: number, rows: number, cols: number, sx: number, sy: number, sz: number, heightOffset: number, px: number, py: number, pz: number, friction: number, restitution: number, collisionGroups: number): number;
233
+ zylem_stage_get_pose(slot: number): number;
234
+ zylem_stage_pose_ptr(): number;
235
+ zylem_stage_pose_len(): number;
236
+ zylem_stage_set_position(slot: number, x: number, y: number, z: number): number;
237
+ zylem_stage_set_rotation(slot: number, x: number, y: number, z: number, w: number): number;
238
+ zylem_stage_set_linvel(slot: number, x: number, y: number, z: number): number;
239
+ zylem_stage_get_linvel(slot: number): number;
240
+ zylem_stage_set_angvel(slot: number, x: number, y: number, z: number): number;
241
+ zylem_stage_apply_impulse(slot: number, x: number, y: number, z: number): number;
242
+ zylem_stage_vec3_ptr(): number;
243
+ zylem_stage_render_ptr(): number;
244
+ zylem_stage_render_len(): number;
245
+ zylem_stage_render_stride(): number;
246
+ zylem_stage_event_ptr(): number;
247
+ zylem_stage_event_len(): number;
248
+ zylem_stage_event_count(): number;
249
+ zylem_stage_event_stride(): number;
250
+ zylem_stage_query_ptr(): number;
251
+ zylem_stage_query_len(): number;
252
+ zylem_stage_scratch_ptr(): number;
253
+ zylem_stage_scratch_capacity(): number;
254
+ zylem_stage_attach_cooldown(slot: number): number;
255
+ zylem_stage_cooldown_register(slot: number, id: number, duration: number, immediate: number): number;
256
+ zylem_stage_cooldown_fire(slot: number, id: number): number;
257
+ zylem_stage_cooldown_reset(slot: number, id: number): number;
258
+ zylem_stage_cooldown_remaining(slot: number, id: number): number;
259
+ zylem_stage_attach_world_boundary(slot: number, dim: number, top: number, bottom: number, left: number, right: number, front: number, back: number, padding: number): number;
260
+ zylem_stage_query_world_boundary(slot: number): number;
261
+ zylem_stage_attach_screen_wrap(slot: number, width: number, height: number, centerX: number, centerY: number, edgeThreshold: number): number;
262
+ zylem_stage_query_screen_wrap(slot: number): number;
263
+ zylem_stage_attach_ricochet(slot: number, dim: number, minSpeed: number, maxSpeed: number, speedMultiplier: number, maxAngleDeg: number, reflectionMode: number): number;
264
+ zylem_stage_query_ricochet(slot: number): number;
265
+ zylem_stage_attach_thruster(slot: number, maxSpeed: number, acceleration: number, turnRateRadS: number, linearDamping: number): number;
266
+ zylem_stage_set_thruster_input(slot: number, thrust: number, turn: number): void;
267
+ zylem_stage_query_thruster(slot: number): number;
268
+ zylem_stage_attach_top_down(slot: number, plane: number, speed: number, faceMovement: number): number;
269
+ zylem_stage_set_top_down_input(slot: number, a: number, b: number): void;
270
+ zylem_stage_attach_jumper_2d(slot: number, jumpForce: number, maxJumps: number, jumpBufferTime: number, coyoteTime: number, gravity: number): number;
271
+ zylem_stage_set_jumper_2d_input(slot: number, jumpPressed: number): void;
272
+ zylem_stage_query_jumper_2d(slot: number): number;
273
+ zylem_stage_attach_jumper_3d(slot: number, jumpForce: number, maxJumps: number, gravity: number): number;
274
+ zylem_stage_set_jumper_3d_input(slot: number, jump: number): void;
275
+ zylem_stage_query_jumper_3d(slot: number): number;
276
+ zylem_stage_attach_shooter_2d(slot: number, fireRateHz: number, muzzleOffsetX: number, muzzleOffsetY: number, muzzleSpeed: number): number;
277
+ zylem_stage_shooter_2d_fire(slot: number, x: number, y: number, z: number, yaw: number): number;
278
+ zylem_stage_query_shooter_2d(slot: number): number;
279
+ zylem_stage_attach_platformer_3d(slot: number, halfHeight: number, radius: number, walkSpeed: number, runSpeed: number, jumpForce: number, maxJumps: number, gravity: number): number;
280
+ zylem_stage_set_platformer_3d_input_axes(slot: number, moveX: number, moveZ: number): void;
281
+ zylem_stage_set_platformer_3d_input_buttons(slot: number, jump: number, run: number): void;
282
+ zylem_stage_query_platformer_3d(slot: number): number;
283
+ zylem_stage_attach_first_person(slot: number, walkSpeed: number, runSpeed: number, eyeHeight: number, lookSensitivity: number): number;
284
+ zylem_stage_set_first_person_input(slot: number, moveX: number, moveZ: number, lookYaw: number, lookPitch: number, run: number): void;
285
+ zylem_stage_query_first_person(slot: number): number;
286
+ zylem_stage_invalid_slot(): number;
287
+ }
288
+ /** Default options for `createWasmStageRuntime`. */
289
+ interface WasmStageRuntimeOptions {
290
+ initialCapacity?: number;
291
+ gravity?: readonly [number, number, number];
292
+ imports?: WebAssembly.Imports;
293
+ }
294
+ /**
295
+ * Owns the wasm instance plus the live float-views over its render / event /
296
+ * pose / scratch buffers. The instance is per-`ZylemStage`; each stage gets
297
+ * its own `WebAssembly.Instance` so the singleton inside `stage_ffi.rs`
298
+ * stays single-stage scoped (today's `thread_local!` contract).
299
+ */
300
+ declare class WasmStageRuntime {
301
+ readonly exports: StageWasmExports;
302
+ private readonly memory;
303
+ private renderView;
304
+ private eventView;
305
+ private poseView;
306
+ private vec3View;
307
+ private queryView;
308
+ private scratchView;
309
+ constructor(exports: StageWasmExports, options?: WasmStageRuntimeOptions);
310
+ /** Recreate typed views over wasm memory. Call after step() or whenever memory may have grown. */
311
+ refreshViews(): void;
312
+ /** Step the simulation by `dt` seconds. Refreshes views afterwards. */
313
+ step(dt: number): number;
314
+ dispose(): void;
315
+ get tickCount(): number;
316
+ get activeCount(): number;
317
+ setGravity(x: number, y: number, z: number): void;
318
+ createEntity(): number;
319
+ destroyEntity(slot: number): boolean;
320
+ attachBody(slot: number, config: StageBodyConfig): boolean;
321
+ addCollider(slot: number, config: StageColliderConfig): boolean;
322
+ private stageScratch;
323
+ private stageScratchIndices;
324
+ getPose(slot: number, out?: StagePose): StagePose | null;
325
+ setPosition(slot: number, x: number, y: number, z: number): boolean;
326
+ setRotation(slot: number, x: number, y: number, z: number, w: number): boolean;
327
+ setLinearVelocity(slot: number, x: number, y: number, z: number): boolean;
328
+ getLinearVelocity(slot: number, out?: [number, number, number]): [number, number, number] | null;
329
+ setAngularVelocity(slot: number, x: number, y: number, z: number): boolean;
330
+ applyImpulse(slot: number, x: number, y: number, z: number): boolean;
331
+ /** Read-only view over the render buffer; one slot occupies {@link STAGE_RENDER_STRIDE} floats. */
332
+ get render(): Float32Array;
333
+ get renderStride(): number;
334
+ /** Drain the wasm event buffer into a fresh array of typed events. */
335
+ drainEvents(): StageEvent[];
336
+ get queryScratch(): Float32Array;
337
+ attachCooldown(slot: number): boolean;
338
+ registerCooldown(slot: number, id: number, durationSeconds: number, immediate?: boolean): boolean;
339
+ fireCooldown(slot: number, id: number): boolean;
340
+ resetCooldown(slot: number, id: number): boolean;
341
+ cooldownRemaining(slot: number, id: number): number;
342
+ attachWorldBoundary(slot: number, dim: StageBoundaryDim, bounds: {
343
+ top: number;
344
+ bottom: number;
345
+ left: number;
346
+ right: number;
347
+ front: number;
348
+ back: number;
349
+ padding?: number;
350
+ }): boolean;
351
+ queryWorldBoundary(slot: number): {
352
+ hits: number;
353
+ clamped: [number, number, number];
354
+ } | null;
355
+ attachScreenWrap(slot: number, opts: {
356
+ width: number;
357
+ height: number;
358
+ centerX?: number;
359
+ centerY?: number;
360
+ edgeThreshold?: number;
361
+ }): boolean;
362
+ queryScreenWrap(slot: number): {
363
+ fsm: number;
364
+ lastWrappedAxes: number;
365
+ } | null;
366
+ attachRicochet(slot: number, dim: StageRicochetDim, opts: {
367
+ minSpeed: number;
368
+ maxSpeed: number;
369
+ speedMultiplier: number;
370
+ maxAngleDeg: number;
371
+ reflectionMode: StageRicochetReflection;
372
+ }): boolean;
373
+ queryRicochet(slot: number): {
374
+ bounces: number;
375
+ lastKind: number;
376
+ } | null;
377
+ attachThruster(slot: number, opts: {
378
+ maxSpeed: number;
379
+ acceleration: number;
380
+ turnRateRadPerSec: number;
381
+ linearDamping: number;
382
+ }): boolean;
383
+ setThrusterInput(slot: number, thrust: number, turn: number): void;
384
+ queryThruster(slot: number): {
385
+ headingRad: number;
386
+ speed: number;
387
+ } | null;
388
+ attachTopDown(slot: number, opts: {
389
+ plane: StageTopDownPlane;
390
+ speed: number;
391
+ faceMovement?: boolean;
392
+ }): boolean;
393
+ setTopDownInput(slot: number, axisA: number, axisB: number): void;
394
+ attachJumper2D(slot: number, opts: {
395
+ jumpForce: number;
396
+ maxJumps: number;
397
+ jumpBufferTime: number;
398
+ coyoteTime: number;
399
+ gravity: number;
400
+ }): boolean;
401
+ setJumper2DInput(slot: number, jumpPressed: boolean): void;
402
+ queryJumper2D(slot: number): {
403
+ grounded: boolean;
404
+ jumpCount: number;
405
+ coyote: number;
406
+ jumpBuffer: number;
407
+ } | null;
408
+ attachJumper3D(slot: number, opts: {
409
+ jumpForce: number;
410
+ maxJumps: number;
411
+ gravity: number;
412
+ }): boolean;
413
+ setJumper3DInput(slot: number, jump: boolean): void;
414
+ queryJumper3D(slot: number): {
415
+ grounded: boolean;
416
+ jumpCount: number;
417
+ verticalVelocity: number;
418
+ } | null;
419
+ attachShooter2D(slot: number, opts: {
420
+ fireRateHz: number;
421
+ muzzleOffsetX: number;
422
+ muzzleOffsetY: number;
423
+ muzzleSpeed: number;
424
+ }): boolean;
425
+ fireShooter2D(slot: number, x: number, y: number, z: number, yaw: number): boolean;
426
+ queryShooter2D(slot: number): {
427
+ cooldown: number;
428
+ firedCount: number;
429
+ } | null;
430
+ attachPlatformer3D(slot: number, opts: {
431
+ halfHeight: number;
432
+ radius: number;
433
+ walkSpeed: number;
434
+ runSpeed: number;
435
+ jumpForce: number;
436
+ maxJumps: number;
437
+ gravity: number;
438
+ }): boolean;
439
+ setPlatformer3DInputAxes(slot: number, moveX: number, moveZ: number): void;
440
+ setPlatformer3DInputButtons(slot: number, jump: boolean, run: boolean): void;
441
+ queryPlatformer3D(slot: number): {
442
+ grounded: boolean;
443
+ jumpCount: number;
444
+ fsmState: number;
445
+ speed: number;
446
+ } | null;
447
+ attachFirstPerson(slot: number, opts: {
448
+ walkSpeed: number;
449
+ runSpeed: number;
450
+ eyeHeight: number;
451
+ lookSensitivity: number;
452
+ }): boolean;
453
+ setFirstPersonInput(slot: number, opts: {
454
+ moveX: number;
455
+ moveZ: number;
456
+ lookYawDelta: number;
457
+ lookPitchDelta: number;
458
+ run: boolean;
459
+ }): void;
460
+ queryFirstPerson(slot: number): {
461
+ yaw: number;
462
+ pitch: number;
463
+ speed: number;
464
+ eyeHeight: number;
465
+ } | null;
466
+ }
467
+ /** Loads + instantiates a wasm module and constructs a `WasmStageRuntime`. */
468
+ declare function createWasmStageRuntime(source: RequestInfo | URL | ArrayBuffer, options?: WasmStageRuntimeOptions): Promise<WasmStageRuntime>;
469
+
470
+ /**
471
+ * Options for configuring entity collision behavior.
472
+ */
473
+ interface CollisionOptions {
474
+ static?: boolean;
475
+ sensor?: boolean;
476
+ size?: Vec3Input;
477
+ position?: Vec3Input;
478
+ collisionType?: string;
479
+ collisionFilter?: string[];
480
+ }
481
+ declare class CollisionBuilder {
482
+ static: boolean;
483
+ sensor: boolean;
484
+ gravity: Vec3;
485
+ build(options: Partial<CollisionOptions>): [RigidBodyDesc, ColliderDesc];
486
+ withCollision(collisionOptions: Partial<CollisionOptions>): this;
487
+ collider(options: CollisionOptions): ColliderDesc;
488
+ bodyDesc({ isDynamicBody }: {
489
+ isDynamicBody?: boolean | undefined;
490
+ }): RigidBodyDesc;
491
+ }
492
+
493
+ /**
494
+ * TODO: allow for multiple materials requires geometry groups
495
+ * TODO: allow for instanced uniforms
496
+ * TODO: allow for geometry groups
497
+ * TODO: allow for batched meshes
498
+ * import { InstancedUniformsMesh } from 'three-instanced-uniforms-mesh';
499
+ * may not need geometry groups for shaders though
500
+ * setGeometry<T extends BufferGeometry>(geometry: T) {
501
+ * MeshBuilder.bachedMesh = new BatchedMesh(10, 5000, 10000, material);
502
+ * }
503
+ */
504
+ type MeshBuilderOptions = Partial<Pick<GameEntityOptions, 'batched' | 'material'>>;
505
+ declare class MeshBuilder {
506
+ _build(meshOptions: MeshBuilderOptions, geometry: BufferGeometry, materials: Material[]): Mesh;
507
+ _postBuild(): void;
508
+ }
509
+
510
+ declare abstract class EntityCollisionBuilder extends CollisionBuilder {
511
+ abstract collider(options: GameEntityOptions): ColliderDesc;
512
+ }
513
+ declare abstract class EntityMeshBuilder extends MeshBuilder {
514
+ build(options: GameEntityOptions): BufferGeometry;
515
+ postBuild(): void;
516
+ }
517
+ declare abstract class EntityBuilder<T extends GameEntity<U> & P, U extends GameEntityOptions, P = any> {
518
+ protected meshBuilder: EntityMeshBuilder | null;
519
+ protected collisionBuilder: EntityCollisionBuilder | null;
520
+ protected materialBuilder: MaterialBuilder | null;
521
+ protected options: Partial<U>;
522
+ protected entity: T;
523
+ constructor(options: Partial<U>, entity: T, meshBuilder: EntityMeshBuilder | null, collisionBuilder: EntityCollisionBuilder | null);
524
+ withPosition(setupPosition: Vec3): this;
525
+ withMaterial(options: Partial<MaterialOptions>, entityType: symbol): this;
526
+ applyMaterialToGroup(group: Group, materials: Material[]): void;
527
+ build(): T;
528
+ protected abstract createEntity(options: Partial<U>): T;
529
+ }
530
+
531
+ interface RotatableEntity {
532
+ body: RigidBody | null;
533
+ group: any;
534
+ transformStore?: TransformState;
535
+ }
536
+ /**
537
+ * Rotate an entity in the direction of a movement vector
538
+ */
539
+ declare function rotateInDirection(entity: RotatableEntity, moveVector: Vector3): void;
540
+ /**
541
+ * Rotate an entity around the Y axis using Euler angles
542
+ */
543
+ declare function rotateYEuler(entity: RotatableEntity, amount: number): void;
544
+ /**
545
+ * Rotate an entity using Euler angles
546
+ */
547
+ declare function rotateEuler(entity: RotatableEntity, rotation: Vector3): void;
548
+ /**
549
+ * Rotate an entity around the Y axis.
550
+ */
551
+ declare function rotateY(entity: RotatableEntity, delta: number): void;
552
+ /**
553
+ * Rotate an entity around the X axis.
554
+ */
555
+ declare function rotateX(entity: RotatableEntity, delta: number): void;
556
+ /**
557
+ * Rotate an entity around the Z axis.
558
+ */
559
+ declare function rotateZ(entity: RotatableEntity, delta: number): void;
560
+ /**
561
+ * Set rotation around Y axis.
562
+ */
563
+ declare function setRotationY(entity: RotatableEntity, y: number): void;
564
+ /**
565
+ * Set rotation around Y axis
566
+ */
567
+ declare function setRotationDegreesY(entity: RotatableEntity, y: number): void;
568
+ /**
569
+ * Set rotation around X axis.
570
+ */
571
+ declare function setRotationX(entity: RotatableEntity, x: number): void;
572
+ /**
573
+ * Set rotation around X axis
574
+ */
575
+ declare function setRotationDegreesX(entity: RotatableEntity, x: number): void;
576
+ /**
577
+ * Set rotation around Z axis.
578
+ */
579
+ declare function setRotationZ(entity: RotatableEntity, z: number): void;
580
+ /**
581
+ * Set rotation around Z axis
582
+ */
583
+ declare function setRotationDegreesZ(entity: RotatableEntity, z: number): void;
584
+ /**
585
+ * Set rotation for all axes.
586
+ */
587
+ declare function setRotation(entity: RotatableEntity, x: number, y: number, z: number): void;
588
+ /**
589
+ * Set rotation for all axes
590
+ */
591
+ declare function setRotationDegrees(entity: RotatableEntity, x: number, y: number, z: number): void;
592
+ /**
593
+ * Get current rotation
594
+ */
595
+ declare function getRotation(entity: RotatableEntity): any;
596
+ /**
597
+ * Rotatable entity API with bound methods
598
+ */
599
+ interface RotatableEntityAPI extends RotatableEntity {
600
+ rotateInDirection(moveVector: Vector3): void;
601
+ rotateYEuler(amount: number): void;
602
+ rotateEuler(rotation: Vector3): void;
603
+ rotateY(delta: number): void;
604
+ rotateX(delta: number): void;
605
+ rotateZ(delta: number): void;
606
+ setRotationY(y: number): void;
607
+ setRotationX(x: number): void;
608
+ setRotationZ(z: number): void;
609
+ setRotationDegrees(x: number, y: number, z: number): void;
610
+ setRotationDegreesY(y: number): void;
611
+ setRotationDegreesX(x: number): void;
612
+ setRotationDegreesZ(z: number): void;
613
+ setRotation(x: number, y: number, z: number): void;
614
+ getRotation(): any;
615
+ }
616
+
617
+ /**
618
+ * A built collision component containing a rigid body description and collider description.
619
+ * Returned by collision factory functions (boxCollision, sphereCollision, etc.)
620
+ * and consumed by GameEntity.add().
621
+ */
622
+ interface CollisionComponent {
623
+ __kind: 'collision';
624
+ bodyDesc: RigidBodyDesc;
625
+ colliderDesc: ColliderDesc;
626
+ cloneComponent: () => CollisionComponent;
627
+ }
628
+ interface BaseCollisionOptions {
629
+ /** Whether the body is static (fixed) or dynamic */
630
+ static?: boolean;
631
+ /** Whether this collider is a sensor */
632
+ sensor?: boolean;
633
+ /** Position offset relative to the entity origin */
634
+ offset?: Vec3Input;
635
+ /** Collision type string for group filtering */
636
+ collisionType?: string;
637
+ /** Allowed collision types for filtering */
638
+ collisionFilter?: string[];
639
+ }
640
+ interface BoxCollisionOptions extends BaseCollisionOptions {
641
+ /** Box dimensions (default: 1x1x1) */
642
+ size?: Vec3Input;
643
+ }
644
+ /**
645
+ * Create a box (cuboid) collision component.
646
+ */
647
+ declare function boxCollision(opts?: BoxCollisionOptions): CollisionComponent;
648
+ interface SphereCollisionOptions extends BaseCollisionOptions {
649
+ /** Sphere radius (default: 1) */
650
+ radius?: number;
651
+ }
652
+ /**
653
+ * Create a sphere (ball) collision component.
654
+ */
655
+ declare function sphereCollision(opts?: SphereCollisionOptions): CollisionComponent;
656
+ interface ConeCollisionOptions extends BaseCollisionOptions {
657
+ /** Base radius (default: 1) */
658
+ radius?: number;
659
+ /** Height (default: 2) */
660
+ height?: number;
661
+ }
662
+ /**
663
+ * Create a cone collision component.
664
+ */
665
+ declare function coneCollision(opts?: ConeCollisionOptions): CollisionComponent;
666
+ interface PyramidCollisionOptions extends BaseCollisionOptions {
667
+ /** Base radius (default: 1) */
668
+ radius?: number;
669
+ /** Height (default: 2) */
670
+ height?: number;
671
+ }
672
+ /**
673
+ * Create a pyramid collision component (approximated as a cone).
674
+ */
675
+ declare function pyramidCollision(opts?: PyramidCollisionOptions): CollisionComponent;
676
+ interface CylinderCollisionOptions extends BaseCollisionOptions {
677
+ /** Top radius (default: 1) */
678
+ radiusTop?: number;
679
+ /** Bottom radius (default: 1) */
680
+ radiusBottom?: number;
681
+ /** Height (default: 2) */
682
+ height?: number;
683
+ }
684
+ /**
685
+ * Create a cylinder collision component.
686
+ */
687
+ declare function cylinderCollision(opts?: CylinderCollisionOptions): CollisionComponent;
688
+ interface PillCollisionOptions extends BaseCollisionOptions {
689
+ /** Capsule hemisphere radius (default: 0.5) */
690
+ radius?: number;
691
+ /** Cylindrical section length (default: 1) */
692
+ length?: number;
693
+ }
694
+ /**
695
+ * Create a pill (capsule) collision component.
696
+ */
697
+ declare function pillCollision(opts?: PillCollisionOptions): CollisionComponent;
698
+ interface PlaneCollisionOptions extends BaseCollisionOptions {
699
+ /** Tile dimensions (default: 10x10) */
700
+ tile?: Vec2Input;
701
+ /** Number of subdivisions per axis (default: 10) */
702
+ subdivisions?: number;
703
+ /** Pre-computed height data for the heightfield */
704
+ heightData?: Float32Array;
705
+ }
706
+ /**
707
+ * Create a plane (heightfield) collision component.
708
+ * For flat planes, pass no heightData — a zeroed heightfield is used.
709
+ */
710
+ declare function planeCollision(opts?: PlaneCollisionOptions): CollisionComponent;
711
+ interface ZoneCollisionOptions extends BaseCollisionOptions {
712
+ /** Zone dimensions (default: 1x1x1) */
713
+ size?: Vec3Input;
714
+ }
715
+ /**
716
+ * Create a zone (sensor cuboid) collision component.
717
+ * Always a sensor; static by default.
718
+ */
719
+ declare function zoneCollision(opts?: ZoneCollisionOptions): CollisionComponent;
720
+
721
+ /**
722
+ * Action interface -- the base contract for all actions.
723
+ *
724
+ * Actions are entity-scoped, self-contained objects that modify entity state
725
+ * over time. They are ticked automatically by the entity update loop.
726
+ */
727
+ interface Action {
728
+ /** Internal duration in seconds (0 = instant, Infinity = persistent) */
729
+ readonly duration: number;
730
+ /** Whether this action has completed */
731
+ readonly done: boolean;
732
+ /** Whether this action auto-removes when done (set by entity.action()) */
733
+ persistent: boolean;
734
+ /** Advance the action by delta seconds */
735
+ tick(entity: GameEntity<any>, delta: number): void;
736
+ /** Reset the action to its initial state */
737
+ reset(): void;
738
+ }
739
+
740
+ interface CollisionContext<T, O extends GameEntityOptions, TGlobals extends Record<string, unknown> = any> {
741
+ entity: T;
742
+ other: GameEntity<O | any>;
743
+ globals: TGlobals;
744
+ }
745
+ type CollisionPhase = 'enter' | 'stay';
746
+ interface CollisionRegistrationOptions {
747
+ phase?: CollisionPhase;
748
+ cooldownMs?: number;
749
+ }
750
+ interface NormalizedCollisionRegistrationOptions {
751
+ phase: CollisionPhase;
752
+ cooldownMs?: number;
753
+ }
754
+ interface CollisionRegistration<T, O extends GameEntityOptions> {
755
+ id: number;
756
+ callback: (params: CollisionContext<T, O>) => void;
757
+ options: NormalizedCollisionRegistrationOptions;
758
+ }
759
+ interface CollisionDispatchMetadata {
760
+ phase: CollisionPhase;
761
+ nowMs: number;
762
+ }
763
+ interface CollisionDelegate<T, O extends GameEntityOptions> {
764
+ collision?: CollisionRegistration<any, any>[];
765
+ cooldowns?: Map<string, number>;
766
+ nextId?: number;
767
+ }
768
+ type IBuilder<BuilderOptions = any> = {
769
+ preBuild: (options: BuilderOptions) => BuilderOptions;
770
+ build: (options: BuilderOptions) => BuilderOptions;
771
+ postBuild: (options: BuilderOptions) => BuilderOptions;
772
+ };
773
+ type GameEntitySimulationMode = 'ts' | 'runtime';
774
+ type GameEntityRenderMode = 'mesh' | 'instanced';
775
+ type RuntimeEntityBodyMode = 'dynamic' | 'static' | 'none';
776
+ type RuntimeEntityColorMode = 'base' | 'heatTint';
777
+ interface RuntimeEntityOptions {
778
+ simulation?: GameEntitySimulationMode;
779
+ render?: GameEntityRenderMode;
780
+ batchKeyOverride?: string;
781
+ body?: RuntimeEntityBodyMode;
782
+ colorMode?: RuntimeEntityColorMode;
783
+ }
784
+ type GameEntityOptions = {
785
+ name?: string;
786
+ color?: Color;
787
+ size?: Vec3Input;
788
+ position?: Vec3Input;
789
+ batched?: boolean;
790
+ runtime?: RuntimeEntityOptions;
791
+ collision?: Partial<CollisionOptions>;
792
+ material?: Partial<MaterialOptions>;
793
+ custom?: {
794
+ [key: string]: any;
795
+ };
796
+ collisionType?: string;
797
+ collisionGroup?: string;
798
+ collisionFilter?: string[];
799
+ _builders?: {
800
+ meshBuilder?: IBuilder | EntityMeshBuilder | null;
801
+ collisionBuilder?: IBuilder | EntityCollisionBuilder | null;
802
+ materialBuilder?: MaterialBuilder | null;
803
+ };
804
+ };
805
+ declare abstract class GameEntityLifeCycle {
806
+ abstract _setup(params: SetupContext<this>): void;
807
+ abstract _update(params: UpdateContext<this>): void;
808
+ abstract _destroy(params: DestroyContext<this>): void;
809
+ }
810
+ interface EntityDebugInfo {
811
+ buildInfo: () => Record<string, string>;
812
+ }
813
+ declare class GameEntity<O extends GameEntityOptions> extends BaseNode<O> implements GameEntityLifeCycle, EntityDebugInfo, MoveableEntity, RotatableEntityAPI {
814
+ group: Group | undefined;
815
+ mesh: Mesh | undefined;
816
+ materials: Material[] | undefined;
817
+ bodyDesc: RigidBodyDesc | null;
818
+ body: RigidBody | null;
819
+ physicsAttached: boolean;
820
+ colliderDesc: ColliderDesc | undefined;
821
+ collider: Collider | undefined;
822
+ custom: Record<string, any>;
823
+ /** All collider descriptions for this entity (including primary) */
824
+ colliderDescs: ColliderDesc[];
825
+ /** All colliders attached to this entity's rigid body */
826
+ colliders: Collider[];
827
+ /** Additional meshes for compound visual entities (added via add()) */
828
+ compoundMeshes: Mesh[];
829
+ debugInfo: Record<string, any>;
830
+ debugMaterial: ShaderMaterial | undefined;
831
+ collisionDelegate: CollisionDelegate<this, O>;
832
+ collisionType?: string;
833
+ /** Batch key for instanced rendering (null if not instanced) */
834
+ batchKey: string | null;
835
+ /** Index within the instanced mesh batch */
836
+ instanceId: number;
837
+ /** Whether this entity uses instanced rendering */
838
+ isInstanced: boolean;
839
+ /** Runtime slot index when owned by a stage runtime adapter (legacy alias for runtimeHandle). */
840
+ runtimeSlot: number;
841
+ /**
842
+ * Stable u32 handle into the wasm `StageSimulation`. Returned by
843
+ * `WasmStageRuntime.createEntity()`; -1 means the entity is not currently
844
+ * attached to the runtime. Replaces `runtimeSlot` and the legacy
845
+ * `entity.body` / `entity.collider` fields once Phase 3 lands.
846
+ */
847
+ runtimeHandle: number;
848
+ /** True once the entity has been attached to the wasm `StageSimulation`. */
849
+ runtimeAttached: boolean;
850
+ /**
851
+ * Optional reference to the stage's {@link WasmStageRuntime}. Set by
852
+ * `StageEntityDelegate.spawnEntity()` so {@link GameEntity.getPose} /
853
+ * {@link GameEntity.setPose} can route through the unified-Stage runtime
854
+ * without each call site needing to thread the wasm handle around.
855
+ */
856
+ wasmStageRef: WasmStageRuntime | null;
857
+ protected eventDelegate: EventEmitterDelegate<EntityEvents>;
858
+ private behaviorRefs;
859
+ private cloneFactory;
860
+ private trackAddedComponents;
861
+ private trackedComponents;
862
+ transformStore: TransformState;
863
+ moveX: (delta: number) => void;
864
+ moveY: (delta: number) => void;
865
+ moveZ: (delta: number) => void;
866
+ moveXY: (deltaX: number, deltaY: number) => void;
867
+ moveXZ: (deltaX: number, deltaZ: number) => void;
868
+ move: (vector: Vector3) => void;
869
+ resetVelocity: () => void;
870
+ moveForwardXY: (delta: number, rotation2DAngle: number) => void;
871
+ getPosition: () => Vector | null;
872
+ getVelocity: () => Vector | null;
873
+ setPosition: (x: number, y: number, z: number) => void;
874
+ setPositionX: (x: number) => void;
875
+ setPositionY: (y: number) => void;
876
+ setPositionZ: (z: number) => void;
877
+ wrapAroundXY: (boundsX: number, boundsY: number) => void;
878
+ wrapAround3D: (boundsX: number, boundsY: number, boundsZ: number) => void;
879
+ rotateInDirection: (moveVector: Vector3) => void;
880
+ rotateYEuler: (amount: number) => void;
881
+ rotateEuler: (eulerRotation: Vector3) => void;
882
+ rotateX: (delta: number) => void;
883
+ rotateY: (delta: number) => void;
884
+ rotateZ: (delta: number) => void;
885
+ setRotationY: (y: number) => void;
886
+ setRotationX: (x: number) => void;
887
+ setRotationZ: (z: number) => void;
888
+ setRotationDegrees: (x: number, y: number, z: number) => void;
889
+ setRotationDegreesY: (y: number) => void;
890
+ setRotationDegreesX: (x: number) => void;
891
+ setRotationDegreesZ: (z: number) => void;
892
+ setRotation: (x: number, y: number, z: number) => void;
893
+ getRotation: () => any;
894
+ constructor();
895
+ /**
896
+ * Read the entity's pose. Prefers the unified-Stage wasm runtime when
897
+ * the entity has a live `runtimeHandle`; otherwise falls back to the
898
+ * legacy TS Rapier `RigidBody` translation/rotation. Returns `null` when
899
+ * neither source is available.
900
+ */
901
+ getPose(): {
902
+ position: Vec3;
903
+ rotation: {
904
+ x: number;
905
+ y: number;
906
+ z: number;
907
+ w: number;
908
+ };
909
+ } | null;
910
+ /**
911
+ * Write the entity's pose. Routes through the unified-Stage wasm runtime
912
+ * when present; otherwise writes to the legacy TS Rapier `RigidBody`.
913
+ *
914
+ * Either or both of `position` and `rotation` may be omitted to leave
915
+ * that component unchanged.
916
+ */
917
+ setPose(input: {
918
+ position?: Vec3Input;
919
+ rotation?: {
920
+ x: number;
921
+ y: number;
922
+ z: number;
923
+ w: number;
924
+ };
925
+ }): boolean;
926
+ /**
927
+ * Add meshes, collision components, or child entities to this entity.
928
+ * Supports fluent chaining: `entity.add(boxMesh()).add(boxCollision())`.
929
+ *
930
+ * - `Mesh`: First mesh becomes the primary mesh; subsequent meshes are
931
+ * compound meshes grouped together.
932
+ * - `CollisionComponent`: First sets bodyDesc + colliderDesc; subsequent
933
+ * add extra colliders to the same rigid body.
934
+ * - `NodeInterface`: Added as a child entity (delegates to BaseNode.add).
935
+ */
936
+ add(...components: Array<NodeInterface | Mesh | CollisionComponent>): this;
937
+ private addMeshComponent;
938
+ private addCollisionComponent;
939
+ private trackComponent;
940
+ private _actions;
941
+ /**
942
+ * Run a fire-and-forget action. Auto-removed when done.
943
+ * @example `me.runAction(moveBy({ x: 10, duration: 0.3 }))`
944
+ */
945
+ runAction<A extends Action>(action: A): A;
946
+ /**
947
+ * Register a persistent action (throttle, onPress). Not removed when done.
948
+ * @example `const press = entity.action(onPress())`
949
+ */
950
+ action<A extends Action>(action: A): A;
951
+ /** Remove all registered actions (fire-and-forget and persistent). */
952
+ clearActions(): void;
953
+ /**
954
+ * Tick all registered actions. Called automatically before user onUpdate callbacks.
955
+ *
956
+ * Resets velocity/angularVelocity accumulation before ticking so that
957
+ * actions can compose via `+=` without cross-frame build-up.
958
+ * (The existing move helpers like `moveXY` use `=` which doesn't accumulate,
959
+ * but action composition needs additive writes on a clean slate each frame.)
960
+ */
961
+ _tickActions(delta: number): void;
962
+ create(): this;
963
+ clone(overrides?: Partial<O>): this;
964
+ finalizeCloneSupport(factory: (options?: Partial<O>) => GameEntity<O>): this;
965
+ /**
966
+ * Add collision callbacks
967
+ */
968
+ onCollision(callback: (params: CollisionContext<this, O>) => void, options?: CollisionRegistrationOptions): this;
969
+ onCollision(...callbacks: ((params: CollisionContext<this, O>) => void)[]): this;
970
+ /**
971
+ * Use a behavior on this entity via typed descriptor.
972
+ * Behaviors will be auto-registered as systems when the entity is spawned.
973
+ * @param descriptor The behavior descriptor (import from behaviors module)
974
+ * @param options Optional overrides for the behavior's default options
975
+ * @returns BehaviorHandle with behavior-specific methods for lazy FSM access
976
+ */
977
+ use<O extends Record<string, any>, H extends Record<string, any> = Record<string, never>>(descriptor: BehaviorDescriptor<O, H>, options?: Partial<O>): BehaviorHandle<O, H>;
978
+ /**
979
+ * Get all behavior references attached to this entity.
980
+ * Used by the stage to auto-register required systems.
981
+ */
982
+ getBehaviorRefs(): BehaviorRef[];
983
+ getCollisionCallbacks(): Array<(params: CollisionContext<this, O>) => void>;
984
+ getCollisionRegistrations(): Array<CollisionRegistration<this, O>>;
985
+ private copyBehaviorRefsTo;
986
+ /**
987
+ * Entity-specific setup - resets actions for a fresh stage session.
988
+ * (User callbacks are handled by BaseNode's lifecycleCallbacks.setup)
989
+ */
990
+ _setup(params: SetupContext<this>): void;
991
+ protected _loaded(_params: LoadedContext<this>): Promise<void>;
992
+ /**
993
+ * Entity-specific update - updates materials.
994
+ * Transform changes are applied by the stage after all update callbacks complete.
995
+ * (User callbacks are handled by BaseNode's lifecycleCallbacks.update)
996
+ */
997
+ _update(params: UpdateContext<this>): void;
998
+ /**
999
+ * Entity-specific destroy -- reserved for consumer game logic.
1000
+ * Engine-internal resource disposal runs in _cleanup() instead.
1001
+ */
1002
+ _destroy(params: DestroyContext<this>): void;
1003
+ /**
1004
+ * Engine-internal resource cleanup -- runs automatically after destroy.
1005
+ * Disposes GPU/DOM resources (meshes, materials, debug material).
1006
+ *
1007
+ * Note: actions, collision callbacks, and behavior refs are intentionally
1008
+ * NOT cleared here -- they are registered by consumer code at module level
1009
+ * and must persist across stage reloads. Actions are reset in _setup().
1010
+ */
1011
+ protected _cleanup(_params: CleanupContext<this>): void;
1012
+ _collision(other: GameEntity<O>, globals?: any, dispatch?: CollisionDispatchMetadata): void;
1013
+ protected updateMaterials(params: any): void;
1014
+ buildInfo(): Record<string, string>;
1015
+ /**
1016
+ * Dispatch an event from this entity.
1017
+ * Events are emitted both locally and to the global event bus.
1018
+ */
1019
+ dispatch<K extends keyof EntityEvents>(event: K, payload: EntityEvents[K]): void;
1020
+ /**
1021
+ * Listen for events on this entity instance.
1022
+ * @returns Unsubscribe function
1023
+ */
1024
+ listen<K extends keyof EntityEvents>(event: K, handler: (payload: EntityEvents[K]) => void): () => void;
1025
+ /**
1026
+ * Clean up entity event subscriptions.
1027
+ */
1028
+ disposeEvents(): void;
1029
+ }
1030
+ /**
1031
+ * Create a bare entity with no mesh or collision.
1032
+ * Use `.add(boxMesh(), boxCollision())` to compose its shape.
1033
+ *
1034
+ * @example
1035
+ * ```ts
1036
+ * const box = create({ position: { x: 0, y: 5, z: 0 } })
1037
+ * .add(boxMesh({ size: { x: 2, y: 2, z: 2 } }))
1038
+ * .add(boxCollision({ size: { x: 2, y: 2, z: 2 } }));
1039
+ * ```
1040
+ */
1041
+ declare function create(options?: Partial<GameEntityOptions>): GameEntity<GameEntityOptions>;
1042
+
1043
+ export { type Action as A, setRotationDegrees as B, setRotationDegreesY as C, setRotationDegreesX as D, setRotationDegreesZ as E, setRotation as F, GameEntity as G, getRotation as H, type GameEntityOptions as I, EntityBuilder as J, EntityMeshBuilder as K, EntityCollisionBuilder as L, BaseNode as M, create as N, boxCollision as O, sphereCollision as P, coneCollision as Q, pyramidCollision as R, StageBodyKind as S, cylinderCollision as T, pillCollision as U, planeCollision as V, type WasmStageRuntimeOptions as W, zoneCollision as X, type CollisionComponent as Y, type NodeInterface as Z, GameEntityLifeCycle as _, type StageBodyConfig as a, type StageColliderConfig as b, type StageColliderShape as c, type StageEvent as d, type StagePose as e, type StageWasmExports as f, StageBoundaryDim as g, StageEventType as h, StageRicochetDim as i, StageRicochetReflection as j, StageTopDownPlane as k, STAGE_EVENT_STRIDE as l, STAGE_INVALID_SLOT as m, STAGE_POSE_LEN as n, STAGE_RENDER_STRIDE as o, WasmStageRuntime as p, createWasmStageRuntime as q, rotateInDirection as r, rotateYEuler as s, rotateEuler as t, rotateX as u, rotateY as v, rotateZ as w, setRotationY as x, setRotationX as y, setRotationZ as z };