Game.StudentSystem
Assembly: Assembly-CSharp
Namespace: Game.Simulation
Type: class
Base: GameSystemBase
Summary:
Manages student citizens' behavior related to schooling. The system schedules two burst-compiled jobs each update: one (GoToSchoolJob) that decides when students should start moving to school and enqueues TripNeeded entries / reserves cars, and another (StudyJob) that enforces study hours (removing TravelPurpose or Student components when schools are gone or when study time ends). It uses ECS queries and parallel jobs (IJobChunk) with EntityCommandBuffer for structural changes and integrates with EndFrameBarrier, CitizenBehaviorSystem, TimeSystem and SimulationSystem. The system runs at a reduced frequency (GetUpdateInterval returns 16), so it executes every 16 frames.
Fields
-
private EndFrameBarrier m_EndFrameBarrier
Used to create an EntityCommandBuffer. Jobs produce structural changes via a parallel writer created from this barrier; the barrier then receives job handles so changes are applied safely at the end of the frame. -
private TimeSystem m_TimeSystem
Reference to the TimeSystem used to obtain normalized time of day. -
private CitizenBehaviorSystem m_CitizenBehaviorSystem
Reference to the system that provides the car reservation queue and coordinates car reservation writers. -
private SimulationSystem m_SimulationSystem
Reference to get simulation-wide data such as the current frame index. -
private EntityQuery m_EconomyParameterQuery
Query to read EconomyParameterData singleton used for workday start/end and traffic parameters. -
private EntityQuery m_GotoSchoolQuery
Query selecting students that should be considered for going to school (students without TravelPurpose, not resource buyers, not health-problem flagged, etc.). Used by GoToSchoolJob. -
private EntityQuery m_StudentQuery
Query selecting students with TravelPurpose and CurrentBuilding etc. Used by StudyJob. -
private EntityQuery m_TimeDataQuery
Query to read TimeData singleton required for day calculation. -
private EntityQuery m_PopulationQuery
Query to read Population singleton (used when computing probability of going to school). -
private TypeHandle __TypeHandle
Container storing component/entity type handles lookups used by jobs. Assigned in OnCreateForCompiler / __AssignHandles.
Properties
- None (no public properties on this class)
Constructors
public StudentSystem()
Default constructor. The system relies on OnCreate to initialize queries and system references.
Methods
-
public override int GetUpdateInterval(SystemUpdatePhase phase)
Returns 16. The system is scheduled every 16 frames (reduced update frequency to avoid running every frame). -
public static float GetStudyOffset(Citizen citizen)
Computes a pseudo-random time offset for when the citizen's study/workday starts relative to the global economy parameters. Uses citizen pseudo-random data to spread start times. -
public static bool IsTimeToStudy(Citizen citizen, Game.Citizens.Student student, ref EconomyParameterData economyParameters, float timeOfDay, uint frame, TimeData timeData, int population)
Determines whether it is currently time for a given citizen to attend school. It: - Calculates a chance threshold that depends on population and traffic reduction parameter,
- Uses a day-specific pseudo-random decision to avoid everyone leaving at once,
-
Checks if the current normalized time of day falls into the student's computed study window (taking wrap-around into account). Returns true when the citizen should attempt to go study.
-
public static float2 GetTimeToStudy(Citizen citizen, Game.Citizens.Student student, ref EconomyParameterData economyParameters)
Returns a float2 (start, end) representing the normalized time window for this citizen's study period. It factors in: - A pseudo-random study offset per citizen,
- The student's last commute time (to shift start earlier for long commutes),
-
The economy-defined workday start / end.
-
[Preserve] protected override void OnCreate()
Initializes the system: obtains required systems (CitizenBehaviorSystem, EndFrameBarrier, TimeSystem, SimulationSystem), creates the EntityQueries used by the system (student queries, economy/time/population queries), and registers requirements for updating. Also assigns TypeHandle lookups in compiler-on-create flow. This sets up the data the parallel jobs will use. -
[Preserve] protected override void OnUpdate()
Main scheduling method: - Schedules GoToSchoolJob in parallel on m_GotoSchoolQuery. That job enqueues car reservations when students need to leave, adds TripNeeded buffers with Purpose.GoingToSchool, and removes Student/TravelPurpose components for invalid schools.
- Adds the produced job handle to m_EndFrameBarrier and registers the car-reserver writer with CitizenBehaviorSystem.
- Schedules StudyJob in parallel on m_StudentQuery. That job ensures students attending school keep their TravelPurpose only during allowed study hours and removes Student or TravelPurpose components when schools disappear or student arrives/ends study.
-
Adds the StudyJob handle to m_EndFrameBarrier and sets the system's dependency to the StudyJob handle. The scheduled jobs are Burst-compiled and operate with ComponentLookup/BufferAccessor patterns.
-
private void __AssignQueries(ref SystemState state)
Compiler helper used in OnCreateForCompiler; currently empty aside from creating and disposing a temporary EntityQueryBuilder (likely for deterministic handle assignment/ordering in compiled output). -
protected override void OnCreateForCompiler()
Compiler-time setup: calls __AssignQueries and assigns component/entity handles inside __TypeHandle.
Nested job types (important to understand behavior):
- GoToSchoolJob (BurstCompile, IJobChunk)
- Reads Citizen, Game.Citizens.Student, CurrentBuilding, etc.
- Writes TripNeeded buffer and uses ComponentLookup to inspect building/property/car keeper/etc.
-
For students that IsTimeToStudy returns true:
- If the target school exists and differs from current building, it attempts to reserve a car (via m_CarReserverQueue) if the citizen doesn't have car keeper enabled, and enqueues a TripNeeded with Purpose.GoingToSchool.
- If the school's property/building is invalid, removes TravelPurpose if it was Studying/GoingToSchool, adds StudentsRemoved to the school entity, and removes the Game.Citizens.Student component from the citizen.
-
StudyJob (BurstCompile, IJobChunk)
- Reads Student, TravelPurpose, Citizen, plus lookups for schools, targets, current buildings and attendings.
- If the referenced school no longer exists, removes TravelPurpose and Student components.
- If the citizen is not at the school's building and has no Target, and the current TravelPurpose is Studying, removes the TravelPurpose.
- If the current time is outside the student's computed study window (GetTimeToStudy) or the citizen is attending a meeting, removes TravelPurpose when it is Studying.
Notes for modders:
- The system uses EntityCommandBuffer.ParallelWriter when scheduling structural changes inside jobs; ensure any added jobs also use this pattern if modifying entities in parallel.
- The job uses ComponentLookup (ComponentLookup
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
// minimal example showing obtaining one of the required systems
m_CitizenBehaviorSystem = World.GetOrCreateSystemManaged<CitizenBehaviorSystem>();
m_EndFrameBarrier = World.GetOrCreateSystemManaged<EndFrameBarrier>();
m_TimeSystem = World.GetOrCreateSystemManaged<TimeSystem>();
// queries are initialized in base.OnCreate flow in this system
}