Skip to content

Game.Simulation.SicknessCheckSystem

Assembly: Assembly-CSharp
Namespace: Game.Simulation

Type: class

Base: GameSystemBase

Summary:
SicknessCheckSystem periodically evaluates citizens for health-related events (disease, injury, death) and either spawns tracking event entities (prefabs) or enqueues an AddHealthProblem command to the world. The system: - Runs at a configurable interval (kUpdatesPerDay = 1 relative to internal update scaling). - Iterates citizens that do not already have HealthProblem and that match the UpdateFrame. - Uses a burst-compiled SicknessCheckJob that executes in parallel, queries health event prefabs, evaluates probabilistic occurrence and transport/no-healthcare conditions, applies city modifiers and fees, and writes results through an EndFrameBarrier EntityCommandBuffer (parallel writer). - Uses city-level data such as service fees, tax rates, economy parameters and city modifiers to influence the outcome.


Fields

  • public readonly int kUpdatesPerDay
    Constant controlling how many sickness-check updates are considered "per day" for the update-frame calculation. In this implementation it is 1 (used together with SimulationUtils.GetUpdateFrame).

  • private EndFrameBarrier m_EndFrameBarrier
    Barrier system used to obtain an EntityCommandBuffer. The job creates entities / records results via a parallel command buffer produced by this barrier.

  • private SimulationSystem m_SimulationSystem
    Reference to the SimulationSystem used to obtain the global frame index (frameIndex) when computing which update frame this system should run on.

  • private CitySystem m_CitySystem
    Reference to the CitySystem to access the city entity and city-level buffers (e.g., service fees, modifiers).

  • private TaxSystem m_TaxSystem
    Reference to the TaxSystem (used to fetch current tax rates that feed into household income/economy decisions).

  • private EntityArchetype m_AddProblemArchetype
    Archetype used to create AddHealthProblem entities (non-tracking health problem command).

  • private EntityQuery m_CitizenQuery
    Query selecting citizens to check: ReadOnly, ReadOnly, excludes HealthProblem, Deleted, Temp. Required for update.

  • private EntityQuery m_EventQuery
    Query selecting health event prefabs: contains HealthEventData and excludes Locked (prefabs that are available to instantiate).

  • private EntityQuery m_EconomyParameterQuery
    Query to fetch singleton EconomyParameterData used for economy-related probability calculations.

  • private TypeHandle __TypeHandle
    Generated container holding component & lookup handles used when scheduling the job (component type handles, lookup handles and shared component handles). Used to request Unity ECS typed accessors.

  • Nested (private) types:

  • SicknessCheckJob (Burst compiled IJobChunk) — the worker that evaluates citizens, reads event prefabs, applies probabilities and enqueues commands.
  • TypeHandle (struct) — helper that assigns component/lookup handles from SystemState.

Properties

  • None (this system exposes no public properties).

