Skip to content

Game.EvacuationDispatchSystem

Assembly:
Game (inferred from namespace and project)

Namespace:
Game.Simulation

Type:
class

Base:
GameSystemBase

Summary:
EvacuationDispatchSystem is an ECS system that processes evacuation requests and coordinates vehicle dispatches for Cities: Skylines 2. It runs periodically (update interval 16) and uses burst-compiled jobs to: - Validate and tick ServiceRequest state on EvacuationRequest entities, - Start pathfinding for vehicle origins or destinations, - Mark requests as Dispatched when a vehicle source is found, - Reset failed or completed requests and enqueue actual vehicle-dispatch operations for later processing.

The system cooperates with EndFrameBarrier (for safe command-buffer writes), SimulationSystem (to get the global frame index), and PathfindSetupSystem (to enqueue pathfinding setup requests). It uses two primary jobs: EvacuationDispatchJob (IJobChunk, parallel over matching chunks) and DispatchVehiclesJob (IJob, consumes enqueued vehicle dispatches to update buffers/requests).


Fields

  • private EndFrameBarrier m_EndFrameBarrier
    Reference to EndFrameBarrier system used to create an EntityCommandBuffer. The system uses the barrier to issue structural changes (add/remove components, destroy entities) safely from jobs and to register job handles as producer handles.

  • private SimulationSystem m_SimulationSystem
    Reference to the SimulationSystem to read the current frameIndex. The system divides frameIndex into a small modulo to determine which update-stage to run.

  • private PathfindSetupSystem m_PathfindSetupSystem
    Reference to the PathfindSetupSystem used to obtain a pathfind-setup queue writer. Evacuation requests enqueue SetupQueueItem entries here for pathfinding origin/destination resolution.

  • private EntityQuery m_RequestQuery
    EntityQuery for entities that have EvacuationRequest and UpdateFrame (used to require the system only when relevant requests exist and for scheduling the IJobChunk over those entities).

  • private TypeHandle __TypeHandle
    Internal container of EntityTypeHandle / ComponentTypeHandle / ComponentLookup / BufferLookup instances; assigned in OnCreateForCompiler and used to fetch read/write handles for jobs.

Properties

  • None (no public properties exposed by this class)

Constructors

  • public EvacuationDispatchSystem()
    Default constructor (preserved). System initialization that relies on OnCreate to set up required references and query.

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns the system's desired update interval. EvacuationDispatchSystem returns 16, meaning it runs effectively once every 16 simulation frames (the system uses the simulation frameIndex and small modulo math to stagger updates).

  • protected override void OnCreate()
    Initializes the system:

  • Gets EndFrameBarrier, SimulationSystem, and PathfindSetupSystem via World.GetOrCreateSystemManaged.
  • Creates the EntityQuery for EvacuationRequest + UpdateFrame and calls RequireForUpdate to only run when there are matching entities. This is where the system binds itself into the simulation and pathfinding subsystems.

  • protected override void OnUpdate()
    Main scheduling method. Key responsibilities:

  • Computes which sub-frame the system should operate on using simulation frameIndex >> 4 & 3 and the nextUpdateFrameIndex.
  • Creates a NativeQueue (persistent for the scheduled job usage) to transfer vehicle-dispatch actions from the chunk job to the single-threaded job.
  • Prepares EvacuationDispatchJob with a wide set of handles, lookups, the command buffer (from EndFrameBarrier), and the pathfind queue writer (from PathfindSetupSystem).
  • Prepares DispatchVehiclesJob which dequeues vehicle dispatches and either appends ServiceDispatch buffers to vehicle sources or flags ServiceRequest to skip cooldown.
  • Schedules EvacuationDispatchJob as a parallel JobChunk over m_RequestQuery, then schedules DispatchVehiclesJob after it.
  • Disposes the vehicleDispatches queue after the jobs complete and registers the pathfind queue writer / command buffer job handle with their respective systems (PathfindSetupSystem.AddQueueWriter, EndFrameBarrier.AddJobHandleForProducer). Behavior details implemented inside the EvacuationDispatchJob (see nested job descriptions).

  • protected override void OnCreateForCompiler()
    Compiler-time helper: assigns type handles (calls __TypeHandle.__AssignHandles) and executes __AssignQueries. This is part of the generated glue that sets up type handles for jobs.

  • private void __AssignQueries(ref SystemState state)
    Internal method used during OnCreateForCompiler to ensure any queries are assigned (empty in this implementation aside from an EntityQueryBuilder disposal).

