Game.Simulation.BuildingUpkeepSystem
Assembly: Game
Namespace: Game.Simulation
Type: class
Base: GameSystemBase
Summary:
BuildingUpkeepSystem is the simulation system that handles building upkeep and automatic leveling (level up / level down) for spawnable buildings. It:
- Calculates upkeep costs and charges renters.
- Updates building condition and queues buildings for level changes.
- Processes level-up and level-down actions (including applying Abandoned state, removing consumers/producers, icon notifications, and triggering game events).
- Uses Burst-compiled jobs (IJobChunk / IJob) and multiple NativeQueues to perform work in parallel and defer structural changes through an EndFrameBarrier command buffer.
Fields
-
public static readonly int kUpdatesPerDay = 16
Constant: how many building upkeep update ticks occur per in-game day. -
public static readonly int kMaterialUpkeep = 4
Constant used to split upkeep into material vs monetary components. -
private SimulationSystem m_SimulationSystem
Reference to the central simulation system (used for frame index and scheduling). -
private EndFrameBarrier m_EndFrameBarrier
Barrier system used to create command buffers for structural changes made by jobs. -
private ResourceSystem m_ResourceSystem
Reference to the resource system (used to read resource prefabs and write resource changes). -
private ClimateSystem m_ClimateSystem
Reference to climate data (used to factor temperature into upkeep/heating). -
private CitySystem m_CitySystem
Reference to the city entity (used to get city modifiers). -
private IconCommandSystem m_IconCommandSystem
Used to add/remove icons (level-up, abandoned, problems, etc.). -
private TriggerSystem m_TriggerSystem
Used to enqueue trigger actions for level changes. -
private ZoneBuiltRequirementSystem m_ZoneBuiltRequirementSystemSystem
Used to report zone built level updates when buildings level up. -
private Game.Zones.SearchSystem m_ZoneSearchSystem
Used by the level-up logic to determine max building height on a lot. -
private ElectricityRoadConnectionGraphSystem m_ElectricityRoadConnectionGraphSystem
Used to enqueue updates when electricity consumers are removed on level down. -
private WaterPipeRoadConnectionGraphSystem m_WaterPipeRoadConnectionGraphSystem
Used to enqueue updates when water consumers are removed on level down. -
private NativeQueue<UpkeepPayment> m_UpkeepExpenseQueue
Queue of upkeep payment items (renter entity + price) produced by the upkeep job and consumed by UpkeepPaymentJob. -
private NativeQueue<Entity> m_LevelupQueue
Queue of building entities that should attempt to level up (processed by LevelupJob). -
private NativeQueue<Entity> m_LeveldownQueue
Queue of building entities that should level down / be abandoned (processed by LeveldownJob). -
private EntityQuery m_BuildingPrefabGroup
Query used to enumerate spawnable building prefabs (used by LevelupJob to pick replacements). -
private EntityQuery m_BuildingSettingsQuery
Query to fetch BuildingConfigurationData singleton. -
private EntityQuery m_BuildingGroup
Query for active buildings with BuildingCondition, PrefabRef and UpdateFrame (and not abandoned/destroyed/deleted/temp). -
public bool debugFastLeveling
Public toggle allowing the upkeep job to immediately set building condition to the leveling cost (useful for testing fast level changes). -
private TypeHandle __TypeHandle
Internal cached component/handle collection used to obtain ComponentTypeHandle / ComponentLookup instances for jobs.
Properties
This system does not expose public properties besides the public field debugFastLeveling. Most data exchange is done via jobs, queues and ECS component lookups.
Constructors
public BuildingUpkeepSystem()
Default constructor. Initialization of managed references happens in OnCreate; this ctor is preserved for ECS creation.
Methods
-
public override int GetUpdateInterval(SystemUpdatePhase phase)
Returns the system update interval (derived from kUpdatesPerDay). Controls how often the system runs relative to the simulation phase. -
public static float GetHeatingMultiplier(float temperature)
Utility: returns a heating multiplier based on temperature (clamped: max(0, 15 - temperature)). Used to scale heating-related upkeep. -
[Preserve] protected override void OnCreate()
Initializes system dependencies (GetOrCreateSystemManaged), allocates NativeQueues, sets up EntityQueries and calls RequireForUpdate for relevant queries. Prepares the system to run. -
[Preserve] protected override void OnDestroy()
Disposes persistent NativeQueues (m_UpkeepExpenseQueue, m_LevelupQueue, m_LeveldownQueue). -
[Preserve] protected override void OnUpdate()
Core scheduling method. Creates and schedules the following jobs (Burst compiled): - BuildingUpkeepJob (IJobChunk): iterates active buildings for the current update frame, computes upkeep, updates BuildingCondition, enqueues UpkeepPayment items and level change requests.
- LevelupJob (IJob): processes the m_LevelupQueue, selects appropriate higher-level spawnable building prefab, marks building UnderConstruction, sends triggers and icon notifications, and reports to zone built-level system.
- LeveldownJob (IJob): processes the m_LeveldownQueue, marks buildings Abandoned, removes consumers/producers, removes renters, sends triggers and adjusts crime producers/icons.
-
UpkeepPaymentJob (IJob): consumes m_UpkeepExpenseQueue and writes monetary changes to renters' resource buffers. The method wires dependencies, adds readers/writers to other systems, and uses the EndFrameBarrier command buffer to defer structural changes.
-
public void DebugLevelUp(Entity building, ComponentLookup<BuildingCondition> conditions, ComponentLookup<SpawnableBuildingData> spawnables, ComponentLookup<PrefabRef> prefabRefs, ComponentLookup<ZoneData> zoneDatas, ComponentLookup<BuildingPropertyData> propertyDatas)
Debug helper: enqueues a building into m_LevelupQueue if it has valid prefab/spawnable data and belongs to a valid zone prefab. Does minimal checks before enqueueing. -
public void DebugLevelDown(Entity building, ComponentLookup<BuildingCondition> conditions, ComponentLookup<SpawnableBuildingData> spawnables, ComponentLookup<PrefabRef> prefabRefs, ComponentLookup<ZoneData> zoneDatas, ComponentLookup<BuildingPropertyData> propertyDatas)
Debug helper: forces a building to level down by setting its BuildingCondition to a large negative value (relative to leveling cost) and enqueueing it into m_LeveldownQueue. Useful for testing abandonment / level-down behavior. -
protected override void OnCreateForCompiler()
Internal ECS/compiler helper (assigns queries & type handles). Not intended for modder use. -
private void __AssignQueries(ref SystemState state)
Internal method used during compiler-time initialization (no-op in this source).
Inner Job structs (Burst compiled) — key details:
- BuildingUpkeepJob : IJobChunk
- Iterates chunks of buildings whose UpdateFrame matches the current update index.
- Reads prefab consumption and building spawn data, renters, city modifiers, household/company resources.
- Calculates per-building upkeep (monetary & material split), charges renters by enqueueing UpkeepPayment items, and updates BuildingCondition using configuration increments/decrements scaled by level and number of renters.
- Enqueues buildings to m_LevelupQueue when condition >= leveling cost.
-
Enqueues buildings to m_LevelDownQueue when condition <= -levelingThreshold (and not signature building, abandoned or destroyed).
-
UpkeepPaymentJob : IJob
-
Dequeues UpkeepPayment items and applies monetary resource changes to renters' resource buffers.
-
LeveldownJob : IJob
-
Dequeues buildings and applies abandonment/level-down effects: adds Abandoned component, removes consumer/producer components, removes PropertyRenter components from renters, updates icons and triggers level-down events, and enqueues road-edge updates as needed.
-
LevelupJob : IJob
- Dequeues buildings and tries to select a suitable spawnable building prefab for the next level (matching lot size, max height, access flags and property constraints). If a replacement is found, marks the building UnderConstruction with the new prefab and progress, enqueues triggers and zone built-level updates, and adds level-up icon notifications.
Notes on threading and data safety: - Jobs are Burst-compiled where possible and use ComponentLookup / BufferLookup with explicit ReadOnly flags. - Structural changes are deferred via EndFrameBarrier command buffers (parallel writer for chunk job; single writer for scheduled IJob). - Several systems are registered as readers/writers (e.g., ZoneSearchSystem, ResourceSystem) to manage job dependencies.
Usage Example
// Enable fast leveling globally for testing:
var world = Unity.Entities.World.DefaultGameObjectInjectionWorld;
var upkeep = world.GetOrCreateSystemManaged<Game.Simulation.BuildingUpkeepSystem>();
upkeep.debugFastLeveling = true;
// Force a single building to level up (example, requires valid lookups obtained from your system context):
// upkeep.DebugLevelUp(buildingEntity, conditionsLookup, spawnablesLookup, prefabRefsLookup, zoneDatasLookup, propertyDatasLookup);
Additional tips: - Do not call Job data or ComponentLookup writes from main thread while the system is running; use the provided queues or command buffers. - Use DebugLevelUp / DebugLevelDown only in editor or debug contexts; they bypass normal economics checks.