Skip to content

Game.Net.SecondaryLaneReferencesSystem

Assembly:
Namespace: Game.Net

Type: class

Base: GameSystemBase

Summary:
SecondaryLaneReferencesSystem is a compiler-generated ECS system used to maintain per-owner references to "secondary" lanes (SubLane buffers) in the Cities: Skylines 2 game code. It finds entities that represent lanes marked as SecondaryLane and updates the owner's DynamicBuffer by adding or removing SubLane entries. The system schedules a Burst-compiled IJobChunk (UpdateLaneReferencesJob) which: - Removes SubLane entries when lane entities are marked Deleted. - Adds unique SubLane entries for created/active lanes, computing PathMethod flags based on component presence (PedestrianLane, CarLane, TrackLane) and optional ParkingLane and ConnectionLane flags (including special parking/boarding handling). The system uses ComponentTypeHandle, EntityTypeHandle and BufferLookup for efficient chunked processing and is required for update only when there are relevant lanes (m_LanesQuery).


Fields

  • private Unity.Entities.EntityQuery m_LanesQuery
    This EntityQuery selects entities that have Lane, SecondaryLane and Owner components and that have either Created or Deleted. The system uses this query to determine when it should run (RequireForUpdate).

  • private TypeHandle __TypeHandle
    Holds the cached EntityTypeHandle, ComponentTypeHandle entries (for Owner, PedestrianLane, CarLane, TrackLane, ParkingLane, ConnectionLane, Deleted) and a BufferLookup. The TypeHandle exposes an __AssignHandles(ref SystemState) method used to initialize these handles for the system.


Properties

  • None.
    This system does not expose public properties.

Constructors

  • public SecondaryLaneReferencesSystem()
    Default constructor (annotated with [Preserve]) used by the runtime. No custom logic beyond default initialization.

Methods

  • protected override void OnCreate()
    Initializes m_LanesQuery to match entities that are Lane + SecondaryLane + Owner and have Created or Deleted. Calls RequireForUpdate(m_LanesQuery) so the system runs only when such entities exist.

  • protected override void OnUpdate()
    Builds an UpdateLaneReferencesJob, populating its EntityTypeHandle, ComponentTypeHandles and BufferLookup via InternalCompilerInterface.GetX calls (using __TypeHandle entries and base.CheckedStateRef). The job is scheduled with JobChunkExtensions.Schedule against m_LanesQuery and the returned JobHandle is assigned to base.Dependency.

  • private void __AssignQueries(ref SystemState state)
    Compiler helper method; currently contains a no-op EntityQueryBuilder that is disposed. Present to satisfy codegen patterns.

  • protected override void OnCreateForCompiler()
    Called by the generated system initialization: calls __AssignQueries and __TypeHandle.__AssignHandles(ref base.CheckedStateRef) to prepare type handles for runtime use.

  • Nested: UpdateLaneReferencesJob : IJobChunk (BurstCompiled)
    This is the core job that processes archetype chunks from m_LanesQuery. Key behavior:

  • Reads chunk entity array and Owner components.
  • If the chunk has the Deleted component, it removes the SubLane corresponding to each lane entity from the owner's SubLane buffer (if present) via m_Lanes.TryGetBuffer and CollectionUtils.RemoveValue.
  • Otherwise, it inspects optional component arrays (ParkingLane and ConnectionLane) as well as the chunk-level presence of PedestrianLane, CarLane and TrackLane to compute a PathMethod bitmask for the lane.
    • Parking lanes set Parking/Boarding or SpecialParking/Boarding depending on flags.
    • ConnectionLane flags can add Pedestrian, Road, Track or Parking/Boarding to the path method.
  • Adds a unique SubLane (entity + PathMethod) to the owner's buffer using CollectionUtils.TryAddUniqueValue.
  • Uses CollectionUtils.TryGet for safely reading optional component arrays by index.
  • Implemented with Burst and uses BufferLookup and ComponentTypeHandles for performance.

  • TypeHandle.__AssignHandles(ref SystemState state)
    Populates the TypeHandle fields using state.GetEntityTypeHandle(), state.GetComponentTypeHandle(isReadOnly: true), and state.GetBufferLookup(). Called in OnCreateForCompiler to prepare handles required when constructing the job.


Usage Example

The system runs automatically when entities matching the query are created/removed. A modder normally does not need to call this system manually; however, below is an example showing the system's OnCreate logic and how created/removed lane entities will trigger updates.

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    // This matches Lane + SecondaryLane + Owner and (Created or Deleted)
    m_LanesQuery = GetEntityQuery(new EntityQueryDesc
    {
        All = new ComponentType[]
        {
            ComponentType.ReadOnly<Lane>(),
            ComponentType.ReadOnly<SecondaryLane>(),
            ComponentType.ReadOnly<Owner>()
        },
        Any = new ComponentType[]
        {
            ComponentType.ReadOnly<Created>(),
            ComponentType.ReadOnly<Deleted>()
        }
    });
    RequireForUpdate(m_LanesQuery);
}

// When lane entities are created/marked deleted, SecondaryLaneReferencesSystem will:
// - Add a SubLane(entity, pathMethod) to the owner's DynamicBuffer<SubLane>
// - Or remove it when the lane entity is deleted.

If you need to trigger a refresh from custom code, ensure the lane entity gets a Created/Deleted component (or toggle one of the components matched by the query) so the system will run and update the owner's SubLane buffer accordingly.