Skip to content

Game.PartnerSystem

Assembly: Assembly-CSharp
Namespace: Game.Simulation

Type: class

Base: GameSystemBase, IPostDeserialize

Summary:
PartnerSystem is a compiler-generated ECS system responsible for matching citizens who are looking for partners. It scans a singleton buffer of LookingForPartner entries, finds compatible pairs according to partner preferences (Any/Same/Other), merges their households (transferring resources, citizens and pets), clears the "looking" flags on matched citizens, and enqueues trigger actions (TriggerType.CitizenPartneredUp). Matching work is performed in a Burst-compiled IJob (MatchJob). The system coordinates with EndFrameBarrier to produce entity commands and with TriggerSystem to record trigger actions. It also ensures a singleton buffer entity for LookingForPartner exists after deserialization.


Fields

  • public static readonly int kUpdatesPerDay
    This constant determines how often the system updates per in-game day (value: 4). It is used to compute the system's update interval in GetUpdateInterval.

  • private EndFrameBarrier m_EndFrameBarrier
    Reference to the EndFrameBarrier system used to produce an EntityCommandBuffer for structural changes (e.g., adding household buffers when merging households). Job producer handle is registered with this barrier.

  • private EntityQuery m_PartnerQuery
    An EntityQuery used to find the singleton entity that holds the LookingForPartner buffer (the list of citizens currently looking for partners).

  • private TriggerSystem m_TriggerSystem
    Reference to the TriggerSystem used to obtain an action buffer for enqueuing TriggerAction events when citizens get partnered up.

  • private TypeHandle __TypeHandle
    Holds BufferLookup and ComponentLookup handles (generated helpers) used by the system to access various component and buffer types inside the job (e.g., LookingForPartner buffer, Citizen component, Household buffers, Resources buffer). These are assigned in OnCreateForCompiler.

Properties

  • None (this type does not expose public properties).
    All component and buffer access used by the scheduled job is passed explicitly via the MatchJob struct and the generated TypeHandle.

Constructors

  • public PartnerSystem()
    Default (compiler-generated) constructor. The system initializes state in OnCreate and OnCreateForCompiler; no explicit runtime construction logic is present in the constructor itself.

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns the system update interval in ticks. Implementation: returns 262144 / (kUpdatesPerDay * 16). Controls how frequently the system runs relative to simulation updates.

  • [Preserve] protected override void OnCreate()
    Initializes the system references: obtains TriggerSystem and EndFrameBarrier from the world and creates an EntityQuery for LookingForPartner (m_PartnerQuery). This sets up the system to find the singleton partner buffer entity at runtime.

  • public void PostDeserialize(Context context)
    Implements IPostDeserialize. After loading, ensures the singleton entity holding the LookingForPartner buffer exists. If the partner query is empty, it creates an entity with a LookingForPartner buffer so the system has a place to store entries.

  • [Preserve] protected override void OnUpdate()
    Constructs and schedules the Burst-compiled MatchJob. The job is given:

  • m_PartnerEntity (the singleton buffer entity)
  • BufferLookup/ComponentLookup handles from __TypeHandle (via InternalCompilerInterface)
  • an EntityCommandBuffer from m_EndFrameBarrier for structural changes
  • a NativeQueue from m_TriggerSystem for triggers

The job is scheduled (IJob) and its handle is registered with EndFrameBarrier and TriggerSystem to maintain correct dependencies.

  • private void __AssignQueries(ref SystemState state)
    Compiler helper called during compiler-time initialization (OnCreateForCompiler). Presently does no query initialization but is called to satisfy generated wiring.

  • protected override void OnCreateForCompiler()
    Called by generated code to bind queries and assign lookup handles. It calls __AssignQueries and __TypeHandle.__AssignHandles to set up the BufferLookup/ComponentLookup handles used in jobs.

Nested / job-related internals (summary):

  • private struct MatchJob : IJob (BurstCompile)
    This job performs the actual partner matching and merging. Major points:
  • Reads the DynamicBuffer from the singleton partner entity.
  • For each pair of entries, checks that both citizen entities exist and that their Citizen component flags (male/female) satisfy both entries' PartnerType preferences (Any, Same, Other).
  • When a match is found:
    • Calls MoveTogether to merge households: transfers resource totals, moves Resources buffer entries, moves HouseholdCitizen entries, updates HouseholdMember components, transfers HouseholdAnimal entries and updates HouseholdPet components, and clears the source household's citizen/animal buffers.
    • Clears PartnerType on both LookingForPartner entries and removes the LookingForPartner flag on both Citizen components (clears CitizenFlags.LookingForPartner).
    • Enqueues TriggerAction entries (TriggerType.CitizenPartneredUp) for both citizens (one per direction).
  • After attempting matches, it removes entries whose PartnerType is None or whose citizen no longer exists from the buffer (compacting the buffer).
  • MoveTogether uses the provided ComponentLookup and BufferLookup handles and the EntityCommandBuffer to add missing buffers when needed.

  • private struct TypeHandle
    Generated helper that stores BufferLookup and ComponentLookup fields for:

  • LookingForPartner buffer
  • Citizen component
  • HouseholdCitizen buffer
  • HouseholdAnimal buffer
  • Household component
  • HouseholdPet component
  • HouseholdMember component
  • Resources buffer

It provides __AssignHandles(ref SystemState) which obtains the lookups from the given SystemState; these are then converted to runtime-accessible lookups via InternalCompilerInterface in OnUpdate.

Notes: - Matching logic considers CitizenFlags.Male to determine sex and compares it to PartnerType (Any / Same / Other). - Household merging clamps combined resource totals to int range. - Structural changes (adding buffers, modifying components across households) are performed through an EntityCommandBuffer produced by EndFrameBarrier; job is Burst-compiled and scheduled as an IJob to run off the main thread, so all accesses are done via lookups and buffers passed into the job. - Trigger actions are enqueued in a NativeQueue via TriggerSystem and the system registers its job handle with both EndFrameBarrier and TriggerSystem to ensure proper synchronization.

Usage Example

// Example: register a citizen entity as looking for a partner by adding an entry
// to the singleton LookingForPartner buffer that PartnerSystem uses.

var world = /* obtain World reference, e.g., World.DefaultGameObjectInjectionWorld for DOTS setups */;

// Get the partner singleton entity (PartnerSystem creates one in PostDeserialize if needed)
var partnerQuery = world.EntityManager.CreateEntityQuery(ComponentType.ReadWrite<LookingForPartner>());
Entity partnerEntity = partnerQuery.GetSingletonEntity();

// Get the buffer and add an entry
var buffer = world.EntityManager.GetBuffer<LookingForPartner>(partnerEntity);
buffer.Add(new LookingForPartner {
    m_Citizen = citizenEntity,         // an Entity representing the citizen
    m_PartnerType = PartnerType.Any    // preference: Any / Same / Other
});

Notes for modders: - PartnerSystem runs at a reduced frequency determined by GetUpdateInterval; updates are not per-frame. - Because matching logic runs in a Burst job and uses command buffers, structural changes will be applied later via EndFrameBarrier—do not expect immediate EntityManager structural state changes inside the job. - To react to partner events, listen for TriggerType.CitizenPartneredUp via TriggerSystem.