@series-inc/rundot-3d-engine 0.3.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 (38) hide show
  1. package/LICENSE.txt +6 -0
  2. package/README.md +80 -0
  3. package/dist/ComponentRegistry-V_7WauAE.d.ts +448 -0
  4. package/dist/chunk-ZNDJR3RD.js +5623 -0
  5. package/dist/chunk-ZNDJR3RD.js.map +1 -0
  6. package/dist/index.d.ts +1484 -0
  7. package/dist/index.js +1390 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/systems/index.d.ts +3356 -0
  10. package/dist/systems/index.js +9652 -0
  11. package/dist/systems/index.js.map +1 -0
  12. package/docs/core/Component.md +321 -0
  13. package/docs/core/GameObject.md +204 -0
  14. package/docs/core/VenusGame.md +316 -0
  15. package/docs/patterns/ComponentCommunication.md +337 -0
  16. package/docs/patterns/CreatingGameObjects.md +290 -0
  17. package/docs/patterns/MeshColliders.md +338 -0
  18. package/docs/patterns/MeshLoading.md +316 -0
  19. package/docs/physics/Colliders.md +249 -0
  20. package/docs/physics/PhysicsSystem.md +151 -0
  21. package/docs/physics/RigidBodyComponent.md +201 -0
  22. package/docs/rendering/AssetManager.md +308 -0
  23. package/docs/rendering/InstancedRenderer.md +286 -0
  24. package/docs/rendering/MeshRenderer.md +286 -0
  25. package/docs/rendering/SkeletalRenderer.md +308 -0
  26. package/docs/systems/AnimationSystem.md +75 -0
  27. package/docs/systems/AudioSystem.md +79 -0
  28. package/docs/systems/InputManager.md +101 -0
  29. package/docs/systems/LightingSystem.md +101 -0
  30. package/docs/systems/NavigationSystem.md +246 -0
  31. package/docs/systems/ParticleSystem.md +44 -0
  32. package/docs/systems/PrefabSystem.md +60 -0
  33. package/docs/systems/SplineSystem.md +194 -0
  34. package/docs/systems/StowKitSystem.md +77 -0
  35. package/docs/systems/TweenSystem.md +132 -0
  36. package/docs/systems/UISystem.md +73 -0
  37. package/package.json +62 -0
  38. package/scripts/postinstall.mjs +51 -0
