Game.Simulation.HealthProblemSystem
Assembly: Game (assembly containing simulation systems)
Namespace: Game.Simulation
Type: class
Base: GameSystemBase
Summary:
HealthProblemSystem is an ECS simulation system responsible for processing citizens' health-related states each update interval. It schedules a Burst-compiled IJobChunk (HealthProblemJob) that:
- Evaluates and updates HealthProblem components for citizens (sick, injured, dead, trapped, in danger, requiring transport, etc.).
- Requests or handles healthcare service requests (ambulance/hearse) and spawns HealthcareRequest entities when needed.
- Directs citizens to appropriate TripNeeded entries for Hospital, Deathcare or Safety purposes, or resets trips for in-transit creatures.
- Interacts with various game subsystems: EndFrameBarrier (for command buffers), IconCommandSystem (notification icons), TriggerSystem (game triggers), CityStatisticsSystem (statistics events), and Dispatch/vehicle data.
- Handles special cases such as being on fire, destroyed buildings, outside connections, and immediate transfers when an ambulance/hearse is present.
This system runs at a fixed simulation interval (16 frames) and uses component lookups and buffer accessors to perform parallel jobged processing.
Fields
-
private const uint SYSTEM_UPDATE_INTERVAL = 16u
System update interval (number of simulation frames between updates). HealthProblemSystem runs on this fixed interval. -
private EndFrameBarrier m_EndFrameBarrier
Barrier system used to create a parallel EntityCommandBuffer for scheduling structural changes at end of frame. -
private SimulationSystem m_SimulationSystem
Reference to the simulation system used to derive the current frame index. -
private IconCommandSystem m_IconCommandSystem
Used to add/remove in-world UI notification icons (ambulance/hearse icons etc). -
private EntityArchetype m_HealthcareRequestArchetype
Archetype used when creating new HealthcareRequest entities. -
private EntityArchetype m_JournalDataArchetype
Archetype used for creating journal/event data entities when casualties occur. -
private EntityArchetype m_ResetTripArchetype
Archetype for ResetTrip events (used to change creature targets/trips). -
private EntityArchetype m_HandleRequestArchetype
Archetype for HandleRequest events (used to mark service requests handled). -
private EntityQuery m_HealthProblemQuery
Query selecting citizens with HealthProblem component and required context for processing. -
private EntityQuery m_HealthcareSettingsQuery
Query to obtain healthcare parameter data singleton. -
private EntityQuery m_FireSettingsQuery
Query to obtain fire configuration data singleton. -
private TriggerSystem m_TriggerSystem
Reference to the TriggerSystem used to append trigger actions. -
private CityStatisticsSystem m_CityStatisticsSystem
Reference to statistics system used to report events. -
private TypeHandle __TypeHandle
Struct holding cached type handles / component lookups used when scheduling the job.
Properties
- No public properties.
All state is encapsulated via private fields; component data is accessed and cached in the TypeHandle for job scheduling.
Constructors
public HealthProblemSystem()
Default constructor. The main setup is performed in OnCreate; constructor does not perform expensive initialization.
Methods
-
public override int GetUpdateInterval(SystemUpdatePhase phase)
Returns the interval used by the system. This implementation returns 16 (the SYSTEM_UPDATE_INTERVAL) so the system executes every 16 simulation frames. -
[Preserve] protected override void OnCreate()
Initializes system references and entity archetypes: - Gets required systems (EndFrameBarrier, SimulationSystem, IconCommandSystem, TriggerSystem, CityStatisticsSystem).
- Builds EntityQueries for health problems and settings singletons.
- Creates archetypes for HealthcareRequest, Journal data, ResetTrip and HandleRequest events.
-
Calls RequireForUpdate to ensure system only runs when relevant queries exist.
-
[Preserve] protected override void OnUpdate()
Main scheduling method: - Computes an updateFrameIndex derived from the simulation frame.
- Fills a HealthProblemJob with component type handles, lookups, archetypes, parameters (healthcare/fire settings), command buffers and parallel queues.
- Schedules the job as a parallel JobChunk against m_HealthProblemQuery.
-
Registers writers with CityStatisticsSystem, TriggerSystem, IconCommandSystem and EndFrameBarrier so dependencies are tracked.
-
protected override void OnCreateForCompiler()
Internal helper used by the compiled code path to assign queries and type handles for the compiler-time generated code. -
private void __AssignQueries(ref SystemState state)
Compiler-utility method (generated pattern) to set up queries — no runtime logic beyond assigning.
Inner job and helper methods (part of HealthProblemJob struct — executed in parallel per chunk):
HealthProblemJob.Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
Core job loop that iterates citizens in the chunk to:- Filter by current UpdateFrame shared component.
- Evaluate HealthProblem flags and take action (remove HealthProblem if only NoHealthcare flag is set, handle trapped/in-danger/dead/injured/sick cases).
- Interact with OnFire, Destroyed, Hospital and DeathcareFacility components to decide moves (GoToSafety / GoToHospital / GoToDeathcare).
- Create/handle HealthcareRequest entities and add or remove notification icons after timers expire.
-
Add journal data when deaths occur and invoke appropriate trigger/statistics actions.
-
private void HandleRequest(int jobIndex, HealthProblem healthProblem)
If the HealthProblem references an existing HealthcareRequest, emits a HandleRequest event entity to mark the request as completed. -
private bool RequestVehicleIfNeeded(int jobIndex, Entity entity, CurrentBuilding currentBuilding, TravelPurpose travelPurpose, CurrentTransport currentTransport, DynamicBuffer<TripNeeded> tripNeededs, HealthProblem healthProblem)
Core logic that: - Checks if a HealthcareRequest already exists or has been dispatched (Dispatched component) and reacts if the assigned vehicle is at target (causing immediate GoToHospital/GoToDeathcare).
- If no current vehicle, decides whether to create a new HealthcareRequest entity (ambulance or hearse) based on the situation and prefab/building flags.
- Resets trips for creatures already moving toward other targets when appropriate.
-
Returns true if after the function there is still a need to request a vehicle or continue handling; false if no request needed (vehicle present or other blocking condition).
-
private void GoToHospital(int jobIndex, Entity entity, CurrentBuilding currentBuilding, TravelPurpose travelPurpose, CurrentTransport currentTransport, DynamicBuffer<TripNeeded> tripNeededs, Entity ambulance, bool immediate)
Adds or resets TripNeeded entries to send the citizen to hospital. If 'immediate' and citizen is at a building, clears other components (ResourceBuyer, TravelPurpose, AttendingMeeting) and clears trip buffer when appropriate. If citizen is already on a creature and ambulance is present, produces ResetTrip event to redirect the creature immediately. -
private void GoToDeathcare(int jobIndex, Entity entity, CurrentBuilding currentBuilding, TravelPurpose travelPurpose, CurrentTransport currentTransport, DynamicBuffer<TripNeeded> tripNeededs, Entity hearse)
Same pattern as GoToHospital but for deathcare target; clears trips and relevant components for immediate processing. -
private void GoToSafety(int jobIndex, Entity entity, CurrentBuilding currentBuilding, TravelPurpose travelPurpose, CurrentTransport currentTransport, DynamicBuffer<TripNeeded> tripNeededs)
If the citizen is inside a building, replaces its trip buffer with a Safety trip and clears travel-related components so the citizen stays/evacuates to safety. -
private void AddJournalData(int chunkIndex, HealthProblem problem)
Creates a journal/event data entity for casualty events (used for event tracking / statistics).
HealthProblemJob also includes explicit implementation for IJobChunk.Execute delegating to its typed Execute method.
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
// Typical initialization performed by the system:
m_EndFrameBarrier = base.World.GetOrCreateSystemManaged<EndFrameBarrier>();
m_SimulationSystem = base.World.GetOrCreateSystemManaged<SimulationSystem>();
m_IconCommandSystem = base.World.GetOrCreateSystemManaged<IconCommandSystem>();
// Set up queries and archetypes (done in the real implementation)
}
Notes and modding tips: - HealthProblemSystem uses ECS-style Jobs with many component lookups; altering its behavior safely requires either: - Hooking into TriggerSystem/Dispatch systems to change how vehicles are assigned, OR - Replacing or injecting a modified system with the same update semantics (careful with dependencies and barriers). - To change ambulance/hearse notification behavior, inspect IconCommandSystem usage and HealthcareParameterData singleton values. - The job uses UpdateFrame shared component filtering; only chunks with the matching UpdateFrame index are processed each run—use GetUpdateInterval to understand scheduling. - When testing mods that touch healthcare, watch for race conditions with EndFrameBarrier command buffers and ensure proper synchronization (AddWriter / AddActionBufferWriter patterns are used here).