Nested/Worker types (summarized because they contain the actual core logic):

  • EvacuationDispatchJob (private struct, BurstCompile, implements IJobChunk)
  • Runs on matching archetype chunks and does the per-entity evacuation handling. Major responsibilities:
    • For requests whose UpdateFrame shared component matches the "next" sub-frame, it ticks ServiceRequest state and starts pathfinding for either vehicle source (FindVehicleSource) or vehicle target (FindVehicleTarget) depending on the ServiceRequestFlags.Reversed flag.
    • For requests whose UpdateFrame matches the active UpdateFrameIndex, handles entities that have Dispatched or PathInformation:
    • If Dispatched exists: validates handler presence (ValidateHandler) and adjusts cooldown, or resets failing requests.
    • If PathInformation exists: if path contains origin/destination, either resets reverse requests (ResetReverseRequest) or dispatches vehicles (DispatchVehicle); otherwise marks request failed/reset.
    • Validations:
    • ValidateReversed: checks EmergencyShelter and PublicTransport components for available vehicles and marks their m_TargetRequest to the request entity.
    • ValidateTarget: checks InDanger component flags and associates the evacuation request to the danger entity, preventing duplicate requests.
    • Enqueues VehicleDispatch entries to a NativeQueue to be consumed by DispatchVehiclesJob, and enqueues pathfinding setup items into PathfindSetupSystem's queue for origin/destination resolution.
  • Uses many ComponentLookup/BufferLookup/ComponentTypeHandle fields. Some ComponentLookup fields are annotated with NativeDisableParallelForRestriction because the job updates components across entities in parallel (the job carefully ensures correctness through validations and checks).

  • DispatchVehiclesJob (private struct, BurstCompile, implements IJob)

  • Single-threaded consumer that dequeues VehicleDispatch items produced by EvacuationDispatchJob.
  • For each VehicleDispatch:
    • If the source entity has a ServiceDispatch buffer, adds a new ServiceDispatch entry referring to the request.
    • Else, if the source entity has only a ServiceRequest component, sets the ServiceRequest m_Flags to include SkipCooldown so the source will be considered again soon (bypassing cooldown).
  • This job applies the actual "assign vehicle to request" semantics without structural changes (buffer appends or simple component writes).

  • TypeHandle (private struct)

  • Container of EntityTypeHandle, ComponentTypeHandle, SharedComponentTypeHandle, ComponentLookup and BufferLookup instances used by EvacuationDispatchJob and DispatchVehiclesJob. __AssignHandles(ref SystemState) sets them up.

Notes / Important behavior and constraints: - The system depends on the UpdateFrame shared component pattern to split and stagger processing across sub-frames. It compares both a "next" frame index and the active index to determine whether to start a pathfind or to finalize dispatching. - Structural changes to request entities (AddComponent, AddBuffer, RemoveComponent, RemoveComponent, DestroyEntity, etc.) are performed via an EndFrameBarrier's parallel EntityCommandBuffer writer. - The pathfind work is created via PathfindSetupSystem.GetQueue(this, 64).AsParallelWriter() and m_PathfindQueue.Enqueue(new SetupQueueItem(...)). The system enqueues SetupQueueItem entries rather than computing paths synchronously. - Uses NativeDisableParallelForRestriction on some ComponentLookup fields to update shared components; these updates are carefully guarded by validation checks to avoid race conditions. - Update interval 16 and the usage of frameIndex bit shifts means the system processes requests in a coarse, batched manner. Expect up to 16 frames between repeated ticks for requests.

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    // Typical initialization performed by EvacuationDispatchSystem:
    m_EndFrameBarrier = World.GetOrCreateSystemManaged<EndFrameBarrier>();
    m_SimulationSystem = World.GetOrCreateSystemManaged<SimulationSystem>();
    m_PathfindSetupSystem = World.GetOrCreateSystemManaged<PathfindSetupSystem>();
    m_RequestQuery = GetEntityQuery(ComponentType.ReadOnly<EvacuationRequest>(), ComponentType.ReadOnly<UpdateFrame>());
    RequireForUpdate(m_RequestQuery);
}

Additional notes for modders: - To add custom evacuation-related behavior you can: - Create/modify EvacuationRequest entities with appropriate ServiceRequest component data and UpdateFrame shared component to drive scheduling. - Interact with PathfindSetupSystem queue items if you need to intercept path setup for evacuation transport. - Be careful when modifying components that EvacuationDispatchJob expects (InDanger, EmergencyShelter, PublicTransport, ParkedCar, Owner, ServiceDispatch buffers, ServiceRequest). Changes to those types can affect this system. - If you add systems that also write to the same components, ensure you synchronize via job handles or use the same barrier systems (EndFrameBarrier, PathfindSetupSystem) to avoid data races.