Skip to content

Game.LotHeightSystem

Assembly:
Assembly-CSharp.dll

Namespace:
Game.Buildings

Type:
class

Base:
GameSystemBase

Summary:
LotHeightSystem scans "lots" (building footprint entities) and updates per-edge height information based on nearby static objects and net geometry. It batches work using Unity DOTS jobs (Burst compiled), quad-tree searches and deferred parallel jobs to find lots that need recalculation, then computes front/right/back/left corner and middle heights for each lot. The system marks lots as Updated (via an Updated component) when their stored heights change so other systems can respond. This system is intended to run inside the game's ECS world and is optimized for large-scale updates (uses NativeQuadTree, NativeQueue, NativeList, and EntityCommandBuffer.ParallelWriter).

Additional info: - Uses several inner jobs: AddUpdatedLotsJob, FindUpdatedLotsJob, CollectLotsJob and UpdateLotHeightsJob. The heavy lifting and geometry checks are inside UpdateLotHeightsJob.LotIterator. - Considers both "rigid" (hard) and "flexible" (soft) height influences and blends them to produce the final values. - Honors prefab-level flags (e.g., flatten terrain, dontRaise/dontLower, lot size, circular objects) and special net composition flags when deciding whether and how to affect lot heights.


Fields

  • private Game.Objects.UpdateCollectSystem m_ObjectUpdateCollectSystem
    Provides updated bounds for static objects. LotHeightSystem reads this to discover which world regions have had object changes.

  • private Game.Net.UpdateCollectSystem m_NetUpdateCollectSystem
    Provides updated bounds for net (road) geometry. Used to detect net changes that could affect lots.

  • private Game.Objects.SearchSystem m_ObjectSearchSystem
    Gives access to a NativeQuadTree of static objects for spatial queries. The system registers job readers/writers to this search tree.

  • private Game.Net.SearchSystem m_NetSearchSystem
    Provides a NativeQuadTree for net geometry used during lot height sampling.

  • private ModificationBarrier5 m_ModificationBarrier
    Used to create an EntityCommandBuffer.ParallelWriter so jobs can add an Updated component to lots that change. Essential for thread-safe structural changes.

  • private EntityQuery m_UpdateQuery
    Query used to enumerate only lots that have an Updated component (i.e., changed) when not doing a full scan.

  • private EntityQuery m_AllQuery
    Query used to enumerate all lots (used after a load / full refresh).

  • private bool m_Loaded
    Transient flag set when the game serialization finishes loading. Forces a full lot scan on the first update after load.

  • private TypeHandle __TypeHandle
    Container for EntityTypeHandle and ComponentLookup handles used by jobs. Assigned in OnCreateForCompiler and used to get ComponentLookup / EntityTypeHandle for job scheduling.

{{ YOUR_INFO }} - These fields are the core integration points with other update/search systems; modders should avoid directly mutating them and instead interact via the world/system APIs.


Properties

  • None (this system exposes no public properties)

{{ YOUR_INFO }} - All component lookups and handles are managed internally via the TypeHandle. If you need to read lot heights, query Lot component data through ECS (ComponentLookup/ComponentDataFromEntity) rather than reaching into this system's fields.


Constructors

  • public LotHeightSystem()
    Default constructor. The system is preserved for injection and created via the ECS World.

{{ YOUR_INFO }} - Typical usage: the system is created by the ECS World automatically. Modders should not instantiate this directly; instead request it via World.GetOrCreateSystemManaged().


Methods

  • protected override void OnCreate()
    Initializes references to other systems and prepares the entity queries:
  • Gets UpdateCollectSystem for objects and nets, and their SearchSystem counterparts.
  • Gets the ModificationBarrier5 for command buffer creation.
  • Sets up m_UpdateQuery (lots with Updated) and m_AllQuery (all lots).

{{ YOUR_INFO }} - Important for modders: OnCreate wires this system into the game's update/collect/search pipeline. If you add a new update source (e.g., custom object types), ensure they feed bounds into the UpdateCollectSystem or provide an equivalent mechanism so LotHeightSystem will consider them.

  • protected override void OnGameLoaded(Context serializationContext)
    Sets m_Loaded to true which triggers a full refresh (m_AllQuery) on the next OnUpdate call.

{{ YOUR_INFO }} - This ensures that after loading a saved game the system recalculates heights for all lots once.

  • private bool GetLoaded()
    Checks and consumes the m_Loaded flag. Returns true once immediately after load to force a full scan.

