Skip to content

Game.StreetLightSystem

Assembly: Game (Game.dll)
Namespace: Game.Simulation

Type: class

Base: GameSystemBase

Summary:
Manages the on/off state of street light objects for roads, buildings and watercraft. Runs a Burst-compiled IJobChunk (UpdateStreetLightsJob) on a scheduled interval to: - Check whether roads, buildings and watercraft should have their lights on based on time-of-day brightness and random seed. - Check electricity connectivity through electricity node connections and flow edges. - Flip entity flags (RoadFlags.LightsOff, BuildingFlags.StreetLightsOff, WatercraftFlags.LightsOff / Illuminated) as appropriate. - Update associated StreetLight component data for sub-objects and enqueue EffectsUpdated / BatchesUpdated via an EndFrameBarrier command buffer so rendering/effects are refreshed.

This system is optimized for parallel execution using Unity ECS job chunking, ComponentLookup/BufferLookup, and Burst. It queries all entities that have UpdateFrame and either Road, Building or Watercraft components, excluding Deleted/Destroyed/Temp.


Fields

  • private const uint UPDATE_INTERVAL = 256u
    {{ Internal constant used when computing update frames (not used directly in GetUpdateInterval override). }}

  • private SimulationSystem m_SimulationSystem
    {{ Reference to the global SimulationSystem used to obtain the current frame index / simulation timing. }}

  • private LightingSystem m_LightingSystem
    {{ Reference to the LightingSystem used to obtain current day/night brightness (m_LightingSystem.dayLightBrightness). }}

  • private EndFrameBarrier m_EndFrameBarrier
    {{ Reference to the EndFrameBarrier system — used to create a parallel command buffer (EntityCommandBuffer.ParallelWriter) so entity/component changes are recorded safely from jobs and applied at the end of the frame. }}

  • private EntityQuery m_StreetLightQuery
    {{ EntityQuery that selects entities with UpdateFrame and any of Road, Building or Watercraft, while excluding Deleted, Destroyed and Temp. Used to schedule the UpdateStreetLightsJob. }}

  • private TypeHandle __TypeHandle
    {{ Internal structure storing component/buffer type handles and lookups used for job scheduling. }}

  • private struct UpdateStreetLightsJob (nested)
    {{ Burst-compiled IJobChunk that performs the bulk of the work per-chunk: reads Road/Building/Watercraft, PseudoRandomSeed, electricity connections, subobjects and streetlight component data; computes whether lights should be on or off; updates component flags and enqueues EffectsUpdated/BatchesUpdated through an EntityCommandBuffer.ParallelWriter. Uses ComponentLookup and BufferLookup for safe parallel access. }}

  • private struct TypeHandle (nested)
    {{ Holds pre-resolved EntityTypeHandle, ComponentTypeHandle, BufferTypeHandle and ComponentLookup/BufferLookup instances and a helper to assign them from a SystemState. }}


Properties

  • (none public)
    {{ The system exposes no modifiable public properties. Internal TypeHandle and query/state are private. }}

