Game.HouseholdBehaviorSystem
Assembly: Assembly-CSharp (game)
Namespace: Game.Simulation
Type: class
Base: GameSystemBase
Summary:
HouseholdBehaviorSystem is an ECS system responsible for simulating household-level behavior each simulation tick. It updates household consumption, decides shopping needs, handles tourist lodging seeking, triggers households to move away, toggles property-seeker state, and manages vehicle/ownership related decisions. The system schedules a Burst-compiled parallel IJobChunk (HouseholdTickJob) to process household archetype chunks and depends on other game systems (ResourceSystem, TaxSystem, CitySystem, SimulationSystem) and shared update-frame semantics (EndFrameBarrier). It exposes several utility static methods used by other systems or mods (consumption/weight calculations, free-car lookup, commute aggregation, etc.).
Fields
-
public static readonly int kCarAmount
Constant amount used when a household decides to buy a car (value: 50). Represents the "amount" unit used when assigning vehicle resource need. -
public static readonly int kUpdatesPerDay
Number of household updates per in-game day (value: 256). Used to convert per-update consumption to per-day values. -
public static readonly int kMaxShoppingPossibility
Maximum shopping probability factor (value: 80). Used when determining whether a household attempts shopping in a tick. -
public static readonly int kMaxHouseholdNeedAmount
Maximum quantity assigned for a household need (value: 2000). -
public static readonly int kCarBuyingMinimumMoney
Minimum spendable money threshold to consider buying a car (value: 10000). -
public static readonly int KMinimumShoppingAmount
Minimum shopping amount constant (value: 50). -
private EntityQuery m_HouseholdGroup
Query selecting households to update. The system requires this query for update scheduling. -
private EntityQuery m_EconomyParameterGroup
Query used to fetch EconomyParameterData singleton which contains resource consumption parameters. -
private EntityQuery m_GameModeSettingQuery
Query used to fetch ModeSettingData (to adjust resource demand multiplier when a game mode is enabled). -
private SimulationSystem m_SimulationSystem
Reference to the simulation system (used to compute update-frame indexes and intervals). -
private EndFrameBarrier m_EndFrameBarrier
Barrier used to create command buffers for jobs that write entity/component changes at end of frame. -
private ResourceSystem m_ResourceSystem
Reference to ResourceSystem (used to read resource prefabs and register readers). -
private TaxSystem m_TaxSystem
Reference to TaxSystem (used to read current tax rates impacting household decisions). -
private CitySystem m_CitySystem
Reference to CitySystem (to access city population and entity). -
private float m_ResourceDemandPerCitizenMultiplier
Multiplier applied to household resource demand per citizen (adjusted by game mode settings). -
private TypeHandle __TypeHandle
Internal structure holding entity/component type handles used for job scheduling and execution. -
(Nested)
HouseholdTickJob
(private Burst-compiled struct, IJobChunk) - Implements the per-chunk processing of households. Reads/writes Household, HouseholdNeed, resource buffers and many lookups (citizens, workers, resource data, lodging providers, etc.). Contains core logic for:
- Removing empty households (deleted)
- Calculating happiness/children-only households and moving-away logic
- Performing resource consumption if household has resources
- If resources exhausted: computing shopping need using resource weights, possible car purchase decision, adding LodgingSeeker for tourists, and toggling PropertySeeker on chance/conditions
- Uses a RandomSeed, reads EconomyParameterData, Tax rates, and City population
- Main methods:
- Execute(...) — per-chunk entry point
- UpdateHouseholdNeed(...) — logic for consumption and shopping decision per household
- NeedsCar(...) — helper to probabilistically determine car buying
Properties
- (This system does not expose public properties; internal TypeHandle and query references are private.)
Constructors
public HouseholdBehaviorSystem()
Default constructor. Initializes system instance; OnCreate will initialize dependencies and queries when the system is created by the World.
Methods
-
public override int GetUpdateInterval(SystemUpdatePhase phase)
Returns the update interval in simulation ticks for this system. The interval is computed using kUpdatesPerDay to spread household updates across simulation frames. -
protected override void OnCreate()
Initializes system references to other systems (SimulationSystem, EndFrameBarrier, ResourceSystem, TaxSystem, CitySystem), constructs entity queries (household, economy parameter, game mode setting), sets default resource demand multiplier and marks required queries for update. The method is annotated with [Preserve] in-game to avoid stripping. -
protected override void OnDestroy()
Cleanup on destruction (calls base). Present primarily for completeness; no custom destruction logic beyond base in the decompiled code. -
protected override void OnUpdate()
Main scheduling entry point: computes an update-frame index for this tick, constructs HouseholdTickJob with many handles/lookups and parameters (random seed, economy params, tax rates, prefabs, etc.), schedules the job as a parallel JobChunk over m_HouseholdGroup and registers its dependency with the EndFrameBarrier, ResourceSystem, and TaxSystem. This is where the household processing is dispatched. -
protected override void OnGameLoaded(Context serializationContext)
Reads ModeSettingData (if present) and applies the ModeSettingData.m_ResourceDemandPerCitizenMultiplier to m_ResourceDemandPerCitizenMultiplier when a game mode is enabled; otherwise defaults to 1. Called after game load for game-mode dependent configuration. -
public static float GetLastCommutePerCitizen(DynamicBuffer<HouseholdCitizen> householdCitizens, ComponentLookup<Worker> workers)
Returns average last commute time for the citizens in a household. Iterates citizens, accumulating worker.m_LastCommuteTime for those who are workers and dividing by household size. -
public static float GetConsumptionMultiplier(float2 parameter, int householdWealth)
Computes a consumption multiplier using a two-component parameter (parameter.x + parameter.y * smoothstep(...)). The smoothstep input is based on household wealth normalized and clamped. Used to scale resource consumption relative to wealth. -
public static bool GetFreeCar(Entity household, BufferLookup<OwnedVehicle> ownedVehicles, ComponentLookup<Game.Vehicles.PersonalCar> personalCars, ref Entity car)
Checks the household's owned vehicles for a free personal car (a PersonalCar that has no keeper). If found, returns true and sets car to that Entity; otherwise sets car to Entity.Null and returns false. -
public static int GetAgeWeight(ResourceData resourceData, DynamicBuffer<HouseholdCitizen> citizens, ref ComponentLookup<Citizen> citizenDatas)
Computes an age-based weight sum from ResourceData weights (child/teen/adult/elderly) across the household citizens. -
public static int GetResourceShopWeightWithAge(int wealth, Resource resource, ResourcePrefabs resourcePrefabs, ref ComponentLookup<ResourceData> resourceDatas, int carCount, bool leisureIncluded, DynamicBuffer<HouseholdCitizen> citizens, ref ComponentLookup<Citizen> citizenDatas)
Overload that resolves ResourceData via ResourcePrefabs and delegates to the ResourceData overload. Returns an integer "shopping weight" that factors age composition, base consumption, car influence, and wealth-based scaling. -
public static int GetResourceShopWeightWithAge(int wealth, ResourceData resourceData, int carCount, bool leisureIncluded, DynamicBuffer<HouseholdCitizen> citizens, ref ComponentLookup<Citizen> citizenDatas)
Computes a shopping weight (int) that indicates how likely a household is to shop for a resource, factoring in base consumption, car consumption, age weights, leisure flags, and wealth smoothstep scaling. -
public static int GetWeight(int wealth, Resource resource, ResourcePrefabs resourcePrefabs, ref ComponentLookup<ResourceData> resourceDatas, int carCount, bool leisureIncluded)
Overload that resolves ResourceData via ResourcePrefabs to the ResourceData variant. -
public static int GetWeight(int wealth, ResourceData resourceData, int carCount, bool leisureIncluded)
Simpler weight computation (not age-aware) that combines base consumption and car consumption then applies wealth-based smoothstep scaling to produce an int weight. -
public static int GetHighestEducation(DynamicBuffer<HouseholdCitizen> citizenBuffer, ref ComponentLookup<Citizen> citizens)
Returns the highest education level among teens/adults in the household. Iterates household citizens and reads their education level via Citizen component where applicable. -
private void __AssignQueries(ref SystemState state)
Internal helper used by the compiled system to set up queries; no user-level behavior. -
protected override void OnCreateForCompiler()
Compiler-inserted method for assigning handles / queries when building via the compiler pipeline (internal use in generated code). -
(Nested) HouseholdTickJob.Execute/UpdateHouseholdNeed/NeedsCar
- Execute: runs for each chunk whose UpdateFrame matches the computed update-frame index; it loops households in the chunk and applies the core logic described above (consumption, shopping, move-away, lodging seeking, property seeking toggling). Uses many lookups and writes via a parallel EntityCommandBuffer.
- UpdateHouseholdNeed: handles consumption when household has stored resources and shopping need creation when resources are exhausted; calculates consumptionPerDay, decrements stored resources, picks a resource need based on weighted random (age-weighted and wealth-smoothstep), and sets amounts. Special handling for tourists and lodging seekers.
- NeedsCar: probabilistically decides whether household should buy a car based on spendable money, family size, and current car count.
Usage Example
// Example 1: Compute consumption multiplier for a household with some economy parameters:
float2 param = new float2(1.0f, 0.5f); // example parameters
int householdWealth = 3500;
float multiplier = HouseholdBehaviorSystem.GetConsumptionMultiplier(param, householdWealth);
// Example 2: Check average commute of a household:
float avgCommute = HouseholdBehaviorSystem.GetLastCommutePerCitizen(householdCitizensBuffer, workersLookup);
// Example 3: Check whether household has a free personal car (from a system or job using lookups):
Entity freeCar;
bool hasFree = HouseholdBehaviorSystem.GetFreeCar(householdEntity, ownedVehiclesBufferLookup, personalCarLookup, ref freeCar);
if (hasFree) {
// freeCar contains an entity id of an available personal car
}
Notes for modders: - HouseholdBehaviorSystem is highly integrated with the game's ECS world and other systems (ResourceSystem, TaxSystem, CitySystem). Many public static helpers (GetWeight, GetResourceShopWeightWithAge, GetConsumptionMultiplier, GetHighestEducation, GetFreeCar, GetLastCommutePerCitizen) are safe to call from other managed code or jobs provided you have the proper lookups/buffers. - To influence household resource demand globally, ModeSettingData (game mode) sets m_ResourceDemandPerCitizenMultiplier read at OnGameLoaded; alternatively, a mod could update EconomyParameterData or the ModeSettingData singleton (with care). - The heavy-lifting is done inside a Burst-compiled JobChunk (HouseholdTickJob). If creating custom jobs that interact with households, ensure correct read/write safety and register job dependencies with EndFrameBarrier/ResourceSystem/TaxSystem where appropriate.