Skip to content

Game.Simulation.AmbulanceAISystem

Assembly: Assembly-CSharp
Namespace: Game.Simulation

Type: public class AmbulanceAISystem

Base: GameSystemBase

Summary:
AmbulanceAISystem is the Entity Component System (ECS) system that manages ambulance vehicles' AI and behaviour. It schedules a Burst-compiled parallel IJobChunk (AmbulanceTickJob) to process all ambulance entities: handling dispatches, pathfinding setup, loading/unloading patients, parking, returning to depot, emergency flags, and interacting with healthcare requests. The system integrates with PathfindSetupSystem (to enqueue pathfind tasks), EndFrameBarrier (for a parallel command buffer), and the SimulationSystem (for accessing the current simulation frame index and random seed). It runs at a reduced frequency (GetUpdateInterval returns 16) to limit how often ambulances are ticked.


Fields

  • private EndFrameBarrier m_EndFrameBarrier
    Reference to the EndFrameBarrier system used to create a parallel EntityCommandBuffer for making structural changes safely at end of frame.

  • private PathfindSetupSystem m_PathfindSetupSystem
    Reference to the system used to enqueue pathfinding setup requests (provides the m_PathfindQueue).

  • private SimulationSystem m_SimulationSystem
    Reference to the SimulationSystem used to query the current simulation frame index and to obtain random seeds.

  • private EntityQuery m_VehicleQuery
    Query used to select ambulance entities processed by this system (includes filters like excluding Deleted, Temp, TripSource, OutOfControl).

  • private EntityArchetype m_HealthcareRequestArchetype
    Archetype used when creating new healthcare request entities (ServiceRequest + HealthcareRequest + RequestGroup).

  • private EntityArchetype m_HandleRequestArchetype
    Archetype used for handle-request events (HandleRequest + Event).

  • private ComponentTypeSet m_MovingToParkedCarRemoveTypes
    Set of component types that are removed from a vehicle when it transitions from moving to parked state (e.g., Moving, TransformFrame, PathElement, PathInformation, ServiceDispatch, etc.).

  • private ComponentTypeSet m_MovingToParkedAddTypes
    Set of component types that are added when a vehicle becomes parked (e.g., ParkedCar, Stopped, Updated).

  • private TypeHandle __TypeHandle
    Internal container for the various Entity/Component/Buffer type handles and ComponentLookup/BufferLookup instances used by the AmbulanceTickJob. Populated in OnCreateForCompiler and used in OnUpdate to create the job's handles.

Properties

  • None (no public properties exposed by this system).

