Skip to content

Game.Simulation.PoliceCarAISystem

Assembly:
Game (assembly inferred from namespace and project layout)

Namespace:
Game.Simulation

Type:
class

Base:
GameSystemBase

Summary:
PoliceCarAISystem is the simulation system that drives police car behavior each simulation tick. It schedules a parallel chunk job (PoliceCarTickJob) to update individual police vehicle entities (pathfinding, dispatch handling, parking, crime reduction, accident securing, boarding/disembarking, etc.) and a follow-up single-threaded job (PoliceActionJob) to apply aggregated world changes (reduce crime values, add patrol requests, mark accident sites secured, bump dispatch indices). The system uses the ECS Job system, command buffers, and a NativeQueue to communicate actions from the parallel job to the single-threaded action job. It also interfaces with the pathfinding setup system and the simulation frame index.


Fields

  • private struct PoliceAction
    Holds information about actions the parallel tick job wants to apply on the main world (sent via a NativeQueue). Contains an action type, a target entity, optionally the request entity, crime reduction rate, and dispatch index.

  • private enum PoliceActionType
    Action kinds produced by the tick job: ReduceCrime, AddPatrolRequest, SecureAccidentSite, BumpDispatchIndex.

  • private struct PoliceCarTickJob : IJobChunk
    Burst-compiled, parallel chunk job that performs the main per-police-car logic. Reads and writes many components (PoliceCar, Car, CarCurrentLane, PathOwner, Target, buffers such as ServiceDispatch and CarNavigationLane). Produces actions via a NativeQueue and enqueues pathfinding requests to the PathfindSetupSystem.

  • private struct PoliceActionJob : IJob
    Burst-compiled single-threaded job that dequeues PoliceAction items and applies component updates (CrimeProducer, AccidentSite, PolicePatrolRequest dispatch index) to the world.

  • private struct TypeHandle
    Container that caches Entity/Component/Buffer lookups and handles. Used during OnCreateForCompiler to assign and cache handles for faster job setup.

  • private EndFrameBarrier m_EndFrameBarrier
    Command buffer barrier used to create an end-of-frame parallel command buffer for jobs to record structural changes.

  • private SimulationSystem m_SimulationSystem
    Reference to simulation system to read the simulation frame index.

  • private PathfindSetupSystem m_PathfindSetupSystem
    Reference to the pathfind setup system used to enqueue pathfinding requests produced by police car agents.

  • private EntityQuery m_VehicleQuery
    EntityQuery used to select police car entities (CarCurrentLane, Owner, PrefabRef, PathOwner, PoliceCar, Car, Target, etc.).

  • private EntityArchetype m_PolicePatrolRequestArchetype
    Archetype used to create patrol ServiceRequest entities.

  • private EntityArchetype m_PoliceEmergencyRequestArchetype
    Archetype used to create emergency ServiceRequest entities.

  • private EntityArchetype m_HandleRequestArchetype
    Archetype used to create HandleRequest event entities (when a vehicle takes responsibility for a request).

  • private ComponentTypeSet m_MovingToParkedCarRemoveTypes
    ComponentTypeSet listing components to remove when a car transitions from moving to parked.

  • private ComponentTypeSet m_MovingToParkedAddTypes
    ComponentTypeSet listing components to add when a car is parked.

  • private TypeHandle __TypeHandle
    Instance of the TypeHandle struct used to cache component and buffer handles.

Properties

  • None (this system exposes no public properties).