package/LICENSE.txt ADDED
@@ -0,0 +1,6 @@
1
+ By downloading, copying, or using this template, you agree to the
2
+ RUN.game Terms of Service:
3
+
4
+ https://policy.run.game/eula.html
5
+
6
+ © Series Inc. All rights reserved.
package/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # Run.3DEngine
2
+
3
+ A Three.js-based game engine with ECS architecture, physics, navigation, and comprehensive game systems.
4
+
5
+ ## Features
6
+
7
+ - **ECS Architecture**: Component-based GameObject system
8
+ - **Physics**: Rapier3D integration with RigidBody components
9
+ - **Navigation**: Dynamic navigation system with A* pathfinding
10
+ - **Animation**: Advanced animation system with blending and retargeting
11
+ - **Audio**: 2D/3D audio system with music management
12
+ - **UI**: Comprehensive UI system with utilities
13
+ - **Camera**: Follow camera, free camera with smooth transitions
14
+ - **Asset Loading**: FBX, GLB, OBJ loaders with skeleton caching
15
+ - **Particles**: Flexible particle system
16
+ - **Input**: Cross-platform input management with mobile support
17
+
18
+ ## Installation
19
+
20
+ ### As npm workspace dependency
21
+ ```json
22
+ {
23
+ "dependencies": {
24
+ "@series-ai/rundot-3d-engine": "^0.2.0"
25
+ }
26
+ }
27
+ ```
28
+
29
+ ### As git submodule
30
+ ```bash
31
+ git submodule add https://github.com/series-ai/Run.3DEngine.git rundot-3D-engine
32
+ git submodule update --init --recursive
33
+ ```
34
+
35
+ ## Usage
36
+
37
+ ```typescript
38
+ import { VenusGame, GameObject, Component } from "@series-ai/rundot-3d-engine"
39
+ import { PhysicsSystem, UISystem } from "@series-ai/rundot-3d-engine/systems"
40
+
41
+ class MyGame extends VenusGame {
42
+ async onCreate(): Promise<void> {
43
+ // Initialize game
44
+ }
45
+
46
+ async onStart(): Promise<void> {
47
+ // Start game logic
48
+ }
49
+ }
50
+ ```
51
+
52
+ ## Dependencies
53
+
54
+ - **three** ^0.180.0
55
+ - **@dimforge/rapier3d** ^0.11.2
56
+ - **@series-inc/rundot-game-sdk** 5.0.4
57
+ - **@stowkit/reader** ^0.1.39
58
+ - **@stowkit/three-loader** ^0.1.40
59
+
60
+ ## Development
61
+
62
+ ```bash
63
+ # Install dependencies
64
+ npm install
65
+
66
+ # Build
67
+ npm run build
68
+
69
+ # Watch mode
70
+ npm run dev
71
+
72
+ # Lint
73
+ npm run lint
74
+ ```
75
+
76
+ ## License
77
+
78
+ See LICENSE file in root repository.
79
+
80
+
@@ -0,0 +1,448 @@
1
+ import * as THREE from 'three';
2
+ import { RigidBody, Collider } from '@dimforge/rapier3d';
3
+
4
+ /**
5
+ * Three.js version of GameObject
6
+ * Clean implementation without Babylon.js dependencies
7
+ */
8
+ declare class GameObject extends THREE.Object3D {
9
+ private components;
10
+ private isDestroyed;
11
+ private static idCounter;
12
+ /**
13
+ * Create a new Three.js GameObject
14
+ * @param name Optional name for the GameObject. If not provided, an auto-generated name will be used.
15
+ */
16
+ constructor(name?: string);
17
+ /**
18
+ * Adds a component instance to the GameObject
19
+ * @returns The component instance
20
+ * @throws If component of same type already exists
21
+ */
22
+ addComponent<T extends Component>(component: T): T;
23
+ /**
24
+ * Gets a component of the specified type
25
+ * @returns The component if found, undefined otherwise
26
+ */
27
+ getComponent<T extends Component>(componentType: new (...args: any[]) => T): T | undefined;
28
+ /**
29
+ * Checks if the GameObject has a component of the specified type
30
+ */
31
+ hasComponent<T extends Component>(componentType: new (...args: any[]) => T): boolean;
32
+ /**
33
+ * Removes a component of the specified type
34
+ * @returns true if component was found and removed
35
+ */
36
+ removeComponent<T extends Component>(componentType: new (...args: any[]) => T): boolean;
37
+ /**
38
+ * Disposes of the GameObject and all its components
39
+ */
40
+ dispose(): void;
41
+ /**
42
+ * Get the Three.js scene the GameObject is in
43
+ */
44
+ getScene(): THREE.Scene;
45
+ /**
46
+ * Three.js equivalent of setEnabled - uses visible property
47
+ */
48
+ setEnabled(value: boolean): void;
49
+ /**
50
+ * Three.js equivalent of isEnabled - checks visible property AND parent hierarchy
51
+ */
52
+ isEnabled(): boolean;
53
+ /**
54
+ * Override THREE.Object3D.add() to handle enabled state propagation
55
+ * When adding a child to a disabled parent, the child should be effectively disabled too
56
+ */
57
+ add(...objects: THREE.Object3D[]): this;
58
+ /**
59
+ * Recursively notify all children that their enabled state may have changed
60
+ */
61
+ protected notifyChildrenEnabledStateChanged(): void;
62
+ /**
63
+ * Internal method to trigger enabled state change notifications
64
+ * This causes components to receive onEnabled/onDisabled callbacks
65
+ */
66
+ protected notifyEnabledStateChanged(isEnabled: boolean): void;
67
+ }
68
+ /**
69
+ * Three.js Component base class
70
+ * Clean implementation without Babylon.js dependencies
71
+ */
72
+ declare abstract class Component {
73
+ protected gameObject: GameObject;
74
+ private _isAttached;
75
+ /**
76
+ * Get the GameObject this component is attached to
77
+ */
78
+ getGameObject(): GameObject;
79
+ /**
80
+ * Get the scene the GameObject is in
81
+ */
82
+ protected get scene(): THREE.Scene;
83
+ /**
84
+ * Attach this component to a GameObject
85
+ * @internal Called by GameObject.addComponent
86
+ */
87
+ attach(gameObject: GameObject): void;
88
+ /**
89
+ * Clean up this component
90
+ * @internal Called by GameObject when removing component
91
+ */
92
+ cleanup(): void;
93
+ /**
94
+ * Called when the component is first added to a GameObject
95
+ * Override this method to implement component initialization
96
+ */
97
+ protected onCreate(): void;
98
+ /**
99
+ * Called when the component is being removed/destroyed
100
+ * Override this method to implement component cleanup
101
+ */
102
+ protected onCleanup(): void;
103
+ /**
104
+ * Called when the GameObject becomes enabled
105
+ * Override this method to react to enable state changes
106
+ */
107
+ onEnabled(): void;
108
+ /**
109
+ * Called when the GameObject becomes disabled
110
+ * Override this method to react to enable state changes
111
+ */
112
+ onDisabled(): void;
113
+ /**
114
+ * Called every frame if the component's GameObject is enabled
115
+ * Override this method to implement per-frame logic
116
+ * @param deltaTime Time in seconds since last frame
117
+ */
118
+ update?(deltaTime: number): void;
119
+ /**
120
+ * Called every frame after all update() calls have completed
121
+ * Perfect for camera movement, UI updates, and anything that should happen last
122
+ * @param deltaTime Time in seconds since last frame
123
+ */
124
+ lateUpdate?(deltaTime: number): void;
125
+ /**
126
+ * Check if the component is attached to a GameObject
127
+ */
128
+ isAttached(): boolean;
129
+ /**
130
+ * Gets a component of the specified type from the same GameObject
131
+ * @returns The component if found, undefined otherwise
132
+ */
133
+ getComponent<T extends Component>(componentType: new (...args: any[]) => T): T | undefined;
134
+ }
135
+
136
+ /**
137
+ * Animation Culling Manager
138
+ * Handles frustum culling and distance-based optimization for animated characters
139
+ */
140
+ declare class AnimationCullingManager {
141
+ private static instance;
142
+ private cameras;
143
+ private primaryCamera;
144
+ private readonly frustum;
145
+ private readonly projScreenMatrix;
146
+ private readonly _tempSphere;
147
+ private readonly _tempBox;
148
+ private readonly _tempVec;
149
+ private frustumCullingEnabled;
150
+ private distanceCullingEnabled;
151
+ private maxUpdateDistance;
152
+ private lodDistance;
153
+ private frustumExpansion;
154
+ private frameCounter;
155
+ private constructor();
156
+ static getInstance(): AnimationCullingManager;
157
+ /**
158
+ * Add a camera for frustum culling
159
+ */
160
+ addCamera(camera: THREE.Camera, isPrimary?: boolean): void;
161
+ /**
162
+ * Remove a camera from culling
163
+ */
164
+ removeCamera(camera: THREE.Camera): void;
165
+ /**
166
+ * Set the primary camera (used for distance calculations)
167
+ */
168
+ setPrimaryCamera(camera: THREE.Camera): void;
169
+ /**
170
+ * Enable/disable frustum culling
171
+ */
172
+ setFrustumCullingEnabled(enabled: boolean): void;
173
+ /**
174
+ * Enable/disable distance-based culling
175
+ */
176
+ setDistanceCullingEnabled(enabled: boolean): void;
177
+ /**
178
+ * Set the maximum distance for animation updates
179
+ */
180
+ setMaxUpdateDistance(distance: number): void;
181
+ /**
182
+ * Set the LOD distance threshold
183
+ */
184
+ setLodDistance(distance: number): void;
185
+ /**
186
+ * Set the frustum expansion factor.
187
+ * Values > 1.0 expand the frustum to avoid pop-in when characters enter view.
188
+ * Default is 1.2 (20% larger frustum)
189
+ */
190
+ setFrustumExpansion(factor: number): void;
191
+ /**
192
+ * Call once per frame before animation updates
193
+ */
194
+ beginFrame(): void;
195
+ /**
196
+ * Check if an object should have its animation updated this frame
197
+ * @param object The object containing the animated model
198
+ * @param boundingRadius Optional bounding radius for frustum check (default 2 units)
199
+ * @returns { shouldUpdate: boolean, isLod: boolean }
200
+ */
201
+ shouldUpdateAnimation(object: THREE.Object3D, boundingRadius?: number): {
202
+ shouldUpdate: boolean;
203
+ isLod: boolean;
204
+ };
205
+ /**
206
+ * Get debug stats
207
+ */
208
+ getStats(): {
209
+ cameraCount: number;
210
+ frustumCullingEnabled: boolean;
211
+ distanceCullingEnabled: boolean;
212
+ frameCounter: number;
213
+ };
214
+ }
215
+
216
+ declare enum RigidBodyType {
217
+ DYNAMIC = "dynamic",
218
+ STATIC = "static",
219
+ KINEMATIC = "kinematic"
220
+ }
221
+ declare enum ColliderShape {
222
+ BOX = "box",
223
+ SPHERE = "sphere",
224
+ CAPSULE = "capsule"
225
+ }
226
+ declare function createCollisionGroup(membership: number, filter: number): number;
227
+ interface RigidBodyOptions {
228
+ type?: RigidBodyType;
229
+ shape?: ColliderShape;
230
+ size?: THREE.Vector3;
231
+ radius?: number;
232
+ height?: number;
233
+ mass?: number;
234
+ restitution?: number;
235
+ friction?: number;
236
+ isSensor?: boolean;
237
+ fitToMesh?: boolean;
238
+ centerOffset?: THREE.Vector3;
239
+ linearDamping?: number;
240
+ angularDamping?: number;
241
+ lockRotationX?: boolean;
242
+ lockRotationY?: boolean;
243
+ lockRotationZ?: boolean;
244
+ lockTranslationX?: boolean;
245
+ lockTranslationY?: boolean;
246
+ lockTranslationZ?: boolean;
247
+ enableCollisionEvents?: boolean;
248
+ collisionGroups?: number;
249
+ }
250
+ /**
251
+ * Simple component for adding Rapier physics to GameObjects
252
+ * Automatically syncs GameObject position with physics body
253
+ */
254
+ declare class RigidBodyComponentThree extends Component {
255
+ private rigidBody;
256
+ private collider;
257
+ private options;
258
+ private bodyId;
259
+ private onTriggerEnterCallback;
260
+ private onTriggerExitCallback;
261
+ private isRegisteredWithPhysics;
262
+ constructor(options?: RigidBodyOptions);
263
+ protected onCreate(): void;
264
+ private createPhysicsBody;
265
+ /**
266
+ * Update syncs between GameObject and physics body based on rigidbody type
267
+ * - DYNAMIC: Physics drives GameObject position (physics simulation)
268
+ * - KINEMATIC: GameObject drives physics position (nav agents, scripts)
269
+ * - STATIC: No updates needed
270
+ */
271
+ update(_: number): void;
272
+ /**
273
+ * Apply force to the rigid body
274
+ */
275
+ applyForce(force: THREE.Vector3, point?: THREE.Vector3): void;
276
+ /**
277
+ * Apply impulse to the rigid body
278
+ */
279
+ applyImpulse(impulse: THREE.Vector3, point?: THREE.Vector3): void;
280
+ /**
281
+ * Set the velocity of the rigid body
282
+ */
283
+ setVelocity(velocity: THREE.Vector3): void;
284
+ /**
285
+ * Get linear velocity into the provided output vector (zero allocation)
286
+ */
287
+ getVelocity(out: THREE.Vector3): void;
288
+ /**
289
+ * Set angular velocity
290
+ */
291
+ setAngularVelocity(velocity: THREE.Vector3): void;
292
+ /**
293
+ * Get the rigid body for advanced operations
294
+ */
295
+ getRigidBody(): RigidBody | null;
296
+ /**
297
+ * Get the collider for advanced operations
298
+ */
299
+ getCollider(): Collider | null;
300
+ /**
301
+ * Enable/disable the rigid body
302
+ */
303
+ setEnabled(enabled: boolean): void;
304
+ /**
305
+ * Check if the rigid body is enabled
306
+ */
307
+ isEnabled(): boolean;
308
+ /**
309
+ * Get the unique body ID for this physics body
310
+ */
311
+ getBodyId(): string;
312
+ /**
313
+ * Register a callback for when objects enter this trigger
314
+ * @param callback Function to call when an object enters this trigger
315
+ */
316
+ registerOnTriggerEnter(callback: (other: any) => void): void;
317
+ /**
318
+ * Register a callback for when objects exit this trigger
319
+ * @param callback Function to call when an object exits this trigger
320
+ */
321
+ registerOnTriggerExit(callback: (other: any) => void): void;
322
+ /**
323
+ * Unregister trigger enter callback
324
+ */
325
+ unregisterOnTriggerEnter(): void;
326
+ /**
327
+ * Unregister trigger exit callback
328
+ */
329
+ unregisterOnTriggerExit(): void;
330
+ /**
331
+ * Called by physics system when an object enters this trigger
332
+ */
333
+ onTriggerEnter(other: any): void;
334
+ /**
335
+ * Called by physics system when an object exits this trigger
336
+ */
337
+ onTriggerExit(other: any): void;
338
+ /**
339
+ * Ensure this RigidBody is registered with physics system if it has any trigger callbacks
340
+ */
341
+ private ensureRegisteredWithPhysicsSystem;
342
+ /**
343
+ * Check if we should unregister from physics system (no more callbacks)
344
+ */
345
+ private checkIfShouldUnregisterFromPhysics;
346
+ /**
347
+ * Create a RigidBodyComponent from bounds size
348
+ * @param bounds The size vector from renderer.getBounds()
349
+ * @param options Physics options (size will be overridden by bounds)
350
+ * @returns A new RigidBodyComponentThree with bounds-fitted size
351
+ */
352
+ static fromBounds(bounds: THREE.Vector3, options?: Omit<RigidBodyOptions, "fitToMesh" | "size">): RigidBodyComponentThree;
353
+ /**
354
+ * Get the bounding box dimensions of all meshes in a GameObject hierarchy
355
+ * @param gameObject The GameObject to analyze
356
+ * @returns Vector3 containing width, height, depth of the combined mesh bounds
357
+ */
358
+ static getMeshBounds(gameObject: GameObject): THREE.Vector3;
359
+ /**
360
+ * Called when GameObject becomes enabled
361
+ */
362
+ onEnabled(): void;
363
+ getBounds(): THREE.Box3;
364
+ /**
365
+ * Called when GameObject becomes disabled
366
+ */
367
+ onDisabled(): void;
368
+ protected onCleanup(): void;
369
+ }
370
+
371
+ interface PrefabCollectionJSON {
372
+ prefabs: PrefabJSON[];
373
+ }
374
+ interface PrefabJSON {
375
+ schema: string;
376
+ version: number;
377
+ meta: {
378
+ name: string;
379
+ created: string;
380
+ };
381
+ mounts: PrefabMountJSON[];
382
+ root: PrefabNodeJSON;
383
+ }
384
+ interface PrefabMountJSON {
385
+ alias: string;
386
+ path: string;
387
+ }
388
+ interface TransformComponentJSON {
389
+ type: "transform";
390
+ position: number[];
391
+ rotation: number[];
392
+ scale: number[];
393
+ [key: string]: unknown;
394
+ }
395
+ interface PrefabComponentJSON {
396
+ type: string;
397
+ [key: string]: unknown;
398
+ }
399
+ interface PrefabNodeJSON {
400
+ name: string;
401
+ components?: PrefabComponentJSON[];
402
+ children?: PrefabNodeJSON[];
403
+ }
404
+ declare function isTransformComponent(c: PrefabComponentJSON): c is TransformComponentJSON;
405
+
406
+ declare class PrefabNode {
407
+ static createFromJSON(json: PrefabNodeJSON): PrefabNode;
408
+ private readonly _name;
409
+ private readonly _transform;
410
+ private readonly _components;
411
+ private readonly _children;
412
+ private readonly _childByNameLookup;
413
+ private readonly _nodeByPathLookup;
414
+ constructor(name: string, transform: TransformComponentJSON, components: PrefabComponentJSON[], children: PrefabNode[]);
415
+ get name(): string;
416
+ get id(): string;
417
+ get transform(): TransformComponentJSON;
418
+ get components(): ReadonlyArray<PrefabComponentJSON>;
419
+ get children(): ReadonlyArray<PrefabNode>;
420
+ get position(): THREE.Vector3;
421
+ get rotation(): THREE.Euler;
422
+ get scale(): THREE.Vector3;
423
+ getChildByName(name: string): PrefabNode | undefined;
424
+ getNodeByPath(path: string): PrefabNode | undefined;
425
+ get descendants(): MapIterator<[string, PrefabNode]>;
426
+ depthFirstSearchForNode(nodeName: string): PrefabNode | undefined;
427
+ getComponentData<T extends PrefabComponentJSON>(type: string): T | undefined;
428
+ applyTransformTo(object: THREE.Object3D): void;
429
+ private mapDescendant;
430
+ }
431
+
432
+ type ComponentJSON = Record<string, unknown> & {
433
+ type: string;
434
+ };
435
+ interface PrefabComponentFactory {
436
+ fromPrefabJSON(json: ComponentJSON, node: PrefabNode): Component | null;
437
+ }
438
+ type PrefabComponentConstructor = (new (...args: any[]) => Component) & PrefabComponentFactory;
439
+ declare class ComponentRegistryImpl {
440
+ private registry;
441
+ register(typeName: string, componentClass: PrefabComponentConstructor): void;
442
+ get(typeName: string): PrefabComponentConstructor | undefined;
443
+ has(typeName: string): boolean;
444
+ getRegisteredTypes(): string[];
445
+ }
446
+ declare const ComponentRegistry: ComponentRegistryImpl;
447
+
448
+ export { AnimationCullingManager as A, Component as C, GameObject as G, PrefabNode as P, RigidBodyComponentThree as R, type TransformComponentJSON as T, type ComponentJSON as a, type PrefabComponentConstructor as b, type PrefabJSON as c, type PrefabCollectionJSON as d, RigidBodyType as e, ColliderShape as f, createCollisionGroup as g, type RigidBodyOptions as h, ComponentRegistry as i, type PrefabComponentFactory as j, type PrefabMountJSON as k, type PrefabComponentJSON as l, type PrefabNodeJSON as m, isTransformComponent as n };