Skip to content

Game.WeatherHazardSystem

Assembly: Game
Namespace: Game.Simulation

Type: class

Base: GameSystemBase

Summary:
WeatherHazardSystem is a simulation system that periodically evaluates weather phenomenon prefabs (WeatherPhenomenonData + EventData) and spawns weather event entities (hazards) based on the current climate (temperature and precipitation), a time-step multiplier, and the city configuration (whether natural disasters are enabled). The evaluation is performed as a parallel IJobChunk (WeatherHazardJob) over a query of phenomenon prefabs; actual entity creation is deferred via an EndFrameBarrier command buffer. The system uses a simple probabilistic model that weights occurrence probability by how well current temperature and rainfall match a phenomenon's configured occurrence ranges.


Fields

  • private const int UPDATES_PER_DAY = 128
    Defines the number of weather update ticks per in-game day. Used to reason about update frequency and time scaling in the job (the job uses a fixed m_TimeDelta currently).

  • private ClimateSystem m_ClimateSystem
    Reference to the ClimateSystem retrieved from the World in OnCreate. Used to read current temperature and precipitation when computing event spawn probabilities.

  • private CityConfigurationSystem m_CityConfigurationSystem
    Reference to the CityConfigurationSystem retrieved from the World in OnCreate. Used to check whether natural disasters are enabled; phenomena with non-zero damage severity are skipped if natural disasters are disabled.

  • private EndFrameBarrier m_EndFrameBarrier
    EndFrameBarrier system used to create an EntityCommandBuffer (as a ParallelWriter) so that event entities can safely be created from the scheduled job and executed at end of frame.

  • private EntityQuery m_PhenomenonQuery
    EntityQuery created in OnCreate that selects entities with EventData and WeatherPhenomenonData and excludes Locked. This query defines which phenomenon prefabs will be processed each update and is marked as RequiredForUpdate to prevent running if there are no phenomenons.

  • private TypeHandle __TypeHandle
    Internal struct holding EntityTypeHandle and ComponentTypeHandle references (for EventData, WeatherPhenomenonData, Locked). Populated in OnCreateForCompiler and used to build the IJobChunk's type handles via InternalCompilerInterface when scheduling.

Properties

  • (No public properties on this system.)

Constructors

  • public WeatherHazardSystem()
    Default constructor. The system uses OnCreate to initialize references to other systems and to set up the entity query.

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns the system update interval in frames/units. In this implementation it returns 2048 (the system schedules work with that cadence via the engine). This affects how often the system is considered for updating by the engine.

  • [Preserve] protected override void OnCreate()
    Initializes references to other world systems:

  • Gets ClimateSystem and CityConfigurationSystem from the World.
  • Gets EndFrameBarrier for deferred entity creation.
  • Creates the m_PhenomenonQuery to select EventData + WeatherPhenomenonData and exclude Locked.
  • Calls RequireForUpdate(m_PhenomenonQuery) so the system only runs if there are phenomenon prefabs available.

  • [Preserve] protected override void OnUpdate()
    Prepares and schedules the WeatherHazardJob:

  • Builds a WeatherHazardJob struct with RandomSeed.Next(), a fixed m_TimeDelta (34.133335f), current temperature and precipitation from the climate system, and the city's naturalDisasters flag.
  • Converts the EndFrameBarrier command buffer to a ParallelWriter and passes it to the job so entities can be created from worker threads.
  • Acquires EntityTypeHandle and ComponentTypeHandles (EventData, WeatherPhenomenonData, Locked) from __TypeHandle via InternalCompilerInterface and sets them on the job.
  • Schedules the job in parallel over m_PhenomenonQuery using JobChunkExtensions.ScheduleParallel and attaches the returned JobHandle to the end-frame barrier (AddJobHandleForProducer) so the command buffer is played back after the producer completes.

  • [MethodImpl(MethodImplOptions.AggressiveInlining)] private void __AssignQueries(ref SystemState state)
    Compiler helper that would normally set up queries; in this build it only contains a placeholder new EntityQueryBuilder(Allocator.Temp).Dispose().

  • protected override void OnCreateForCompiler()
    Compiler-time initialization: calls __AssignQueries and assigns handles in __TypeHandle. Used by generated/compiled systems to initialize type handles for jobs.

  • [Preserve] public WeatherHazardSystem()
    (Repeated - default constructor is preserved by attribute.)