Constructors

  • public PoliceCarAISystem()
    Default constructor. System is created by World/System management. OnCreate override initializes subsystems and queries.

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns update interval (16). Controls coarser tick scheduling (modifiers in system scheduling).

  • public override int GetUpdateOffset(SystemUpdatePhase phase)
    Returns update offset (5). Used together with interval to determine when the system runs relative to the global phase.

  • [Preserve] protected override void OnCreate()
    Initializes references:

  • Grabs EndFrameBarrier, SimulationSystem and PathfindSetupSystem.
  • Creates the EntityQuery selecting police car entities (excludes Deleted/Temp/TripSource/OutOfControl).
  • Creates archetypes for patrol and emergency requests and handle request events.
  • Prepares ComponentTypeSets for parking transitions.
  • Calls RequireForUpdate(m_VehicleQuery) to only run when relevant entities exist.

  • [Preserve] protected override void OnUpdate()
    Main runtime logic:

  • Creates a NativeQueue (temporary job allocator).
  • Fills and schedules a PoliceCarTickJob (parallel) which:
    • Updates each vehicle: shift timers, path reset/creation, selecting next dispatch, returning to station, parking, disembarking, accident securing, crime reduction, pathfinding setup.
    • Enqueues pathfind setups to PathfindSetupSystem via its queue writer.
    • Enqueues PoliceAction items into the shared action queue for changes that must run on main thread.
    • Writes structural changes to an end-of-frame command buffer (m_EndFrameBarrier).
  • Schedules PoliceActionJob dependent on the tick job which consumes the queue and applies component changes to CrimeProducer, AccidentSite and PolicePatrolRequest.
  • Disposes the queue after the action job completes, registers job handles with pathfind setup and EndFrameBarrier, and sets base.Dependency.

  • protected override void OnCreateForCompiler()
    Internal helper to assign queries and call __TypeHandle.__AssignHandles. Used by generated/compiled runtime patterns.

  • private void __AssignQueries(ref SystemState state)
    Internal (compiler) stub that ensures query builder code exists; used by OnCreateForCompiler.

  • (Private inner job methods) PoliceCarTickJob members:

  • void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask) — main chunk execution method reading/writing arrays and calling Tick for each entity.
  • private void Tick(...) — per-vehicle tick logic (very large method). Handles shift logic, crime reduction, path resets, selecting/handling dispatches, starting/stopping vehicle, parking, disembark, return to station, path creation (FindNewPath), accident securing and more.
  • Helper methods used by Tick:

    • CheckParkingSpace
    • ParkCar
    • StartDisembarking / StopDisembarking
    • FindNewPath
    • SecureAccidentSite
    • EndNavigation
    • IsCloseEnough
    • StopVehicle / StartVehicle
    • CheckServiceDispatches
    • BumpDispachIndex
    • PreAddPatrolRequests
    • RequestTargetIfNeeded
    • SelectNextDispatch
    • ReturnToStation
    • ResetPath
    • AddPatrolRequests
    • TryReduceCrime (overloads) — enqueue PoliceAction to reduce crime or add patrol requests.
  • (Private inner job) PoliceActionJob members:

  • public void Execute() — dequeues PoliceAction items and applies them to the component lookups:
    • ReduceCrime: reduces CrimeProducer.m_Crime (clamps by available crime value).
    • AddPatrolRequest: sets CrimeProducer.m_PatrolRequest and m_DispatchIndex.
    • SecureAccidentSite: sets AccidentSiteFlags.Secured and m_SecuredFrame.
    • BumpDispatchIndex: increments PolicePatrolRequest.m_DispatchIndex.

Notes about concurrency and design: - The parallel PoliceCarTickJob does not directly mutate shared components like CrimeProducer or AccidentSite; instead it enqueues PoliceAction items on a NativeQueue and a single-threaded PoliceActionJob applies those changes. Structural changes are recorded through an EndFrameBarrier command buffer created in OnUpdate and passed to the parallel job as a ParallelWriter. - Pathfinding requests are queued into PathfindSetupSystem via m_PathfindSetupSystem.GetQueue(...). This system receives JobHandle and queue writer integration in OnUpdate. - The system relies heavily on component lookups (ComponentLookup / BufferLookup) and PathElements buffer to append/trim paths and to evaluate dispatches. - PoliceCarTickJob is Burst-compiled for performance.

Usage Example

// Example: override OnCreate to inspect or extend behavior (modders typically hook into components/events rather than subclassing systems).
[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    // Example: get the vehicle query to read its filter
    // m_VehicleQuery is created in the original system; you can mirror the component set to create your own query if you want to track police cars.
    // You can also create custom ServiceRequest entities using the archetypes (created in original system) if you want custom dispatches.
}

Additional hints for modders - To influence police behavior: - Modify CrimeProducer components on buildings to change how patrol requests are created or how crime is tracked. - Add or modify PolicePatrolRequest or PoliceEmergencyRequest entities (the system creates these using archetypes). You can create ServiceRequest entities with the same component layout to inject requests. - Adjust PoliceCarData on prefabs (m_CrimeReductionRate, m_CriminalCapacity, m_ShiftDuration) to change vehicle capabilities. - To interpose on actions: - The system centralizes world changes into PoliceAction entries that are executed in PoliceActionJob. A mod could replicate the pattern or schedule a dependent job that runs after PoliceActionJob (use the system's Dependency handle) to inspect or override changes. - Be mindful of jobs and thread-safety: - Do not mutate components read by the parallel job from the main thread during its execution. - Use command buffers (EndFrameBarrier.CreateCommandBuffer) or enqueue your own jobs to safely modify the world from a job. - Pathfinding: police cars add pathfind setups through PathfindSetupSystem. If you change pathfinding or path elements, ensure your changes are compatible with PathfindSetupSystem (queue writers and job dependencies).

If you want, I can: - Generate a short patch showing how to create a custom PoliceEmergencyRequest entity (example code). - Extract and document specific inner methods (e.g., Tick or FindNewPath) in more detail for modding guidance.