Skip to content

Game.Simulation.ParkAISystem

Assembly: Assembly-CSharp (game assembly)
Namespace: Game.Simulation

Type: class

Base: GameSystemBase

Summary:
ParkAISystem is the simulation system responsible for updating park buildings each tick interval. It updates park maintenance levels, computes modified service coverage based on maintenance and city modifiers, and creates maintenance request entities when parks need servicing. The per-chunk work is performed in a Burst-compiled IJobChunk (ParkTickJob) and uses an EndFrameBarrier command buffer to enqueue entity changes from the job.


Fields

  • public static readonly int kUpdatesPerDay = 256
    Used to convert the system's logical updates-per-day into the system update interval. The system uses this constant when returning GetUpdateInterval and when computing maintenance decay per update.

  • private CitySystem m_CitySystem
    Cached reference to the game's CitySystem acquired in OnCreate. Used to access the city entity (m_City) for reading city-wide modifiers.

  • private EndFrameBarrier m_EndFrameBarrier
    Barrier system used to create a parallel command buffer for the ParkTickJob and to register the job handle as a producer so structural changes are applied at the end of the frame.

  • private EntityQuery m_ParkQuery
    EntityQuery that selects park entities to update. Constructed to require Game.Buildings.Park (read), ModifiedServiceCoverage (read/write), Renter buffer (read) and to exclude Temp, Destroyed and Deleted entities.

  • private EntityArchetype m_MaintenanceRequestArchetype
    Archetype used when creating new maintenance request entities (ServiceRequest, MaintenanceRequest, RequestGroup).

  • private TypeHandle __TypeHandle
    Internal helper struct instance that caches the various Entity/Component/Buffer handles and ComponentLookup/BufferLookup instances used by the Burst job. Assigned in OnCreateForCompiler.

  • Nested: ParkTickJob (Burst-compiled struct implementing IJobChunk)
    Job that performs per-chunk updates for park entities: decreases maintenance, computes modified coverage, requests maintenance, and adds CurrentDistrict/Updated when missing. Uses component handles, lookups and a parallel EntityCommandBuffer to enqueue structural changes.

  • Nested: TypeHandle (struct)
    Holds component type handles and lookups and provides an __AssignHandles method to populate them from a SystemState.


Properties

  • (This system does not expose public properties.)