Constructors

  • public StreetLightSystem()
    {{ Default constructor — standard system instantiation. System setup primarily happens in OnCreate/OnCreateForCompiler. Marked with [Preserve] on lifecycle methods to avoid stripping. }}

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    {{ Returns the interval used by the system's UpdateFrame logic. In this implementation it always returns 16, meaning the system selects the UpdateFrame based on a 16-frame interval when scheduling. This interacts with the UpdateFrame shared component filter in OnUpdate. }}

  • [Preserve] protected override void OnCreate()
    {{ System initialization:

  • Resolves SimulationSystem, LightingSystem and EndFrameBarrier from the World.
  • Builds the EntityQuery (m_StreetLightQuery) that matches UpdateFrame and any of Road/Building/Watercraft and excludes Deleted/Destroyed/Temp.
  • Calls RequireForUpdate(m_StreetLightQuery) so the system only runs when matching entities exist.
  • Contains asserts (no-op checks here). This is where system-level references and the query are created; no heavy work is done here. }}

  • [Preserve] protected override void OnUpdate()
    {{ Main scheduling function:

  • Resets filters on m_StreetLightQuery and sets a shared component filter UpdateFrame computed from m_SimulationSystem.frameIndex and GetUpdateInterval (16).
  • Prepares an UpdateStreetLightsJob instance:
    • Assigns entity/component/buffer handles through InternalCompilerInterface.Get... helpers (wired to __TypeHandle).
    • Computes m_Brightness = Mathf.RoundToInt(m_LightingSystem.dayLightBrightness * 1000f).
    • Creates a parallel command buffer from m_EndFrameBarrier.
  • Schedules the job in parallel using JobChunkExtensions.ScheduleParallel with the query and current Dependency.
  • Adds the returned JobHandle to the EndFrameBarrier (AddJobHandleForProducer) so the barrier knows to wait for / play back commands after the job finishes.
  • Stores the job handle on base.Dependency. }}

  • public static void UpdateStreetLightState(ref StreetLight streetLight, Road road)
    {{ Static helper to update a StreetLight component based on a Road's flags. If road has RoadFlags.LightsOff set, sets StreetLightState.TurnedOff on the component; otherwise clears that flag. Intended to be used when a road's light state changes to update associated sub-object StreetLight components. }}

  • public static void UpdateStreetLightState(ref StreetLight streetLight, Building building)
    {{ Same as above but for Building: toggles StreetLightState.TurnedOff depending on BuildingFlags.StreetLightsOff. }}

  • public static void UpdateStreetLightState(ref StreetLight streetLight, Watercraft watercraft)
    {{ Same as above but for Watercraft: toggles StreetLightState.TurnedOff depending on WatercraftFlags.LightsOff / DeckLights. }}

  • protected override void OnCreateForCompiler()
    {{ Internal helper used by generated code paths: assigns queries and type handles from the SystemState to prepare for job scheduling. }}

  • private void __AssignQueries(ref SystemState state)
    {{ Internal placeholder used by compiler-generated code to prepare query builders / validations. }}

  • Note on UpdateStreetLightsJob internal methods:

  • Execute(in ArchetypeChunk, int, bool, in v128): iterates chunk entities and for each Road/Building/Watercraft:
    • Uses PseudoRandomSeed to add randomness to brightness checks.
    • Checks electricity connectivity:
      • For roads/buildings: uses ElectricityNodeConnection and ConnectedFlowEdge/ElectricityFlowEdge lookups to detect disconnected nodes.
      • For buildings: may consult ElectricityConsumer component if present.
    • Compares m_Brightness against a randomized threshold (random.NextInt(200,300)) to decide if lights should be on.
    • Toggles entity flags and updates sub-objects' StreetLight components via ComponentLookup and writes EffectsUpdated/BatchesUpdated using m_CommandBuffer.AddComponent.
  • The job uses NativeArray, BufferAccessor, ComponentLookup and BufferLookup for high-performance parallel reads and writes, and uses an EntityCommandBuffer.ParallelWriter for structural/side-effect changes. The job is Burst-compiled for speed. }}

Usage Example

// Example: force-update a subobject StreetLight component from your own system.
// You might call this if you want to manually set a light state for a subobject.

void SetSubObjectStreetLight(EntityManager em, Entity subObject, bool turnOff)
{
    if (em.HasComponent<StreetLight>(subObject))
    {
        var streetLight = em.GetComponentData<StreetLight>(subObject);
        if (turnOff)
            streetLight.m_State |= StreetLightState.TurnedOff;
        else
            streetLight.m_State &= ~StreetLightState.TurnedOff;
        em.SetComponentData(subObject, streetLight);

        // Make sure effects/rendering are updated
        em.AddComponent<EffectsUpdated>(subObject);
    }
}

Additional notes for modders: - The system relies on m_LightingSystem.dayLightBrightness to determine global brightness; brightness is multiplied by 1000 and compared against random thresholds in [200,300). - Electricity connectivity checks traverse electricity node connections and connected flow edges: if any connected ElectricityFlowEdge has isDisconnected, the node is considered disconnected and lights will not turn on. - The system schedules work on background threads (Burst/IJobChunk). Do not access UnityEngine.Object or main-thread-only APIs from within UpdateStreetLightsJob. - To observe or modify behavior, either: - Replace/extend this system by creating a new system that runs earlier/later and changes relevant flags/components, or - Intercept / modify StreetLight components or Road/Building/Watercraft flags and ensure EffectsUpdated / BatchesUpdated are added when needed so rendering updates. - Because changes are applied via EndFrameBarrier command buffer, component adds/structural changes are deferred until job completion and playback at frame end.