The codebase has been refactored into a modular architecture for better maintainability and scalability.
src/main.ts- Application bootstrap and engine initializationsrc/game.ts- Main game orchestrator class (525 lines)
The game logic has been separated into focused modules:
-
physics.ts(41 lines) - Rapier physics engine integration- Physics world management
- Collision event handling
- Gravity configuration
-
types.ts(47 lines) - Shared TypeScript interfaces and enums- GameState, DisplayState enums
- PhysicsBinding, BumperVisual, CaughtBall interfaces
- Common type definitions
-
game-objects.ts(424 lines) - Scene objects and physics bodies- Ground, walls, flippers, bumpers
- Pachinko field pins
- Slingshots and targets
- Collision body management
-
ball-manager.ts(220 lines) - Ball lifecycle and behavior- Main ball creation and reset
- Extra ball spawning
- Ball removal and loss handling
- Hologram catch mechanics
-
display.ts(355 lines) - Backbox display and slot machine- WGSL shader reels (WebGPU)
- Canvas-based fallback reels
- Display states (IDLE, REACH, FEVER)
- Overlay and scanline effects
-
effects.ts(167 lines) - Visual and audio effects- Audio beeps and feedback
- Particle system (shards)
- Bloom post-processing
- Cabinet lighting animations
-
input.ts(140 lines) - Player input handling- Keyboard controls
- Touch controls
- Flipper, plunger, nudge actions
- Game state-aware input
-
adventure-mode.ts(152 lines) - Holo-deck adventure mode- Dynamic track generation
- Camera management
- Mode activation/deactivation
index.ts(8 lines) - Central export point for all game elements
- Separation of Concerns - Each module has a single, clear responsibility
- Maintainability - Smaller files are easier to understand and modify
- Testability - Isolated modules can be tested independently
- Scalability - New features can be added without touching core game logic
- Reusability - Systems can be reused or swapped out easily
game.ts
├── physics.ts
├── display.ts (uses types.ts)
├── effects.ts (uses types.ts)
├── game-objects.ts (uses types.ts, physics)
├── ball-manager.ts (uses types.ts, physics)
├── adventure-mode.ts (uses physics)
└── input.ts (uses types.ts)
To add new game mechanics:
- Determine which module(s) are affected
- Add necessary types to
types.tsif needed - Implement feature in the appropriate module
- Update
game.tsto orchestrate the new feature - Export new classes/functions from
index.tsif they're used elsewhere
- Keep modules focused - Each file should handle one aspect of the game
- Use dependency injection - Pass required dependencies to constructors
- Maintain clear interfaces - Public methods should be well-documented
- Minimize coupling - Modules should depend on interfaces, not implementations