Constructors

  • public ParkAISystem()
    Default constructor. Marked with [Preserve] in source. Initialization of runtime state is performed in OnCreate rather than the constructor.

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns the update interval used by the system scheduler. Implementation: returns 262144 / kUpdatesPerDay (i.e., the number of frames/ticks between system runs). The class asserts this value is >= 512 in OnCreate to ensure a minimum interval.

  • [Preserve] protected override void OnCreate()
    Initializes the system: caches CitySystem and EndFrameBarrier, builds the m_ParkQuery, creates the m_MaintenanceRequestArchetype, and calls RequireForUpdate(m_ParkQuery). Also checks the update interval assertion.

  • [Preserve] protected override void OnUpdate()
    Schedules the Burst-compiled ParkTickJob in parallel over m_ParkQuery. The job receives component handles and lookups from __TypeHandle via InternalCompilerInterface.Get... calls, gets the city entity via m_CitySystem.City, and uses m_EndFrameBarrier.CreateCommandBuffer().AsParallelWriter() to make structural changes safely from the job. The system then registers the job handle with the EndFrameBarrier (AddJobHandleForProducer) and stores the handle into base.Dependency.

  • public static int GetMaintenancePriority(Game.Buildings.Park park, ParkData prefabParkData)
    Computes maintenance request priority for a park. Formula (from source): prefabParkData.m_MaintenancePool - park.m_Maintenance - prefabParkData.m_MaintenancePool / 10. If result > 0, a maintenance request is created for that priority.

  • public static ModifiedServiceCoverage GetModifiedServiceCoverage(Game.Buildings.Park park, ParkData prefabParkData, CoverageData prefabCoverageData, DynamicBuffer<CityModifier> cityModifiers)
    Computes a ModifiedServiceCoverage instance derived from the prefab coverage data and the park's current maintenance fraction. The method:

  • Computes maintenance fraction = park.m_Maintenance / max(1, prefabParkData.m_MaintenancePool).
  • Adjusts magnitude and range based on maintenance thresholds (num2 = floor(num / 0.3f)):
    • magnitude multiplier = 0.95 + 0.05min(1, num2) + 0.1max(0, num2-1)
    • range multiplier = 0.95 + 0.05*num2
  • Applies city-wide park entertainment modifiers (CityModifierType.ParkEntertainment) if the cityModifiers buffer exists. Returns the modified coverage which is used for service computations.

  • private void __AssignQueries(ref SystemState state)
    Internal helper used in compiler-created OnCreateForCompiler to assign any required queries. In source the body creates and disposes an empty EntityQueryBuilder; it exists to match generated code expectations.

  • protected override void OnCreateForCompiler()
    Compiler/interop entry used to assign handles/queries at startup. Calls __AssignQueries and __TypeHandle.__AssignHandles to populate internal type handles using the SystemState.

  • Nested (ParkTickJob): public void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
    Per-chunk execution:

  • Reads city modifiers from the city entity.
  • Iterates over entities in chunk:
    • If the entity's prefab has ParkData, decreases park.m_Maintenance by a computed decay: (400 + 50 * numberOfRenters)/kUpdatesPerDay, clamped at 0.
    • If a MaintenanceConsumer component exists, calls RequestMaintenanceIfNeeded which uses GetMaintenancePriority and, if appropriate, creates a MaintenanceRequest entity using the parallel command buffer.
    • If CoverageData exists on the prefab, computes and stores ModifiedServiceCoverage using GetModifiedServiceCoverage.
    • If CurrentDistrict is absent, adds default(CurrentDistrict) and default(Updated) components via the command buffer.
  • The job uses lookups (ComponentLookup/BufferLookup) to check prefab components (ParkData, CoverageData, MaintenanceRequest) and uses an EntityCommandBuffer.ParallelWriter to perform structural changes.

  • Nested (ParkTickJob): private void RequestMaintenanceIfNeeded(int jobIndex, Entity entity, Game.Buildings.Park park, MaintenanceConsumer maintenanceConsumer, ParkData prefabParkData)
    Helper called from Execute to create a maintenance request if GetMaintenancePriority returns > 0 and if the maintenanceConsumer.m_Request is not already tracked by m_MaintenanceRequestData. It creates an entity with m_MaintenanceRequestArchetype and sets MaintenanceRequest and RequestGroup components.

  • Nested (ParkTickJob): explicit interface void IJobChunk.Execute(...)
    Interface implementation that forwards to the typed Execute method.

  • Nested (TypeHandle): public void __AssignHandles(ref SystemState state)
    Fills the TypeHandle's EntityTypeHandle, ComponentTypeHandles, BufferTypeHandle and ComponentLookup/BufferLookup instances from the provided SystemState. Used by the system to pass the proper handles to the Burst job.


Usage Example

// Example: compute maintenance priority and modified coverage for a park (single-entity context).
// Note: In normal runtime usage, ParkAISystem schedules a job that updates parks automatically.
// This snippet demonstrates calling the static helper methods for testing or tools.

Game.Buildings.Park park = ...;               // current park runtime component
ParkData prefabParkData = ...;               // Prefab ParkData for this park
CoverageData prefabCoverage = ...;           // Prefab coverage info
DynamicBuffer<CityModifier> cityModifiers = ...; // from the City entity

int priority = ParkAISystem.GetMaintenancePriority(park, prefabParkData);
ModifiedServiceCoverage coverage = ParkAISystem.GetModifiedServiceCoverage(park, prefabParkData, prefabCoverage, cityModifiers);
Debug.Log($"Maintenance priority: {priority}, Coverage magnitude: {coverage.m_Magnitude}, range: {coverage.m_Range}");

Notes and tips: - The system uses a Burst IJobChunk to process parks in parallel; structural changes are queued through EndFrameBarrier's parallel command buffer. - The maintenance decay depends on the number of Renter buffer items; parks with more renters decay faster. - CityModifiers of type CityModifierType.ParkEntertainment can increase park coverage magnitude.