Skip to content

Game.CitizenSystem

Assembly: Game
Namespace: Game.Serialization

Type: class

Base: GameSystemBase

Summary:
CitizenSystem is an ECS system that assigns a PrefabRef to citizen entities. It queries entities that have a Citizen component and a PrefabRef (excluding those with RandomLocalization), gathers available citizen prefabs (CitizenData entities), and schedules a Burst-compiled IJobChunk (CitizenJob) to pick a prefab per citizen using a RandomSeed. The system prepares component/ entity type handles for efficient chunk iteration and uses ToEntityListAsync to fetch the list of citizen prefab Entities asynchronously.


Fields

  • private EntityQuery m_Query
    Used to find all entities that have a Citizen component and a PrefabRef and that do not have RandomLocalization. This query is also passed to RequireForUpdate to ensure the system only runs when relevant entities exist.

  • private EntityQuery m_CitizenPrefabQuery
    Query to locate all CitizenData prefab entities. The results are converted to a NativeList via ToEntityListAsync and consumed by the scheduled job.

  • private TypeHandle __TypeHandle
    Container for precomputed type handles (EntityTypeHandle, ComponentTypeHandle, ComponentTypeHandle, ComponentLookup). The __AssignHandles method initializes these handles from a SystemState for use in job scheduling and chunk iteration.

  • (nested) private struct CitizenJob
    Burst-compiled IJobChunk that:

  • Reads the list of citizen prefab Entities (NativeList m_CitizenPrefabs).
  • Reads Citizen components and CitizenData lookup.
  • Writes PrefabRef components for each entity in the chunk.
  • Uses a RandomSeed to select an appropriate prefab via CitizenUtils.GetCitizenPrefabFromCitizen. Implementation detail: it implements Execute(in ArchetypeChunk, ...) and calls a private Execute helper to do the work.

  • (nested) private struct TypeHandle
    Small helper struct that stores the various type handles and provides __AssignHandles(ref SystemState) to cache them.

Properties

  • No public properties.
    All required component and entity handles are stored in the private TypeHandle and passed into jobs.

Constructors

  • public CitizenSystem()
    Default constructor. The system uses OnCreate to initialize queries and requires the main query for update.

Methods

  • protected override void OnCreate()
    Initializes:
  • m_Query = GetEntityQuery(Citizen read-only, PrefabRef read-only, exclude RandomLocalization)
  • m_CitizenPrefabQuery = GetEntityQuery(CitizenData read-only)
  • RequireForUpdate(m_Query) so the system only runs when there are matched entities.

  • protected override void OnUpdate()
    Prepares and schedules the CitizenJob:

  • Retrieves entity/component type handles from __TypeHandle via InternalCompilerInterface helper calls.
  • Calls m_CitizenPrefabQuery.ToEntityListAsync(...) to get a NativeList of citizen prefabs and receives an out job handle for the async list build.
  • Configures CitizenJob with the handles, prefab list, CitizenData lookup, and a RandomSeed.Next().
  • Schedules the burst-compiled IJobChunk (JobChunkExtensions.Schedule) over m_Query, combining dependencies with the outJobHandle and setting base.Dependency to the returned handle.

  • protected override void OnCreateForCompiler()
    Called by the generated/compiled pipeline to set up type handles and queries for the compiler path:

  • Calls __AssignQueries(ref base.CheckedStateRef)
  • Calls __TypeHandle.__AssignHandles(ref base.CheckedStateRef)

  • private void __AssignQueries(ref SystemState state)
    Currently creates and disposes a temporary EntityQueryBuilder(Allocator.Temp). Appears to be a placeholder used for generated-compiler setup; real query initialization is done in OnCreate.

  • (in nested CitizenJob) public void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
    Iterates entities in the provided ArchetypeChunk:

  • Reads Entity, Citizen, and PrefabRef arrays for the chunk.
  • Gets a Random instance from m_RandomSeed.GetRandom(unfilteredChunkIndex).
  • For each citizen in the chunk, chooses a prefab Entity using CitizenUtils.GetCitizenPrefabFromCitizen(m_CitizenPrefabs, citizen, m_CitizenDatas, random) and writes it into the PrefabRef slot.
  • This method is Burst-compiled for performance.

  • (in nested CitizenJob) void IJobChunk.Execute(...)
    Explicit interface implementation that forwards to the public Execute helper.

Notes / Implementation details: - The job is Burst-compiled (BurstCompile attribute) to maximize performance across many citizens. - CitizenData lookup is provided as a ComponentLookup (read-only) to allow per-entity data reads inside the job. - The use of ToEntityListAsync with an allocator and an out job handle allows building the prefab list in parallel; its JobHandle is combined into the job schedule dependencies. - RandomSeed.Next() is used to provide per-schedule randomness seeded appropriately for deterministic behavior across runs.

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    m_Query = GetEntityQuery(ComponentType.ReadOnly<Citizen>(),
                             ComponentType.ReadOnly<PrefabRef>(),
                             ComponentType.Exclude<RandomLocalization>());
    m_CitizenPrefabQuery = GetEntityQuery(ComponentType.ReadOnly<CitizenData>());
    RequireForUpdate(m_Query);
}

Additional tips: - Ensure CitizenData prefabs (queried by m_CitizenPrefabQuery) are populated before this system runs, otherwise the prefab list may be empty and PrefabRef assignments will be invalid. - When modifying or extending selection logic, update CitizenUtils.GetCitizenPrefabFromCitizen to keep selection centralized and testable. - Because the job writes PrefabRef, be careful about concurrent writers to the same components from other systems — preserve proper dependencies via JobHandle combination.