Entity Component System (ECS)
Hyperscape uses a component-based Entity Component System for managing all game objects. This architecture separates data (Components) from logic (Systems), enabling modular, maintainable game development.The ECS implementation lives in
packages/shared/src/ and runs on both client and server for consistency.Core Concepts
Entities
Entities are the fundamental game objects. Each entity has:- Unique ID (
string) - UUID for identification - Type -
player,mob,item,npc,resource,static - Three.js Node - 3D representation in the scene
- Components Map - Attached data containers
- Network State - Synchronization flags
Entity Hierarchy
Entities follow an inheritance hierarchy for specialized behavior:Entity Lifecycle
- Constructor - Creates entity with initial data/config
spawn()- Called when entity is added to worldupdate(delta)- Called every frame for visual updatesfixedUpdate(delta)- Called at fixed timestep (30 FPS) for physicsdestroy()- Cleanup when entity is removed
Components
Components are pure data containers attached to entities. They store state but contain no logic.Base Component Class
Built-in Components
Adding Components to Entities
Component Events
When components are added/removed, events are emitted:Systems
Systems contain game logic that operates on entities with specific components. They run during the game loop.System Organization
Systems are organized by domain inpackages/shared/src/systems/shared/:
System Base Class
All systems extendSystemBase:
Example: Skills System
World Class
TheWorld class is the central container for all game state. It manages systems, entities, and the game loop.
Core Properties
Game Loop
System Registration
Network Synchronization
Entities automatically synchronize between server and clients.Network Dirty Flag
Serialization
Best Practices
1
Keep Components Data-Only
Components should only store data. Put logic in Systems.
2
Use Type Guards
Use helper functions like
isMobEntity() for safe type narrowing.3
Emit Events for Cross-System Communication
Use the EventBus instead of direct system-to-system calls.
4
Mark Network Dirty When State Changes
Call
entity.markNetworkDirty() after modifying replicated state.