Game.CitizenFindJobSystem
Assembly:
Unknown (game runtime assembly containing simulation systems)
Namespace: Game.Simulation
Type:
public class CitizenFindJobSystem
Base:
GameSystemBase
Summary:
CitizenFindJobSystem is an ECS simulation system responsible for deciding when citizens should look for work and for spawning JobSeeker entities that represent individual job-seeking attempts. It runs as a scheduled job (burst-compiled IJobChunk) over two queries: unemployed citizens and employed citizens (for potential job switching). The system consults workplace availability (CountWorkplacesSystem), game simulation frame state (SimulationSystem), and citizen parameters to determine probabilities, respects cooldowns, household states (renter, tourist, homeless, moving away), and only creates job seeker entities when a valid origin building/home is found. It uses EndFrameBarrier to create entity command buffers for safe parallel entity changes and leverages RandomSeed for nondeterministic decisions.
Fields
-
public static readonly int kUpdatesPerDay
Constant controlling how many update frames per in-game day are used to compute updateFrame indices (value: 256). Used to determine which simulation update frame to process. -
public static readonly int kJobSeekCoolDownMax
Maximum cooldown (10000) added to a citizen's last job seek frame when marking them as having looked recently. -
public static readonly int kJobSeekCoolDownMin
Minimum cooldown (5000) used together with randomness. -
private EndFrameBarrier m_EndFrameBarrier
EndFrameBarrier system used to obtain EntityCommandBuffer. Parallel-safe command buffers are used to create JobSeeker entities and set components at the end of the frame. -
private EntityQuery m_UnemployedQuery
EntityQuery selecting unemployed citizens eligible to look for jobs (excludes temps, students, existing seekers, health problems, deleted). -
private EntityQuery m_EmployedQuery
EntityQuery selecting employed citizens who may switch jobs (excludes temps, students, existing seekers, health problems, deleted). -
private EntityQuery m_CitizenParametersQuery
Query used to fetch CitizenParametersData (contains configuration such as m_SwitchJobRate). -
private SimulationSystem m_SimulationSystem
Reference to the SimulationSystem to access the current simulation frame index. -
private CountWorkplacesSystem m_CountWorkplacesSystem
Reference to the CountWorkplacesSystem that reports available/free workplaces by education level. -
private TypeHandle __TypeHandle
Internal struct holding Entity/Component/SharedComponent type handles and ComponentLookup instances used by the job; assigned during OnCreateForCompiler. Contains handles for Citizen, CurrentBuilding, Worker, UpdateFrame, and multiple ComponentLookup read-only lookups (HouseholdMember, PropertyRenter, TouristHousehold, HomelessHousehold, MovingAway, OutsideConnection, HasJobSeeker).
Properties
- None
This system does not expose public properties. All configuration is internal via fields, queries and constant values.
Constructors
public CitizenFindJobSystem()
Default constructor annotated with [Preserve] in compiled source. Standard initialization occurs in OnCreate rather than the constructor.
Methods
-
public override int GetUpdateInterval(SystemUpdatePhase phase)
Returns the interval (in frames) at which this system should be considered for updates. The value is computed as 262144 / (kUpdatesPerDay * 16). Controls how frequently the system's OnUpdate runs relative to the engine update phases. -
[Preserve] protected override void OnCreate()
Sets up EntityQueries (m_UnemployedQuery, m_EmployedQuery, m_CitizenParametersQuery), resolves references to EndFrameBarrier, SimulationSystem and CountWorkplacesSystem, and calls RequireForUpdate for the citizen parameters and unemployed query so the system only runs when relevant data exists. -
[Preserve] protected override void OnUpdate()
Main scheduling logic: - Computes the current update frame index (SimulationUtils.GetUpdateFrame).
- Prepares and schedules a burst-compiled CitizenFindJobJob for the unemployed query (m_IsUnemployedFindJob = true) using available unemployed workspace counts.
- Conditionally (based on random and m_SwitchJobRate) prepares and schedules a second job for employed citizens (m_IsUnemployedFindJob = false) using free workplaces.
- Both jobs receive an EntityCommandBuffer.ParallelWriter from m_EndFrameBarrier to create JobSeeker entities and to set HasJobSeeker components on citizens.
-
Adds the job handle to m_EndFrameBarrier via AddJobHandleForProducer to ensure ECB playback happens after jobs complete.
-
private void __AssignQueries(ref SystemState state)
Compiler helper used on startup (called from OnCreateForCompiler). The implementation in the decompiled source is effectively empty aside from creating/disposing a temporary EntityQueryBuilder. -
protected override void OnCreateForCompiler()
Compiler-generated helper invoked during system creation which assigns type handles by calling __TypeHandle.__AssignHandles and prepares internal state for job scheduling. -
private struct TypeHandle.__AssignHandles(ref SystemState state)
Assigns the EntityTypeHandle, ComponentTypeHandle and ComponentLookup instances from the given SystemState. Used by the job to access component data and lookups inside IJobChunk. -
private struct CitizenFindJobJob.Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
The IJobChunk implementation that runs per-chunk: - Filters chunks by shared UpdateFrame index so only citizens scheduled for this update frame are processed.
- For each citizen in the chunk:
- Skips children/elderly, citizens that are cooling down from last job seek, or households that are moving away.
- Determines education level and whether this is an unemployed search or employed switch scenario.
- Uses workplace availability arrays (m_AvailableWorkspacesByLevel) and probabilistic checks to decide whether the citizen will try to find a job at this time.
- Determines a source building (rented property, temporary home for homeless, or current building for commuters) to attach the JobSeeker to.
- If valid, creates a new entity, sets Owner, JobSeeker, and CurrentBuilding components, and updates the citizen's HasJobSeeker component (enables it and records the created seeker entity and last seek frame).
-
Uses RandomSeed per-chunk to add variability and per-citizen cool-down.
-
void IJobChunk.Execute(...)
Explicit interface implementation which calls the job's Execute method.
Usage Example
// The system is created and managed by the World; modders typically don't instantiate it directly.
// Example: reading the switch-job probability from within another system
protected override void OnUpdate()
{
if (!SystemAPI.HasComponent<CitizenParametersData>(someEntity))
return;
var paramsData = SystemAPI.GetSingleton<CitizenParametersData>();
float switchRate = paramsData.m_SwitchJobRate;
// Use switchRate in custom logic or to influence CountWorkplacesSystem results.
}
// The system already creates JobSeeker entities for citizens when appropriate.
// To react to new JobSeeker entities, create a system that queries for JobSeeker + Owner components
// (or listen for the HasJobSeeker component on citizens) and schedule logic accordingly.
Additional notes: - The internal job is Burst-compiled and uses parallel command buffers; make sure any custom code interacting with the created JobSeeker entities or HasJobSeeker components accounts for the producer job dependency (i.e., use system ordering or AddJobHandleForProducer when interacting with EndFrameBarrier). - The system respects per-citizen cool-downs to avoid frequent repeated job-seeking attempts.