@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.
- package/LICENSE.txt +6 -6
- package/docs/core/Component.md +321 -321
- package/docs/core/GameObject.md +204 -204
- package/docs/core/VenusGame.md +316 -316
- package/docs/patterns/ComponentCommunication.md +337 -337
- package/docs/patterns/CreatingGameObjects.md +290 -290
- package/docs/patterns/MeshColliders.md +338 -338
- package/docs/patterns/MeshLoading.md +316 -316
- package/docs/physics/Colliders.md +249 -249
- package/docs/physics/PhysicsSystem.md +151 -151
- package/docs/physics/RigidBodyComponent.md +201 -201
- package/docs/rendering/AssetManager.md +308 -308
- package/docs/rendering/InstancedRenderer.md +286 -286
- package/docs/rendering/MeshRenderer.md +286 -286
- package/docs/rendering/SkeletalRenderer.md +308 -308
- package/docs/systems/AnimationSystem.md +75 -75
- package/docs/systems/AudioSystem.md +79 -79
- package/docs/systems/InputManager.md +101 -101
- package/docs/systems/LightingSystem.md +101 -101
- package/docs/systems/ParticleSystem.md +44 -44
- package/docs/systems/PrefabSystem.md +60 -60
- package/docs/systems/StowKitSystem.md +77 -77
- package/docs/systems/TweenSystem.md +132 -132
- package/docs/systems/UISystem.md +73 -73
- package/package.json +1 -1
- package/scripts/postinstall.mjs +63 -51
package/docs/core/VenusGame.md
CHANGED
|
@@ -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
|
+
|