Game.Simulation.WorkerSystem
Assembly: Assembly-CSharp
Namespace: Game.Simulation
Type: class
Base: GameSystemBase
Summary:
WorkerSystem is an ECS system that manages citizens who are workers: deciding when they should start commuting, enqueueing trips to workplaces, handling when they arrive and should start/stop working, and handling cases where workplaces no longer exist (making citizens unemployed). It uses Burst-compiled chunk jobs (GoToWorkJob and WorkJob) scheduled in parallel and integrates with TimeSystem, CitizenBehaviorSystem (for car reservation), TriggerSystem (to emit events like CitizenBecameUnemployed), SimulationSystem (frame index), and an EndFrameBarrier (for command buffer playback). It also exposes several static helper functions for calculating work times and offsets used by the jobs.
Fields
-
private EndFrameBarrier m_EndFrameBarrier
Holds a reference to the EndFrameBarrier system used to create an EntityCommandBuffer. Commands from the parallel jobs are enqueued into this barrier's command buffer to be applied at the end of the frame. -
private TimeSystem m_TimeSystem
Reference to the TimeSystem used to read normalized time and compute day/time data. -
private CitizenBehaviorSystem m_CitizenBehaviorSystem
Reference used to obtain the car reservation queue and to register car-reserve job writers. -
private EntityQuery m_EconomyParameterQuery
Query used to get EconomyParameterData singleton required by the jobs. -
private EntityQuery m_GotoWorkQuery
EntityQuery matching citizens that should be considered for creating trip-needed entries (citizens that are workers but currently have no TravelPurpose). -
private EntityQuery m_WorkerQuery
EntityQuery matching worker citizens that may currently have TravelPurpose and need to be validated each update. -
private EntityQuery m_TimeDataQuery
Query used to get TimeData singleton. -
private EntityQuery m_PopulationQuery
Query used to get Population singleton/entity for population-based calculations. -
private SimulationSystem m_SimulationSystem
Reference to SimulationSystem for obtaining the current frame index. -
private TriggerSystem m_TriggerSystem
Reference used to create trigger action buffers to emit events (e.g., CitizenBecameUnemployed). -
private TypeHandle __TypeHandle
Internal structure that holds Entity/Component/Buffer/SharedComponent type handles and ComponentLookup instances used when scheduling jobs.
Properties
- (none publicly exposed)
WorkerSystem does not define public properties; it works through injected systems, queries and the jobs it schedules.
Constructors
public WorkerSystem()
Default constructor. System initialization is done in OnCreate; constructor itself is empty.
Methods
-
public override int GetUpdateInterval(SystemUpdatePhase phase)
Returns the system's update interval (returns 16). This interval is used by SimulationUtils.GetUpdateFrameWithInterval to throttle how often worker logic runs relative to simulation frames. -
public static float GetWorkOffset(Citizen citizen)
Returns a small pseudo-random offset for when a citizen's workday should be considered to start relative to the city's defined work day, based on the citizen's pseudo-random state. -
public static bool IsTodayOffDay(Citizen citizen, ref EconomyParameterData economyParameters, uint frame, TimeData timeData, int population)
Determines whether the given citizen should have the day off (not go to work) on the specified frame. The chance of a day off depends on economy parameters and population. -
public static bool IsTimeToWork(Citizen citizen, Worker worker, ref EconomyParameterData economyParameters, float timeOfDay)
Returns true if the current normalized timeOfDay falls within the worker's working window (taking shift and commute time into account). Uses GetTimeToWork internally. -
public static float2 GetTimeToWork(Citizen citizen, Worker worker, ref EconomyParameterData economyParameters, bool includeCommute)
Computes the normalized start/end times (float2.x = start, float2.y = end) when the citizen should be considered going to/at work. This takes into account workshift, random offset, workday configuration, and optionally the last commute time (to widen the window when commute time is long). -
[Preserve] protected override void OnCreate()
Sets up references to dependent systems, creates required EntityQueries and registers queries required for update. Specifically: - Obtains references to CitizenBehaviorSystem, EndFrameBarrier, TimeSystem, SimulationSystem, TriggerSystem.
- Builds queries: m_WorkerQuery, m_GotoWorkQuery, m_EconomyParameterQuery, m_TimeDataQuery, m_PopulationQuery.
-
Calls RequireAnyForUpdate / RequireForUpdate to control when the system updates.
-
[Preserve] protected override void OnUpdate()
Main scheduling method. It: - Computes an updateFrameIndex with the configured update interval (16).
- Schedules GoToWorkJob in parallel on m_GotoWorkQuery. GoToWorkJob:
- Filters chunks by UpdateFrame shared component.
- For each citizen in the chunk decides whether the citizen should add a TripNeeded to go to work (checks off day, time to work, whether already at current building, etc.).
- Enqueues car reservation requests for citizens that need a car (via CitizenBehaviorSystem's car reserve queue).
- If the target workplace no longer exists (property/building/outside connection missing), clears Worker and TravelPurpose components, resets failed education, and enqueues a CitizenBecameUnemployed trigger.
- Registers job handles with EndFrameBarrier/CitizenBehaviorSystem/TriggerSystem as needed.
- Schedules WorkJob in parallel on m_WorkerQuery. WorkJob:
- Validates that the workplace still exists and handles citizens who have lost their workplace (similar to GoToWorkJob).
- If citizen is currently TravelPurpose.Working but no longer in a work time or is attending a meeting, the WorkJob removes TravelPurpose.
-
Combines dependencies and sets base.Dependency so other systems see the job dependencies.
-
private void __AssignQueries(ref SystemState state)
Internal helper used by OnCreateForCompiler—present in generated/compiled form; here effectively a placeholder. -
protected override void OnCreateForCompiler()
Internal override used by the code-generation/compilation layer to assign type handles and queries for the system before runtime. -
Nested types:
GoToWorkJob : IJobChunk
(BurstCompile)
Chunk job that finds worker citizens who should begin traveling to work. It reads/writes the following:- Reads: Entity, Worker, CurrentBuilding, various ComponentLookup collections (Workplaces, Properties, Buildings, OutsideConnection, AttendingMeeting, Population).
- Reads/writes: Citizen (RW), TripNeeded buffer (RW). It enqueues TriggerAction events for unemployment and submits car-reservation requests into a NativeQueue obtained from CitizenBehaviorSystem.
WorkJob : IJobChunk
(BurstCompile)
Chunk job that validates current worker states for citizens that already have TravelPurpose and/or Worker components. It removes TravelPurpose/Worker when the workplace is gone and removes Working TravelPurpose when it's no longer appropriate (time finished or attending a meeting).TypeHandle
Internal struct that caches EntityTypeHandle, ComponentTypeHandles, BufferTypeHandles, SharedComponentTypeHandle and ComponentLookup instances used to avoid repeated handle acquisition per job scheduling.
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
// Typical WorkerSystem initialization (taken from game's implementation):
m_CitizenBehaviorSystem = base.World.GetOrCreateSystemManaged<CitizenBehaviorSystem>();
m_EndFrameBarrier = base.World.GetOrCreateSystemManaged<EndFrameBarrier>();
m_TimeSystem = base.World.GetOrCreateSystemManaged<TimeSystem>();
m_SimulationSystem = base.World.GetOrCreateSystemManaged<SimulationSystem>();
m_TriggerSystem = base.World.GetOrCreateSystemManaged<TriggerSystem>();
m_WorkerQuery = GetEntityQuery(
ComponentType.ReadOnly<Worker>(),
ComponentType.ReadOnly<Citizen>(),
ComponentType.ReadOnly<TravelPurpose>(),
ComponentType.ReadOnly<CurrentBuilding>(),
ComponentType.Exclude<Deleted>(),
ComponentType.Exclude<Temp>());
m_GotoWorkQuery = GetEntityQuery(
ComponentType.ReadOnly<Worker>(),
ComponentType.ReadOnly<Citizen>(),
ComponentType.ReadOnly<CurrentBuilding>(),
ComponentType.Exclude<TravelPurpose>(),
ComponentType.Exclude<HealthProblem>(),
ComponentType.Exclude<ResourceBuyer>(),
ComponentType.ReadWrite<TripNeeded>(),
ComponentType.Exclude<Deleted>(),
ComponentType.Exclude<Temp>());
m_EconomyParameterQuery = GetEntityQuery(ComponentType.ReadOnly<EconomyParameterData>());
m_TimeDataQuery = GetEntityQuery(ComponentType.ReadOnly<TimeData>());
m_PopulationQuery = GetEntityQuery(ComponentType.ReadOnly<Population>());
RequireAnyForUpdate(m_GotoWorkQuery, m_WorkerQuery);
RequireForUpdate(m_EconomyParameterQuery);
}
Additional tip for modders: - Use the static helpers (GetWorkOffset, GetTimeToWork, IsTimeToWork, IsTodayOffDay) if you need to compute or simulate worker schedules or when adjusting economy parameters, shifts, or custom workplace behaviour. - When adding or removing components that interact with WorkerSystem (Worker, TravelPurpose, TripNeeded), ensure you respect the system's update interval (it runs every 16 simulation frames) and use the appropriate command buffers / barriers for thread-safety if doing work from jobs.