Skip to content

Game.RoadSafetySystem

Assembly: Game
Namespace: Game.Simulation

Type: class (public)

Base: GameSystemBase

Summary:
RoadSafetySystem is an ECS system that periodically evaluates roadway safety and attempts to spawn traffic-accident events on roads. It schedules a parallel IJobChunk (RoadSafetyJob) that samples road traffic flow, distance, net condition (wear), road composition flags (street lights, highway rules, separated carriageways), daytime brightness, city- and district-level modifiers, and a randomized seed to compute a per-road "roadSafety" factor. Based on accident prefab definitions (EventData + TrafficAccidentData) and per-prefab occurrence probabilities, the job may create accident event entities via an EndFrameBarrier command buffer. The system runs infrequently (GetUpdateInterval returns 4096) and uses the EndFrameBarrier to enqueue event creation at the end of the frame.


Fields

  • private const int UPDATES_PER_DAY = 64
    Description: Constant used by the system (not otherwise exposed) — likely used to reason about sampling frequency relative to in-game day/time.

  • private TimeSystem m_TimeSystem
    Description: Reference to the game's TimeSystem; used to compute time-of-day factors for traffic/lighting.

  • private CitySystem m_CitySystem
    Description: Reference to the CitySystem to access city-level data such as the city entity (m_City) and city modifiers.

  • private LightingSystem m_LightingSystem
    Description: Reference used to read lighting-related data (dayLightBrightness) to factor brightness into accident probability.

  • private EndFrameBarrier m_EndFrameBarrier
    Description: Barrier system used to create entities (events) safely at the end of frame from a parallel job (the command buffer is obtained and used as a ParallelWriter).

  • private EntityQuery m_RoadQuery
    Description: Query selecting road/edge composition entities to be processed by the job. Required for update.

  • private EntityQuery m_AccidentPrefabQuery
    Description: Query selecting accident-event prefabs (EventData + TrafficAccidentData) that are not Locked. Required for update.

  • private TypeHandle __TypeHandle
    Description: Generated struct holding Entity/Component/Buffer/Lookup type handles required by the job; assigned at system creation for fast access during scheduling.

Properties

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

Constructors

  • public RoadSafetySystem()
    Description: Default constructor. The system is registered with the ECS world and relies on OnCreate to initialize its queries and cached system references.

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Description: Returns 4096. This controls how frequently the system should be updated relative to the engine's scheduling (the system does not run every frame).

  • [Preserve] protected override void OnCreate()
    Description: Initializes references to other managed systems (TimeSystem, CitySystem, LightingSystem, EndFrameBarrier) and creates the two EntityQuery objects:

  • m_RoadQuery: Entities that have Edge + Composition and optionally Road, excluding Deleted and Temp.
  • m_AccidentPrefabQuery: Entities that have EventData + TrafficAccidentData and are not Locked. Both queries are marked as required for update (RequireForUpdate).

  • [Preserve] protected override void OnUpdate()
    Description: Builds time-of-day factors (float4) and schedules the RoadSafetyJob as a parallel IJobChunk. The job:

  • Gets a list of archetype chunks for accident prefabs asynchronously.
  • Acquires type handles and lookups via the compiled TypeHandle.
  • Passes city entity, random seed, time factors, brightness and a ParallelWriter command buffer created from the EndFrameBarrier.
  • Combines dependencies and registers the produced job handle with the EndFrameBarrier so commands are executed safely at frame end.

  • protected override void OnCreateForCompiler()
    Description: Internal helper called by the generated code path; assigns queries and type handles for the compiler-generated wiring.

  • [MethodImpl(MethodImplOptions.AggressiveInlining)] private void __AssignQueries(ref SystemState state)
    Description: Internal (compiler-generated) query assignment stub used when building with the ECS codegen pipeline.

  • Nested struct: RoadSafetyJob : IJobChunk (Burst-compiled)
    Description: The main worker job executed in parallel over road chunks. Key behaviors:

  • Uses a random seed per chunk (RandomSeed.Next()) and early-exits most chunks (random.NextInt(64) != 0) to space out updates.
  • Reads NetCondition, Road, Composition, BorderDistrict, and road composition data to compute:
    • duration and distance derived from traffic flow fields and time factors,
    • trafficFlowSpeed via NetUtils.GetTrafficFlowSpeed(duration, distance),
    • base accident occurrence inverse factor ("roadSafety") which is influenced by street lights, brightness, wear, separated carriageways, highway rules, and district/city modifiers.
  • Iterates available accident prefabs (from the accident prefab chunk list) and for matching target types (EventTargetType.Road) tests probabilistic occurrence based on prefab.m_OccurenceProbability / max(1, roadSafety). On success, creates a new event entity using the EndFrameBarrier command buffer with:
    • PrefabRef set to the chosen event prefab entity,
    • TargetElement buffer containing the target road entity.
  • Methods inside the job:
    • TryStartAccident(int jobIndex, ref Random random, Entity entity, float roadSafety, EventTargetType targetType) — scans prefab chunks and attempts to pick an accident according to probability.
    • CreateAccidentEvent(int jobIndex, Entity targetEntity, Entity eventPrefab, EventData eventData, TrafficAccidentData trafficAccidentData) — enqueues creation of the Event entity with PrefabRef and target buffer.

Notes about concurrency and safety: - The job uses a ParallelWriter command buffer from EndFrameBarrier and registers the job handle with the barrier via m_EndFrameBarrier.AddJobHandleForProducer(jobHandle). The prefab archetype list is retrieved asynchronously and dependency-combined when scheduling.

Usage Example

// Example showing how the system creates an event entity in the same pattern used internally.
// This snippet mirrors the CreateAccidentEvent behavior and is suitable when issuing commands
// from a system using an EndFrameBarrier command buffer.

var commandBuffer = endFrameBarrier.CreateCommandBuffer(); // typically obtained inside system
// Suppose we have:
// - EventData eventData (contains m_Archetype for the event entity)
// - Entity eventPrefab (the prefab entity with EventData and TrafficAccidentData)
// - Entity targetRoad (the road entity to target)

Entity e = commandBuffer.CreateEntity(eventData.m_Archetype);
commandBuffer.SetComponent(e, new PrefabRef(eventPrefab));
var targetBuffer = commandBuffer.SetBuffer<TargetElement>(e);
targetBuffer.Add(new TargetElement(targetRoad));

If you are modding: - Ensure you provide accident prefab entities that include EventData and TrafficAccidentData and are not Locked to be discovered by m_AccidentPrefabQuery. - City and district modifiers (CityModifier / DistrictModifier buffers) influence computed road safety; adjust these buffers to tune accident rates. - Light-level and road flags (HasStreetLights, LightsOff, UseHighwayRules, SeparatedCarriageways) are considered by the system — changing those prefab flags will affect accident probabilities.