Skip to content

Game.Simulation.GroundHeightSystem

Assembly: Assembly-CSharp
Namespace: Game.Simulation

Type: class

Base: GameSystemBase, IJobSerializable

Summary:
GroundHeightSystem is responsible for tracking regions of the world whose terrain/water heights may have changed and for updating entity positions (objects, nets, nodes, areas) to match the current terrain and water surface. It collects update regions as Bounds2 lists, finds affected entities using quadtrees (static objects, lanes, nets, areas), and schedules Burst-compiled jobs to adjust transforms, curves and area node positions. It also implements serialization hooks (Serialize/Deserialize/SetDefaults) so the update buffers are saved/loaded with the game and coordinates with TerrainSystem, WaterSystem, search systems and the modification barrier to produce the required entity update commands safely on worker threads. The system uses several NativeList buffers to stage updates through distinct phases (New -> Pending -> Reading -> Ready) and a LoadHeightsState to coordinate the loading lifecycle.


Fields

  • private TerrainSystem m_TerrainSystem
    Internal reference to the TerrainSystem used to read terrain height data during updates and to register readers for CPU height reads.

  • private WaterSystem m_WaterSystem
    Reference to the WaterSystem used to read water surface heights (used for objects/areas that care about water surface).

  • private ModificationBarrier2 m_ModificationBarrier
    Used to obtain an EntityCommandBuffer.ParallelWriter to apply component additions/updates as part of jobs.

  • private Game.Objects.SearchSystem m_ObjectSearchSystem
    Search tree provider for static object queries (quad-tree).

  • private Game.Net.SearchSystem m_NetSearchSystem
    Search tree provider for net/lanes queries.

  • private Game.Areas.SearchSystem m_AreaSearchSystem
    Search tree provider for area queries.

  • private ToolSystem m_ToolSystem
    Used to check editor/action mode (affects update behavior for objects/sub-objects).

  • private Game.Areas.GeometrySystem m_AreaGeometrySystem
    Used to notify area geometry once terrain heights are ready after loading.

  • private NativeList<Bounds2> m_NewUpdates
    NativeList storing newly requested update bounds. Returned to callers by GetUpdateBuffer() for adding new update regions. Allocated with Allocator.Persistent when needed.

  • private NativeList<Bounds2> m_PendingUpdates
    NativeList storing updates that were promoted from New and are awaiting the next phase (reading).

  • private NativeList<Bounds2> m_ReadingUpdates
    NativeList used when reading terrain heights. Regions moved here are read from terrain/water and then promoted to Ready.

  • private NativeList<Bounds2> m_ReadyUpdates
    NativeList of bounds that have finished the read phase and are ready to have affected entities found and heights updated.

  • private JobHandle m_UpdateDeps
    JobHandle tracking the last scheduled serialization/deserialization/setdefaults job or other internal job dependencies. Completed where necessary before modifying lists on the main thread.

  • private LoadHeightsState m_LoadHeightsState
    Enum value tracking the load lifecycle for heights (Loaded, Pending, Reading, Ready). Used when loading/saving games to trigger callbacks (e.g., TerrainHeightsReadyAfterLoading).

  • private TypeHandle __TypeHandle
    Generated type handle storing ComponentLookup/BufferLookup handles used to build jobs (assigned in OnCreateForCompiler).


Properties

  • None (no public properties)

Constructors

  • public GroundHeightSystem()
    Default constructor. System initialization occurs in the OnCreate override where dependent systems and type handles are acquired.

