Game.Simulation.CityServiceUpkeepSystem
Assembly: Assembly-CSharp
Namespace: Game.Simulation
Type: class CityServiceUpkeepSystem
Base: GameSystemBase
Summary:
Processes city service building upkeep, storage and resource consumption each simulation tick slice. This system schedules a burst-compiled IJobChunk (CityServiceUpkeepJob) over entities with CityServiceUpkeep and resource buffers. The job computes upkeep (including upgrades and service-usage scaling), decrements material resources, enqueues ResourceBuyer components when imports are needed, updates quantity/subobject batching, and manages no-resource notifications (icons). It integrates with city budget data, delivery truck state, storage limits, upgrade stats and the ResourceSystem / IconCommandSystem / EndFrameBarrier for command buffering.
Fields
-
private static readonly int kUpdatesPerDay = 64
Number of job updates per in-game day used to slice upkeep processing across frames. Influences GetUpdateInterval and random tick sizing. -
private CitySystem m_CitySystem
Cached reference to the CitySystem used to fetch the city entity. -
private SimulationSystem m_SimulationSystem
Cached SimulationSystem used to compute update frame index. -
private CityStatisticsSystem m_CityStatisticsSystem
Reference to city statistics (present but not directly used in shown code — kept for potential statistics interactions). -
private ResourceSystem m_ResourceSystem
Reference to ResourceSystem to read resource prefabs and register read dependencies. -
private IconCommandSystem m_IconCommandSystem
Used to create icon command buffers to add/remove problem icons (no-resource notifications). -
private EndFrameBarrier m_EndFrameBarrier
Barrier used to create an EntityCommandBuffer for modifications produced by the job. -
private VehicleCapacitySystem m_VehicleCapacitySystem
Used to query delivery truck capacity ranges (to decide how many resources to request). -
private EntityQuery m_UpkeepGroup
Query selecting CityServiceUpkeep entities with resources and relevant components. -
private EntityQuery m_BudgetDataQuery
Query selecting service budget data entity (singleton). -
private TypeHandle __TypeHandle
Internal struct bundling component / buffer / lookup type handles used by JobChunk. Assigned on create-for-compiler.
Properties
- (none)
Constructors
public CityServiceUpkeepSystem()
Default constructor. Marked with [Preserve] in OnCreate; constructs system normally under the ECS framework.
Methods
-
public override int GetUpdateInterval(SystemUpdatePhase phase)
Returns an update interval based on kUpdatesPerDay. Used by the game scheduler to space system updates across frames. -
[Preserve] protected override void OnCreate()
Acquires references to required systems, sets up EntityQuery objects (m_UpkeepGroup, m_BudgetDataQuery) and prepares internal state. This is where the system binds to CitySystem, SimulationSystem, ResourceSystem, IconCommandSystem, EndFrameBarrier and VehicleCapacitySystem. -
[Preserve] protected override void OnUpdate()
Builds and schedules the CityServiceUpkeepJob: - Computes current updateFrame slice from SimulationUtils.GetUpdateFrame.
- Populates jobData with component lookups, buffers, system references, city/budget entities, random seed and command buffers.
- Schedules the job over m_UpkeepGroup with JobChunk scheduling.
-
Registers resource readers and adds producer handles to EndFrameBarrier / IconCommandSystem.
-
private struct CityServiceUpkeepJob : IJobChunk (BurstCompile)
The chunk job implementing the core per-building upkeep logic. Key points: - Uses SharedComponent UpdateFrame to only process entities assigned to the current update slice.
- Collects service upkeep entries (including installed upgrades and those scaling with service usage).
- Collects upkeep modifiers (from installed upgrades).
- Computes storage targets for material resources required by the service.
- Applies storage limits (from StorageLimitData and upgrades).
- Calls TickConsumer to consume material resources per tick (with randomized rounding).
- Updates ResourceConsumer availability and enqueues notification icons when availability changes.
- Subtracts already-assigned delivery truck payloads (delivery trucks and layout elements) from desired storage.
- Spawns ResourceBuyer components (via EntityCommandBuffer) when additional imports are needed, selecting requested amounts using delivery truck capacity ranges and randomness.
- Calls QuantityUpdated to flag subobjects for visual batching updates when quantities change.
- Uses CommandBuffer and IconCommandBuffer to produce entity/component changes and icon adds/removes safely from the job.
Important Job fields (not exhaustive): m_UpdateFrameType, m_EntityType, m_PrefabType, m_OwnedVehicleBufType, m_ResourcesType, m_ResourceConsumerType, m_Prefabs, m_ServiceObjects, m_ResourceDatas, m_ServiceUpkeepDatas, m_UpkeepModifiers, m_InstalledUpgrades, m_ResourceConsumerDatas, m_ServiceUsages, m_Limits, m_ServiceBudgetDatas, m_DeliveryTrucks, m_LayoutElements, m_QuantityData, m_SubObjects, m_PlayerMoney, m_UpdateFrameIndex, m_City, m_BudgetDataEntity, m_RandomSeed, m_DeliveryTruckSelectData, m_ResourcePrefabs, m_CommandBuffer, m_IconCommandBuffer.
Key job helper methods:
- Execute(in ArchetypeChunk chunk, ...)
Main per-chunk entry. Filters by update frame, iterates entities and applies upkeep/storage logic described above.
- private void GetStorageTargets(NativeArray
Computes per-resource storage targets from ServiceUpkeepData on the prefab and its installed upgrades (taking upkeep modifiers into account).
- private int GetServiceBudget(Entity prefab, DynamicBuffer
Looks up the budget percentage for the service (default 100% if not found).
- private bool TickConsumer(int serviceBudget, int storageLimit, NativeList
Applies upkeep consumption for material resources and returns whether a quantity change threshold was crossed (used to update quantities/visuals).
- private void QuantityUpdated(Entity buildingEntity, bool updateAll = false)
Recursively marks subobjects with BatchesUpdated so rendering/visual batching is updated when resource quantities change.
- private static UpkeepModifierData GetUpkeepModifier(Resource resource, NativeList
Look up a modifier for a resource or return a default (multiplier 1).
- private void UpdateNotification(NativeParallelHashMap
Adds entries to the temporary notifications map for the prefab's no-resource notification prefab when availability changed.
-
public static byte GetResourceAvailability(NativeList<ServiceUpkeepData> upkeeps, DynamicBuffer<Game.Economy.Resources> resources, NativeArray<int> storageTargets)
Computes a 0–255 availability byte across all material upkeeps relative to their storage targets. Returns the minimum availability across all required material resources. -
public static int CalculateUpkeep(int amount, Entity prefabEntity, Entity budgetEntity, EntityManager entityManager)
Calculate money upkeep scaled by the service budget for the prefab's service (looks up ServiceObjectData -> service, then reads ServiceBudgetData). Returns rounded integer upkeep. -
public static void GetUpkeepModifierData(NativeList<UpkeepModifierData> upkeepModifierList, BufferLookup<InstalledUpgrade> installedUpgrades, ComponentLookup<PrefabRef> prefabs, BufferLookup<UpkeepModifierData> upkeepModifiers, Entity entity)
Populates an upkeepModifierList by combining installed upgrade stats. -
public static bool IsMaterialResource(ComponentLookup<ResourceData> resourceDatas, ResourcePrefabs resourcePrefabs, ResourceStack upkeep)
Returns true if the upkeep resource has a positive weight (i.e., is a material resource rather than e.g. money). -
public static int GetUpkeepOfEmployeeWage(BufferLookup<Employee> employeeBufs, Entity entity, EconomyParameterData economyParameterData, bool mainBuildingDisabled)
Sums wages for employees of a building (used elsewhere to compute wage upkeep). Returns 0 if main building disabled. -
public static void GetUpkeepWithUsageScale(NativeList<ServiceUpkeepData> totalUpkeepDatas, BufferLookup<ServiceUpkeepData> serviceUpkeepDatas, BufferLookup<InstalledUpgrade> installedUpgradeBufs, ComponentLookup<PrefabRef> prefabRefs, ComponentLookup<ServiceUsage> serviceUsages, Entity entity, Entity prefab, bool mainBuildingDisabled)
Collects base upkeep from prefab and installed upgrades, applying service usage scaling and handling upgrade options (e.g., inactive upgrade halves some money upkeep) and combining stats appropriately. -
[MethodImpl(MethodImplOptions.AggressiveInlining)] private void __AssignQueries(ref SystemState state)
Internal/compiler helper for assigning queries (kept minimal in decompiled code). -
protected override void OnCreateForCompiler()
Internal initialization path used by compiled code to assign type handles and queries (calls __AssignQueries and __TypeHandle.__AssignHandles).
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
// Bind systems and create entity queries
m_CitySystem = base.World.GetOrCreateSystemManaged<CitySystem>();
m_SimulationSystem = base.World.GetOrCreateSystemManaged<SimulationSystem>();
m_ResourceSystem = base.World.GetOrCreateSystemManaged<ResourceSystem>();
m_IconCommandSystem = base.World.GetOrCreateSystemManaged<IconCommandSystem>();
m_EndFrameBarrier = base.World.GetOrCreateSystemManaged<EndFrameBarrier>();
m_UpkeepGroup = GetEntityQuery(
ComponentType.ReadOnly<CityServiceUpkeep>(),
ComponentType.ReadWrite<Game.Economy.Resources>(),
ComponentType.ReadOnly<PrefabRef>(),
ComponentType.ReadOnly<UpdateFrame>(),
ComponentType.Exclude<Deleted>(),
ComponentType.Exclude<Destroyed>(),
ComponentType.Exclude<Temp>());
m_BudgetDataQuery = GetEntityQuery(ComponentType.ReadOnly<ServiceBudgetData>());
}
Additional notes and modding tips: - The system is very performance-sensitive and uses Burst + IJobChunk with many Native containers. Changes should respect read/write handles and add any new readers/writers to barriers (EndFrameBarrier, IconCommandSystem, ResourceSystem) to avoid race conditions. - To influence upkeep behavior, mods can add/modify ServiceUpkeepData, UpkeepModifierData or InstalledUpgrade buffers on prefabs/entities. Changing ServiceBudgetData affects money upkeep via CalculateUpkeep. - The job uses a 0–255 availability byte (GetResourceAvailability) for UI/notification decisions — when producing or consuming resources, ensure your resource weights and storage targets are set appropriately for intended visual behavior.