Skip to content

Game.Areas.SurfaceUpdateSystem

Assembly: Game
Namespace: Game.Areas

Type: class

Base: GameSystemBase

Summary:
SurfaceUpdateSystem is an ECS system used by Cities: Skylines 2 to propagate surface/area updates from network nodes into area entities. It listens for network nodes that have been marked Updated (and are owned and not temporary/deleted), queries the spatial search tree (from SearchSystem) to find areas whose triangles contain the node position, and adds an Updated component to those area entities via a parallel EntityCommandBuffer. The system uses a ModificationBarrier5 to safely produce structural changes and registers itself as a reader of the SearchSystem's NativeQuadTree to coordinate dependencies.


Fields

  • private ModificationBarrier5 m_ModificationBarrier
    Holds the modification barrier system used to create an EntityCommandBuffer. The buffer is produced in parallel by the scheduled job so structural changes (adding Updated to area entities) are deferred and synchronized via this barrier.

  • private SearchSystem m_AreaSearchSystem
    Reference to the SearchSystem that exposes a NativeQuadTree. The system requests a read-only reader of the tree (and registers the job as a reader) so it can iterate spatially over areas.

  • private EntityQuery m_UpdatedNetQuery
    EntityQuery that matches network node entities to process. It requires Game.Net.Node, Owner and Updated components and excludes Temp and Deleted. The system uses RequireForUpdate(m_UpdatedNetQuery) so it runs only when matching nodes exist.

  • private TypeHandle __TypeHandle
    Struct instance that caches ComponentTypeHandle/ComponentLookup/BufferLookup instances used by the job. Handles are assigned in OnCreateForCompiler for efficient access inside jobs.

Properties

  • This system does not expose public properties.

Constructors

  • public SurfaceUpdateSystem()
    Default constructor. Marked with [Preserve] so it is kept by stripping tools. The real initialization is performed in OnCreate/OnCreateForCompiler.

Methods

  • protected override void OnCreate() : System.Void
    Initializes runtime references: gets the ModificationBarrier5 and SearchSystem from the World, builds the EntityQuery (m_UpdatedNetQuery) that filters for updated network nodes, and calls RequireForUpdate to avoid running when there are no matching nodes.

  • protected override void OnUpdate() : System.Void
    Creates and schedules the UpdateAreasJob (IJobChunk) over the m_UpdatedNetQuery. It:

  • obtains component/buffer lookups and the node ComponentTypeHandle via the __TypeHandle helpers,
  • asks the SearchSystem for a read-only search tree and receives a dependency JobHandle for the tree,
  • schedules the job in parallel and combines dependencies with the system's current dependency,
  • registers the returned job as a reader with the SearchSystem (m_AreaSearchSystem.AddSearchTreeReader),
  • informs the ModificationBarrier5 of the producer job handle,
  • and assigns the scheduled job handle back to base.Dependency.

  • private void __AssignQueries(ref SystemState state) : System.Void
    Compiler helper called from OnCreateForCompiler. In this compiled code it performs minimal query initialization (here it only creates and disposes a temporary EntityQueryBuilder), but in general this is the place query assignments would be set for the compiler-generated code path.

  • protected override void OnCreateForCompiler() : System.Void
    Compiler-time initialization method that calls __AssignQueries and instructs the __TypeHandle to assign the component/buffer handles (via __AssignHandles). This ensures the TypeHandle fields are prepared for use when scheduling jobs.

  • (Nested) TypeHandle.__AssignHandles(ref SystemState state)
    Assigns the actual ComponentTypeHandle (read-only), ComponentLookup, BufferLookup, and BufferLookup from the provided SystemState. These are then used by the scheduled job for safe, efficient access inside the job.

  • (Nested) UpdateAreasJob.Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask) : System.Void
    IJobChunk entry point. Iterates all Game.Net.Node components in the chunk and for each node calls UpdateSurfaces(unfilteredChunkIndex, node.m_Position).

  • (Nested) UpdateAreasJob.UpdateSurfaces(int jobIndex, float3 position) : System.Void
    Builds a SurfaceIterator instance for the given node position (and job index/handles) and iterates the NativeQuadTree obtained from the SearchSystem. The iterator checks triangle containment and, when a matching area is found that has a Surface component and whose triangle contains the node position, it enqueues an Added Updated component on the area via the parallel EntityCommandBuffer.

  • (Nested) SurfaceIterator.Intersect / Iterate
    SurfaceIterator implements INativeQuadTreeIterator and IUnsafeQuadTreeIterator to query the search tree: Intersect checks if the node's xz position intersects a bounds node; Iterate verifies that the area entity has a Surface component, fetches its nodes/triangle buffers, computes the triangle shape, checks if the node position lies inside that triangle and then uses the command buffer to AddComponent to the area entity (using the job index for parallel command ordering).

Usage Example

// To trigger SurfaceUpdateSystem you must mark a network node entity with Updated (and it must have an Owner).
// Example: mark a node entity as Updated so the system will propagate to overlapping areas next frame.
var ecb = new EntityCommandBuffer(Allocator.Temp);
ecb.AddComponent<Updated>(nodeEntity);
ecb.Playback(entityManager);
ecb.Dispose();

// The SurfaceUpdateSystem will run when there are nodes matching:
//   Game.Net.Node (read-only), Owner (read-only), Updated (read-only)
// and will add Updated to any area entities whose triangle contains the node position.

Additional notes: - The system is burst-eligible through its nested job types and uses parallel scheduling for performance on many nodes. - It relies on SearchSystem's NativeQuadTree to efficiently limit triangle checks to nearby areas. - Structural changes are deferred via ModificationBarrier5 to avoid race conditions and to integrate with the ECS dependency system.