@series-inc/rundot-3d-engine 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,316 +1,316 @@
1
- # VenusGame
2
-
3
- VenusGame is the base class for your game application. It manages the Three.js renderer, scene, camera, and orchestrates all engine systems.
4
-
5
- ## Quick Start
6
-
7
- ```typescript
8
- import { VenusGame } from "@series-ai/rundot-3d-engine"
9
- import { GameObject, Component } from "@series-ai/rundot-3d-engine"
10
-
11
- class MyGame extends VenusGame {
12
- protected async onStart(): Promise<void> {
13
- // Initialize your game here
14
- console.log("Game starting!")
15
-
16
- // Create game objects
17
- const player = new GameObject("Player")
18
- player.position.set(0, 1, 0)
19
-
20
- // Add lighting
21
- const light = new THREE.DirectionalLight(0xffffff, 1)
22
- light.position.set(5, 10, 5)
23
- this.scene.add(light)
24
- }
25
-
26
- protected preRender(deltaTime: number): void {
27
- // Called every frame before rendering
28
- // Use deltaTime for time-based calculations
29
- }
30
-
31
- protected async onDispose(): Promise<void> {
32
- // Cleanup your game resources
33
- console.log("Game shutting down")
34
- }
35
- }
36
-
37
- // Start the game
38
- MyGame.create()
39
- ```
40
-
41
- ## Common Use Cases
42
-
43
- ### Configuring Rendering
44
-
45
- ```typescript
46
- class MyGame extends VenusGame {
47
- protected getConfig(): VenusGameConfig {
48
- return {
49
- backgroundColor: 0x87CEEB, // Sky blue
50
- antialias: true,
51
- shadowMapEnabled: true,
52
- shadowMapType: "vsm", // or "pcf_soft"
53
- toneMapping: "aces", // Filmic look
54
- toneMappingExposure: 1.0,
55
- audioEnabled: true
56
- }
57
- }
58
- }
59
- ```
60
-
61
- ### Accessing Global Scene/Camera
62
-
63
- ```typescript
64
- // From anywhere in your code after game initialization
65
- import { VenusGame } from "@series-ai/rundot-3d-engine"
66
-
67
- // Access the scene
68
- const scene = VenusGame.scene
69
-
70
- // Access the camera
71
- const camera = VenusGame.camera
72
-
73
- // Access the renderer
74
- const renderer = VenusGame.renderer
75
-
76
- // Access the game instance
77
- const game = VenusGame.instance
78
- ```
79
-
80
- ### Custom Render Pipeline
81
-
82
- ```typescript
83
- class MyGame extends VenusGame {
84
- private composer: EffectComposer
85
-
86
- protected async onStart(): Promise<void> {
87
- // Set up post-processing
88
- this.composer = new EffectComposer(this.renderer)
89
- // ... add passes ...
90
- }
91
-
92
- protected render(): void {
93
- // Override default rendering
94
- this.composer.render()
95
- }
96
- }
97
- ```
98
-
99
- ### Time-Based Logic
100
-
101
- ```typescript
102
- class MyGame extends VenusGame {
103
- private gameTime: number = 0
104
-
105
- protected preRender(deltaTime: number): void {
106
- // IMPORTANT: Use deltaTime parameter, not this.clock.getDelta()!
107
- this.gameTime += deltaTime
108
-
109
- // Do time-based updates
110
- if (this.gameTime > 60) {
111
- console.log("One minute elapsed!")
112
- }
113
- }
114
- }
115
- ```
116
-
117
- ## API Overview
118
-
119
- ### Static Methods
120
-
121
- - `VenusGame.create<T>(): Promise<T>` - Create and initialize game instance
122
- - `VenusGame.scene` - Get the active Three.js scene
123
- - `VenusGame.camera` - Get the active camera
124
- - `VenusGame.renderer` - Get the WebGL renderer
125
- - `VenusGame.instance` - Get the game instance
126
- - `VenusGame.setAnimationCullingCamera(camera, expansion?)` - Enable animation frustum culling
127
- - `VenusGame.getAnimationCulling()` - Get animation culling manager for advanced config
128
-
129
- ### Protected Properties
130
-
131
- - `scene: THREE.Scene` - The Three.js scene
132
- - `camera: THREE.PerspectiveCamera` - The main camera
133
- - `renderer: THREE.WebGLRenderer` - The WebGL renderer
134
- - `canvas: HTMLCanvasElement` - The render canvas
135
- - `config: VenusGameConfig` - Merged configuration
136
- - `audioListener: THREE.AudioListener | null` - Auto-created audio listener
137
-
138
- ### Abstract Methods (Override These)
139
-
140
- - `onStart(): Promise<void>` - Initialize game, called after engine setup
141
- - `preRender(deltaTime: number): void` - Called every frame before rendering
142
- - `onDispose(): Promise<void>` - Cleanup game resources
143
-
144
- ### Configuration Method
145
-
146
- - `getConfig(): VenusGameConfig` - Return game-specific config (merged with defaults)
147
-
148
- ### Protected Methods
149
-
150
- - `render(): void` - Render the scene (override for custom pipelines)
151
- - `getElapsedTime(): number` - Get total elapsed time (not delta)
152
- - `dispose(): Promise<void>` - Dispose game and all resources
153
-
154
- ## Configuration Options
155
-
156
- ```typescript
157
- interface VenusGameConfig {
158
- backgroundColor?: number // Default: 0x000000
159
- antialias?: boolean // Default: true
160
- shadowMapEnabled?: boolean // Default: true
161
- shadowMapType?: "vsm" | "pcf_soft" // Default: "vsm"
162
- toneMapping?: "aces" | "linear" | "none" // Default: "aces"
163
- toneMappingExposure?: number // Default: 1.0
164
- audioEnabled?: boolean // Default: true
165
- }
166
- ```
167
-
168
- ## Lifecycle
169
-
170
- The game follows this initialization sequence:
171
-
172
- 1. `constructor()` - Creates renderer, scene, camera
173
- 2. `PhysicsSystem.initialize()` - Rapier physics setup
174
- 3. `InputManager.initialize()` - Input system setup
175
- 4. Other systems initialized (lighting, components, audio)
176
- 5. `onStart()` - Your game initialization
177
- 6. Render loop starts
178
- 7. Every frame: physics → tweens → components → `preRender()` → `render()`
179
-
180
- ## Patterns & Best Practices
181
-
182
- ### Initialize Systems in onStart
183
-
184
- ```typescript
185
- protected async onStart(): Promise<void> {
186
- // Load assets first
187
- await this.loadAssets()
188
-
189
- // Create game objects
190
- this.setupScene()
191
-
192
- // Initialize game logic
193
- this.setupGameSystems()
194
- }
195
- ```
196
-
197
- ### Use deltaTime Correctly
198
-
199
- ```typescript
200
- // Good - Use deltaTime parameter
201
- protected preRender(deltaTime: number): void {
202
- this.player.position.x += this.speed * deltaTime
203
- }
204
-
205
- // Bad - Don't call getDelta() multiple times
206
- protected preRender(deltaTime: number): void {
207
- const dt = this.clock.getDelta() // Wrong! Causes timing issues
208
- }
209
- ```
210
-
211
- ### Proper Resource Cleanup
212
-
213
- ```typescript
214
- protected async onDispose(): Promise<void> {
215
- // Dispose custom systems
216
- this.customSystem?.cleanup()
217
-
218
- // Dispose game objects (they auto-cleanup)
219
- this.level?.dispose()
220
-
221
- // Clean up event listeners
222
- document.removeEventListener("keydown", this.boundKeyHandler)
223
- }
224
- ```
225
-
226
- ### Responsive Camera
227
-
228
- ```typescript
229
- protected async onStart(): Promise<void> {
230
- // Camera is automatically resized
231
- // Just set initial position
232
- this.camera.position.set(0, 10, 20)
233
- this.camera.lookAt(0, 0, 0)
234
- }
235
- ```
236
-
237
- ### Performance Optimization
238
-
239
- ```typescript
240
- protected getConfig(): VenusGameConfig {
241
- return {
242
- // Use VSM shadows for better quality
243
- shadowMapType: "vsm",
244
-
245
- // Enable ACES for filmic look
246
- toneMapping: "aces",
247
- toneMappingExposure: 1.0,
248
-
249
- // Antialiasing for smoothness (disable for better mobile perf)
250
- antialias: true
251
- }
252
- }
253
- ```
254
-
255
- ## Anti-Patterns
256
-
257
- ### Don't Create Multiple Instances
258
-
259
- ```typescript
260
- // Bad - Only one VenusGame should exist
261
- const game1 = await MyGame.create()
262
- const game2 = await MyGame.create() // Conflicts!
263
-
264
- // Good - Create once
265
- const game = await MyGame.create()
266
- ```
267
-
268
- ### Don't Access Clock Directly
269
-
270
- ```typescript
271
- // Bad - Causes frame rate dependent behavior
272
- protected preRender(deltaTime: number): void {
273
- const dt = this.getElapsedTime() // Wrong context!
274
- // Use deltaTime parameter instead
275
- }
276
-
277
- // Good - Use the parameter
278
- protected preRender(deltaTime: number): void {
279
- this.gameTime += deltaTime
280
- }
281
- ```
282
-
283
- ### Don't Forget to Call Super if Overriding
284
-
285
- ```typescript
286
- // If you override dispose
287
- public async dispose(): Promise<void> {
288
- this.myCustomCleanup()
289
- await super.dispose() // Important!
290
- }
291
- ```
292
-
293
- ## Engine Initialization Order
294
-
295
- When `VenusGame.create()` is called:
296
-
297
- 1. Rundot SDK initialized
298
- 2. Physics system (Rapier) initialized
299
- 3. Input manager initialized
300
- 4. Lighting system initialized
301
- 5. Component updater initialized
302
- 6. Instanced mesh manager initialized
303
- 7. Audio listener created (if enabled)
304
- 8. **Your `onStart()` method called**
305
- 9. Render loop starts
306
- 10. Loading screen hidden
307
-
308
- ## Related Systems
309
-
310
- - [GameObject](GameObject.md) - Entities that populate the scene
311
- - [Component](Component.md) - Behaviors attached to GameObjects
312
- - [PhysicsSystem](../physics/PhysicsSystem.md) - Physics simulation
313
- - [InputManager](../systems/InputManager.md) - Input handling
314
- - [AudioSystem](../systems/AudioSystem.md) - Audio management
315
- - [TweenSystem](../systems/TweenSystem.md) - Animation system
316
-
1
+ # VenusGame
2
+
3
+ VenusGame is the base class for your game application. It manages the Three.js renderer, scene, camera, and orchestrates all engine systems.
4
+
5
+ ## Quick Start
6
+
7
+ ```typescript
8
+ import { VenusGame } from "@series-ai/rundot-3d-engine"
9
+ import { GameObject, Component } from "@series-ai/rundot-3d-engine"
10
+
11
+ class MyGame extends VenusGame {
12
+ protected async onStart(): Promise<void> {
13
+ // Initialize your game here
14
+ console.log("Game starting!")
15
+
16
+ // Create game objects
17
+ const player = new GameObject("Player")
18
+ player.position.set(0, 1, 0)
19
+
20
+ // Add lighting
21
+ const light = new THREE.DirectionalLight(0xffffff, 1)
22
+ light.position.set(5, 10, 5)
23
+ this.scene.add(light)
24
+ }
25
+
26
+ protected preRender(deltaTime: number): void {
27
+ // Called every frame before rendering
28
+ // Use deltaTime for time-based calculations
29
+ }
30
+
31
+ protected async onDispose(): Promise<void> {
32
+ // Cleanup your game resources
33
+ console.log("Game shutting down")
34
+ }
35
+ }
36
+
37
+ // Start the game
38
+ MyGame.create()
39
+ ```
40
+
41
+ ## Common Use Cases
42
+
43
+ ### Configuring Rendering
44
+
45
+ ```typescript
46
+ class MyGame extends VenusGame {
47
+ protected getConfig(): VenusGameConfig {
48
+ return {
49
+ backgroundColor: 0x87CEEB, // Sky blue
50
+ antialias: true,
51
+ shadowMapEnabled: true,
52
+ shadowMapType: "vsm", // or "pcf_soft"
53
+ toneMapping: "aces", // Filmic look
54
+ toneMappingExposure: 1.0,
55
+ audioEnabled: true
56
+ }
57
+ }
58
+ }
59
+ ```
60
+
61
+ ### Accessing Global Scene/Camera
62
+
63
+ ```typescript
64
+ // From anywhere in your code after game initialization
65
+ import { VenusGame } from "@series-ai/rundot-3d-engine"
66
+
67
+ // Access the scene
68
+ const scene = VenusGame.scene
69
+
70
+ // Access the camera
71
+ const camera = VenusGame.camera
72
+
73
+ // Access the renderer
74
+ const renderer = VenusGame.renderer
75
+
76
+ // Access the game instance
77
+ const game = VenusGame.instance
78
+ ```
79
+
80
+ ### Custom Render Pipeline
81
+
82
+ ```typescript
83
+ class MyGame extends VenusGame {
84
+ private composer: EffectComposer
85
+
86
+ protected async onStart(): Promise<void> {
87
+ // Set up post-processing
88
+ this.composer = new EffectComposer(this.renderer)
89
+ // ... add passes ...
90
+ }
91
+
92
+ protected render(): void {
93
+ // Override default rendering
94
+ this.composer.render()
95
+ }
96
+ }
97
+ ```
98
+
99
+ ### Time-Based Logic
100
+
101
+ ```typescript
102
+ class MyGame extends VenusGame {
103
+ private gameTime: number = 0
104
+
105
+ protected preRender(deltaTime: number): void {
106
+ // IMPORTANT: Use deltaTime parameter, not this.clock.getDelta()!
107
+ this.gameTime += deltaTime
108
+
109
+ // Do time-based updates
110
+ if (this.gameTime > 60) {
111
+ console.log("One minute elapsed!")
112
+ }
113
+ }
114
+ }
115
+ ```
116
+
117
+ ## API Overview
118
+
119
+ ### Static Methods
120
+
121
+ - `VenusGame.create<T>(): Promise<T>` - Create and initialize game instance
122
+ - `VenusGame.scene` - Get the active Three.js scene
123
+ - `VenusGame.camera` - Get the active camera
124
+ - `VenusGame.renderer` - Get the WebGL renderer
125
+ - `VenusGame.instance` - Get the game instance
126
+ - `VenusGame.setAnimationCullingCamera(camera, expansion?)` - Enable animation frustum culling
127
+ - `VenusGame.getAnimationCulling()` - Get animation culling manager for advanced config
128
+
129
+ ### Protected Properties
130
+
131
+ - `scene: THREE.Scene` - The Three.js scene
132
+ - `camera: THREE.PerspectiveCamera` - The main camera
133
+ - `renderer: THREE.WebGLRenderer` - The WebGL renderer
134
+ - `canvas: HTMLCanvasElement` - The render canvas
135
+ - `config: VenusGameConfig` - Merged configuration
136
+ - `audioListener: THREE.AudioListener | null` - Auto-created audio listener
137
+
138
+ ### Abstract Methods (Override These)
139
+
140
+ - `onStart(): Promise<void>` - Initialize game, called after engine setup
141
+ - `preRender(deltaTime: number): void` - Called every frame before rendering
142
+ - `onDispose(): Promise<void>` - Cleanup game resources
143
+
144
+ ### Configuration Method
145
+
146
+ - `getConfig(): VenusGameConfig` - Return game-specific config (merged with defaults)
147
+
148
+ ### Protected Methods
149
+
150
+ - `render(): void` - Render the scene (override for custom pipelines)
151
+ - `getElapsedTime(): number` - Get total elapsed time (not delta)
152
+ - `dispose(): Promise<void>` - Dispose game and all resources
153
+
154
+ ## Configuration Options
155
+
156
+ ```typescript
157
+ interface VenusGameConfig {
158
+ backgroundColor?: number // Default: 0x000000
159
+ antialias?: boolean // Default: true
160
+ shadowMapEnabled?: boolean // Default: true
161
+ shadowMapType?: "vsm" | "pcf_soft" // Default: "vsm"
162
+ toneMapping?: "aces" | "linear" | "none" // Default: "aces"
163
+ toneMappingExposure?: number // Default: 1.0
164
+ audioEnabled?: boolean // Default: true
165
+ }
166
+ ```
167
+
168
+ ## Lifecycle
169
+
170
+ The game follows this initialization sequence:
171
+
172
+ 1. `constructor()` - Creates renderer, scene, camera
173
+ 2. `PhysicsSystem.initialize()` - Rapier physics setup
174
+ 3. `InputManager.initialize()` - Input system setup
175
+ 4. Other systems initialized (lighting, components, audio)
176
+ 5. `onStart()` - Your game initialization
177
+ 6. Render loop starts
178
+ 7. Every frame: physics → tweens → components → `preRender()` → `render()`
179
+
180
+ ## Patterns & Best Practices
181
+
182
+ ### Initialize Systems in onStart
183
+
184
+ ```typescript
185
+ protected async onStart(): Promise<void> {
186
+ // Load assets first
187
+ await this.loadAssets()
188
+
189
+ // Create game objects
190
+ this.setupScene()
191
+
192
+ // Initialize game logic
193
+ this.setupGameSystems()
194
+ }
195
+ ```
196
+
197
+ ### Use deltaTime Correctly
198
+
199
+ ```typescript
200
+ // Good - Use deltaTime parameter
201
+ protected preRender(deltaTime: number): void {
202
+ this.player.position.x += this.speed * deltaTime
203
+ }
204
+
205
+ // Bad - Don't call getDelta() multiple times
206
+ protected preRender(deltaTime: number): void {
207
+ const dt = this.clock.getDelta() // Wrong! Causes timing issues
208
+ }
209
+ ```
210
+
211
+ ### Proper Resource Cleanup
212
+
213
+ ```typescript
214
+ protected async onDispose(): Promise<void> {
215
+ // Dispose custom systems
216
+ this.customSystem?.cleanup()
217
+
218
+ // Dispose game objects (they auto-cleanup)
219
+ this.level?.dispose()
220
+
221
+ // Clean up event listeners
222
+ document.removeEventListener("keydown", this.boundKeyHandler)
223
+ }
224
+ ```
225
+
226
+ ### Responsive Camera
227
+
228
+ ```typescript
229
+ protected async onStart(): Promise<void> {
230
+ // Camera is automatically resized
231
+ // Just set initial position
232
+ this.camera.position.set(0, 10, 20)
233
+ this.camera.lookAt(0, 0, 0)
234
+ }
235
+ ```
236
+
237
+ ### Performance Optimization
238
+
239
+ ```typescript
240
+ protected getConfig(): VenusGameConfig {
241
+ return {
242
+ // Use VSM shadows for better quality
243
+ shadowMapType: "vsm",
244
+
245
+ // Enable ACES for filmic look
246
+ toneMapping: "aces",
247
+ toneMappingExposure: 1.0,
248
+
249
+ // Antialiasing for smoothness (disable for better mobile perf)
250
+ antialias: true
251
+ }
252
+ }
253
+ ```
254
+
255
+ ## Anti-Patterns
256
+
257
+ ### Don't Create Multiple Instances
258
+
259
+ ```typescript
260
+ // Bad - Only one VenusGame should exist
261
+ const game1 = await MyGame.create()
262
+ const game2 = await MyGame.create() // Conflicts!
263
+
264
+ // Good - Create once
265
+ const game = await MyGame.create()
266
+ ```
267
+
268
+ ### Don't Access Clock Directly
269
+
270
+ ```typescript
271
+ // Bad - Causes frame rate dependent behavior
272
+ protected preRender(deltaTime: number): void {
273
+ const dt = this.getElapsedTime() // Wrong context!
274
+ // Use deltaTime parameter instead
275
+ }
276
+
277
+ // Good - Use the parameter
278
+ protected preRender(deltaTime: number): void {
279
+ this.gameTime += deltaTime
280
+ }
281
+ ```
282
+
283
+ ### Don't Forget to Call Super if Overriding
284
+
285
+ ```typescript
286
+ // If you override dispose
287
+ public async dispose(): Promise<void> {
288
+ this.myCustomCleanup()
289
+ await super.dispose() // Important!
290
+ }
291
+ ```
292
+
293
+ ## Engine Initialization Order
294
+
295
+ When `VenusGame.create()` is called:
296
+
297
+ 1. Rundot SDK initialized
298
+ 2. Physics system (Rapier) initialized
299
+ 3. Input manager initialized
300
+ 4. Lighting system initialized
301
+ 5. Component updater initialized
302
+ 6. Instanced mesh manager initialized
303
+ 7. Audio listener created (if enabled)
304
+ 8. **Your `onStart()` method called**
305
+ 9. Render loop starts
306
+ 10. Loading screen hidden
307
+
308
+ ## Related Systems
309
+
310
+ - [GameObject](GameObject.md) - Entities that populate the scene
311
+ - [Component](Component.md) - Behaviors attached to GameObjects
312
+ - [PhysicsSystem](../physics/PhysicsSystem.md) - Physics simulation
313
+ - [InputManager](../systems/InputManager.md) - Input handling
314
+ - [AudioSystem](../systems/AudioSystem.md) - Audio management
315
+ - [TweenSystem](../systems/TweenSystem.md) - Animation system
316
+