Methods

  • protected override void OnCreate() : System.Void
    Initializes references to TerrainSystem, WaterSystem, ModificationBarrier2 and search/tool/area systems via World.GetOrCreateSystemManaged. Sets up the system for runtime use.

  • protected override void OnDestroy() : System.Void
    Completes outstanding update jobs, disposes any created NativeList lists, and calls base.OnDestroy. Ensures native allocations are cleaned up.

  • protected override void OnGameLoaded(Context serializationContext) : System.Void
    Called after a game is loaded; sets the internal load state to Loaded so loading-related promotion of buffers can begin.

  • public NativeList<Bounds2> GetUpdateBuffer() : NativeList
    Returns a NativeList that callers can write bounds into to request height updates. Ensures outstanding jobs are completed and lazily allocates the New updates list (Allocator.Persistent). If a Ready list exists but is empty, it may reuse it for New to avoid extra allocation.

  • public void BeforeUpdateHeights() : System.Void
    Promotes New updates into Pending (merging lists if needed) and, when in the Loaded state, moves the load state to Pending. Completes m_UpdateDeps before manipulating lists.

  • public void BeforeReadHeights() : System.Void
    Promotes Pending updates into Reading and sets the load state to Reading if it was Pending. Completes m_UpdateDeps before manipulating lists.

  • public void AfterReadHeights() : System.Void
    Promotes Reading updates into Ready and if load state was Reading sets it to Ready and notifies m_AreaGeometrySystem.TerrainHeightsReadyAfterLoading() and m_TerrainSystem.TerrainHeightsReadyAfterLoading(). Completes m_UpdateDeps before manipulating lists.

  • public JobHandle Serialize<TWriter>(EntityWriterData writerData, JobHandle inputDeps) where TWriter : struct, IWriter : JobHandle
    Schedules a SerializeJob that writes all four update lists (New/Pending/Reading/Ready) to the provided writer. The scheduled job handle is stored in m_UpdateDeps and returned. Used by entity serialization.

  • public JobHandle Deserialize<TReader>(EntityReaderData readerData, JobHandle inputDeps) where TReader : struct, IReader : JobHandle
    Schedules a DeserializeJob to populate m_ReadingUpdates from serialized data (reads number of bounds and their min/max). Ensures m_ReadingUpdates exists. Stores and returns dependency in m_UpdateDeps.

  • public JobHandle SetDefaults(Context context) : JobHandle
    Schedules a SetDefaultsJob that clears any created update lists (safe defaulting on new contexts). Stores the returned job handle in m_UpdateDeps.

  • protected override void OnUpdate() : System.Void
    Main runtime update: if there are ready update bounds, it builds and schedules:

  • BoundsFindJob (IJobParallelFor) — scans quadtrees to find entities / area items that intersect the ready bounds and enqueues them into a NativeQueue.
  • DequeueJob — drains and deduplicates the queue into a NativeList.
  • UpdateHeightsJob (IJobParallelForDefer) — iterates the entity list and updates transforms/curve/node/area data using TerrainHeightData and WaterSurfaceData, and enqueues Updated/BatchesUpdated components via the command buffer. It registers readers with each search system and registers CPU readers with Terrain/Water systems and the modification barrier. The OnUpdate completes and chains job dependencies appropriately and stores m_UpdateDeps for serialization jobs.

  • private void __AssignQueries(ref SystemState state) : System.Void
    Compiler-generated placeholder that sets up any entity queries. (Called by OnCreateForCompiler.)

  • protected override void OnCreateForCompiler() : System.Void
    Called by generated code path to assign queries and component lookups (via __TypeHandle.__AssignHandles).

  • private JobHandle SerializeJob<TWriter>.Execute() etc. (nested job/iterator types)
    This class contains several nested Burst-compiled jobs and iterators used internally:

  • SerializeJob / DeserializeJob — IJob serializers for the update buffers.
  • SetDefaultsJob — clears lists.
  • BoundsFindJob — parallel job which uses multiple quad-tree iterators (ObjectIterator, LaneIterator, NetIterator, AreaIterator) to find affected entities/area items for each ready bounds and enqueue them into a NativeQueue.
  • DequeueJob — converst the queue into a deduplicated NativeList.
  • UpdateHeightsJob — parallel update job that adjusts object transforms, net curves, nodes and area nodes according to terrain/water heights and adds Updated/BatchesUpdated/MovedLocation components using an EntityCommandBuffer.ParallelWriter. Contains helper methods to determine lot owners, fixed nodes and to handle sub-objects.
  • TypeHandle (struct) — stores ComponentLookup/BufferLookup handles used to populate jobs.

These nested types are internal implementation details used to parallelize and Burst-compile the heavy lifting.


Usage Example

// Example: Requesting a terrain height update for a specific 2D area from a mod/system.
var groundSystem = World.GetOrCreateSystemManaged<Game.Simulation.GroundHeightSystem>();

// Get the update buffer and add a region to update (Bounds2 has min/max as float2)
var updates = groundSystem.GetUpdateBuffer();
updates.Add(new Bounds2 { min = new float2(100f, 200f), max = new float2(140f, 240f) });

// Inform the GroundHeightSystem that we finished adding updates for this frame phase:
groundSystem.BeforeUpdateHeights();

// Later, when the game is about to read terrain heights:
groundSystem.BeforeReadHeights();

// After terrain/water height reading is done (promotes to Ready and triggers processing):
groundSystem.AfterReadHeights();

Notes and modding tips: - GetUpdateBuffer() returns a NativeList with Allocator.Persistent. Do not dispose this list yourself — GroundHeightSystem manages its lifetime and disposes it in OnDestroy. - Calls such as BeforeUpdateHeights/BeforeReadHeights/AfterReadHeights must be invoked at the appropriate game phases (matching main game loop behavior) to correctly move regions through the New -> Pending -> Reading -> Ready pipeline. - Serialize/Deserialize/SetDefaults are used by the game's save/load machinery. If you interact with serialization, ensure you combine JobHandles correctly with the returned JobHandle from these methods. - The system schedules Burst jobs and uses EntityCommandBuffer.ParallelWriter. If you create jobs that depend on entity data or search trees, use the same reader registrations (or ensure ordering) to avoid race conditions.