Game.Simulation.CrimeEffectSystem
Assembly:
Game
Namespace:
Game.Simulation
Type:
class
Base:
GameSystemBase
Summary:
This system processes CrimeVictim components for citizens on a per-update-frame basis. It runs a Burst-compiled IJobChunk (CrimeEffectJob) that iterates over an EntityQuery of citizens that have CrimeVictim and UpdateFrame components (and excludes Deleted and Temp). For entities whose shared UpdateFrame matches the computed update frame, the job decrements the CrimeVictim.m_Effect counter each tick; if the counter is <= 1 it sets m_Effect to 0 and disables the CrimeVictim component for that entity using an EntityCommandBuffer. The system is scheduled to run periodically according to GetUpdateInterval and registers the scheduled job with an EndFrameBarrier so structural changes are applied safely at the end of the frame. The system uses SimulationSystem.frameIndex together with SimulationUtils.GetUpdateFrame to determine which subset of entities to process each tick.
Fields
-
public static readonly int kUpdatesPerDay = 4
This constant controls how many times per simulated day the system cycles its updates (used by SimulationUtils.GetUpdateFrame). The system divides the simulation into kUpdatesPerDay × 16 subdivisions when computing the update frame. -
private EndFrameBarrier m_EndFrameBarrier
Barrier system used to create an EntityCommandBuffer. The system uses the barrier's command buffer (AsParallelWriter) to disable CrimeVictim components safely from a parallel job and calls AddJobHandleForProducer to ensure the barrier waits for the job. -
private SimulationSystem m_SimulationSystem
Reference to the SimulationSystem from which the current frameIndex is read. frameIndex is passed to SimulationUtils.GetUpdateFrame to determine which shared UpdateFrame group to process. -
private EntityQuery m_VictimQuery
EntityQuery that matches entities to process: requires Citizen (read-only), UpdateFrame (shared component), CrimeVictim (read-write), and excludes Deleted and Temp. The query is required for update via RequireForUpdate. -
private TypeHandle __TypeHandle
Container for compiled EntityTypeHandle / SharedComponentTypeHandle / ComponentTypeHandle used by the Burst job. Assigned by the generated OnCreateForCompiler flow (__AssignHandles).
Properties
This type exposes no public properties.
Constructors
public CrimeEffectSystem()
Default constructor. Marked with [Preserve] in the original to prevent stripping. No custom initialization beyond what GameSystemBase does; actual setup happens in OnCreate.
Methods
-
public override int GetUpdateInterval(SystemUpdatePhase phase)
Returns the interval (in "ticks" used by the engine scheduling) at which this system should be considered for update. Implementation returns 262144 / (kUpdatesPerDay * 16), distributing work across simulation subdivisions so the CrimeEffectJob runs at the intended cadence. -
[Preserve] protected override void OnCreate()
Initializes system references and queries: - Retrieves (or creates) the EndFrameBarrier and SimulationSystem from the world.
- Builds m_VictimQuery to select citizens with an UpdateFrame and CrimeVictim, excluding Deleted and Temp.
-
Calls RequireForUpdate(m_VictimQuery) so the system only updates when matching entities exist.
-
[Preserve] protected override void OnUpdate()
Main scheduling method: - Computes the current update frame via SimulationUtils.GetUpdateFrame(m_SimulationSystem.frameIndex, kUpdatesPerDay, 16).
- Constructs and populates CrimeEffectJob with:
- m_UpdateFrameIndex (computed frame)
- EntityTypeHandle, SharedComponentTypeHandle
, ComponentTypeHandle (obtained via InternalCompilerInterface helpers and stored __TypeHandle) - An EntityCommandBuffer.ParallelWriter from m_EndFrameBarrier.CreateCommandBuffer()
- Schedules the job in parallel over m_VictimQuery using JobChunkExtensions.ScheduleParallel and attaches the returned JobHandle to base.Dependency.
-
Calls m_EndFrameBarrier.AddJobHandleForProducer with the scheduled dependency so the barrier knows to wait for the job before applying structural changes.
-
private void __AssignQueries(ref SystemState state)
Compiler-generated helper used by OnCreateForCompiler. In this implementation it creates and disposes an EntityQueryBuilder(Allocator.Temp) (placeholder to satisfy generated compiler flow). -
protected override void OnCreateForCompiler()
Compiler hookup that calls __AssignQueries and __TypeHandle.__AssignHandles(ref base.CheckedStateRef) to ensure handles are assigned correctly for Burst/AOT scenarios. -
Nested type:
CrimeEffectJob : IJobChunk
(private, BurstCompile) - Fields: m_UpdateFrameIndex (read-only), m_EntityType (EntityTypeHandle read-only), m_UpdateFrameType (SharedComponentTypeHandle
read-only), m_CrimeVictimType (ComponentTypeHandle read/write), m_CommandBuffer (EntityCommandBuffer.ParallelWriter). -
Execute semantics:
- Skip the chunk if the chunk's UpdateFrame shared component index does not match m_UpdateFrameIndex.
- Iterate entities in the chunk (respecting the enabled mask).
- For each entity, read CrimeVictim value:
- If m_Effect <= 1: set m_Effect = 0, write back, and call m_CommandBuffer.SetComponentEnabled
(unfilteredChunkIndex, entity, value: false) to disable the component. - Else: decrement m_Effect and write back.
- The job is Burst-compiled and scheduled in parallel via ScheduleParallel.
-
Nested type:
TypeHandle
- Holds EntityTypeHandle, SharedComponentTypeHandle
, and ComponentTypeHandle . - __AssignHandles(ref SystemState state) populates these handles from the SystemState for later use in job construction.
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
m_EndFrameBarrier = base.World.GetOrCreateSystemManaged<EndFrameBarrier>();
m_SimulationSystem = base.World.GetOrCreateSystemManaged<SimulationSystem>();
m_VictimQuery = GetEntityQuery(
ComponentType.ReadOnly<Citizen>(),
ComponentType.ReadOnly<UpdateFrame>(),
ComponentType.ReadWrite<CrimeVictim>(),
ComponentType.Exclude<Deleted>(),
ComponentType.Exclude<Temp>()
);
RequireForUpdate(m_VictimQuery);
}
[Preserve]
protected override void OnUpdate()
{
uint updateFrame = SimulationUtils.GetUpdateFrame(m_SimulationSystem.frameIndex, kUpdatesPerDay, 16);
var jobData = new CrimeEffectJob
{
m_UpdateFrameIndex = updateFrame,
m_EntityType = InternalCompilerInterface.GetEntityTypeHandle(ref __TypeHandle.__Unity_Entities_Entity_TypeHandle, ref base.CheckedStateRef),
m_UpdateFrameType = InternalCompilerInterface.GetSharedComponentTypeHandle(ref __TypeHandle.__Game_Simulation_UpdateFrame_SharedComponentTypeHandle, ref base.CheckedStateRef),
m_CrimeVictimType = InternalCompilerInterface.GetComponentTypeHandle(ref __TypeHandle.__Game_Citizens_CrimeVictim_RW_ComponentTypeHandle, ref base.CheckedStateRef),
m_CommandBuffer = m_EndFrameBarrier.CreateCommandBuffer().AsParallelWriter()
};
base.Dependency = JobChunkExtensions.ScheduleParallel(jobData, m_VictimQuery, base.Dependency);
m_EndFrameBarrier.AddJobHandleForProducer(base.Dependency);
}
Notes: - The system relies on the shared UpdateFrame component to spread work across frames and avoid processing all citizens in a single frame. - Disabling the CrimeVictim component via the EntityCommandBuffer ensures the change is safe when issued from a parallel job and applied by the EndFrameBarrier at the correct point in the frame.