A WebGL-based army battle simulation built with Babylon.js and bitECS, designed to handle 10,000+ animated units at 60 FPS.
- Babylon.js - 3D rendering with Thin Instances
- bitECS - High-performance Entity Component System
- Yuka - Steering behaviors and behavior trees
- RecastJS - Navigation mesh pathfinding
- Vite - Fast build tool with HMR
- TypeScript - Type safety
- Node.js 18+
- npm or yarn
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
# Preview production build
npm run previewsrc/
├── main.ts # Entry point
├── core/ # Application core
│ ├── App.ts # Main orchestrator
│ ├── GameLoop.ts # Fixed timestep game loop
│ └── Config.ts # Configuration constants
│
├── renderer/ # Babylon.js rendering
│ ├── BattleScene.ts # Scene, camera, lights
│ ├── UnitRenderer.ts # Thin Instance rendering
│ ├── TerrainRenderer.ts # Battlefield terrain
│ ├── EffectsRenderer.ts # Particles, effects
│ └── shaders/ # Custom shaders
│
├── simulation/ # ECS game logic
│ ├── World.ts # bitECS world
│ ├── components/ # ECS components
│ ├── systems/ # ECS systems
│ └── ai/ # AI and formations
│
├── input/ # Input handling
│ ├── InputManager.ts # Mouse/keyboard
│ ├── CameraController.ts # RTS camera
│ └── SelectionManager.ts # Unit selection
│
├── ui/ # User interface
│ ├── HUD.ts # Performance display
│ ├── UnitPanel.ts # Selection info
│ └── Minimap.ts # Tactical overview
│
├── types/ # TypeScript types
└── utils/ # Utilities
All game entities are managed through bitECS with these core components:
| Component | Data |
|---|---|
| Transform | x, y, z, rotationY, scale |
| Velocity | x, y, z, maxSpeed |
| Unit | health, maxHealth, faction, type, state |
| Combat | attack, defense, range, attackSpeed, target |
| Animation | currentAnim, frame, speed |
| Navigation | targetX, targetZ, pathIndex, hasPath |
Systems run in this order each tick:
- NavigationSystem - Pathfinding queries
- SteeringSystem - Steering behaviors
- FormationSystem - Formation offsets
- MovementSystem - Apply velocity
- CombatSystem - Damage resolution
- AnimationSystem - State transitions
Units are rendered using Babylon.js Thin Instances for maximum performance:
- Single draw call for thousands of units
- Transform matrices updated from ECS data
- VAT (Vertex Animation Textures) for GPU-driven animation
| Input | Action |
|---|---|
| WASD / Arrows | Pan camera |
| Mouse wheel | Zoom |
| Left click | Select unit |
| Shift + click | Add to selection |
| Right click | Move selected units |
| Edge of screen | Edge pan (when enabled) |
- 60 FPS with 10,000 units
- 8ms simulation tick budget
- 8ms render budget
The codebase is structured to support WebWorker-based multithreading:
- Simulation runs on Worker thread
- Rendering stays on Main thread
- SharedArrayBuffer for zero-copy data sync
See docs/SPLIT-BRAIN-MIGRATION.md for the migration plan.
- Create
src/simulation/components/MyComponent.ts - Export from
src/simulation/components/index.ts - Add to relevant systems
- Create
src/simulation/systems/MySystem.ts - Add to pipeline in
src/simulation/systems/index.ts
Place GLSL files in public/assets/shaders/ and create corresponding TypeScript wrappers in src/renderer/shaders/.
MIT