Skip to content

Game.Simulation.HouseholdSpawnSystem

Assembly:
Namespace: Game.Simulation

Type: class

Base: GameSystemBase

Summary:
HouseholdSpawnSystem is a managed ECS system that schedules a Burst-compiled IJob (SpawnHouseholdJob) to create new household entities when residential household demand exists. It reads demand and demand-factor arrays from the ResidentialDemandSystem, selects suitable household prefabs (taking study/education positions into account), randomly picks outside connection targets for some households, and writes entity-creation commands into an EndFrameBarrier command buffer. The system runs infrequently (GetUpdateInterval returns 16) and uses several other game systems (ResidentialDemandSystem, CountStudyPositionsSystem, CitySystem, SimulationSystem) and entity queries to collect prefabs, archetypes, and outside connections.


Fields

  • private EntityQuery m_HouseholdPrefabQuery
    Query to select household prefab entities. It requires ArchetypeData and HouseholdData and excludes DynamicHousehold — used to enumerate available household prefabs and their archetypes/weights.

  • private EntityQuery m_OutsideConnectionQuery
    Query to select outside connection entities that are valid citizen outside-connections (excludes electricity/water outside connections, Temp, Deleted). Used as potential CurrentBuilding targets for newly spawned households.

  • private EntityQuery m_DemandParameterQuery
    Query used to get the singleton DemandParameterData which contains spawning parameters (e.g., spawn speed factor and OC spawn parameters).

  • private ResidentialDemandSystem m_ResidentialDemandSystem
    Reference to the ResidentialDemandSystem used to obtain current householdDemand and low/med/hi density demand factor arrays.

  • private EndFrameBarrier m_EndFrameBarrier
    Reference to the EndFrameBarrier system used to create an EntityCommandBuffer for producing entities safely from a job.

  • private SimulationSystem m_SimulationSystem
    Reference to SimulationSystem (used for frame index when seeding random).

  • private CountStudyPositionsSystem m_CountStudyPositionsSystem
    Reference used to get study/education position counts to influence selection of student/child households.

  • private CitySystem m_CitySystem
    Reference used to obtain the city entity to read city Population component.

  • private TypeHandle __TypeHandle
    Generated struct storing ComponentLookup handles for HouseholdData, DynamicHousehold, Population, OutsideConnectionData and PrefabRef used by the scheduled job.

Properties

  • (none public)

