Skip to content

Game.Tools.ApplyZonesSystem

Assembly: Game
Namespace: Game.Tools

Type: class

Base: GameSystemBase

Summary:
ApplyZonesSystem is a Unity ECS system used by the game's zoning tool pipeline to apply temporary zone changes (Temp entities) to the real zone data (Cell buffers) and to original zone entities. It schedules a Burst-compiled, chunk-parallel job (HandleTempEntitiesJob) that inspects Temp components and performs one of three actions per Temp entity: - Create: finalize the temporary change by removing Temp and adding the "applied" component set (Applied/Created/Updated), - Update: merge temporary cell changes into the original zone entity (or clear Hidden markers), and - Delete: mark both original and temporary entities as Deleted.

The system uses a ToolOutputBarrier to produce EntityCommandBuffer operations from a background job and sets up an EntityQuery so it only runs when Temp entities (and associated Block) are present. It relies on ComponentLookup/BufferLookup and ComponentTypeHandles obtained through the SystemState for correct, burstable access inside the job.


Fields

  • private ToolOutputBarrier m_ToolOutputBarrier
    Holds a reference to the ToolOutputBarrier system. Used to create an EntityCommandBuffer that the parallel job writes to, and to register the job handle with that barrier so command playback is correctly ordered with respect to other tool output operations.

  • private EntityQuery m_TempQuery
    EntityQuery that selects entities containing Temp (and Block) components. The system calls RequireForUpdate(m_TempQuery) in OnCreate to ensure the system only runs when Temp entities exist.

  • private ComponentTypeSet m_AppliedTypes
    A set of component types added to an entity when a Temp is applied (Create). In this system it is initialized with Applied, Created and Updated (ComponentType.ReadWrite). This lets the system mark Temp entities as having been applied and create the appropriate runtime markers.

  • private TypeHandle __TypeHandle
    A helper struct that stores the EntityTypeHandle, ComponentTypeHandle, BufferTypeHandle, ComponentLookup, and BufferLookup. __AssignHandles fills these handles from the SystemState so the job can use them safely with Burst and parallel scheduling.

  • private struct HandleTempEntitiesJob (nested)
    The Burst-compiled IJobChunk implementation that performs the per-chunk processing of Temp entities. It receives the various TypeHandles, lookups and a parallel EntityCommandBuffer writer and contains the logic for Create, Update and Delete operations.

Properties

  • None (no public properties are declared on this system).

Constructors

  • public ApplyZonesSystem()
    Default parameterless constructor (preserved). No special initialization beyond what OnCreate does.

