Skip to content

Game.Simulation.PopulationToGridSystem

Assembly:
Game (assembly for Cities: Skylines 2 runtime systems)

Namespace:
Game.Simulation

Type:
public class PopulationToGridSystem

Base:
CellMapSystem, IJobSerializable

Summary:
PopulationToGridSystem builds a population density grid by iterating residential properties (entities with ResidentialProperty + Renter + Transform) and summing household citizen counts into a fixed-size 2D cell map. It runs as a scheduled job (Burst-compiled inner job) that populates a NativeArray sized kTextureSize × kTextureSize. The system is optimized for Unity's DOTS: it uses EntityQuery to collect residential property entities, BufferLookup / ComponentLookup handles for buffers and components, and schedules a IJob (PopulationToGridJob) that writes into the system's map. The system exposes helpers to convert between world positions and cell indices and to sample interpolated population from the grid.


Fields

  • public static readonly int kTextureSize
    kTextureSize = 64. The grid resolution (width and height) used by this system. The map is kTextureSize × kTextureSize cells.

  • public static readonly int kUpdatesPerDay
    kUpdatesPerDay = 32. Used to compute the update interval in GetUpdateInterval; determines how many times per in-game day the map is refreshed.

  • private EntityQuery m_ResidentialPropertyQuery
    EntityQuery used to select residential-property entities for processing. The query includes ResidentialProperty, Renter, and Transform and excludes Destroyed, Deleted, and Temp.

  • private TypeHandle __TypeHandle
    Internal container for ComponentLookup/BufferLookup handles used by the job (Renter buffer, HouseholdCitizen buffer, Transform component). Assigned during OnCreateForCompiler.

  • (Nested) PopulationToGridJob (private, BurstCompile)
    IJob implementation run by the system. Reads the entity list, reads Renter and Transform data and HouseholdCitizen buffers, and aggregates population counts into the NativeArray map. Clears the map at start of Execute and then accumulates per-residential-entity citizen counts into the corresponding cell.

  • (Nested) TypeHandle (private)
    Struct that stores BufferLookup, BufferLookup, and ComponentLookup and provides __AssignHandles to initialize them from a SystemState.

Properties

  • public int2 TextureSize { get; }
    Returns a vector (kTextureSize, kTextureSize). Convenience property exposing the grid dimensions.

Constructors

  • public PopulationToGridSystem()
    Default constructor. The system also relies on OnCreate to initialize textures and the residential property query.

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase) : int
    Returns the update interval in ticks (frames/units used by the engine) based on kUpdatesPerDay. Implementation: return 262144 / kUpdatesPerDay.

  • public static float3 GetCellCenter(int index) : float3
    Helper that returns the world-space center of the cell at the given linear index. Delegates to CellMapSystem.GetCellCenter with kTextureSize.

  • public static PopulationCell GetPopulation(float3 position, NativeArray<PopulationCell> populationMap) : PopulationCell
    Samples population for an arbitrary world position. This computes the cell for the position and performs bilinear interpolation between neighboring cell population values to return a PopulationCell with an interpolated m_Population. Returns a default PopulationCell if position is outside the grid.

  • [Preserve] protected override void OnCreate()
    Initializes the system: calls base.OnCreate(), creates textures for the map using CreateTextures(kTextureSize) and sets up m_ResidentialPropertyQuery to select ResidentialProperty + Renter + Transform and exclude Destroyed/Deleted/Temp. Also prepares internal handles in OnCreateForCompiler.

  • [Preserve] protected override void OnUpdate()
    Schedules the PopulationToGridJob. It:

  • Converts the residential property query into a NativeList asynchronously.
  • Constructs PopulationToGridJob with references to the entity list, the internal m_Map (NativeArray), and BufferLookup/ComponentLookup obtained via InternalCompilerInterface.GetBufferLookup / GetComponentLookup using __TypeHandle and the checked state reference.
  • Schedules the job combining async entity list handle and read/write dependencies, assigns the resulting JobHandle to base.Dependency, and registers the system as a writer (AddWriter).

  • [MethodImpl(MethodImplOptions.AggressiveInlining)] private void __AssignQueries(ref SystemState state)
    Compiler helper (generated pattern). Here it performs an EntityQueryBuilder temporary creation and disposal. Called from OnCreateForCompiler.

  • protected override void OnCreateForCompiler()
    Compiler-time setup: calls base.OnCreateForCompiler(), assigns queries via __AssignQueries and initializes __TypeHandle via __AssignHandles. Typically used by generated code paths to wire up lookups.

  • [Preserve] public and other attributes on nested job/struct methods
    PopulationToGridJob.Execute does the main work: zeroes the map and iterates residential entities to accumulate population counts into appropriate cells. TypeHandle.__AssignHandles initializes the component/buffer lookups from the SystemState.

Usage Example

// Example: sampling population at a world position using the static API.
// 'populationMap' should be the NativeArray<PopulationCell> exposed/owned by the running system.
// In game code you need to obtain that array from the system instance; shown here as a placeholder.

float3 worldPos = new float3(100f, 0f, 250f);
NativeArray<PopulationCell> populationMap = /* obtain from PopulationToGridSystem instance (m_Map) */;
PopulationCell sampled = PopulationToGridSystem.GetPopulation(worldPos, populationMap);
float populationAtPos = sampled.m_Population;

Notes / Implementation details: - The actual per-frame or scheduled update logic is implemented in a Burst-compiled IJob (PopulationToGridJob) for performance. - BufferLookup and ComponentLookup are obtained through an internal compiler interface using a stored TypeHandle; this matches typical DOTS generated code patterns. - The system uses fixed-size grid (kTextureSize = 64) and interpolates population values for arbitrary positions. - The EntityQuery filters out temporary, destroyed or deleted entities to avoid counting invalid entities.