Nested Types

  • private struct SpawnHouseholdJob : IJob
    Burst-compiled job that performs the main spawning work on a worker thread:
  • Inputs: lists of prefab entities and their archetype data, outside connection entities, several ComponentLookup read-only handles (Population, HouseholdData, DynamicHousehold, OutsideConnectionData, PrefabRef), DemandParameterData, demand-factor NativeArrays (low/med/hi), study position counts, city entity, demand integer and Random state.
  • Behavior: computes how many households to spawn according to random ticks and the provided household demand; decides whether to spawn student vs non-student households using study positions; selects a prefab randomly weighted by HouseholdData.m_Weight; creates an entity using the prefab's archetype; sets a PrefabRef component to point at the selected prefab; attempts to choose a random outside connection (via BuildingUtils.GetRandomOutsideConnectionByParameters) and either adds a CurrentBuilding (target) component or adds Deleted when no suitable outside connection was chosen.
  • Notes: uses Random seeded from SimulationSystem.frameIndex; clamps the spawn speed factor when computing random threshold; sums demand factor indices [6] and [12] (low/med/hi arrays) to decide student vs non-student probability (index 6 and 12 correspond to demand buckets used in the game's demand system).

  • private struct TypeHandle
    Holds ComponentLookup caches for several component types and contains method __AssignHandles(ref SystemState) to populate them. These are used by the job to get read-only access to component data.

Constructors

  • public HouseholdSpawnSystem()
    Default constructor. The system is also initialized in OnCreate where it fetches other systems and creates entity queries.

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns 16. The system updates every 16 frames (gives coarse periodicity for household spawning).

  • protected override void OnCreate()
    Initializes system references and entity queries:

  • Gets ResidentialDemandSystem, EndFrameBarrier, SimulationSystem, CitySystem, CountStudyPositionsSystem.
  • Creates m_HouseholdPrefabQuery requiring ArchetypeData and HouseholdData and excluding DynamicHousehold.
  • Creates m_OutsideConnectionQuery for outside connections (excludes electricity/water/Temp/Deleted).
  • Creates m_DemandParameterQuery for DemandParameterData.
  • Calls RequireForUpdate on the prefab and outside connection queries to prevent updating without those present.

  • protected override void OnUpdate()
    Core execution logic:

  • Reads household demand from ResidentialDemandSystem.
  • If demand > 0, obtains low/med/hi demand factor arrays (as NativeArray) from ResidentialDemandSystem, and gets study position counts from CountStudyPositionsSystem.
  • Assembles a SpawnHouseholdJob with lists of prefab entities/archetypes, outside connections, component lookups, demand parameters, city, demand, and a seeded Random.
  • Schedules the job with dependencies and marks ResidentialDemandSystem and EndFrameBarrier with the job handle so they know about the produced artifacts / resource readers and producers.
  • The job creates entities via the EndFrameBarrier command buffer so entity creation is deferred safely to end-of-frame.

  • protected override void OnCreateForCompiler()
    Generated helper that assigns query state and the TypeHandle component lookups — called by compiler-generated infrastructure.

  • private void __AssignQueries(ref SystemState state)
    Generated stub related to query setup used by the compiler; empty in this decompiled listing.

Behavior Notes / Implementation Details

  • Spawn frequency and count:
  • The job computes a variable "max" based on DemandParameterData.m_HouseholdSpawnSpeedFactor and current population using: Mathf.RoundToInt(300f / clamp(spawnSpeedFactor * log(1 + 0.001 * population), 0.5f, 20f)). It then draws random NextInt(max) values to determine how many households to spawn from the reported demand.
  • If no households are chosen (num2 == 0) the job returns early.

  • Prefab selection:

  • Prefabs are filtered by IsValidStudyPrefab which inspects HouseholdData for child/student counts and the study position counts (m_StudyPositions). IsValidStudyPrefab returns true only when the prefab matches the educational needs logic; the job picks either a study-prefab or non-study-prefab based on a random coin weighted by the available study/non-study positions.
  • After filtering, prefab selection uses m_HouseholdDatas[prefab].m_Weight as selection weights.

  • Outside connection assignment:

  • For spawned households, BuildingUtils.GetRandomOutsideConnectionByParameters is called with demand parameters for citizen OCs; if found, a CurrentBuilding component is set with that outside connection entity; otherwise a Deleted component is added (so the household is created but not assigned a current building target).

  • Concurrency:

  • The job uses read-only ComponentLookup handles and NativeList/NativeArray structures provided via queries and system methods.
  • Entities are created via an EntityCommandBuffer from EndFrameBarrier, so the job is safe to run asynchronously.
  • The system tracks dependencies and registers the produced job with both the ResidentialDemandSystem (AddReader) and EndFrameBarrier (AddJobHandleForProducer).

  • Developer / Modder notes:

  • If adding or modifying household prefabs, ensure they have ArchetypeData and HouseholdData components and that weights are set on HouseholdData.m_Weight.
  • Education-related spawning behavior depends on CountStudyPositionsSystem output; changes to study position counting will affect which prefabs are considered "study" prefabs.
  • Demand-factor arrays (low/med/hi) are indexed at 6 and 12 in this code to compute a student vs non-student ratio — these indices correspond to demand buckets and must be understood if modifying demand calculations.
  • The system excludes DynamicHousehold prefabs from spawn list — dynamic households are handled elsewhere.
  • Random seed uses SimulationSystem.frameIndex — predictable per-frame seeding; if you want non-deterministic behavior you must change how Random is seeded.

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    // The system gets required systems and sets up queries to discover household prefabs and outside connections.
    m_ResidentialDemandSystem = base.World.GetOrCreateSystemManaged<ResidentialDemandSystem>();
    m_EndFrameBarrier = base.World.GetOrCreateSystemManaged<EndFrameBarrier>();
    m_SimulationSystem = base.World.GetOrCreateSystemManaged<SimulationSystem>();
    m_CitySystem = base.World.GetOrCreateSystemManaged<CitySystem>();
    m_CountStudyPositionsSystem = base.World.GetOrCreateSystemManaged<CountStudyPositionsSystem>();
    m_HouseholdPrefabQuery = GetEntityQuery(ComponentType.ReadOnly<ArchetypeData>(), ComponentType.ReadOnly<HouseholdData>(), ComponentType.Exclude<DynamicHousehold>());
    m_OutsideConnectionQuery = GetEntityQuery(ComponentType.ReadOnly<Game.Objects.OutsideConnection>(), ComponentType.Exclude<Game.Objects.ElectricityOutsideConnection>(), ComponentType.Exclude<Game.Objects.WaterPipeOutsideConnection>(), ComponentType.Exclude<Temp>(), ComponentType.Exclude<Deleted>());
    m_DemandParameterQuery = GetEntityQuery(ComponentType.ReadOnly<DemandParameterData>());
    RequireForUpdate(m_HouseholdPrefabQuery);
    RequireForUpdate(m_OutsideConnectionQuery);
}

If you want a specific part of this system documented in more detail (the prefab selection logic, how the demand arrays map to categories, or how to extend outside connection selection), tell me which part and I will expand it.