Game.Simulation.PollutionTriggerSystem
Assembly: Game
Namespace: Game.Simulation
Type: class
Base: GameSystemBase
Summary:
PollutionTriggerSystem is a game simulation system that computes the average air pollution experienced by households and sends that value as a trigger action (TriggerType.AverageAirPollution) to the TriggerSystem. It uses the AirPollutionSystem to read pollution map data, iterates over household entities (PropertyRenter + Household), accumulates per-household pollution contributions in a parallel job (IJobChunk), reduces them into an average, then enqueues a TriggerAction via TriggerSystem. The system allocates a persistent NativeArray used for intermediate storage and coordinates job dependencies and reader/writer registrations with other systems.
Fields
-
private AirPollutionSystem m_AirPollutionSystem
m_AirPollutionSystem is a reference to the game's AirPollutionSystem retrieved in OnCreate. It's used to obtain the air pollution map (NativeArray) and to register the system as a reader for produced job dependencies. -
private TriggerSystem m_TriggerSystem
Reference to TriggerSystem used to create an action buffer (NativeQueue/ActionBuffer) to enqueue the resulting AverageAirPollution TriggerAction. -
private CitySystem m_CitySystem
Reference to CitySystem to access a City entity (m_City) used when reading city modifiers (city-level modifiers are read per-city). -
private EntityQuery m_HouseholdQuery
EntityQuery selecting the household entities to process. It is configured to include entities with PropertyRenter and Household components and UpdateFrame, and to exclude CommuterHousehold and MovingAway — i.e., active households that should be included in pollution averaging. -
private EntityQuery m_HappinessParameterQuery
Declared but not used directly in OnUpdate (note: there is a query built/assigned with a generated name __query_380796347_0 used to fetch CitizenHappinessParameterData). Holds query information related to happiness parameters used by CitizenHappinessSystem calculations. -
private NativeArray<float> m_AirPollutionResult
A persistent NativeArray(length 1) allocated in OnCreate and disposed in OnDestroy. In the current implementation the per-frame flow doesn't directly write into this array, but it exists for intermediate/persistent storage needs or legacy reasons. -
private TypeHandle __TypeHandle
Generated struct collecting ComponentTypeHandle, ComponentLookup and BufferLookup handles required by job(s). It's assigned in OnCreateForCompiler via __AssignHandles to cache access handles for job scheduling. -
private EntityQuery __query_380796347_0
Generated EntityQuery (constructed in __AssignQueries) used to fetch the singleton CitizenHappinessParameterData in OnUpdate. -
(Nested)
CalculateAverageAirPollutionJob
(private struct, BurstCompile)
IJobChunk that: - Reads PropertyRenter components from household chunks.
- Uses ComponentLookup
, BufferLookup , and a NativeArray map to compute per-household air pollution contribution through CitizenHappinessSystem.GetAirPollutionBonuses. -
Accumulates a running AverageFloat into a NativeAccumulator
.ParallelWriter to compute sum and count across chunks in parallel. -
(Nested)
SendPollutionTriggerJob
(private struct, BurstCompile)
IJob that reads the NativeAccumulator, computes the final average, and enqueues a TriggerAction(TriggerType.AverageAirPollution, Entity.Null, average) into the TriggerSystem's action buffer. -
(Nested)
TypeHandle
(private struct)
Generated helper struct that stores the component/buffer/lookup handles and provides __AssignHandles(ref SystemState) to populate them using state.GetComponentTypeHandle / GetComponentLookup / GetBufferLookup.
Properties
- None (no public properties are declared on this system)
Constructors
public PollutionTriggerSystem()
Default constructor. Marked with [Preserve] in OnCreate/OnDestroy/OnUpdate methods, but the constructor itself is the standard system ctor — the system is created by the world / runtime. No special initialization occurs here; resource initialization is performed in OnCreate.
Methods
-
public override int GetUpdateInterval(SystemUpdatePhase phase)
Returns 4096. This indicates the system's update interval used by the framework — it's a scheduling constant (not a frame count) that affects how the system is selected/ordered by the engine update sequencing. -
protected override void OnCreate()
Initializes the system: - Retrieves references to AirPollutionSystem, TriggerSystem, and CitySystem via World.GetOrCreateSystemManaged.
- Builds the household entity query to target PropertyRenter + Household + UpdateFrame, excluding CommuterHousehold and MovingAway.
- Allocates m_AirPollutionResult as a persistent NativeArray
(1). -
Note: __AssignQueries and __TypeHandle.__AssignHandles are invoked in OnCreateForCompiler (generated call path).
-
protected override void OnDestroy()
Disposes the persistent m_AirPollutionResult NativeArray and calls base.OnDestroy. Ensure any persistent native resources added later are also disposed here. -
protected override void OnUpdate()
Main scheduling and execution flow per update: - Creates a NativeAccumulator
(Allocator.TempJob) to accumulate totals and counts in parallel. - Prepares and schedules CalculateAverageAirPollutionJob (IJobChunk) as a parallel chunk job:
- Fills in component handles (PropertyRenter, Transform lookup, CityModifier buffer lookup) via the generated TypeHandle and InternalCompilerInterface.
- Requests an air pollution map from m_AirPollutionSystem.GetMap(readOnly: true, out dependencies) which returns a NativeArray
and a JobHandle dependency; these dependencies are combined with the system base.Dependency. - m_Result is passed as a ParallelWriter for the accumulator.
- Registers the dependency with m_AirPollutionSystem via AddReader so the AirPollutionSystem is aware of the read.
- Schedules SendPollutionTriggerJob (IJob) to run after the chunk job; that job reads the accumulator, computes the average, and enqueues a TriggerAction into a TriggerSystem action buffer obtained via CreateActionBuffer().
- Disposes the accumulator with result.Dispose(base.Dependency) so the TempJob is freed after the dependent jobs complete.
- Calls m_TriggerSystem.AddActionBufferWriter(base.Dependency) to register the writer dependency.
-
The overall pattern ensures correct cross-system dependency handling for the native arrays / job scheduling.
-
private void __AssignQueries(ref SystemState state)
Generated helper that builds & assigns __query_380796347_0 to query for CitizenHappinessParameterData (with IncludeSystems option). Called from OnCreateForCompiler to initialize EntityQuery(s) the system needs. -
protected override void OnCreateForCompiler()
Generated method called during system creation that sets up generated queries and assigns component/buffer/lookup handles by calling __AssignQueries and __TypeHandle.__AssignHandles. -
(Nested) CalculateAverageAirPollutionJob.Execute(...)
For each chunk it: - Fetches the city modifiers from the city entity's CityModifier buffer.
- Iterates through PropertyRenter components in the chunk and calls CitizenHappinessSystem.GetAirPollutionBonuses to get an int2 representing pollution bonuses (or penalties).
-
Accumulates each household's pollution total into the NativeAccumulator
.ParallelWriter by writing AverageFloat { m_Total = sum, m_Count = 1 }. -
(Nested) SendPollutionTriggerJob.Execute()
Reads the aggregator result via m_Result.GetResult().average and enqueues a new TriggerAction(TriggerType.AverageAirPollution, Entity.Null, average) to the trigger queue.
Usage Example
// Typical pattern implemented by the system: scheduling the chunk job and sending a trigger.
// If you create a custom system that needs similar functionality, mirror this pattern:
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
// Acquire referenced systems
m_AirPollutionSystem = World.GetOrCreateSystemManaged<AirPollutionSystem>();
m_TriggerSystem = World.GetOrCreateSystemManaged<TriggerSystem>();
m_CitySystem = World.GetOrCreateSystemManaged<CitySystem>();
// Build your queries, allocate persistent native resources if needed
m_HouseholdQuery = GetEntityQuery(
ComponentType.ReadOnly<PropertyRenter>(),
ComponentType.ReadOnly<Household>(),
ComponentType.ReadOnly<UpdateFrame>(),
ComponentType.Exclude<CommuterHousehold>(),
ComponentType.Exclude<MovingAway>()
);
m_AirPollutionResult = new NativeArray<float>(1, Allocator.Persistent);
}
protected override void OnUpdate()
{
var accumulator = new NativeAccumulator<AverageFloat>(Allocator.TempJob);
// Prepare chunk job (pseudo-assignment shown, real code uses InternalCompilerInterface in generated systems)
var chunkJob = new CalculateAverageAirPollutionJob
{
m_PropertyRenterType = /* component type handle */,
m_Transforms = /* component lookup */,
m_CityModifiers = /* buffer lookup */,
m_AirPollutionMap = m_AirPollutionSystem.GetMap(readOnly: true, out var mapDeps),
m_HappinessParameters = /* fetch singleton params */,
m_City = m_CitySystem.City,
m_Result = accumulator.AsParallelWriter()
};
// Schedule chunk job for households and chain a send job that enqueues to the trigger system
Dependency = JobChunkExtensions.ScheduleParallel(chunkJob, m_HouseholdQuery, JobHandle.CombineDependencies(Dependency, mapDeps));
m_AirPollutionSystem.AddReader(Dependency);
var sendJob = new SendPollutionTriggerJob
{
m_Result = accumulator,
m_TriggerQueue = m_TriggerSystem.CreateActionBuffer()
};
Dependency = IJobExtensions.Schedule(sendJob, Dependency);
accumulator.Dispose(Dependency);
m_TriggerSystem.AddActionBufferWriter(Dependency);
}
Notes / Modding tips: - The system uses Burst-compiled jobs and Native containers; maintain correct allocation lifetimes (TempJob vs Persistent) and dispose patterns to avoid leaks. - When reading the AirPollution map, the system receives a JobHandle dependency — always combine it with your system dependency to ensure correct ordering. - To react to the AverageAirPollution trigger, subscribe to TriggerSystem or provide a handler that processes TriggerAction entries of type TriggerType.AverageAirPollution. - The household query excludes CommuterHousehold and MovingAway so the average is computed only for resident households that are active; adjust query filters if you need a different population subset.