Game.Routes.InitializeSystem
Assembly:
Assembly-CSharp (game runtime assembly)
Namespace:
Game.Routes
Type:
class
Base:
GameSystemBase
Summary:
InitializeSystem is a DOTS/ECS game system used during route initialization in Cities: Skylines 2. Its responsibilities include:
- Assigning unique route numbers per transport prefab for newly created routes.
- Selecting and assigning vehicle prefabs (primary/secondary) for newly created transport routes based on TransportLineData and the TransportVehicleSelectData helper.
- Coordinating asynchronous jobs (Burst-compiled) for both tasks and combining JobHandle dependencies.
This system uses EntityQueries to find route entities and vehicle prefabs, and relies on CityConfigurationSystem and TransportVehicleSelectData to choose vehicles.
Fields
-
private CityConfigurationSystem m_CityConfigurationSystem
This holds a reference to the CityConfigurationSystem for retrieving city-wide configuration data required by transport vehicle selection (e.g., configuration that affects available vehicles). Initialized in OnCreate via World.GetOrCreateSystemManaged. -
private EntityQuery m_CreatedQuery
EntityQuery that matches Route entities which are newly created (have Created and not Temp). It is used with RequireForUpdate so the system only runs when there are newly created routes to initialize. -
private EntityQuery m_RouteQuery
EntityQuery matching all non-deleted route entities (used to gather archetype chunks of route entities for route-number assignment). Used to produce an ArchetypeChunk list asynchronously. -
private EntityQuery m_VehiclePrefabQuery
EntityQuery for vehicle prefab data used by TransportVehicleSelectData. It is passed to TransportVehicleSelectData.PreUpdate so that vehicle selection logic can inspect available vehicle prefabs. -
private TransportVehicleSelectData m_TransportVehicleSelectData
Helper / utility that encapsulates vehicle selection logic for transport lines. The system constructs it in OnCreate and calls PreUpdate/PostUpdate around the jobs that need it. It contains vehicle-selection rules and state. -
private TypeHandle __TypeHandle
Internal container of component type handles and lookups used by jobs (ComponentTypeHandle, ComponentTypeHandle , ComponentTypeHandle , ComponentTypeHandle , ComponentLookup ). Populated in OnCreateForCompiler (or equivalent) so the system can obtain type handles efficiently each frame.
Properties
- None (no public properties are exposed by this system).
Constructors
public InitializeSystem()
Default constructor. Marked with [Preserve] in source. The constructor doesn't perform initialization beyond standard managed construction; real initialization occurs in OnCreate.
Methods
protected override void OnCreate()
Initializes the system:- Retrieves CityConfigurationSystem and constructs TransportVehicleSelectData.
- Builds EntityQueries:
- m_CreatedQuery: Route + RouteNumber + Created, excluding Temp.
- m_RouteQuery: Route + RouteNumber, excluding Deleted and Temp.
- m_VehiclePrefabQuery: derived from TransportVehicleSelectData.
-
Calls RequireForUpdate(m_CreatedQuery) so the system only runs when there are newly created routes. This is where type handles and query setup logic is prepared (and TransportVehicleSelectData is created).
-
protected override void OnUpdate()
Main runtime logic executed when m_CreatedQuery indicates there are newly created routes: - Asynchronously collects route archetype chunks via m_RouteQuery.ToArchetypeChunkListAsync.
- Calls m_TransportVehicleSelectData.PreUpdate(...) to prepare vehicle selection and schedule any necessary preprocessing jobs (returns a JobHandle).
- Prepares and schedules two Burst-compiled jobs:
- AssignRouteNumbersJob (IJob): Goes through route chunks and assigns route numbers for entities that have Created set by finding the first free number for the prefab across existing routes (uses NativeBitArray and chunk inspection).
- SelectVehicleJob (IJobChunk): For created route entities, uses TransportLineData (via ComponentLookup) to determine transport purpose/capacity and calls m_TransportVehicleSelectData.SelectVehicle to set VehicleModel primary/secondary prefabs.
-
Combines dependencies, posts the m_TransportVehicleSelectData.PostUpdate(...) for any needed cleanup, and disposes of temporary lists with dependency chaining. Key notes: Job scheduling uses JobHandle.CombineDependencies to ensure correct ordering. routeChunks disposal and TransportVehicleSelectData lifecycle are handled with correct JobHandles.
-
private void __AssignQueries(ref SystemState state)
Internal helper (compiler-generated) used to initialize or validate queries for compilation/emulation; in this class it just constructs and disposes a temporary EntityQueryBuilder. Not intended to be modified by mods. -
protected override void OnCreateForCompiler()
Compiler/emitter helper that calls __AssignQueries and assigns component type handles from __TypeHandle. Ensures the system has prepared component handles used by jobs. -
Nested types / jobs:
-
AssignRouteNumbersJob : IJob (BurstCompile)
- Execute(): Iterates all route archetype chunks and for entities with Created set, assigns a RouteNumber.m_Number by calling FindFreeRouteNumber(prefab).
- FindFreeRouteNumber(Entity prefab): Computes how many existing routes use the given prefab, builds a NativeBitArray of used numbers, and returns the first unused number (or num+1). Uses Allocator.Temp for the NativeBitArray and inspects both "created" and existing routes appropriately.
- Purpose: Ensure route numbers are unique and compact per transport prefab. Runs in a single-threaded IJob because it aggregates across chunks and writes RouteNumber for created entities.
-
SelectVehicleJob : IJobChunk (BurstCompile)
- Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask):
- For each entity in the chunk, reads PrefabRef and TransportLineData (via ComponentLookup).
- Determines PublicTransportPurpose, cargo/passenger resource/capacity ranges based on TransportLineData.
- Uses m_TransportVehicleSelectData.SelectVehicle to select primary/secondary vehicle prefabs and writes them to VehicleModel on the entity.
- Uses a Random seeded by RandomSeed.Next() so selection can be randomized deterministically per-chunk.
- Scheduled in parallel across matching query chunks (ScheduleParallel).
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
// Typical initialization the system performs:
m_CityConfigurationSystem = base.World.GetOrCreateSystemManaged<CityConfigurationSystem>();
m_TransportVehicleSelectData = new TransportVehicleSelectData(this);
m_CreatedQuery = GetEntityQuery(ComponentType.ReadOnly<Route>(), ComponentType.ReadOnly<RouteNumber>(), ComponentType.ReadOnly<Created>(), ComponentType.Exclude<Temp>());
RequireForUpdate(m_CreatedQuery);
}
Additional notes for modders: - This system runs inside the DOTS/ECS world and is tightly integrated with transport prefab metadata (TransportLineData) and the TransportVehicleSelectData selection logic. - If you add custom transport prefabs, ensure TransportLineData is populated for them so the SelectVehicleJob can choose appropriate vehicles. - If you need to change how route numbers are assigned or how vehicles are selected, consider creating a separate system that runs before or after this one, or modify TransportVehicleSelectData behavior (if extending mod APIs allow it). Be careful with job dependencies and thread-safety when interacting with the same components; use the ECS JobHandle pattern and query synchronization as done here.