Skip to content

Game.Pathfind.LaneDataSystem

Assembly: Assembly-CSharp
Namespace: Game.Pathfind

Type: class

Base: GameSystemBase

Summary:
LaneDataSystem is a performance-critical ECS system that refreshes per-lane runtime data used by pathfinding and vehicle/pedestrian logic. It updates CarLane, PedestrianLane, TrackLane and ConnectionLane components by scheduling two Burst-compiled IJobChunk jobs: - UpdateLaneDataJob: computes access restrictions, blockages/caution areas, speed limits, secured/emergency flags and other per-lane options based on city/district/building state and lane objects. - UpdateLaneData2Job: merges caution/blockage information across related lanes in the same carriageway (combines caution ranges and secured flags).

The system uses many ComponentLookup and BufferLookup handles (lanes, owners, connected nodes/edges, district modifiers, prefab/building data, moving/car/accident data, etc.) and requires the CitySystem to read global city options. It is Burst compiled and scheduled in parallel as JobChunk work, and is optimized for large numbers of lanes.


Fields

  • private CitySystem m_CitySystem
    Holds a reference to the CitySystem obtained from the world. Used to get the city entity and read city-level options (e.g. unlimited highway speed).

  • private EntityQuery m_LaneQuery
    EntityQuery that selects lanes that should be updated by UpdateLaneDataJob (lanes with Updated or PathfindUpdated markers and with one of the lane types present). Required for system update.

  • private EntityQuery m_LaneQuery2
    EntityQuery used by UpdateLaneData2Job — targets car lanes that need the second-pass merge of caution/blockage data across carriageways.

  • private TypeHandle __TypeHandle
    Internal aggregated set of ComponentTypeHandle, BufferTypeHandle, EntityTypeHandle and ComponentLookup/BufferLookup handles. It is filled in OnCreateForCompiler / __AssignHandles and used to initialize job structs before scheduling. Contains handles for many components used by the jobs (Lane, Owner, PrefabRef, LaneObject buffers, CarLane, PedestrianLane, TrackLane, ConnectionLane, and lookups for Road, Gate, Edge, Building, Districts, Cars, Accidents, etc.).

  • private struct UpdateLaneDataJob (nested)
    Burst-compiled IJobChunk that performs the main lane update logic. It:

  • Iterates lane chunks and resets/initializes flags, speed limits and blockage/caution ranges.
  • Uses owner/sub-lane buffers to examine lane objects and compute blockages via CheckBlockage.
  • Calls GetAccessRestriction to determine top-level owner restrictions (building flags) and whether entering/exiting is allowed.
  • Applies city/district modifiers (AddOptionData) and prefab-car-lane data to set lane flags and effective speed limits.
  • Contains helper methods: CheckBlockage, AddBlockageData, AddOptionData, GetAccessRestriction, GetTopLevelOwner, FindAccidentSite, IsSecured.

  • private struct UpdateLaneData2Job (nested)
    Burst-compiled IJobChunk that runs after UpdateLaneDataJob for car lanes. It:

  • Iterates car-lane entities and their sibling sub-lanes for carriageway-group merging.
  • Merges caution ranges (m_CautionStart / m_CautionEnd) across lanes in the same carriageway group, accounting for inverted lanes.
  • Propagates IsSecured flag between related lanes.

  • private struct TypeHandle (nested)
    Container struct that holds ComponentTypeHandle, BufferTypeHandle and ComponentLookup/BufferLookup fields and provides an __AssignHandles(ref SystemState) implementation that initializes those handles. Populated in OnCreateForCompiler.

Properties

  • None (no public properties declared on this system).

Constructors

  • public LaneDataSystem()
    Default constructor, decorated with [Preserve] in the source. The system initialization happens in OnCreate / OnCreateForCompiler.