Nested type: WeatherHazardJob (private struct implementing IJobChunk)
Summary of job behavior and important fields: - Fields passed in (read-only where appropriate): - RandomSeed m_RandomSeed — random stream seed per job/chunk. - float m_TimeDelta — multiplier used to scale occurrence probability (set to 34.133335f in the system). - float m_Temperature — current climate temperature read from ClimateSystem. - float m_Rain — current climate precipitation read from ClimateSystem. - bool m_NaturalDisasters — whether natural disasters are enabled in city configuration. - EntityCommandBuffer.ParallelWriter m_CommandBuffer — used to create event entities from job threads. - EntityTypeHandle m_EntityType — for reading entity prefab references in the chunk. - ComponentTypeHandle m_PrefabEventType — EventData component of the prefab (read-only). - ComponentTypeHandle m_PrefabWeatherPhenomenonType — phenomenon parameters. - ComponentTypeHandle m_LockedType — used to check for Locked enabled state and skip locked prefabs.

  • Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, ...) logic:

    • Gets a Random instance for this chunk using m_RandomSeed.GetRandom(unfilteredChunkIndex).
    • Reads NativeArrays for Entity, EventData, and WeatherPhenomenonData for the chunk.
    • Obtains an EnabledMask for the Locked component; skips entries where Locked is enabled.
    • For each non-locked prefab:
    • Skips if phenomenon has non-zero damage severity but natural disasters are disabled (prevents spawning harmful events).
    • Computes a temperature-matching factor:
      • Uses MathUtils.Center to get center of occurrence temperature range and MathUtils.Extents to get extents.
      • num3 = (m_Temperature - center) / extents; then transformed to max(0, 1 - num3^2) to prefer closer matches.
    • Computes a rain-matching factor num4:
      • If occurrence rain max > 0.999f, uses saturate((m_Rain - min) / (max - min)) if min >= 0.001f.
      • Else if occurrence rain min < 0.001f, uses saturate((max - m_Rain) / (max - min)).
      • Default num4 = 1f.
    • Final spawn probability per tick: num5 = occurrenceProbability * tempFactor * rainFactor * m_TimeDelta.
    • Uses a loop: while random.NextFloat(100f) < num5 -> spawn one event, subtract 100f from num5, repeat (allows multiple events if probability large).
    • Spawning: CreateWeatherEvent(jobIndex, eventPrefab, eventData) which uses m_CommandBuffer.CreateEntity with eventData.m_Archetype and sets PrefabRef(eventPrefab) on the new entity.
    • The job thus probabilistically creates Event entities backed by the configured EventData archetype and linked to the phenomenon prefab via PrefabRef.
  • Locked components are used to exclude specific prefabs from being processed when they are marked Locked in a chunk.

  • CreateWeatherEvent:

    • Creates a new entity with the archetype specified in EventData and sets its PrefabRef to the prefab entity representing the phenomenon.

Notes and caveats: - The job uses a fixed m_TimeDelta constant (34.133335f) in OnUpdate; this is the effective multiplier applied to m_OccurenceProbability for each scheduled execution. - The probability calculation multiplies several factors and then compares against a 0..100 random float; because of the while loop, a num5 > 100f may spawn multiple events. - Phenomena that have m_DamageSeverity != 0 are treated as natural disasters and will not spawn if natural disasters are disabled in CityConfigurationSystem. - The system uses parallel job scheduling and a ParallelWriter command buffer; created entities are deferred until the command buffer is played back by the EndFrameBarrier.

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    m_ClimateSystem = base.World.GetOrCreateSystemManaged<ClimateSystem>();
    m_CityConfigurationSystem = base.World.GetOrCreateSystemManaged<CityConfigurationSystem>();
    m_EndFrameBarrier = base.World.GetOrCreateSystemManaged<EndFrameBarrier>();
    m_PhenomenonQuery = GetEntityQuery(
        ComponentType.ReadOnly<EventData>(),
        ComponentType.ReadOnly<WeatherPhenomenonData>(),
        ComponentType.Exclude<Locked>());
    RequireForUpdate(m_PhenomenonQuery);
}

[Preserve]
protected override void OnUpdate()
{
    var jobData = new WeatherHazardJob
    {
        m_RandomSeed = RandomSeed.Next(),
        m_TimeDelta = 34.133335f,
        m_Temperature = m_ClimateSystem.temperature,
        m_Rain = m_ClimateSystem.precipitation,
        m_NaturalDisasters = m_CityConfigurationSystem.naturalDisasters,
        m_CommandBuffer = m_EndFrameBarrier.CreateCommandBuffer().AsParallelWriter(),
        m_EntityType = InternalCompilerInterface.GetEntityTypeHandle(ref __TypeHandle.__Unity_Entities_Entity_TypeHandle, ref base.CheckedStateRef),
        m_PrefabEventType = InternalCompilerInterface.GetComponentTypeHandle(ref __TypeHandle.__Game_Prefabs_EventData_RO_ComponentTypeHandle, ref base.CheckedStateRef),
        m_PrefabWeatherPhenomenonType = InternalCompilerInterface.GetComponentTypeHandle(ref __TypeHandle.__Game_Prefabs_WeatherPhenomenonData_RO_ComponentTypeHandle, ref base.CheckedStateRef),
        m_LockedType = InternalCompilerInterface.GetComponentTypeHandle(ref __TypeHandle.__Game_Prefabs_Locked_RO_ComponentTypeHandle, ref base.CheckedStateRef)
    };
    base.Dependency = JobChunkExtensions.ScheduleParallel(jobData, m_PhenomenonQuery, base.Dependency);
    m_EndFrameBarrier.AddJobHandleForProducer(base.Dependency);
}

If you want, I can also: - produce a summarized flow diagram of how the job computes spawn probability, - annotate how to add custom WeatherPhenomenonData prefabs so they are picked up by this system, - or create a small modding example that toggles natural disaster behavior or adjusts occurrence probabilities.