Skip to content

Game.SoilWaterSystem

Assembly: Assembly-CSharp
Namespace: Game.Simulation

Type: class

Base: CellMapSystem, IJobSerializable, IPostDeserialize

Summary:
SoilWaterSystem manages a discrete soil-water map used by the simulation to model soil moisture, interactions with surface water, rainfall, and flood events. It maintains a 128×128 RFloat texture (SoilWaterTexture) that shaders can read, updates a NativeArray-backed map of SoilWater cells on a scheduled job (SoilWaterTickJob), computes diffusion between neighboring cells, applies rainfall/overflow logic, and triggers Flood events via an Entity-based flood counter. The system interacts with TerrainSystem, WaterSystem, ClimateSystem and uses an EndFrameBarrier to emit event entities safely. Key modding touchpoints: the soil texture (Texture2D, RFloat), SoilWaterParameterData (singleton) for tuning behavior, and flood control via Flood/FloodData/FloodCounterData entities.


Fields

  • public static readonly int kTextureSize = 128
    128 — width and height of the soil map / texture. Each cell in the internal map corresponds to one texel. Use this constant when indexing the texture.

  • public static readonly int kUpdatesPerDay = 1024
    Number of internal soil update ticks considered per day; used to compute update distribution and scheduling.

  • public static readonly int kLoadDistribution = 8
    Number of slices that split the map for incremental updates across frames.

  • private SimulationSystem m_SimulationSystem
    Reference to the SimulationSystem used to obtain frame indices and general simulation timing.

  • private TerrainSystem m_TerrainSystem
    Reference to the TerrainSystem — used to sample terrain heights inside the scheduled job to compute soil surface heights.

  • private WaterSystem m_WaterSystem
    Reference to the WaterSystem — used to obtain water surface data (depths/resolution) consumed when computing soil-water exchange and flooding.

  • private ClimateSystem m_ClimateSystem
    Reference to the ClimateSystem — used to read precipitation (m_Weather / rainfall intensity) that increases soil water.

  • private EndFrameBarrier m_EndFrameBarrier
    Barrier used to produce event entities (flood starter/stopper) safely at the end of the frame. Jobs write into an EntityCommandBuffer produced by this barrier.

  • private Texture2D m_SoilWaterTexture
    Managed Texture2D (RFloat) that mirrors shader-usable soil-water data. GetRawTextureData() returns the per-cell float values written by the job. Texture is created as 128×128, TextureFormat.RFloat, linear, no mip chain.

  • private EntityQuery m_SoilWaterParameterQuery
    Query to obtain the singleton SoilWaterParameterData that contains multiple tuning parameters (rain multiplier, maximum depth, overflow rate, diffusion parameters, etc).

  • private EntityQuery m_FloodQuery
    Query for active Flood entities in the world. Used to detect whether a flood is currently active.

  • private EntityQuery m_FloodPrefabQuery
    Query for FloodData prefabs (prefab event archetypes) used to spawn flood events when the flood counter exceeds threshold.

  • private TypeHandle __TypeHandle
    Generated helper struct that holds ComponentLookup handles (WaterLevelChange, FloodCounterData, EventData) used inside jobs. The handles are assigned in OnCreateForCompiler.

  • private EntityQuery __query_336595330_0
    Generated query used internally to obtain the FloodCounterData entity (single entity used to track a counter). PostDeserialize ensures such entity exists.

Notes for modders: - The texture is updated by the job; do not overwrite it directly without coordinating with system jobs. Read-only access to the texture's raw data is safe on the main thread after the system ensures Apply() and job completion. - To change simulation behavior, create or modify the SoilWaterParameterData singleton entity. This is the intended tuning point.

Properties

  • public int2 TextureSize => new int2(kTextureSize, kTextureSize)
    Provides the texture/map size as int2 {128,128}. Useful for sampling and indexing code.

  • public Texture soilTexture => m_SoilWaterTexture
    Exposes the RFloat Texture2D that contains soil-water shader data. Use Texture.GetRawTextureData() to access the per-cell float values (layout: x + y * kTextureSize).

Constructors

  • public SoilWaterSystem()
    Default constructor (generated/preserved). Initialization happens in OnCreate.

