Skip to content

Game.Simulation.CreatureSpawnSystem

Assembly:
Namespace: Game.Simulation

Type: class

Base: GameSystemBase

Summary:
CreatureSpawnSystem is an ECS System responsible for grouping creature spawn sources (TripSource), selecting which creatures should be spawned/activated during the simulation step, and removing the TripSource component from creature entities when they are processed. The system runs on a fixed interval (16 ticks) and uses Burst-compiled jobs and an EndFrameBarrier command buffer to perform removals safely and efficiently at the end of the frame. It also updates timers on TripSource components and removes related references (Patient, Occupant) for resident creatures when the TripSource is removed.


Fields

  • private EndFrameBarrier m_EndFrameBarrier
    Used to create an EntityCommandBuffer. EndFrameBarrier is obtained during OnCreate and used to schedule component removals (RemoveComponent) via a parallel command buffer so changes are applied safely at end of frame.

  • private EntityQuery m_CreatureQuery
    Query that matches entities with TripSource (read/write) and Creature (read-only), excluding Deleted and Temp. This is the primary query used to find creatures that may spawn.

  • private ComponentTypeSet m_TripSourceRemoveTypes
    Declared but unused in the provided code. Likely intended to express a set of component types to remove when processing spawn, but not referenced in the current implementation.

  • private TypeHandle __TypeHandle
    Generated struct holding EntityTypeHandle, ComponentTypeHandle and Buffer/ComponentLookup handles used by the jobs. __AssignHandles fills these handles from the SystemState.

  • (Nested) private struct SpawnData
    Holds a spawn entry for an individual creature candidate: the source entity, the creature entity, and a priority (m_Priority). Implements IComparable to sort spawn entries primarily by source entity (stable grouping) and then by priority.

  • (Nested) private struct SpawnRange
    Describes a range [m_Start, m_End) within the sorted SpawnData list that corresponds to a single source entity. Used to batch processing per source.

  • (Nested) private struct GroupSpawnSourcesJob : IJob
    Burst-compiled job that iterates creature chunks, collects SpawnData for TripSource entries whose timer <= 0, decrements timers by 16, sorts spawn data and emits spawn groups (SpawnRange) so creatures from the same source are processed together.

  • (Nested) private struct TrySpawnCreaturesJob : IJobParallelForDefer
    Burst-compiled parallel job that receives the grouped spawn ranges and, for each group, removes the TripSource component from each creature in the group via an EntityCommandBuffer. If the creature has a Resident component, it also removes corresponding Patient/Occupant buffer entries for that resident's citizen id (using CollectionUtils.RemoveValue). Uses ComponentLookup and BufferLookup to access Resident, Patient and Occupant data.

  • (Nested) private struct TypeHandle
    Container for entity/component handles and a helper method __AssignHandles(ref SystemState) to obtain handles from the SystemState. Used to prepare handles for scheduling jobs.

Properties

  • This system exposes no public properties. All data and scheduling are internal to the system implementation.

Constructors

  • public CreatureSpawnSystem()
    Default, parameterless constructor. Marked with [Preserve] in the source (attribute applied to OnCreate/OnUpdate but constructor is present without special logic).

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns 16 — the system updates every 16 simulation ticks. This controls how frequently spawn processing is run.

  • [Preserve] protected override void OnCreate()
    Initializes the system: retrieves/creates the EndFrameBarrier and builds the creature query:

  • m_EndFrameBarrier = base.World.GetOrCreateSystemManaged();
  • m_CreatureQuery = GetEntityQuery(ComponentType.ReadWrite(), ComponentType.ReadOnly(), ComponentType.Exclude(), ComponentType.Exclude());
  • Calls RequireForUpdate(m_CreatureQuery) so the system only runs when there are matching entities.

  • [Preserve] protected override void OnUpdate()
    Main scheduling method. High-level steps:

  • Allocate two NativeList containers (SpawnData list and SpawnRange list) with Allocator.TempJob.
  • Build and schedule a GroupSpawnSourcesJob that:
    • Iterates creature archetype chunks from m_CreatureQuery (retrieved asynchronously).
    • For every TripSource whose timer <= 0, captures a SpawnData entry with source, creature entity and priority.
    • Decrements the TripSource.m_Timer by 16 for each entry.
    • Sorts spawn data and produces ranges (SpawnRange) grouping entries by source entity into the spawn groups list.
  • Schedule a TrySpawnCreaturesJob as a deferred parallel-for over the spawn groups list that:
    • For each spawn group (corresponding to a single source), removes TripSource from listed creature entities using the EndFrameBarrier command buffer parallel writer.
    • If a creature has a Resident component, remove corresponding Patient and Occupant buffer entries that reference the resident's citizen id.
  • Dispose the native lists (spawnData and nativeList) with dependencies on the scheduled job.
  • Add the job handle to the EndFrameBarrier as a producer and set base.Dependency to the job handle.

