Skip to content

Game.TrafficBottleneckSystem

Assembly:
Namespace: Game.Simulation

Type: class

Base: GameSystemBase

Summary:
TrafficBottleneckSystem analyzes vehicle "blocker" relationships at the end of each update interval to detect traffic bottlenecks on lanes. It groups entities that are blocking each other, determines whether a group constitutes a bottleneck (and whether an existing bottleneck should be kept or removed), and adds/removes/updates Bottleneck components and UI icon notifications accordingly. The heavy work runs inside a Burst-compiled IJob (TrafficBottleneckJob) using chunked entity queries, Native containers and deferred command buffers (IconCommandBuffer and EndFrameBarrier/EntityCommandBuffer). The job also enqueues a TriggerAction reporting the number of active bottlenecks.


Fields

  • private IconCommandSystem m_IconCommandSystem
    Holds the IconCommandSystem instance used to create IconCommandBuffer writers for adding/removing UI icons for bottlenecks.

  • private TriggerSystem m_TriggerSystem
    Holds the TriggerSystem instance used to create an action buffer to enqueue TriggerAction events (TriggerType.TrafficBottleneck).

  • private EndFrameBarrier m_EndFrameBarrier
    Used to create an EntityCommandBuffer for deferred structural changes (adding/removing components) produced by the job.

  • private EntityQuery m_BlockerQuery
    EntityQuery that selects entities with Blocker and Vehicle components (excluding Deleted and Temp). These are the "blocker" entities used to form groups.

  • private EntityQuery m_BottleneckQuery
    EntityQuery that selects entities with Bottleneck components (excluding Deleted). Used to iterate existing bottlenecks and update timers/visibility.

  • private EntityQuery m_ConfigurationQuery
    EntityQuery used to fetch the singleton TrafficConfigurationData which holds bottleneck notification prefab id and other settings.

  • private TypeHandle __TypeHandle
    Cached helper struct containing EntityTypeHandle, ComponentTypeHandles and ComponentLookup handles used to build the TrafficBottleneckJob.

(Nested helper types in this class: GroupData, BottleneckData, BottleneckState, TrafficBottleneckJob, TypeHandle — see summary for role.)

Properties

  • (none)

Constructors

  • public TrafficBottleneckSystem()
    Default constructor. The class uses [Preserve] on lifecycle methods and constructor to prevent stripping. Initialization of system state is done in OnCreate.

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns 64. This system is intended to run at an interval (every 64 ticks/frames) rather than every frame.

  • [Preserve] protected override void OnCreate()
    Initializes references to dependent systems (IconCommandSystem, TriggerSystem, EndFrameBarrier) and sets up EntityQueries:

  • m_BlockerQuery: Blocker + Vehicle (exclude Deleted, Temp)
  • m_BottleneckQuery: Bottleneck (exclude Deleted)
  • m_ConfigurationQuery: TrafficConfigurationData singleton Also calls RequireAnyForUpdate(m_BlockerQuery, m_BottleneckQuery) so the system only runs when relevant data exists.

  • [Preserve] protected override void OnUpdate()
    Builds chunk lists for blockers and bottlenecks asynchronously, constructs and schedules the Burst-compiled TrafficBottleneckJob with combined dependencies. The job:

  • Fills a map of existing bottlenecks (marking them Remove by default).
  • Forms groups of mutual blockers using Blocker.m_Blocker references (union-find-like merging).
  • For groups above a configured size threshold, decides to Keep or Add bottlenecks based on group size and blocker types.
  • Updates or adds Bottleneck components (with min/max ranges and positions) and manages Bottleneck.m_Timer values to fade in/out notifications.
  • Adds/removes icon notifications via IconCommandBuffer and enqueues a TriggerAction with the count of active bottlenecks. OnUpdate also wires job dependencies to m_IconCommandSystem and m_EndFrameBarrier and disposes temporary chunk lists after the job.

  • protected override void OnCreateForCompiler()
    Compiler helper used by source-generated systems: assigns queries and type handles for the job.

  • private void __AssignQueries(ref SystemState state)
    Internal/inline helper (generated pattern) for query assignment. In this class it is effectively a placeholder called from OnCreateForCompiler.

(Implementation detail — TrafficBottleneckJob (Burst compiled) contains the core algorithms: - Uses NativeParallelHashMap to map lanes to group indices. - Groups are represented by GroupData (count, merged index). - BottleneckData tracks desired state (Remove, Keep, Add) and range when adding. - Add/Keep/Remove logic adjusts Bottleneck component fields (m_MinPos, m_MaxPos, m_Position, m_Timer) and uses Curve data to compute icon positions on the lane Bezier curve. - Enqueues TriggerAction with TriggerType.TrafficBottleneck and payload equal to the number of active bottlenecks.)

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    m_IconCommandSystem = base.World.GetOrCreateSystemManaged<IconCommandSystem>();
    m_TriggerSystem = base.World.GetOrCreateSystemManaged<TriggerSystem>();
    m_EndFrameBarrier = base.World.GetOrCreateSystemManaged<EndFrameBarrier>();

    m_BlockerQuery = GetEntityQuery(
        ComponentType.ReadOnly<Blocker>(),
        ComponentType.ReadOnly<Vehicle>(),
        ComponentType.Exclude<Deleted>(),
        ComponentType.Exclude<Temp>());

    m_BottleneckQuery = GetEntityQuery(
        ComponentType.ReadOnly<Bottleneck>(),
        ComponentType.Exclude<Deleted>());

    m_ConfigurationQuery = GetEntityQuery(
        ComponentType.ReadOnly<TrafficConfigurationData>());

    RequireAnyForUpdate(m_BlockerQuery, m_BottleneckQuery);
}

Notes and tips for modders: - The system runs infrequently (GetUpdateInterval => 64) to reduce cost; changing that value will affect performance and detection responsiveness. - Bottleneck additions/removals are done via an EndFrameBarrier EntityCommandBuffer to avoid structural changes inside the job. - Icon commands are issued via IconCommandSystem; to change the notification prefab or behavior, edit TrafficConfigurationData or intercept IconCommandBuffer usage. - The grouping logic merges blocker relationships transitively; groups with >=10 members are considered for bottleneck creation. The threshold is hard-coded in the job (groupData.m_Count >= 10) and groupData.m_Count < 50 influences whether a Keep vs Add decision is made. Adjusting detection thresholds requires modifying the job code.