Game.Tutorials.TutorialHealthProblemActivationSystem
Assembly:
Assembly-CSharp (Game code / modding assembly)
Namespace:
Game.Tutorials
Type:
class
Base:
GameSystemBase
Summary:
TutorialHealthProblemActivationSystem monitors game health problems (sick, dead, etc.) and activates tutorial entries (adds a TutorialActivated component) when configured conditions are met. It detects whether the player currently has no hospitals or no cemeteries (but those buildings are unlocked in prefabs), and if so scans current HealthProblem components to see if any HealthProblemActivationData entities should be activated. The work of scanning is performed in a Burst-compiled IJobChunk (CheckProblemsJob) and uses an EntityCommandBuffer from a modification barrier to add TutorialActivated in a thread-safe way.
Fields
-
protected EntityCommandBufferSystem m_BarrierSystem
Used to obtain an EntityCommandBuffer (modification barrier) so the system can add the TutorialActivated component from jobs. -
private EntityQuery m_TutorialQuery
Query for tutorial activation entities: reads HealthProblemActivationData and excludes entities already activated or completed. Used as the iteration target for the CheckProblemsJob. -
private EntityQuery m_HealthProblemQuery
Query for current health problems in the world: reads Citizen and HealthProblem components and excludes temporary/deleted entities. Used to gather chunks of HealthProblem components to check against activation requirements. -
private EntityQuery m_MedicalClinicQuery
Query that checks for presence of built Hospital buildings (Game.Buildings.Hospital + Building). Used to determine whether there are hospitals in the scene. -
private EntityQuery m_MedicalClinicUnlockedQuery
Query that checks whether hospital prefabs are unlocked (PrefabData + HospitalData + BuildingData, excluding Locked). Used to know if hospitals are available to the player (built or unlocked). -
private EntityQuery m_CemeteryQuery
Query that checks for presence of built deathcare facilities (Game.Buildings.DeathcareFacility + Building). Used to determine whether there are cemeteries in the scene. -
private EntityQuery m_CemeteryUnlockedQuery
Query that checks whether deathcare facility prefabs are unlocked (PrefabData + DeathcareFacilityData + BuildingData, excluding Locked). -
private TypeHandle __TypeHandle
Internal holder for EntityTypeHandle and ComponentTypeHandles used by the job; populated via __AssignHandles for improved job scheduling and safety.
Properties
- This class does not expose public properties.
Constructors
public TutorialHealthProblemActivationSystem()
Default constructor. Marked with [Preserve] on lifecycle methods; construction follows normal ECS system creation. No special runtime parameters.
Methods
protected override void OnCreate()
: System.Void
Initializes the system: obtains the ModificationBarrier (m_BarrierSystem), sets up all required EntityQuery instances:- m_TutorialQuery = HealthProblemActivationData (read-only) & exclude TutorialActivated & exclude TutorialCompleted
- m_HealthProblemQuery = Citizen (read-only) & HealthProblem (read-only) & exclude Temp & exclude Deleted
- m_MedicalClinicQuery / m_MedicalClinicUnlockedQuery
-
m_CemeteryQuery / m_CemeteryUnlockedQuery
Also calls RequireForUpdate on m_HealthProblemQuery and m_TutorialQuery so the system runs only when relevant entities exist. -
protected override void OnUpdate()
: System.Void
Main runtime logic: - Evaluates whether there are zero built hospitals but hospitals are unlocked (m_MedicalClinicQuery.IsEmptyIgnoreFilter && !m_MedicalClinicUnlockedQuery.IsEmpty) → m_NoHospital flag.
- Evaluates similarly for cemeteries → m_NoCemetery flag.
- If either flag is true, schedules a Burst-compiled CheckProblemsJob (IJobChunk) over m_TutorialQuery. The job:
- Receives an asynchronously produced list of archetype chunks from m_HealthProblemQuery (m_HealthProblemChunks).
- Scans each HealthProblemActivationData entity in m_TutorialQuery; for each, counts matching HealthProblem entries across the pre-collected health-problem chunks until the required count is reached.
- Applies logic for HealthProblemFlags.Dead vs other flags: if activation requires Dead, it only activates when there is no cemetery; otherwise it requires no hospital.
- When activation criteria are satisfied, the job adds the TutorialActivated component to the tutorial entity via m_Writer (EntityCommandBuffer.ParallelWriter).
-
Disposes the chunk list after scheduling and adds the job dependency to the barrier system.
-
private void __AssignQueries(ref SystemState state)
: System.Void
Compiler helper used to initialize/validate queries for compiler-generated code paths. (Called from OnCreateForCompiler.) -
protected override void OnCreateForCompiler()
: System.Void
Compiler-time initialization helper that calls __AssignQueries and assigns handles via __TypeHandle.__AssignHandles. Present for IL2CPP/x64 AOT/compilation concerns.
Nested types (job / handles; Burst-compiled):
private struct CheckProblemsJob : IJobChunk
(BurstCompile)
Fields:- EntityTypeHandle m_EntityTypeHandle (read-only)
- ComponentTypeHandle
m_ActivationType (read-only) - ComponentTypeHandle
m_HealthProblemType (read-only) - NativeList
m_HealthProblemChunks - bool m_NoHospital
- bool m_NoCemetery
- EntityCommandBuffer.ParallelWriter m_Writer
Behavior:
- For each chunk of tutorial activation entities, reads their HealthProblemActivationData and entity IDs.
- For each activation entry it calls private Execute(HealthProblemActivationData):
- If the activation requires HealthProblemFlags.Dead, activation is only considered if m_NoCemetery is true; otherwise (non-dead flags) requires m_NoHospital to be true. If that condition fails, Execute returns false.
- Counts health problems across all m_HealthProblemChunks whose HealthProblem.m_Flags intersect the activation's require flags. If the count reaches or exceeds m_RequiredCount, Execute returns true.
- If Execute returns true for an entity, the job writes TutorialActivated component on that entity using m_Writer.AddComponent
private struct TypeHandle
Holds the typed handles required by jobs:- EntityTypeHandle __Unity_Entities_Entity_TypeHandle
- ComponentTypeHandle
__Game_Tutorials_HealthProblemActivationData_RO_ComponentTypeHandle - ComponentTypeHandle
__Game_Citizens_HealthProblem_RO_ComponentTypeHandle
Provides __AssignHandles(ref SystemState) to retrieve the handles from the state (called prior to scheduling jobs).
Notes: - The job uses BurstCompile and performs chunk-based scanning for performance. - The system uses ToArchetypeChunkListAsync to build a list of health-problem chunks; that list is disposed after job scheduling and its dispose is chained to the job dependency. - The system requires the presence of health-problem entities and tutorial activation data to run.
Usage Example
// Typical usage is internal to the ECS world: the system is created and updated by the world.
// Example: show how the system initializes queries in OnCreate (simplified)
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
m_BarrierSystem = World.GetOrCreateSystemManaged<ModificationBarrier4>();
m_TutorialQuery = GetEntityQuery(
ComponentType.ReadOnly<HealthProblemActivationData>(),
ComponentType.Exclude<TutorialActivated>(),
ComponentType.Exclude<TutorialCompleted>()
);
m_HealthProblemQuery = GetEntityQuery(
ComponentType.ReadOnly<Citizen>(),
ComponentType.ReadOnly<HealthProblem>(),
ComponentType.Exclude<Temp>(),
ComponentType.Exclude<Deleted>()
);
RequireForUpdate(m_HealthProblemQuery);
RequireForUpdate(m_TutorialQuery);
}
If you want, I can also extract and document the data types referenced here (HealthProblemActivationData, HealthProblem, HealthProblemFlags, TutorialActivated, etc.) or produce a sequence diagram showing the job scheduling and barrier interactions.