Important details: - GroupSpawnSourcesJob produces spawnData and spawnGroups lists; TrySpawnCreaturesJob consumes them via AsDeferredJobArray and is scheduled with a deferred parallel-for using those lists as the schedule list. - The command buffer used for component removals is created from m_EndFrameBarrier and used as a ParallelWriter. - All jobs are Burst-compiled and use Unity.Collections primitives; no managed objects are accessed inside them.

  • private void __AssignQueries(ref SystemState state)
    Generated helper called from OnCreateForCompiler. In this implementation it only constructs (and disposes) an EntityQueryBuilder; the real query handles are assigned in OnCreate and TypeHandle.__AssignHandles is used to grab per-job handles.

  • protected override void OnCreateForCompiler()
    Compiler helper that calls __AssignQueries and __TypeHandle.__AssignHandles to ensure handles are initialized for compiled scenarios.

  • (Nested) SpawnData.CompareTo(SpawnData other)
    Comparison implementation used by sorting. Compares by source entity index first (ensures grouping by source), then by priority (m_Priority) to define ordering inside groups.

  • (Nested) GroupSpawnSourcesJob.Execute()
    Collects spawn candidates, decrements timers, sorts spawn data, and produces spawn ranges grouping by source.

  • (Nested) TrySpawnCreaturesJob.Execute(int index)
    For each spawn group index:

  • Retrieves the source entity for that group and any Patient/Occupant buffers attached to the source.
  • Iterates creatures in that range, removes TripSource component from each creature entity via the parallel command buffer.
  • If creature is a Resident, removes Patient/Occupant entries referencing that resident from the source buffers (if present) using CollectionUtils.RemoveValue.

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    // Typical initialization performed by this system:
    m_EndFrameBarrier = base.World.GetOrCreateSystemManaged<EndFrameBarrier>();
    m_CreatureQuery = GetEntityQuery(
        ComponentType.ReadWrite<TripSource>(),
        ComponentType.ReadOnly<Creature>(),
        ComponentType.Exclude<Deleted>(),
        ComponentType.Exclude<Temp>()
    );
    RequireForUpdate(m_CreatureQuery);
}

Additional notes for modders: - If you need to change spawn timing or priority, adjust TripSource.m_Timer or TripSource fields prior to this system running (e.g., other systems that modify TripSource should run earlier than this system's update window). - To prevent a creature from spawning, ensure TripSource is removed before this system runs; otherwise the system will remove TripSource when it processes that creature. - The system uses Burst jobs and native containers — avoid using managed types or calling managed APIs inside the jobs. Modifications that require managed logic should be done outside the Burst-compiled jobs or via command buffers scheduled appropriately. - When adding additional data to be updated/cleared when a spawn occurs, follow the pattern in TrySpawnCreaturesJob: use ComponentLookup (ComponentLookup is read-only by default unless obtained writable) and BufferLookup for buffers and make edits through the EntityCommandBuffer or by scheduling follow-up jobs that run after the command buffer has applied changes.