Reactive Entity Sets guide
Experimental Feature - Reactive Entity Sets are available in v2.1.0. The API may change in future versions. Use in production at your own discretion.
Critical Note: Runtime Data Persistence While ScriptableObjects can store data across scenes, Unity may unload them from memory if they are not referenced by any active object during a scene transition. If unloaded, all runtime data (e.g., entity state) will be lost. To prevent this, use the Manager Scene pattern with
ReactiveEntitySetHolder. See Persistence for details.
Purpose
This guide covers Reactive Entity Sets for centralized entity state management. It walks through what makes them different from Runtime Sets, defining entity data, and subscribing to per-entity state changes.
What are reactive entity sets?
Reactive Entity Sets are ScriptableObject-based state containers that store per-entity data with automatic change notifications. Unlike Runtime Sets that only track object references, Reactive Entity Sets store actual state (health, score, status effects) for each entity.
// Store state by entity ID
entitySet.Register(this, new EnemyState { Health = 100 });
// Read state anywhere
var state = entitySet.GetData(entityId);
// Update state with automatic events
entitySet.UpdateData(this, state => {
state.Health -= 10;
return state;
});
This architecture enables:
- Entity state survives scene loading
- Any entity’s state is accessible by ID
- Sparse Set backing gives constant-time operations (O(1))
- Observers can subscribe to specific entity changes
When to use reactive entity sets
Use reactive entity sets when
- You need per-entity state (health, mana, status effects)
- You need ID-based lookup without finding the object
- State must persist across scenes
- External systems need to read entity data (UI, AI, networking)
Use runtime sets when
- You only need to track active objects (no per-entity state)
- The code iterates over all objects without needing individual data
- ID-based lookup is not required
Comparison
| Feature | Runtime Sets | Reactive Entity Sets |
|---|---|---|
| Stores | Object references | Per-entity data structs |
| Lookup | Iteration only | O(1) by ID |
| Events | Collection changes | Per-entity + collection |
| Persistence | Scene lifecycle | ScriptableObject |
| Use case | Object tracking | State management |
Quick decision guide
| Scenario | Use |
|---|---|
| Track all enemies in level | Runtime Set |
| Store each enemy’s health and status | Reactive Entity Set |
| Display minimap icons | Runtime Set |
| Show individual health bars | Reactive Entity Set |
Architecture overview
flowchart TB
subgraph EntitySet["ReactiveEntitySetSO<EnemyState>"]
SS[Sparse Set]
subgraph Data["Per-Entity State"]
D1["ID: 101 → Health: 80"]
D2["ID: 102 → Health: 100"]
D3["ID: 103 → Health: 45"]
end
Traits["Trait Masks (ulong)"]
subgraph Events["Event Channels"]
E1[OnItemAdded]
E2[OnItemRemoved]
E3[OnDataChanged]
E4[OnTraitAdded]
end
end
View[ReactiveView]
Enemy1[Enemy 101] -->|Register/Update| SS
Enemy2[Enemy 102] -->|Register/Update| SS
SS --> Data
SS --> Traits
Data -->|state changed| E3
Traits -->|trait changed| E4
E3 -->|notifies| UI[Health Bar UI]
E3 -->|notifies| AI[AI System]
E4 -->|filtered membership| View
Sparse Set — A data structure that achieves O(1) registration, lookup, and removal. It provides fast mapping from entity IDs to state data.
The data flows through the system in three stages.
- When an entity spawns,
ReactiveEntity.OnEnable()registers it with the EntitySet. - State updates go through
UpdateData(), which fires per-entity callbacks. - On destruction,
ReactiveEntity.OnDisable()unregisters the entity from the EntitySet.
Guide sections
| Page | Description |
|---|---|
| Basic Usage | Define state structs, create assets, register entities |
| Events | Per-entity subscriptions, set-level notifications |
| Traits | Bitmask flags for entity classification and filtering |
| Views | Reactive filtered subsets with automatic membership |
| Patterns | Boss health bars, status effects, save/load |
| Best Practices | Performance tips, troubleshooting |
| Persistence | Prevent data loss across scene transitions |
| Job System | High-performance parallel processing with Orchestrator |
| Observability | Set theoretic observability and snapshot patterns |
Related documentation
For the design philosophy and theoretical foundations, see RES Design.