Skip to content

Game.Creatures.GroupSystem

Assembly: Game (assembly containing game runtime systems)
Namespace: Game.Creatures

Type: class

Base: GameSystemBase

Summary: GroupSystem is an ECS system that assembles "groups" of creatures (humans, pets, wildlife, domesticated animals) based on trip activity, household relationships and existing group membership. It reads ResetTrip, TripSource, Target, household and ownership buffers to build a queue of candidate groupings, then composes final groups on the main thread using a command buffer from a ModificationBarrier. The system: - detects creatures that need group re-evaluation (ResetTrip or Updated/Deleted), - finds partners from households, current transports and owned-creature buffers, - composes groups and picks a group leader based on heuristics (humans preferred, Resident.PreferredLeader flag and car-keeper priority), - updates GroupMember and GroupCreature components and clears/obsoletes PathOwner/PathElement data when group membership changes.


Fields

  • private ModificationBarrier5 m_ModificationBarrier Used to get an EntityCommandBuffer for structural changes (adding/removing components and buffers) that must be executed safely after jobs. The system stores this barrier and uses it to create a command buffer passed to the GroupCreaturesJob.

  • private EntityQuery m_CreatureQuery EntityQuery used to select Creature entities relevant for grouping. The query requires Creature and ResetTrip components (and matches Updated/Deleted via Any) while excluding Temp. The query is used for scheduling the jobs.

  • private TypeHandle __TypeHandle A generated helper that caches ComponentTypeHandle/EntityTypeHandle/ComponentLookup/BufferLookup and provides an __AssignHandles method to initialize them from a SystemState. This is used to build job data with the correct handles/lookups.

(Additionally, the type defines a small private GroupData struct and several nested job structs: ResetTripSetJob, FillGroupQueueJob, GroupCreaturesJob, and the TypeHandle nested struct. Those are not instance fields but internal types used by the system.)

Properties

  • None (no public properties exposed by GroupSystem)

Constructors

  • public GroupSystem() Default constructor (marked [Preserve] on lifecycle methods in source). The system itself has no special construction logic outside OnCreate.

Methods

  • protected override void OnCreate() : System.Void Initializes the system at creation. It acquires/creates the ModificationBarrier5 system from the World, prepares the entity query used by the system (m_CreatureQuery) and calls RequireForUpdate to ensure the system runs only when relevant entities exist.

  • protected override void OnUpdate() : System.Void Main update method. It:

  • allocates a NativeParallelHashSet (resetTripSet) and a NativeQueue (groupQueue) in TempJob memory,
  • constructs job data for ResetTripSetJob (collects ResetTrip creatures into the set) and FillGroupQueueJob (fills groupQueue with candidate pairings),
  • schedules ResetTripSetJob and FillGroupQueueJob (IJobChunk parallel scheduling) and then schedules GroupCreaturesJob (IJob) to run after those jobs complete,
  • disposes the native collections with dependency on the final job,
  • registers the final job handle with the modification barrier and assigns the dependency to base.Dependency.

  • protected override void OnCreateForCompiler() : System.Void Called by generated code paths; runs __AssignQueries and assigns type handles via the TypeHandle.__AssignHandles method. This is part of the codegen/compile-time support to prepare handles for job usage.

  • private void __AssignQueries(ref SystemState state) : System.Void Helper used by compiled code generation; the implementation in this class is essentially a placeholder that constructs (and disposes) an EntityQueryBuilder. It exists to satisfy the codegen pattern.

  • Nested job types and responsibilities:

  • ResetTripSetJob : IJobChunk Gathers all ResetTrip components from chunks and adds the referenced creature entities to the NativeParallelHashSet (m_ResetTripSet). This identifies creatures whose trips were reset and that must be considered specially (excluded or re-evaluated).
  • FillGroupQueueJob : IJobChunk Walks entities/chunks to find potential group pairings. It:
    • Handles ResetTrip entries, skipping deleted entities and collecting group leader/member checks,
    • When processing chunks (TripSource + Target present), checks Residents, Pets, Wildlife and Domesticated to find household/ownership/transport partners,
    • Enqueues GroupData entries into m_GroupQueue for later group composition,
    • Uses many ComponentLookup and BufferLookup objects to inspect households, owned-creature buffers, current transport relationships and existing group membership/creatures.
  • GroupCreaturesJob : IJob Dequeues GroupData items and composes final groups using an on-job GroupBuilder temporary structure. For each composed group it:

    • If a single-member group, removes any existing GroupMember or GroupCreature buffers for that entity,
    • If multiple members, picks a best leader via FindBestLeader and:
      • removes GroupMember from the leader (if present) and ensures leader has GroupCreature buffer, cleared and re-populated,
      • for other members, removes their GroupCreature buffers and adds/updates GroupMember pointing to the chosen leader,
      • clears/obsoletes PathOwner and PathElement buffers for members where needed,
    • Uses EntityCommandBuffer (from m_ModificationBarrier) for structural changes and direct ComponentLookup writes for some component updates.
  • Helper methods inside jobs (high level):

  • AddExistingGroupMembers: adds current group relationships into the group builder for merging with queued candidates.
  • ComposeGroup: given a collected group, either disbands singletons or selects leader and assigns membership.
  • RemoveGroupMember / RemoveGroupCreatures / AddGroupMember / AddGroupCreatures: helper routines to add/remove components and buffers, and to reset path-related state when membership changes.
  • FindBestLeader: chooses the leader entity from a candidate group using a heuristic that favors humans (+10), Resident.PreferredLeader (+2) and car-keepers (+1).

Usage Example

// The system is a GameSystemBase-derived system and is created/managed by the game's World.
// Typical behavior (excerpt from OnCreate/OnUpdate) — you don't normally instantiate the system yourself:

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    // Acquire the modification barrier so we can create a command buffer for structural changes.
    m_ModificationBarrier = base.World.GetOrCreateSystemManaged<ModificationBarrier5>();

    // Build the query that drives when this system updates.
    m_CreatureQuery = GetEntityQuery(new EntityQueryDesc
    {
        All = new ComponentType[] { ComponentType.ReadOnly<Creature>() },
        Any = new ComponentType[] { ComponentType.ReadOnly<Updated>(), ComponentType.ReadOnly<Deleted>() },
        None = new ComponentType[] { ComponentType.ReadOnly<Temp>() }
    }, new EntityQueryDesc
    {
        All = new ComponentType[] { ComponentType.ReadOnly<ResetTrip>() }
    });

    RequireForUpdate(m_CreatureQuery);
}

// OnUpdate schedules the ResetTripSetJob and FillGroupQueueJob (IJobChunk) and then runs GroupCreaturesJob (IJob)
// to compose groups and perform structural changes using a command buffer from m_ModificationBarrier.

Notes and modding tips: - If you want to influence group leader selection or grouping behavior, consider patching FindBestLeader heuristics or intercepting before GroupCreaturesJob performs structural changes (e.g., with another system that runs earlier and modifies Resident/Human/CarKeeper flags or GroupMember/GroupCreature buffers). - Be careful when modifying component types used by this system (Resident, TripSource, Target, CurrentTransport, OwnedCreature, Household buffers) — changing layout or semantics can change grouping results and might require updating the TypeHandle assignments. - The system uses temporary native collections (NativeParallelHashSet and NativeQueue) and schedules jobs in parallel; ensure any injected code respects thread-safety and read/write access patterns.