5. Entity System
Now that we have our input system, we need something to control. This brings us to the concept of an Entity System - our way of representing objects in the game world.
In our System Stack, the Entity system also sits at the base layer. Like Input, it's a core system that many others depend on.
The Fractal Code Cycle Applied to Entities
Recall our fundamental pattern:
Input → Processing → Output
For our entity system:
- Input: Entity creation requests, entity handle references
- Processing: Managing entity lifecycle, storing entity data
- Output: Entity data accessible to other systems
This will change later when we add general entity processing functionality.
What is an Entity?
An entity is any discrete "thing" in our game world that we want to track and manipulate:
- Characters (player, NPCs)
- Objects (chests, doors)
- Environmental elements (trees, rocks)
- Abstract concepts (spawn points, triggers)
Entity Systems Design Patterns
Entity-Component Systems (ECS)
In a pure ECS:
- Entities are just IDs
- Components store data
- Systems operate on components
Our approach is simpler but borrows some ideas from ECS:
- Entities store basic data (like position)
- We use a handle-based system for referencing entities
Handle-Based Systems
A handle is a reference to an entity that:
- Allows for safe entity lookup
- Protects against "dangling pointers"
- Enables entity recycling
Megastruct
The "megastruct" concept is not new. It's used in many game engines, however most of them are OOP based and so suffer from treating entities as atomic instances rather than collections.
It's simple. We add whatever fields are required across all entity types to our Entity type.
You may be wondering if this is a good idea as it could cause a lot of cache misses. The thing is, we won't know that for sure until we get further into the project.
If something is significantly different from most other things, we won't use an entity to represent it. Examples: terrain, particles
The Concept of Entity Handles
Why Use Handles?
- Memory Safety: Prevents accessing deleted entities
- Recycling: Entity slots can be reused
- Validation: Can check if an entity still exists
The Generation Pattern
- Each entity has a "generation" number
- When an entity is recycled, its generation increases
- Handles with mismatched generations are considered invalid
- This prevents using stale handles to access new entities
The Concept of Nil Entities
What is a Nil Entity?
A nil entity is a special entity that:
- Always exists at index 0
- Acts as a fallback when entity access fails
- Simplifies error handling
Benefits of Nil Entities
- Calling code can always assume it gets something back
- Errors can be logged but don't crash the game
Connecting Input to Entities
Now that we have both input and entities, we can connect them:
- Player input creates movement intention
- We fetch the player entity using its handle
- We update the entity's position based on input
- The rendering system displays the entity in its new position
This demonstrates the Fractal Code Cycle again:
- Input: Player movement commands
- Processing: Position updates
- Output: Visual representation on screen
Entity System in Our Stack
Recall our System Stack organisation:
- Base Layer: Entities, Input, Time, Assets, Save/Load
- Presentation: Camera, Shaders, Animation, UI, Particles
- Interaction: Player, Collisions, AI, Scenes
- Game Systems: Stats, Combat, Inventory, Abilities
- Content: Dialogue, Quests, NPC Schedules
The Entity system sits in the base layer because:
- It has minimal dependencies (just memory management)
- Many higher-level systems depend on it
- It provides a foundation for representing game objects
Entity System Design Considerations
Performance
- Entities should be treated as a collection, not individuals (except, perhaps, the player)
- Memory layout matters for cache efficiency, but we must test
Flexibility
- Should support different types of game objects
- Easy to extend with new features
- Compatible with other systems (like rendering, physics)
Lifetime Management
- Clear interface for creation and "destruction"
- Prevention of memory leaks via recycling
- Reduce errors with generational handles
Try It Yourself
- What other data might entities need to store? (Hint: think about rendering, collision, etc.)
- How would you implement different types of entities? (NPCs vs. items vs. doors)
- How might you implement entity destruction in our handle-based system?
The Big Idea
The entity system is the foundation for nearly everything that makes a game interactive.
Lever needs to be pulled? Make an interactable entity.
Chest needs to be opened? Entity.
Monster roaming the wilds? Entity.
NPCs going about their business? Entities...
Our megastruct handle-based approach with generations gives us flexibility, safety, and efficiency - key requirements for a robust game architecture.