Constructors

  • public AmbulanceAISystem()
    Default constructor. Marked with [Preserve] attribute in the source to avoid stripping. Initialization of references and queries is performed in OnCreate.

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns 16 in source; the system is scheduled to update once every 16 simulation ticks (coarse-grained update).

  • public override int GetUpdateOffset(SystemUpdatePhase phase)
    Returns 0 in source; no offset is applied.

  • protected override void OnCreate()
    Sets up system references and entity query, creates required archetypes and ComponentTypeSets, and calls RequireForUpdate(m_VehicleQuery) to ensure the system only runs when ambulance entities exist. Retrieves EndFrameBarrier, PathfindSetupSystem and SimulationSystem instances.

  • protected override void OnUpdate()
    Creates and schedules the AmbulanceTickJob (Burst compiled) using the pre-populated type handles and lookups. The job gets a parallel writer command buffer from m_EndFrameBarrier, and a pathfind setup queue writer from m_PathfindSetupSystem. Adds the job handle to PathfindSetupSystem and EndFrameBarrier so the job producers are tracked.

  • protected override void OnCreateForCompiler()
    Internal helper used by generated code; assigns queries and type handles by calling __AssignQueries and __TypeHandle.__AssignHandles.

  • private void __AssignQueries(ref SystemState state)
    Internal method used at compile-time to assign any internal queries (generated code stub).

  • Nested struct: AmbulanceTickJob : IJobChunk (Burst-compiled)

  • Role: Processes chunks of ambulance entities in parallel. It contains many read-only and read/write component handles and lookups, a parallel command buffer, and a parallel pathfind-setup queue.
  • Main per-entity flow implemented in Tick(...):
    • CheckServiceDispatches: Validate/trim dispatch queue and set Dispatched flag when applicable.
    • RequestTargetIfNeeded: Periodically create a HealthcareRequest if ambulance has a pending target request but no registered request exists.
    • ResetPath: Reinitialize path elements when an updated path is consumed and update car flags/parking status/effects.
    • Path validity checks: If a target entity no longer exists or pathfinding failed, the vehicle is either deleted (if stuck/returning) or sent back to depot.
    • Arrival handling: When an ambulance reaches path end / parking space / is at target, it handles unloading patients, parking, selecting next dispatch, or returning to depot.
    • Parking and movement: ParkCar sets parked components and fixes parking location; StopVehicle/StartVehicle toggle movement components and ensure relevant lanes are marked PathfindUpdated.
    • LoadPatients/UnloadPatients handle boarding/disembarking logic tied to HealthProblem and CurrentTransport/CurrentBuilding components (including random critical state decisions).
    • FindNewPath constructs PathfindParameters and enqueues path setup via VehicleUtils/PathfindSetupSystem when a new path is required (takes into account flags like FindHospital, Dispatched, Transporting, Critical, owner-vs-foreign-target).
    • SelectDispatch consumes service dispatches, validates request targets, may append precomputed path elements from the healthcare request to the vehicle's path, and sets path/flags accordingly.
    • CheckParkingSpace validates/claims parking curves and parking spaces on the path.
    • ResetPath recalculates ambulance.m_PathElementTime, resets parking lane status and effects, and propagates target/destination changes to passengers.
  • Notable helper methods inside the job (signatures trimmed):

    • void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
    • private void Tick(...)
    • private void ParkCar(int jobIndex, Entity entity, Owner owner, ref Ambulance ambulance, ref Car car, ref CarCurrentLane currentLane)
    • private void StopVehicle(int jobIndex, Entity entity, ref CarCurrentLane currentLaneData)
    • private void StartVehicle(int jobIndex, Entity entity, ref CarCurrentLane currentLaneData)
    • private bool LoadPatients(...)
    • private bool UnloadPatients(DynamicBuffer passengers, ref Ambulance ambulance)
    • private void FindNewPath(...)
    • private Entity FindDistrict(Entity building)
    • private void TransportToHospital(...)
    • private void ReturnToDepot(...)
    • private void CheckServiceDispatches(...)
    • private void RequestTargetIfNeeded(int jobIndex, Entity entity, ref Ambulance ambulance)
    • private bool SelectDispatch(...)
    • private void CheckParkingSpace(...)
    • private void ResetPath(...)
  • Notes: The job uses multiple ComponentLookup and BufferLookup instances (e.g., m_PathElements is NativeDisableParallelForRestriction) and requires careful interaction with the command buffer and pathfind queue. Most vehicle state transitions are implemented by adding/removing components via the parallel writer.

Usage Example

// Obtain the system from the default world (common usage in mods/tools)
var ambulanceSystem = World.DefaultGameObjectInjectionWorld
    .GetExistingSystemManaged<Game.Simulation.AmbulanceAISystem>();

if (ambulanceSystem != null)
{
    // Query the configured update interval (system updates every 16 ticks by default)
    int interval = ambulanceSystem.GetUpdateInterval(SystemUpdatePhase.Simulation);
    UnityEngine.Debug.Log($"AmbulanceAISystem update interval: {interval}");
}

// You typically don't call OnUpdate manually. To affect ambulances from a mod,
// create/modify components (e.g., ServiceRequest, HealthcareRequest, ServiceDispatch)
// on relevant entities and the system will pick them up on its scheduled ticks.

Notes for modders: - The system depends on many internal game component types (HealthProblem, HealthcareRequest, ServiceDispatch, PathElement, etc.). Changing or creating requests must match the expected archetypes and component semantics. - Because the system uses a parallel command buffer (via EndFrameBarrier), structural changes are safe but deferred — expect changes to be applied at the end of the frame. - To influence pathfind behavior, consider interacting with PathfindSetupSystem queues or by setting appropriate component data (Targets, PathElements) on involved entities.