Constructors

  • public SicknessCheckSystem()
    Default constructor (marked Preserve in source). Initializes the system instance; runtime initialization is handled in OnCreate.

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns an interval used by the update scheduling system. Implementation computes a raw interval value: 262144 / (kUpdatesPerDay * 16). This is used by the simulation to determine how frequently the system should be run relative to the global update phases.

  • [Preserve] protected override void OnCreate()
    Initializes references to other systems (EndFrameBarrier, SimulationSystem, CitySystem, TaxSystem), sets up EntityQueries:

  • m_CitizenQuery: citizens that should be checked,
  • m_EventQuery: event prefabs with HealthEventData (excludes locked),
  • m_EconomyParameterQuery: singleton economy parameters. Also creates the m_AddProblemArchetype and registers required queries via RequireForUpdate.

  • [Preserve] protected override void OnUpdate()
    Main scheduling method. It:

  • Computes the update frame index using SimulationUtils.GetUpdateFrame with kUpdatesPerDay.
  • Builds a SicknessCheckJob instance:
    • collects m_EventPrefabChunks (archetype chunks of event prefabs) asynchronously,
    • provides component type & buffer lookups via InternalCompilerInterface and __TypeHandle,
    • provides economy/effect data: EconomyParameterData, tax rates, city entity, RandomSeed, etc.,
    • creates an EntityCommandBuffer.ParallelWriter from EndFrameBarrier for producing output.
  • Schedules the job in parallel over m_CitizenQuery (JobChunkExtensions.ScheduleParallel).
  • Disposes the temporary event chunk list after the job completes.
  • Adds the job handle to the EndFrameBarrier and adds a reader to the TaxSystem so dependencies are tracked.
  • Updates base.Dependency to the scheduled job handle.

  • private void __AssignQueries(ref SystemState state)
    Generated helper that (in this version) creates and disposes a temporary EntityQueryBuilder. Included to satisfy compiler-generated plumbing; actual queries are created in OnCreate.

  • protected override void OnCreateForCompiler()
    Compiler helper that assigns handles and queries at compile-time; calls __AssignQueries and __TypeHandle.__AssignHandles.

  • TypeHandle.__AssignHandles(ref SystemState state)
    Assigns all ComponentTypeHandle, EntityTypeHandle, SharedComponentTypeHandle and Component/Buffer lookup handles used by SicknessCheckJob. This is generated code used to prepare the handles before scheduling.

  • SicknessCheckJob.Execute(...)
    Burst compiled chunk job logic:

  • Skips chunks whose UpdateFrame shared component index does not match the computed m_UpdateFrameIndex.
  • For each citizen in the chunk, calls TryAddHealthProblem which:
    • Computes a base probability scalar from citizen.m_Health (lower health => higher probability).
    • Iterates all HealthEventData prefabs (m_EventPrefabChunks) and for each eligible event (target type Citizen, prefab not locked):
    • Interpolates the event's occurrence probability (min/max) using the health-derived t scalar.
    • Applies city modifiers (CityModifierType.DiseaseProbability) for disease events.
    • Rolls random against the computed chance; on success either:
      • Creates a tracking prefab event (if m_RequireTracking) using the event prefab archetype and adds a TargetElement buffer entry, or
      • Computes flags for a non-tracking AddHealthProblem:
      • Sets Sick/Injured/Dead based on HealthEventType,
      • Rolls for RequireTransport using transport probability adjusted by citizen health,
      • Fetches healthcare fee and household income to calculate NoHealthcare chance,
      • Enqueues an AddHealthProblem entity (using the m_AddProblemArchetype) via the parallel command buffer.
    • Stops after first matching event created for the citizen.

Notes on internal calculations: - t = saturate(pow(2, 10 - (int)health * 0.1) * 0.001) — maps health (integer) to a 0..1 scalar used for lerp of occurrence probability. - transport probability interpolates between max/min using health percentage. - household income is retrieved (if household buffer exists) using EconomyUtils.GetHouseholdIncome which uses workers, citizen data, health problems, and economy parameters + tax rates. - Randomness is seeded per job by RandomSeed.Next() and then per-chunk using m_RandomSeed.GetRandom(unfilteredChunkIndex).

Concurrency & safety: - Uses Burst and ScheduleParallel for performance. - Performs read-only accesses for component lookups and buffer lookups where possible. - Writes are performed through EndFrameBarrier.CreateCommandBuffer().AsParallelWriter() to safely enqueue entity creation and component/buffer writes from worker threads.

Usage Example

// The system itself schedules a burst-parallel job in OnUpdate.
// Example snippet showing the update-frame calculation used by the system:

[Preserve]
protected override void OnUpdate()
{
    // compute which sub-frame this system should run on
    uint updateFrame = SimulationUtils.GetUpdateFrame(m_SimulationSystem.frameIndex, kUpdatesPerDay, 16);

    // SicknessCheckJob is then constructed with required handles, city/economy data and scheduled
    // in parallel over m_CitizenQuery. The job uses EndFrameBarrier's parallel command buffer to
    // create event entities or AddHealthProblem command entities for citizens.
}

{{ Additional notes: - To modify behavior for modding: consider adding or changing HealthEventData prefabs (m_EventQuery), or intercepting/observing AddHealthProblem events created by this system. - If you add new CityModifier types or change ServiceFeeSystem behavior, this system will pick up changes because it reads buffers and fees at runtime. - Be careful when replacing or patching this system; it relies on the exact archetype for AddHealthProblem and the EndFrameBarrier command buffer for thread-safe writes. }}