Systems
Systems in an ECS are typically queries.
So you can still use the world.Query<Position, Velocity>()
shown in the "Hello World" example.
Using Systems is optional but they have some significant advantages.
System features
Enable chaining multiple decoupled QuerySystem classes in a SystemGroup. Each group provide a CommandBuffer.
A system can have state - fields or properties - which can be used as parameters in
OnUpdate()
. The system state can be serialized to JSON.Systems can be enabled/disabled or removed. The order of systems in a group can be changed.
Systems have performance monitoring build-in to measure execution times and memory allocations. If enabled systems detected as bottleneck can be optimized. A perf log (see example below) provide a clear overview of all systems their amount of entities and impact on performance.
Multiple worlds can be added to a single SystemRoot instance.
root.Update()
will execute every system on all worlds.
Example
The example shows the setup of a small system hierarchy. Multiple systems can be added to a system hierarchy.
A valuable strength of an ECS is establishing a clear and decoupled code structure.
Adding the PulseSystem
below to the SystemRoot
above is trivial.
This system uses a foreach (var entity in Query.Entities)
as an alternative to Query.ForEachEntity((...) => {...})
to iterate the query result.
The example also shows how to set a Filter
in a system constructor to limit the query result to entities matching this Filter
.
See all available filters at the QueryFilter - API.
The system hierarchy can be modified at runtime. New systems can be added, inserted or removed.
To prevent running a system when executing Update()
without changing the hierarchy a system can be disabled with
System monitoring
System performance monitoring is disabled by default. To enable monitoring call:
When enabled system monitoring captures
Number of system executions.
System execution duration in ms.
Memory heap allocations per system in bytes.
The number of entities matching a query system.
Realtime monitoring
In a game editor like Unity system monitoring is available in the ECS System Set component.
Log monitoring
The performance statistics available at SystemPerf. To get performance statistics on console use:
The log result will look like:
SystemRoot
The SystemRoot
is a container of systems forming a hierarchy of systems.
These systems are executed in their specified order.
Typically a SystemRoot
operates on single EntityStore
passed to its constructor.
A system hierarchy can also operate on multiple EntityStore
's.
Additional stores are added with root.AddStore()
.
If needed a system hierarchy can be setup without any EntityStore
.
This enables creating the hierarchy without the need of an EntityStore
at initialization phase.
Update Execution
Execution of systems start always with the SystemRoot
. Info - a SystemRoot
is a SystemGroup
.
Its child systems are executed when calling root.Update()
.
The child systems of a SystemGroup
are executed in the order added to the group.
Each QuerySystem
can override the following methods.
The execution of these methods of the group children is shown in the pseudo below.
Each group has a single CommandBuffer
per EntityStore
.
CommandBuffer.Playback()
is called after execution of all OnUpdate()
methods.
Execution order using a single EntityStore
.
Execution order when using multiple EntityStore
's.
Customize Systems
In cases a system requires code which goes beyond common Query
execution a system can be customized.
Therefor a system can override OnAddStore()
Use cases for custom systems are:
Handle user input.
Moving the Camera. E.g. based on user input.
Execute multiple / nested queries in a single system. E.g. to detect collisions between two different entity sets and iterating both sets in nested loops.
Need to make structural changes via the parent group
CommandBuffer
.Want direct access to an
EntityStore
.
Extend QuerySystem
QuerySystem
Example show how to extend a QuerySystem
and execute a customQuery
.
A QuerySystem
enable access to the CommandBuffer
.
Extend BaseSystem
BaseSystem
Example shows how to extend a BaseSystem
to call arbitrary methods on the EntityStore
.
In this case to deal with UniqueEntity
's.
Note: A BaseSystem
has no access to the CommandBuffer
.
Last updated