Skip to content

Game.Simulation.DirtynessSystem

Assembly:
Assembly-CSharp.dll

Namespace:
Game.Simulation

Type:
class

Base:
GameSystemBase

Summary:
DirtynessSystem is a simulation system that updates the Surface.m_Dirtyness value for building-related Surface components. It computes dirtyness from a building's condition, abandonment state, efficiency buffers, prefab/spawnable data and city modifiers, and applies random variation per-chunk. The system runs infrequently (every 256 frames) and is implemented using a Burst-compiled IJobChunk (DirtynessJob) to operate in parallel over chunks of entities with Surface components.


Fields

  • private CitySystem m_CitySystem
    Holds a reference to the CitySystem instance (the city entity provider). Used to obtain the city entity whose CityModifier buffer is read by the DirtynessJob.

  • private EntityQuery m_SurfaceQuery
    EntityQuery that matches entities with a Surface component and excludes Deleted, Overridden and Temp. This query is required for update; it drives which entities the DirtynessJob runs over.

  • private TypeHandle __TypeHandle
    Internal struct that stores ComponentTypeHandle, BufferTypeHandle and ComponentLookup/BufferLookup handles used to build and schedule the DirtynessJob. Populated during system initialization (OnCreateForCompiler).

  • private struct DirtynessJob (nested)
    Burst-compiled IJobChunk that performs the core dirtyness calculation per chunk. It reads BuildingCondition, Abandoned, PrefabRef, Efficiency buffers, and uses ComponentLookup/BufferLookup for SpawnableBuildingData, ZoneData, BuildingPropertyData and CityModifier. It also uses a RandomSeed for per-chunk randomness.

  • private struct TypeHandle (nested)
    Contains ComponentTypeHandle, ComponentTypeHandle, ComponentTypeHandle, BufferTypeHandle, ComponentTypeHandle, and several ComponentLookup/BufferLookup fields. Has an __AssignHandles method used to fetch the actual handles from a SystemState.

Properties

  • None (no public properties exposed by this system)
    This system uses internal TypeHandle members and fields; it does not expose public properties.

Constructors

  • public DirtynessSystem()
    Default constructor. The system is initialized by the ECS framework; additional initialization occurs in OnCreate and OnCreateForCompiler.

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns 256. The system requests to be updated every 256 frames (coarse-grained update interval).

  • [Preserve] protected override void OnCreate()
    Initializes the system: fetches the CitySystem (via World.GetOrCreateSystemManaged()), builds the m_SurfaceQuery to match Surface components (excluding Deleted, Overridden and Temp), and calls RequireForUpdate(m_SurfaceQuery) to ensure the system only runs when matching entities exist.

  • [Preserve] protected override void OnUpdate()
    Schedules the DirtynessJob as a parallel IJobChunk using the m_SurfaceQuery. It populates the job's component type handles/lookups using internal handle references and provides RandomSeed.Next() and the city entity (m_CitySystem.City) to the job. The job updates Surface.m_Dirtyness for each entity in the query and the JobHandle is stored to base.Dependency.

  • private void __AssignQueries(ref SystemState state)
    Internal helper (compiler/init use) — currently a stub that uses EntityQueryBuilder in temporary allocator and disposes it. Present for compiler-generated initialization.

  • protected override void OnCreateForCompiler()
    Called in the compiler/initialization path: calls __AssignQueries and __TypeHandle.__AssignHandles to populate internal handles using base.CheckedStateRef.

  • void DirtynessJob.Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
    Main per-chunk worker: for each chunk it obtains arrays/accessors for Surface, BuildingCondition, PrefabRef or Efficiency buffer as appropriate and applies the dirtyness logic:

  • If there are BuildingCondition components:
    • If chunk has Abandoned component, sets m_Dirtyness = 255 for all surfaces in the chunk.
    • Else calculates dirtyness from negative building condition and leveling cost derived from SpawnableBuildingData, ZoneData, BuildingPropertyData and city modifiers; clamps and writes byte value.
  • Else if there are Efficiency buffers:
    • Computes change in dirtyness based on building efficiency and current dirtyness, applies a small random rounded delta using RandomSeed.
  • Else:

    • Sets m_Dirtyness = 0 for all surfaces in the chunk.
  • TypeHandle.__AssignHandles(ref SystemState state)
    Initializes the ComponentTypeHandle/BufferTypeHandle/ComponentLookup/BufferLookup fields from the provided SystemState. Called from OnCreateForCompiler to prepare handles used when scheduling the job.

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    // Mirror of what DirtynessSystem does: cache CitySystem and build the Surface query
    m_CitySystem = base.World.GetOrCreateSystemManaged<CitySystem>();
    m_SurfaceQuery = GetEntityQuery(
        ComponentType.ReadWrite<Surface>(),
        ComponentType.Exclude<Deleted>(),
        ComponentType.Exclude<Overridden>(),
        ComponentType.Exclude<Temp>()
    );
    RequireForUpdate(m_SurfaceQuery);
}

Notes and tips: - DirtynessSystem is designed to run infrequently and in bulk (every 256 frames) to cheaply maintain surface dirtyness values. - The core logic is in DirtynessJob and uses Burst and Jobs to be efficient; modders should avoid replacing it with single-entity operations for large counts. - If you need to influence dirtyness calculation, consider modifying city modifiers, SpawnableBuildingData / ZoneData / BuildingPropertyData, or the BuildingCondition/Efficiency components rather than changing the system scheduling directly.