Methods

  • protected override void OnCreate()
    Initializes subsystem references (SimulationSystem, TerrainSystem, WaterSystem, ClimateSystem), creates an EndFrameBarrier reference, prepares EntityQueries, creates a FloodCounter entity if needed, allocates and initializes the RFloat texture (SoilWaterTexture), and initializes the internal map (m_Map) with default SoilWater values (m_Amount = 1024, m_Max = 8192). Registers RequireForUpdate on SoilWaterParameterData so the system runs only when parameters exist. Important: the texture is created with name "SoilWaterTexture" and hideFlags = HideAndDontSave.

  • protected override void OnUpdate()
    Main scheduling method. If TerrainHeightData is available, it calls m_SoilWaterTexture.Apply(), reads precipitation from ClimateSystem, computes shaderUpdatesPerSoilUpdate and loadDistributionIndex, constructs a SoilWaterTickJob (populating component lookups, water surface data, flood entity lists and other inputs), schedules the job (combining dependencies and registering write/read dependencies), attaches the job to EndFrameBarrier, and sets up readers for TerrainSystem and WaterSystem. The job updates the internal map, writes per-cell shader data into the texture raw buffer, increments/decrements flood counters and starts/stops flood events.

  • private void CreateFloodCounter()
    Creates a new entity with FloodCounterData component. Called from OnCreate and PostDeserialize if no counter exists.

  • public void PostDeserialize(Context context)
    Deserialization hook — verifies a FloodCounterData entity exists after load and creates one if none present. This ensures saved game loads don't lose the flood counter.

  • private void __AssignQueries(ref SystemState state)
    Generated helper used in OnCreateForCompiler to build the internal entity query used to retrieve the single FloodCounterData entity. Not normally called by modders.

  • protected override void OnCreateForCompiler()
    Generated method invoked to assign queries and component lookups into the TypeHandle. Ensures that the compiled component lookups are available to jobs.

Inner types and jobs:

  • private struct SoilWaterTickJob : IJob
    The job that performs the per-slice soil-water simulation. Responsibilities:
  • Handles diffusion between neighboring cells by calling HandleInterface (considers elevation difference and relative saturation).
  • Applies rainfall (based on climate precipitation) and computes an effective rain multiplier.
  • Samples water surface depths from WaterSurfaceData (depth array) to compute water-soil interactions (infiltration, overflow).
  • Updates each cell's m_Amount, applies overflow logic (m_OverflowRate), and writes a per-cell shader value into the soil texture raw float array.
  • Maintains and updates FloodCounterData; when counter exceeds thresholds it uses EntityCommandBuffer to Create flood event entities (StartFlood) or mark existing flood entities as Deleted (StopFlood).
  • Uses ComponentLookup to read/write WaterLevelChange, FloodCounterData, and EventData. Important details:
  • The job iterates only over a slice of the map determined by m_LoadDistributionIndex and kLoadDistribution (so not all cells are updated each frame).
  • The texture buffer m_SoilWaterTextureData is a float[] (raw RFloat texel buffer) and receives incremental per-job contributions. Shader updates are scaled by m_ShaderUpdatesPerSoilUpdate.
  • Watch for the numeric mapping: one float per cell, order is row-major: index = x + y * kTextureSize.

  • private struct TypeHandle
    Generated struct holding ComponentLookup handles for the job: WaterLevelChange (read/write), EventData (read-only), FloodCounterData (read/write). It contains __AssignHandles(ref SystemState) to initialize lookup handles.

Usage notes (modding): - To tune the soil simulation, modify or create a SoilWaterParameterData singleton entity with your desired parameters. This is the official configuration point. - To read the soil texture from a custom shader or manager: - Get the system from the world: var s = World.GetExistingSystemManaged(); - Use s.soilTexture as a Texture (RFloat) for shader binding. - To read raw floats on C# side (main thread): var raw = s.soilTexture.GetRawTextureData(); index = x + y * SoilWaterSystem.kTextureSize. - To trigger or prevent floods: - Create/modify FloodData prefabs or Flood entities; manipulate the FloodCounterData singleton entity to adjust the m_FloodCounter value directly. - Removing or altering FloodData prefab entities affects what the SoilWaterSystem can spawn.

Usage Example

// Example: read soil water float value at a cell (main thread)
var world = World.DefaultGameObjectInjectionWorld; // or appropriate world in mod context
var soilSystem = world.GetExistingSystemManaged<Game.Simulation.SoilWaterSystem>();
if (soilSystem != null)
{
    Texture tex = soilSystem.soilTexture;
    var raw = tex.GetRawTextureData<float>(); // one float per cell, row-major
    int x = 10;
    int y = 20;
    int idx = x + y * Game.Simulation.SoilWaterSystem.kTextureSize;
    float value = raw[idx]; // this value corresponds to shader delta/infiltration contribution
    Debug.Log($"Soil texture value at ({x},{y}) = {value}");
}

// Example: change soil parameters - create/modify the singleton SoilWaterParameterData entity
var em = world.EntityManager;
if (!em.HasComponent<SoilWaterParameterData>(soilParamEntity))
{
    // Create and set up a singleton SoilWaterParameterData as needed.
}

// Example: sample interpolated SoilWater m_Amount from the internal map is NOT exposed publicly.
// Use soilTexture for visual/shader-driven sampling, or create a small system that reads and exposes needed data.

Notes: - The system schedules its work in a job (SoilWaterTickJob) and writes to the texture raw buffer. Ensure you respect the system's job dependencies if you access the texture raw data outside the system — wait for the system to complete. - Altering internal data structures (m_Map) is not supported directly — use provided parameter singletons or entity components designed for the purpose.