Skip to content

Game.Simulation.ApplyToSchoolSystem

Assembly: Assembly-CSharp (Game)
Namespace: Game.Simulation

Type: class

Base: GameSystemBase

Summary:
ApplyToSchoolSystem evaluates citizens each simulation update to determine if they should attempt to enroll at a school (creating SchoolSeeker entities) or increment a failed-education counter and add a cooldown. The system runs a Burst-compiled IJobChunk (ApplyToSchoolJob) that iterates citizen chunks, inspects ages, education levels, household and city state, and uses randomized probability based on wellbeing, willingness and city modifiers. It schedules its work in parallel and writes structural changes via an EndFrameBarrier command buffer. The system also exposes a static helper GetEnteringProbability for calculating the chance a citizen attempts the next education level.


Fields

  • public static readonly int kCoolDown
    Description: Cooldown value (20000) used to avoid repeatedly trying to apply a citizen to school shortly after a failure.

  • public const uint UPDATE_INTERVAL
    Description: Constant (8192) used when determining the update frame interval.

  • public bool debugFastApplySchool
    Description: Public flag to bypass some checks and allow faster testing of school application logic. Useful for debugging.

  • private EntityQuery m_CitizenGroup
    Description: EntityQuery that selects citizens the system should operate on (citizens without HealthProblem, HasJobSeeker, HasSchoolSeeker, Student or Deleted components, and having UpdateFrame).

  • private SimulationSystem m_SimulationSystem
    Description: Cached reference to the SimulationSystem for obtaining the current simulation frame index.

  • private EndFrameBarrier m_EndFrameBarrier
    Description: Cached reference used to create an EntityCommandBuffer.ParallelWriter for structural changes produced by the job.

  • private CitySystem m_CitySystem
    Description: Cached reference to the CitySystem to get the city entity.

  • private TypeHandle __TypeHandle
    Description: Internal struct holding component / shared component / buffer handles used by the job; assigned in OnCreateForCompiler.

  • private EntityQuery __query_2069025490_0
    Description: Internal queries for singleton components — holds EconomyParameterData.

  • private EntityQuery __query_2069025490_1
    Description: Internal query for EducationParameterData.

  • private EntityQuery __query_2069025490_2
    Description: Internal query for TimeData.

Properties

  • (none)
    This system does not expose public properties. It reads various singleton parameter components via internal queries and uses them in the scheduled job.

Constructors

  • public ApplyToSchoolSystem()
    Constructs the system instance. Most initialization is performed in OnCreate and OnCreateForCompiler (component/type handle assignment and query building).

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns the update interval (512) used by the system scheduler. Useful to control how often the system is considered for execution.

  • [Preserve] protected override void OnCreate()
    Sets up references to required systems (SimulationSystem, EndFrameBarrier, CitySystem), builds the m_CitizenGroup query, and calls RequireForUpdate for required singletons (EconomyParameterData, TimeData) and the citizen query. Also configures which citizen archetypes are eligible.

  • [Preserve] protected override void OnUpdate()
    Creates and populates an ApplyToSchoolJob with component/type handles, random seed, parameter singletons (EconomyParameterData, EducationParameterData, TimeData), the city entity, current frame info, debug flags and the command buffer writer. Schedules the job in parallel over m_CitizenGroup and passes the job handle to the EndFrameBarrier.

  • public static float GetEnteringProbability(CitizenAge age, bool worker, int level, int wellbeing, float willingness, DynamicBuffer<CityModifier> cityModifiers, ref EducationParameterData educationParameterData)
    Calculates the probability a citizen will attempt to enter the specified education level:

  • Level 1 (Elementary): only applies to children, returns 1 for children, 0 otherwise.
  • Level 2 (HighSchool): uses adult/worker probabilities vs teen probability.
  • Level 3 (College) and 4 (University): uses wellbeing, willingness and worker modifiers. University interest modifiers from cityModifiers are applied for level 4.
  • Returns 0 for invalid combinations (e.g., elderly, children for higher levels).

  • [MethodImpl(MethodImplOptions.AggressiveInlining)] private void __AssignQueries(ref SystemState state)
    Internal method that builds EntityQuery instances for singleton parameter components (EconomyParameterData, EducationParameterData, TimeData). Called during compiler-specific initialization path.

  • protected override void OnCreateForCompiler()
    Called by the generated/compiled code path to assign queries and type handles used by the job before runtime.

  • ApplyToSchoolJob (nested struct) : IJobChunk
    Burst-compiled job that performs the per-chunk logic:

  • Fields: various ComponentTypeHandle, ComponentLookup, BufferLookup, RandomSeed, simulation/city/parameter data, command buffer writer and flags.
  • Execute: for each citizen in chunk:
    • Skips if update frame doesn't match (unless debug fast mode).
    • Skips elderly and citizens with recent SchoolSeekerCooldown.
    • Derives target SchoolLevel based on age and current education level.
    • Checks if citizen/household is eligible (moved in, not tourist, not moving away).
    • Computes "enteringProbability" via GetEnteringProbability with citizen wellbeing and pseudo-random willingness.
    • If random check passes and household has a rented property, creates a SchoolSeeker entity and links it to the citizen via HasSchoolSeeker and Owner components, and assigns CurrentBuilding to the household property.
    • If attempt fails for higher levels, increments failed education count up to a limit and adds SchoolSeekerCooldown to the citizen.

Notes: - The job uses a parallel ECB writer (EndFrameBarrier.CreateCommandBuffer().AsParallelWriter()) to create and add components safely. - Random is seeded per chunk using RandomSeed.Next().

Usage Example

// Example: compute entering probability for a single citizen in a mod/tool
DynamicBuffer<CityModifier> cityModifiers = ...; // obtained from city entity
EducationParameterData eduParams = ...; // singleton obtained from ECS
float willingness = 0.4f;
int wellbeing = 45;
float prob = ApplyToSchoolSystem.GetEnteringProbability(
    age: CitizenAge.Teen,
    worker: false,
    level: (int)SchoolLevel.College,
    wellbeing: wellbeing,
    willingness: willingness,
    cityModifiers: cityModifiers,
    educationParameterData: ref eduParams
);

// Example: enable fast debug mode (in your system setup or via reflection)
var applySys = World.DefaultGameObjectInjectionWorld.GetExistingSystemManaged<ApplyToSchoolSystem>();
if (applySys != null)
{
    // Note: debugFastApplySchool is a public field; toggling it will bypass update-frame gating in the job.
    // Use responsibly—intended for debugging only.
    // applySys.debugFastApplySchool = true;
}

Additional modding tips: - If you want to influence school-entering behavior, consider modifying EducationParameterData singleton values or adding CityModifier entries of type UniversityInterest. - To observe SchoolSeeker entity creation at runtime, listen for entities with the SchoolSeeker component or intercept EndFrameBarrier writes in a custom system.