Game.Simulation.CommercialSpawnSystem
Assembly: Assembly-CSharp
Namespace: Game.Simulation
Type: public class CommercialSpawnSystem
Base: GameSystemBase
Summary:
CommercialSpawnSystem is a simulation system that periodically attempts to spawn new commercial company entities in response to commercial resource demand. It queries available commercial company prefabs, existing property-less companies, current resource demand state and demand parameters, then schedules a Burst-compatible job (SpawnCompanyJob) to create new company entities using an EndFrameBarrier EntityCommandBuffer. The system throttles spawning using per-resource last-spawned frame tracking and demand/frame-interval parameters fetched from DemandParameterData.
Fields
-
private EntityQuery m_CommercialCompanyPrefabGroup
Query for commercial company prefab entities (read-only ArchetypeData + CommercialCompanyData + IndustrialProcessData). Used to enumerate candidate company prefab entities that can be spawned. -
private EntityQuery m_PropertyLessCompanyGroup
Query for currently existing commercial companies that do not rent properties (CommercialCompany + PrefabRef, exclude PropertyRenter/Deleted/Temp). Used to avoid spawning duplicate production chains already present. -
private EntityQuery m_DemandParameterQuery
Query to obtain DemandParameterData singleton (contains spawn interval parameters and other demand tuning). -
private CommercialDemandSystem m_CommercialDemandSystem
Reference to the CommercialDemandSystem for reading current company/resource demand and getting per-resource demand arrays. -
private EndFrameBarrier m_EndFrameBarrier
Reference to an EndFrameBarrier system used to create an EntityCommandBuffer for safe entity creation at end of frame. -
private SimulationSystem m_SimulationSystem
Reference to the SimulationSystem to access the current simulation frame index and other global timing. -
private NativeArray<uint> m_LastSpawnedCommercialFrame
Persistent NativeArray sized by EconomyUtils.ResourceCount storing the last simulation frame index when a commercial company for each resource was spawned. Used to enforce minimum frame intervals between spawns per resource. -
private TypeHandle __TypeHandle
Internal struct holding ComponentLookup handles used by jobs for efficient component access (ArchetypeData, IndustrialProcessData, PrefabRef). Assigned in OnCreateForCompiler.
Properties
- (none — CommercialSpawnSystem exposes no public properties)
Constructors
public CommercialSpawnSystem()
Default constructor. Initialization is performed in OnCreate. The constructor is annotated with Preserve to avoid stripping in some builds.
Methods
-
public override int GetUpdateInterval(SystemUpdatePhase phase)
Returns the system's base update interval in frames. This implementation returns 16, indicating the system's nominal update granularity. -
protected override void OnCreate()
Initializes queries and references to supporting systems. Creates the persistent m_LastSpawnedCommercialFrame NativeArray (length = EconomyUtils.ResourceCount) and calls RequireForUpdate(m_CommercialCompanyPrefabGroup) to only run when prefabs exist. Also obtains references to CommercialDemandSystem, EndFrameBarrier and SimulationSystem. -
protected override void OnDestroy()
Disposes of the persistent m_LastSpawnedCommercialFrame NativeArray. -
protected override void OnUpdate()
Main update logic. The system runs a spawn job only when the simulation frame and demand conditions are met: - It checks the simulation frame condition: (frameIndex / 16) % 8 == 1 (a periodic slot).
- It checks that commercial company demand > 0 from CommercialDemandSystem. If conditions hold, it constructs and schedules SpawnCompanyJob, wiring:
- lists of company prefabs and property-less companies (as NativeList
), - component lookups via the TypeHandle,
- resource demand NativeArray from CommercialDemandSystem,
- a Random instance seeded by RandomSeed.Next() and the current frame index,
- demand parameters obtained from DemandParameterData singleton,
-
an EntityCommandBuffer from EndFrameBarrier. It then combines job dependencies, registers the job as a reader with CommercialDemandSystem, and adds the job handle to EndFrameBarrier as a producer job.
-
private void __AssignQueries(ref SystemState state)
Compiler helper that can assign or validate queries at compile-time. The implementation here allocates a temporary EntityQueryBuilder and disposes it (used by the generated OnCreateForCompiler path). -
protected override void OnCreateForCompiler()
Compiler-invoked initialization that calls __AssignQueries and assigns the component lookups in __TypeHandle.
Nested / job types (not top-level methods but important behavior):
private struct SpawnCompanyJob : IJob
Burst-compiled job that performs the main spawning work for each resource. It:- Iterates ResourceIterator.GetIterator(), obtaining each resource type to consider.
- For each resource, checks current demand and last spawn frame to enforce spacing using m_DemandParameterData.m_FrameIntervalForSpawning.y.
- Scans existing property-less companies to ensure an output producer for the resource is not already present.
- If spawn is allowed, selects a matching company prefab at random (filtered by IndustrialProcessData.m_Output.m_Resource) and creates a new entity from its archetype, adding a PrefabRef component pointing to the chosen prefab.
-
Updates m_LastSpawnedCommercialFrame[resourceIndex] to the current frame index after spawning. Important job fields include: m_CompanyPrefabs, m_PropertyLessCompanies, m_ResourceDemands, m_Random, m_FrameIndex, m_DemandParameterData, m_Processes (IndustrialProcessData lookup), m_Archetypes (ArchetypeData lookup), m_Prefabs (PrefabRef lookup), m_EmptySignatureBuildingCount (used to gate spawns), m_LastSpawnedCommercialFrame and m_CommandBuffer.
-
private struct TypeHandle
Holds read-only ComponentLookup instances for ArchetypeData, IndustrialProcessData and PrefabRef and exposes __AssignHandles to initialize them from SystemState.
Usage Example
// The system is created/managed by the game's world; you can access it and inspect its state.
// Example: query whether the system would attempt to spawn on the next eligible update.
var spawnSystem = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged<Game.Simulation.CommercialSpawnSystem>();
var simSystem = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged<SimulationSystem>();
// Rough logic equivalent of the checks performed in OnUpdate:
bool timeSlot = (simSystem.frameIndex / 16) % 8 == 1;
var demandSystem = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged<CommercialDemandSystem>();
bool hasDemand = demandSystem.companyDemand > 0;
if (timeSlot && hasDemand)
{
// The system will schedule a Burst IJob (SpawnCompanyJob) that:
// - reads company prefabs and existing property-less companies,
// - evaluates resource demands and spawn intervals,
// - creates new commercial company entities (PrefabRef + appropriate archetype)
// via an EndFrameBarrier EntityCommandBuffer for safe entity creation.
}
Notes and implementation details: - Spawning is rate-limited per resource using m_LastSpawnedCommercialFrame and values from DemandParameterData (m_FrameIntervalForSpawning). - The system uses a random selection among candidate company prefabs whose IndustrialProcessData outputs include the resource being targeted. - New entities are created via archetype (ArchetypeData.m_Archetype) and assigned a PrefabRef to the chosen prefab. - The SpawnCompanyJob is Burst-compiled and scheduled with combined dependencies; the EndFrameBarrier is used to play back entity creation safely at the end of the frame.