{{ YOUR_INFO }} - Internal helper used by OnUpdate to flip from "loaded" state to normal operation.

  • protected override void OnUpdate()
    Main scheduling function. Behavior:
  • Determines whether to run based on updates from object/net collectors or if any lots are flagged.
  • Gathers a static object search tree and net search tree (NativeQuadTree read-only) and schedules a set of jobs:
    • AddUpdatedLotsJob: optionally add already-marked lots to the list to process.
    • FindUpdatedLotsJob: queries updated bounds (object/net) against the static object search tree to collect potentially affected lots into queues.
    • CollectLotsJob: merges and deduplicates lists/queues into a NativeList.
    • UpdateLotHeightsJob: runs per-lot parallel job that performs spatial iteration around the lot, sampling nearby geometry and updating Lot component heights; adds Updated component if the Lot changed and not in loaded state.
  • Disposes temporary native containers and registers job readers with search systems for safety.

{{ YOUR_INFO }} - This method demonstrates best practices for large-scale spatial updates: use deferred parallel-for scheduling, merge update candidates, and use a command buffer to mark structural changes from jobs. - The heavy geometry work (curve subdivision, line/quad/circle checks) happens inside UpdateLotHeightsJob.LotIterator and is Burst compiled. Avoid calling those routines directly on the main thread.

  • protected override void OnCreateForCompiler()
    Assigns queries and calls __TypeHandle.__AssignHandles to initialize all EntityTypeHandle / ComponentLookup handles needed by jobs (used by the DOTS compiler path).

{{ YOUR_INFO }} - Required to ensure the job handles and lookups are properly populated in compiled builds and by the ECS runtime.

  • private void __AssignQueries(ref SystemState state)
    Compiler helper to setup/validate queries. Present to satisfy ECS codegen/hints.

{{ YOUR_INFO }} - Not intended for modders to call; it's part of the generated plumbing.

Other notable internal/inner methods and types: - AddUpdatedLotsJob, FindUpdatedLotsJob, CollectLotsJob, UpdateLotHeightsJob (and nested LotIterator) — these are the job types used to find and compute height changes. They perform all spatial/geometry logic, consider prefab flags and composition states, and write back to Lot components via ComponentLookup and/or EntityCommandBuffer when needed.

{{ YOUR_INFO }} - If you need to extend behavior (e.g., include new prefab flags, alter sampling radius or strength blending), the UpdateLotHeightsJob.LotIterator.Check* and AddHeight/CalculateMiddleHeights routines are where to modify logic. Because these are Burst-compiled jobs, changes must remain Burst compatible and use allowed types/APIs.


Usage Example

// Example: Trigger a manual height recalculation for a specific lot entity.
// Typically this system will detect changes from UpdateCollectSystems automatically,
// but you can mark a lot as Updated to force it to be processed:

var world = Unity.Entities.World.DefaultGameObjectInjectionWorld;
var lotHeightSystem = world.GetOrCreateSystemManaged<Game.Buildings.LotHeightSystem>();
var modificationBarrier = world.GetOrCreateSystemManaged<Game.ModificationBarrier5>();

var ecb = modificationBarrier.CreateCommandBuffer();
ecb.AddComponent(lotEntity, new Updated()); // mark the lot so LotHeightSystem picks it up next update

// Note: Use the game's normal scheduling / system ordering. Do not call the system's OnUpdate directly.
// If calling from a job or other system, use the proper command buffer (ParallelWriter if inside a job).

{{ YOUR_INFO }} - When adding Updated from a job, use the EntityCommandBuffer.ParallelWriter created by ModificationBarrier5 (as LotHeightSystem does) to keep structural changes thread-safe. - Prefer feeding bounds into the Game.Objects.UpdateCollectSystem or Game.Net.UpdateCollectSystem if you have a custom object/net that should influence lots—this will integrate with FindUpdatedLotsJob and be more efficient than marking many individual lots. - Performance tips: - Avoid marking huge numbers of lots every frame; batch updates where possible. - Keep custom geometry and prefab flags compatible with the checks used by LotHeightSystem so that it can correctly determine flattening/rigidity rules. - Remember that UpdateLotHeightsJob uses NativeQuadTree queries and Burst; large changes will still be efficient but may produce CPU spikes while jobs run.