Skip to content

Game.WaterLevelChangeSystem

Assembly: Assembly-CSharp
Namespace: Game.Simulation

Type: class

Base: GameSystemBase

Summary:
WaterLevelChangeSystem processes WaterLevelChange components each simulation tick (on a reduced update interval) and updates their intensity based on prefab-defined WaterLevelChangeData and the current simulation frame. It uses a Burst-compiled IJobChunk (WaterLevelChangeJob) to iterate matching entities in parallel, reads PrefabRef and Duration data, computes elapsed time since start, and applies wave/tsunami-like intensity curves (currently implemented for the Sine change type). The system schedules its work as a job and registers the job handle with an EndFrameBarrier so work completes before end-of-frame operations. It also exposes utilities like computing a minimum delay for wave arrival at a position.


Fields

  • public static readonly int kUpdateInterval
    Static constant that controls how often the system runs. Its value is 4, so the system updates every 4 ticks (GetUpdateInterval returns this).

  • private SimulationSystem m_SimulationSystem
    Reference to the SimulationSystem. Used to read the current simulation frame (m_SimulationSystem.frameIndex) used to compute progression of water level changes.

  • private EndFrameBarrier m_EndFrameBarrier
    Reference to the EndFrameBarrier system. The system adds its job handle to this barrier to ensure jobs that produce changes complete before other end-of-frame work runs.

  • private EntityQuery m_WaterLevelChangeQuery
    EntityQuery used to find entities that have a WaterLevelChange component (excluding Deleted). The query is required for update so the system only runs when relevant entities exist.

  • private TypeHandle __TypeHandle
    Container of ECS type handles used by the job and system (EntityTypeHandle, ComponentTypeHandle, ComponentTypeHandle, ComponentTypeHandle, ComponentLookup). The TypeHandle provides an __AssignHandles method to initialize these handles from a SystemState.

  • private struct WaterLevelChangeJob (nested)
    Burst-compiled IJobChunk implementation that performs the per-chunk work. Contains:

  • EntityTypeHandle m_EntityType (ReadOnly)
  • ComponentTypeHandle<PrefabRef> m_PrefabRefType (ReadOnly)
  • ComponentTypeHandle<WaterLevelChange> m_WaterLevelChangeType (Read/Write)
  • ComponentTypeHandle<Duration> m_DurationType (ReadOnly)
  • ComponentLookup<WaterLevelChangeData> m_PrefabWaterLevelChangeData (ReadOnly)
  • uint m_SimulationFrame (current simulation frame index used in calculations)

The job computes elapsed time, reads WaterLevelChangeData from prefab, and updates WaterLevelChange.m_Intensity. The main logic implements a "Sine" change type behavior, scaling intensities and applying an escalation delay. If other change types are present they are currently not handled (code hints at other types but no implementation).

  • private struct TypeHandle (nested)
    Struct grouping the various type handles returned by the system. Contains a method __AssignHandles to fetch handles from a given SystemState.

Properties

  • public static int TsunamiEndDelay { get; }
    Computed property returning the Tsunami end delay in frames. It calculates Mathf.RoundToInt((float)WaterSystem.kMapSize / WaterSystem.WaveSpeed). This is used internally to compute wave timings relative to map size and wave speed constants.

Constructors

  • public WaterLevelChangeSystem()
    Default constructor. The system relies on OnCreate to initialize references and queries. Marked with [Preserve] on lifecycle methods to prevent stripping.

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns the update interval (kUpdateInterval). This tells the framework how often the system should run (every 4 simulation frames by default).

  • public static uint GetMinimumDelayAt(WaterLevelChange change, float3 position)
    Utility method that computes the minimum delay (in frames) for a water wave generated by a given WaterLevelChange to reach a world position. It computes an origin point on the map edge based on change.m_Direction and projects the position onto a perpendicular vector to estimate radial distance and divides by WaterSystem.WaveSpeed, rounding to nearest frame. Use this to determine arrival times of waves/tsunamis relative to a change event.

  • protected override void OnCreate()
    System initialization: obtains SimulationSystem and EndFrameBarrier, creates the m_WaterLevelChangeQuery for WaterLevelChange components, and calls RequireForUpdate(m_WaterLevelChangeQuery) so the system only runs when relevant entities exist.

  • protected override void OnUpdate()
    Main update method that prepares a WaterLevelChangeJob with the required type handles and current simulation frame, schedules it as a parallel chunk job (JobChunkExtensions.ScheduleParallel), sets base.Dependency to the returned handle, and registers the handle with m_EndFrameBarrier via AddJobHandleForProducer to ensure ordering with end-of-frame work.

  • private void __AssignQueries(ref SystemState state)
    Compiler helper that sets up queries at compile-time; in this build it's effectively a placeholder that instantiates an EntityQueryBuilder and disposes it. Used by OnCreateForCompiler.

  • protected override void OnCreateForCompiler()
    Compiler helper called during system creation in certain build flows. Calls __AssignQueries and initializes type handles via __TypeHandle.__AssignHandles(ref base.CheckedStateRef).

  • private void TypeHandle.__AssignHandles(ref SystemState state)
    Initializes the internal type handles (EntityTypeHandle, PrefabRef read-only, WaterLevelChange read/write, Duration read-only, WaterLevelChangeData lookup read-only) using the provided SystemState. Called from OnCreateForCompiler to prepare handles used by jobs.

  • private void WaterLevelChangeJob.Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
    Job execution logic (see nested job fields above). For each entity in the chunk it:

  • Reads PrefabRef, WaterLevelChange, Duration
  • Fetches WaterLevelChangeData from the prefab
  • Computes elapsed time since duration.m_StartFrame, subtracting m_EscalationDelay
  • If not yet started (elapsed < 0) continues
  • If change type is Sine, calculates a time window (num2) and applies different sine-based formulas for early escalation and main wave, capping to zero after end. Finally multiplies computed intensity by 4f.
  • Writes back WaterLevelChange.m_Intensity into component array

Note: other change types are present in the data model but currently not implemented in this job (the code has placeholders for other cases).

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    m_SimulationSystem = base.World.GetOrCreateSystemManaged<SimulationSystem>();
    m_EndFrameBarrier = base.World.GetOrCreateSystemManaged<EndFrameBarrier>();
    m_WaterLevelChangeQuery = GetEntityQuery(ComponentType.ReadWrite<WaterLevelChange>(), ComponentType.Exclude<Deleted>());
    RequireForUpdate(m_WaterLevelChangeQuery);
}

Notes and tips: - The system is optimized to run only occasionally (kUpdateInterval) and uses Burst + JobChunk for parallel processing; keep component layouts and chunk sizes in mind for performance. - WaterLevelChangeData (read via prefab lookup) contains configuration like m_MaxIntensity, m_EscalationDelay, and m_ChangeType. Modify those in prefab definitions to adjust behavior. - If adding new change types, extend the WaterLevelChangeJob.Execute logic accordingly and ensure deterministic behavior across frames. - The EndFrameBarrier integration ensures jobs are completed before end-of-frame systems act on the results; remember to register new producer jobs similarly.