Methods

  • protected override void OnCreate()
    Initializes the system:
  • Acquires (or creates) the ToolOutputBarrier from the World.
  • Creates an EntityQuery selecting Temp (read-only) and Block (read-only).
  • Builds the m_AppliedTypes ComponentTypeSet (Applied, Created, Updated).
  • Calls RequireForUpdate(m_TempQuery) so the system updates only when relevant Temp entities exist. This prepares the system for scheduling the burst job in OnUpdate.

  • protected override void OnUpdate()
    Schedules the Burst-compiled HandleTempEntitiesJob in parallel using JobChunkExtensions.ScheduleParallel. The job is provided with:

  • EntityTypeHandle, ComponentTypeHandle, BufferTypeHandle, ComponentLookup, BufferLookup (all resolved via InternalCompilerInterface helper calls and the __TypeHandle).
  • The m_AppliedTypes set.
  • A parallel EntityCommandBuffer obtained from m_ToolOutputBarrier.CreateCommandBuffer().AsParallelWriter(). After scheduling, the job handle is registered with m_ToolOutputBarrier via AddJobHandleForProducer, and base.Dependency is updated to the returned job handle.

  • private void __AssignQueries(ref SystemState state)
    A compiler helper used during system construction. In this implementation, it only constructs and disposes a temporary EntityQueryBuilder. Actual type handle assignment is done in __AssignHandles below.

  • protected override void OnCreateForCompiler()
    Compiler-time initialization hook called by generated code. Calls __AssignQueries and __TypeHandle.__AssignHandles to set up TypeHandles from the SystemState.

  • private struct TypeHandle and __AssignHandles(ref SystemState state)
    TypeHandle holds the required Entity/Component/Buffer handles and lookups for the job. __AssignHandles fills these handles using the provided SystemState so they can later be transformed into runtime handles via InternalCompilerInterface.Get*TypeHandle/GetComponentTypeHandle/GetBufferTypeHandle/GetComponentLookup/GetBufferLookup.

  • HandleTempEntitiesJob methods (inside nested job):

  • Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
    Iterates the chunk's entities and processes each Temp entry. If the zone buffer accessor exists on the chunk, it uses per-entity bufferAccessor[i] overload to provide cell data; otherwise calls the other overloads. Dispatches to Delete, Update, or Create depending on TempFlags and Temp.m_Original.
  • Delete(int chunkIndex, Entity entity, Temp temp)
    If the original entity (temp.m_Original) has a Cells buffer, add Deleted to the original entity. Also add Deleted to the temp entity. This marks both entities for deletion/reclamation by later systems.
  • Update(int chunkIndex, Entity entity, Temp temp, bool updateOriginal = true)
    If the original entity has a Hidden component, remove Hidden (revealing the original). If updateOriginal is false, add BatchesUpdated to the original (indicates partial changes needing batching). If updateOriginal is true and the original has a Cells buffer, add Updated to the original entity. Finally, add Deleted to the temp entity.
  • Update(int chunkIndex, Entity entity, Temp temp, DynamicBuffer cells)
    When cell data (cells) is provided with the Temp, this overload merges selected cell changes into the original entity's buffer:
    • If the original entity has a Cells buffer, copy and modify the original buffer into a new buffer set via the command buffer.
    • For every cell index i: if the temp cell's CellFlags.Selected is set, then:
      • If the existing buffer value has CellFlags.Overridden, and the zones are equal, clear Overridden on the value.
      • Otherwise set value.m_Zone to the temp cell's m_Zone.
    • After finishing buffer updates, it calls the simpler Update overload to perform Hidden removal / Updated marking and add Deleted for the temp.
  • Create(int chunkIndex, Entity entity)
    Finalizes creation: removes Temp from the entity and adds the m_AppliedTypes (Applied, Created, Updated) to mark the entity as applied/finalized.

Notes about flags/components used by the job: - Temp: temporary tool-side component representing a proposed change. Has fields m_Flags, m_Original (Entity). - TempFlags.Delete: used to indicate a temporary entity should be deleted instead of applied. - Cell: buffer element representing per-cell zoning state (m_State flags and m_Zone data). - CellFlags.Selected / CellFlags.Overridden: used to determine whether to apply a cell change and how overridden states are handled. - Hidden: a marker component used to hide original data while temp/preview edits are in progress. Update removes Hidden to reveal original entity. - Updated / Created / Applied / Deleted / BatchesUpdated: marker components used by other systems to react to changes (e.g., re-batching, re-rendering, cleanup).

Concurrency / Safety: - The job is Burst-compiled and scheduled parallel per-chunk. - It uses ComponentLookup and BufferLookup (read-only) to test presence of components and to read original buffers when needed. - All writes to entities are done via an EntityCommandBuffer.ParallelWriter from ToolOutputBarrier to safely defer structural changes to command playback time. - m_ToolOutputBarrier.AddJobHandleForProducer(jobHandle) ensures the barrier knows about the producer job so it can enforce proper ordering.

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    // Example: The system's OnCreate: acquire the tool output barrier and build the Temp query
    m_ToolOutputBarrier = World.GetOrCreateSystemManaged<ToolOutputBarrier>();
    m_TempQuery = GetEntityQuery(ComponentType.ReadOnly<Temp>(), ComponentType.ReadOnly<Block>());
    m_AppliedTypes = new ComponentTypeSet(
        ComponentType.ReadWrite<Applied>(),
        ComponentType.ReadWrite<Created>(),
        ComponentType.ReadWrite<Updated>()
    );
    RequireForUpdate(m_TempQuery);
}

Additional tips for modders: - If you add or change Temp/Cell semantics, ensure the TypeHandle and job logic are updated accordingly and remain Burst-compatible (avoid managed references inside the job). - When debugging command-buffer-driven structural changes, remember that many changes are deferred until the ECB is played back; use barrier job handles to enforce order or add logging before/after playback. - The ApplyZonesSystem expects Temp entities to optionally reference an original entity via Temp.m_Original. If m_Original == Entity.Null, the job assumes a new creation path (Create) and will finalize the Temp entity by removing Temp and adding the applied marker types.