Game.Prefabs.ZoneBuiltRequirementSystem
Assembly:
{{ Likely part of the main game assembly that contains Game.* prefabs and systems (Cities: Skylines 2 game assemblies). }}
Namespace: Game.Prefabs
Type:
Class (Game system derived from GameSystemBase, compiler-generated attribution present)
Base:
GameSystemBase, IPreDeserialize
Summary:
{{ ZoneBuiltRequirementSystem collects and maintains statistics about built zone tiles and built zone counts (per zone prefab, level and/or theme/type) by scanning building entities and consuming queued level-change events. It stores the aggregated data in a native hash map and uses a parallel IJobChunk to evaluate ZoneBuiltRequirementData components (unlock requirements). When requirements are satisfied the system emits Unlock events (creates entities with Unlock components) via a ModificationBarrier command buffer. The system uses persistent Native collections and schedules burst-compiled jobs to run the data-collection and requirement evaluation in parallel. It also supports being told when a load finished (PreDeserialize) so it can rebuild its internal state from all buildings. }}
Fields
-
private ModificationBarrier5 m_ModificationBarrier
{{ Command-buffer barrier system used to create unlock event entities and enqueue commands from jobs in a thread-safe manner. Obtained in OnCreate. }} -
private EntityQuery m_UpdatedBuildingsQuery
{{ Query selecting building entities that were Created or Deleted (and are not Temp) — used for incremental updates. }} -
private EntityQuery m_AllBuildingsQuery
{{ Query selecting all Building entities (excluding Temp) — used when full rebuild is required (e.g. after load). }} -
private EntityQuery m_RequirementQuery
{{ Query selecting entities with ZoneBuiltRequirementData, UnlockRequirementData (read/write) and Locked — used to evaluate unlocks. }} -
private EntityArchetype m_UnlockEventArchetype
{{ Archetype used to create Unlock event entities (components: Event, Unlock). }} -
private NativeParallelHashMap<ZoneBuiltDataKey, ZoneBuiltDataValue> m_ZoneBuiltData
{{ Primary native container mapping (zone prefab, level) keys to aggregated counts and squares built. Persistent allocator; cleared on PreDeserialize and disposed on OnDestroy. }} -
private NativeQueue<ZoneBuiltLevelUpdate> m_ZoneBuiltLevelQueue
{{ Queue used by other systems/jobs to report building level transitions (from one zone level to another) — consumed by UpdateZoneBuiltDataJob to update zone built aggregates. Persistent allocator; disposed on OnDestroy. }} -
private JobHandle m_WriteDeps
{{ JobHandle that tracks outstanding jobs that wrote to m_ZoneBuiltData (used to ensure completion where necessary, e.g. PreDeserialize). }} -
private JobHandle m_QueueWriteDeps
{{ JobHandle that tracks writers that have written to the level-change queue. Consumers can combine dependencies via AddWriter. }} -
private bool m_Loaded
{{ Flag set by PreDeserialize to indicate a full rebuild is required on next update. }} -
private TypeHandle __TypeHandle
{{ Internal struct caching all ComponentTypeHandle/ComponentLookup/BufferLookup used by jobs; assigned in OnCreateForCompiler. }}
Properties
- (none declared)
{{ The system exposes no public C# properties. It exposes methods to access internal queues and to add writer dependencies. }}
Constructors
public ZoneBuiltRequirementSystem()
{{ Default constructor; system uses OnCreate to perform initialization. The class is marked [CompilerGenerated] and has a [Preserve] attribute on lifecycle methods. }}
Methods
-
public NativeQueue<ZoneBuiltLevelUpdate> GetZoneBuiltLevelQueue(out JobHandle deps)
{{ Returns the internal NativeQueueused to enqueue building level-change updates. Also returns current JobHandle dependencies (m_QueueWriteDeps) via out parameter — callers should pass that dependency to any jobs that will write to the queue or call AddWriter with their job handle. Note: returned queue is the actual internal queue (NativeQueue) — be careful with ownership and threading; call AddWriter to register job dependencies. }} -
public void AddWriter(JobHandle jobHandle)
{{ Combine a job handle (writer to the queue) with the internal m_QueueWriteDeps to track concurrent writers. This ensures the UpdateZoneBuiltDataJob will wait on writers when scheduled. }} -
protected override void OnCreate()
{{ Initializes queries, archetypes, and native containers: sets up m_ModificationBarrier, m_UpdatedBuildingsQuery, m_AllBuildingsQuery, m_RequirementQuery, creates m_UnlockEventArchetype, allocates m_ZoneBuiltData and m_ZoneBuiltLevelQueue with persistent allocators. Called when the system is created. }} -
protected override void OnDestroy()
{{ Disposes the persistent native containers (m_ZoneBuiltData and m_ZoneBuiltLevelQueue) and calls base.OnDestroy. Ensure that any outstanding jobs have completed before destruction (the system's lifecycle ensures this). }} -
private bool GetLoaded()
{{ Internal helper used in OnUpdate; returns true if m_Loaded was set (by PreDeserialize) and clears the flag. This triggers a full rebuild pass using m_AllBuildingsQuery. }} -
protected override void OnUpdate()
{{ Main update loop. If there are updated buildings (or a full-load rebuild requested) or pending queued level updates: - Collects building ArchetypeChunks (async) and schedules UpdateZoneBuiltDataJob which scans building entities and the level-change queue to update m_ZoneBuiltData.
- If any ZoneBuiltRequirementData exist (m_RequirementQuery non-empty) schedules ZoneBuiltRequirementJob (IJobChunk) to evaluate requirements using the aggregated m_ZoneBuiltData and create Unlock event entities via the modification barrier.
-
Properly chains job dependencies and adds the job handle to the modification barrier for producer tracking. }}
-
public void PreDeserialize(Context context)
{{ Implementation of IPreDeserialize. Completes m_WriteDeps to ensure jobs updating the internal data are finished, clears m_ZoneBuiltData, and sets m_Loaded = true so the next OnUpdate will perform a full rebuild from all buildings (m_AllBuildingsQuery). This is required during loading to ensure internal aggregates are rebuilt. }} -
protected override void OnCreateForCompiler()
{{ Internal initialization helper called by generated code paths: assigns cached entity/component handles and queries via __AssignQueries and __TypeHandle.__AssignHandles. }} -
private void __AssignQueries(ref SystemState state)
{{ Compiler-generated stub for query assignment; minimal implementation present. }} -
Nested types (summary)
private struct ZoneBuiltData
{{ Local POD struct used to hold per-entry values in some contexts (Entity, Zone, squares, count, area type and level). This nested struct in source is not the persistent hash map value type used externally (this file uses ZoneBuiltDataKey and ZoneBuiltDataValue types which are declared elsewhere). }}private struct UpdateZoneBuiltDataJob : IJob
{{ Burst-compiled IJob that:- Iterates building archetype chunks (m_BuildingChunks).
- Reads PrefabRef and Deleted to determine whether a building contributes positively or negatively.
- Uses SpawnableBuildingData and BuildingData lookups to find zone prefab and lot size to compute squares/count.
- Updates m_ZoneBuiltData (NativeParallelHashMap) accordingly.
- Dequeues ZoneBuiltLevelUpdate items from m_ZoneBuiltLevelQueue and applies their effects (move one building from one level key to another). This job is scheduled from OnUpdate and writes into the system's native hash map. }}
private struct ZoneBuiltRequirementJob : IJobChunk
{{ Burst-compiled IJobChunk that runs over entities with ZoneBuiltRequirementData + UnlockRequirementData (locked). For each entity:- Aggregates squares and counts from m_ZoneBuiltData according to the requirement (by specific zone prefab & min level, or by theme, or by area type).
- Updates the UnlockRequirementData.m_Progress (either progress toward minimum squares or toward minimum count).
- If the requirement is satisfied (enough squares and count), it uses an EntityCommandBuffer.ParallelWriter to create an Unlock event entity with the Unlock component pointing at the target entity. This job is scheduled in parallel via JobChunkExtensions.ScheduleParallel. }}
Usage Example
// Example: enqueue a level-change update from another system/job and register its job dependency.
var zoneSystem = World.GetExistingSystemManaged<ZoneBuiltRequirementSystem>();
JobHandle writerDeps = someJobHandleThatProducesLevelUpdates; // your job that enqueues updates
zoneSystem.AddWriter(writerDeps);
// From main thread (or a safe thread) you can also enqueue directly:
JobHandle deps;
var queue = zoneSystem.GetZoneBuiltLevelQueue(out deps); // get queue and producer deps
// Ensure any jobs that will write have been added via AddWriter before enqueueing from jobs.
// Enqueue an update (example struct fields depend on ZoneBuiltLevelUpdate definition):
queue.Enqueue(new ZoneBuiltLevelUpdate { m_Zone = myZoneEntity, m_FromLevel = 1, m_ToLevel = 2, m_Squares = 4 });
// The system will pick up queued updates on its next OnUpdate and rebuild/adjust aggregates as needed.
{{ Notes: - The system relies on types defined elsewhere: ZoneBuiltDataKey, ZoneBuiltDataValue, ZoneBuiltLevelUpdate, ZoneBuiltRequirementData, UnlockRequirementData, ObjectRequirementElement, ThemeData, ZoneData, SpawnableBuildingData, BuildingData, etc. - Because it uses NativeParallelHashMap and NativeQueue with Allocator.Persistent, make sure the system's lifecycle is respected; do not attempt to use returned NativeQueue after the system has been destroyed. - To ensure correct multithreading, always call AddWriter with the job handle of any job that writes to the queue so the system can combine dependencies and avoid race conditions. - PreDeserialize is important on load: it completes outstanding writes, clears cached aggregates and forces a full rebuild from all building entities. }}