Game.Simulation.TransportDepotAISystem
Assembly:
Assembly-CSharp
Namespace:
Game.Simulation
Type:
class
Base:
GameSystemBase
Summary:
Handles the simulation logic for transport depots (bus/metro/train/taxi/cargo depots). The system:
- Iterates depot buildings (TransportDepot) and their OwnedVehicle and ServiceDispatch buffers.
- Computes available/producing vehicles based on building efficiency, maintenance and production timers.
- Spawns vehicles (or marks produced vehicles) and converts parked vehicles into moving vehicles by adding/removing appropriate ECS components.
- Creates/handles transport/taxi requests (TransportVehicleRequest / TaxiRequest) and produces launch events when needed.
- Enqueues lightweight depot actions (SetDisabled, ClearOdometer) to be processed on the main thread job via TransportDepotActionJob.
- Uses Burst-compiled jobs (TransportDepotTickJob, TransportDepotActionJob), the EndFrameBarrier command buffer, and a TransportVehicleSelectData helper for vehicle selection/creation.
This is an ECS (DOTS) system tightly coupled to the game's component types (ParkedCar/ParkedTrain, PublicTransport/CargoTransport/Taxi, Odometer, Produced, PathInformation, etc.) and to prefab data (TransportDepotData, VehicleModel, TransportLineData, etc.). It's scheduled to run periodically (see GetUpdateInterval/GetUpdateOffset).
Fields
-
private EndFrameBarrier m_EndFrameBarrier
Used to create an EntityCommandBuffer (parallel writer) to make entity/component changes produced by the worker job (TransportDepotTickJob). Ensures changes are applied at the end of frame in a safe producer/consumer manner. -
private TransportVehicleSelectData m_TransportVehicleSelectData
Helper used to select and instantiate vehicle prefabs matching depot and request criteria. Prepares vehicle-prefab-related lookups in PreUpdate and finalizes in PostUpdate. Important for controlling which vehicle prefabs are eligible for spawning by this system.
(Other notable fields in the class: EntityQuery instances m_BuildingQuery / m_VehiclePrefabQuery / m_EventPrefabQuery; archetypes for requests and handle entities; several ComponentTypeSet definitions used to transition parked vehicles to moving states; m_CityConfigurationSystem for game config access.)
Properties
public TransportVehicleSelectData TransportVehicleSelectData { get; }
Accessor-style information: m_TransportVehicleSelectData is the subsystem responsible for prefab selection and vehicle creation logic. Modders can look into TransportVehicleSelectData to understand how vehicle prefabs are chosen, or to extend selection criteria if creating custom depots/vehicles.
Constructors
public TransportDepotAISystem()
Default public constructor. The system initialization is done in OnCreate where queries, archetypes and supporting data are allocated/created (EndFrameBarrier, CityConfigurationSystem lookup, TransportVehicleSelectData construction, EntityQuery setup, archetype creation and component type sets). No custom parameters.
Methods
protected override void OnCreate()
: System.Void
Initializes the system:- Obtains EndFrameBarrier and CityConfigurationSystem from the World.
- Constructs m_TransportVehicleSelectData and the EntityQueries used by the system (depot buildings, vehicle prefabs, event prefabs).
- Creates archetypes used for spawning request entities (TransportVehicleRequest / TaxiRequest and HandleRequest).
- Builds ComponentTypeSet instances used when moving parked vehicles into moving state (taxi, bus, train variants).
-
Calls RequireForUpdate(m_BuildingQuery) to ensure the system only runs when depots exist. Important for modders who want to extend or replace behavior: if you override or call base.OnCreate you must re-create/adjust these queries/archetypes similarly.
-
protected override void OnUpdate()
: System.Void
Main scheduling method: - Calls m_TransportVehicleSelectData.PreUpdate(...) to prepare vehicle prefab selection data.
- Gathers event prefabs (vehicle-launch events) asynchronously.
- Creates a NativeQueue
used by the parallel tick job to defer small per-vehicle modifications (disable flags, clear odometer). - Builds and schedules TransportDepotTickJob (IJobChunk, Burst) to process depot chunks in parallel. It:
- Iterates OwnedVehicle and ServiceDispatch buffers,
- Updates maintenance/production state,
- Spawns vehicles or marks them as Produced,
- Enqueues DepotAction entries for SetDisabled / ClearOdometer,
- Ensures parked vehicle capacity is enforced (randomly deleting excess parked vehicles).
- Schedules TransportDepotActionJob (IJob) to dequeue DepotAction items and apply component updates that are not safe or convenient to do inside the chunk job (update PublicTransport/CargoTransport/Taxi states and Odometer clearing).
-
Disposes TempJob allocations (event prefab chunk list, action queue) with proper dependencies and registers producer job handles with m_EndFrameBarrier. This method demonstrates the canonical DOTS pattern: heavy parallel chunk work (IJobChunk) + a small main-thread job to apply per-entity component mutations that are not handled in-parallel.
-
public override int GetUpdateInterval(SystemUpdatePhase phase)
: int
Returns 256 — the intended update interval (in simulation ticks) for this system. -
public override int GetUpdateOffset(SystemUpdatePhase phase)
: int
Returns 32 — the offset for the periodic update. Combined with interval this controls when depots tick relative to other systems.
(Internally there are many private helper functions implemented inside TransportDepotTickJob: Tick, RequestTargetIfNeeded, TryCreateLaunchEvent, SpawnVehicle, RemoveCollidingParkedTrain. These contain the core spawn/dispatch/maintenance logic — examine them to understand exact conditions for spawning, Produced usage, how parked vehicles are transitioned, and which components/archetypes are used.)
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
m_EndFrameBarrier = base.World.GetOrCreateSystemManaged<EndFrameBarrier>();
m_CityConfigurationSystem = base.World.GetOrCreateSystemManaged<CityConfigurationSystem>();
m_TransportVehicleSelectData = new TransportVehicleSelectData(this);
m_BuildingQuery = GetEntityQuery(
ComponentType.ReadOnly<Game.Buildings.TransportDepot>(),
ComponentType.ReadOnly<ServiceDispatch>(),
ComponentType.ReadOnly<PrefabRef>(),
ComponentType.Exclude<Temp>(),
ComponentType.Exclude<Deleted>());
m_VehiclePrefabQuery = GetEntityQuery(TransportVehicleSelectData.GetEntityQueryDesc());
m_EventPrefabQuery = GetEntityQuery(ComponentType.ReadOnly<VehicleLaunchData>(), ComponentType.ReadOnly<PrefabData>(), ComponentType.Exclude<Locked>());
// create request archetypes used by the system
m_TransportVehicleRequestArchetype = base.EntityManager.CreateArchetype(
ComponentType.ReadWrite<ServiceRequest>(),
ComponentType.ReadWrite<TransportVehicleRequest>(),
ComponentType.ReadWrite<RequestGroup>());
m_TaxiRequestArchetype = base.EntityManager.CreateArchetype(
ComponentType.ReadWrite<ServiceRequest>(),
ComponentType.ReadWrite<TaxiRequest>(),
ComponentType.ReadWrite<RequestGroup>());
// ... ComponentTypeSet initialization ...
RequireForUpdate(m_BuildingQuery);
}
Notes for modders: - To customize spawning behavior, check TransportVehicleSelectData and the SpawnVehicle logic in TransportDepotTickJob. Careful changes here affect how vehicles are created and which components are added. - The system relies heavily on specific component types (Produced, ParkedCar/ParkedTrain, Odometer, PathInformation, etc.). When adding custom vehicle/prefab types, ensure prefab data contains the expected component sets (VehicleModel, TransportLineData, TaxiData, PublicTransportVehicleData, CargoTransportVehicleData) so the system can read capacities/maintenance ranges. - DepotAction is intentionally lightweight so the parallel tick job can avoid heavy write contention — use that pattern if adding new deferred per-vehicle mutations.