Methods

  • protected override void OnCreate()
    Initializes the system: acquires the CitySystem from the world, builds the two EntityQuery objects (m_LaneQuery and m_LaneQuery2) used to select lanes to update and calls RequireForUpdate(m_LaneQuery) so the system only runs when there are matching entities. The OnCreate mirrors the runtime registration of required queries and initial handles.

  • protected override void OnUpdate()
    Creates and populates the UpdateLaneDataJob with the appropriate ComponentTypeHandles, BufferLookups and ComponentLookups (via the __TypeHandle values + InternalCompilerInterface helper calls). Schedules UpdateLaneDataJob via JobChunkExtensions.ScheduleParallel with m_LaneQuery. If there are relevant car-lane entities, schedules UpdateLaneData2Job afterwards (m_LaneQuery2) to combine caution/secured data across carriageways. Sets base.Dependency appropriately so jobs are chained and synchronized.

  • protected override void OnCreateForCompiler()
    Compiler helper used to assign queries and handles ahead of time. It calls __AssignQueries and __TypeHandle.__AssignHandles(ref base.CheckedStateRef). Used by the generated/compiled system boilerplate.

  • private void __AssignQueries(ref SystemState state)
    Internal helper (boilerplate) — in this file it contains a minimal EntityQueryBuilder usage (placeholder) and is used by OnCreateForCompiler to ensure queries are prepared for AOT/IL2CPP build-time requirements.

  • private struct UpdateLaneDataJob.Execute(...) (IJobChunk implementation)
    See nested UpdateLaneDataJob description above. This method contains most of the domain logic for lane evaluation: resetting flags, checking lane objects for blockages and emergencies, resolving access restrictions (GetAccessRestriction), handling district/building options to set Forbidden/Forbid* flags, computing speed limits based on city/district modifiers and prefab data, and writing updated lane component values back to chunk arrays or buffers.

  • private struct UpdateLaneData2Job.Execute(...) (IJobChunk implementation)
    Second-pass logic (see nested description) for merging caution ranges and secured flags across lanes in the same carriageway group.

Notes about important private helpers inside UpdateLaneDataJob: - GetAccessRestriction(Owner owner, BuildingFlags flag, bool isEdgeLane, bool isSideConnection, Lane lane, out bool allowEnter, out bool allowExit) - Resolves top-level owner and building flags (parking/track/car/ped restrictions), handles SubOwner geometry, gates and connected edges/nodes to determine whether entering/exiting is allowed and which entity imposes the access restriction. May return Entity.Null if no top-level restriction applies. - CheckBlockage(DynamicBuffer laneObjects, out bool isEmergency, out bool isSecured) - Scans lane objects for moving/parked cars and involved-in-accident markers to produce a Bounds1 representing blockage along the lane (per-curve-position), whether an emergency vehicle is present, and whether any involved-in-accident is secured. - AddOptionData(...) and AddBlockageData(...) helpers apply city/district/prefab options and convert continuous bounds into byte-based start/end blockade/caution values (0..255).

Usage Example

// The system is created and managed by the ECS world. You normally don't instantiate it manually.
// Example: relevant parts shown from the system's OnCreate implementation.

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    // acquire CitySystem (used to read city-level options like UnlimitedHighwaySpeed)
    m_CitySystem = base.World.GetOrCreateSystemManaged<CitySystem>();

    // build queries that select lanes we want to refresh, then require the main query
    // so the system only runs when there are matching lane entities.
    m_LaneQuery = GetEntityQuery(new EntityQueryDesc {
        All = new [] { ComponentType.ReadOnly<Updated>(), ComponentType.ReadOnly<Lane>() },
        Any = new [] { ComponentType.ReadOnly<Game.Net.CarLane>(), ComponentType.ReadOnly<Game.Net.PedestrianLane>(),
                       ComponentType.ReadOnly<Game.Net.TrackLane>(), ComponentType.ReadOnly<Game.Net.ConnectionLane>() },
        None = new [] { ComponentType.ReadOnly<GarageLane>(), ComponentType.ReadOnly<Deleted>(), ComponentType.ReadOnly<Temp>() }
    });

    RequireForUpdate(m_LaneQuery);
}

Additional notes for modders: - The heavy logic is inside UpdateLaneDataJob; if you need to tweak lane behavior consider intercepting or replacing parts of GetAccessRestriction, AddOptionData or CheckBlockage, or writing a custom system that runs before/after LaneDataSystem. - Because this system uses Burst and JobChunk scheduling and relies on many ComponentLookup/BufferLookup handles, changes to component layout or adding new cross-references should be done carefully to preserve job safety and performance. - Many flags and byte-packed values (blockage/caution as bytes 0..255) are used; when modifying them ensure consistency with other pathfinding and vehicle systems that expect those encodings.