Skip to content

Game.Simulation.FindEventAttendantsSystem

Assembly:
Game (Assembly-CSharp) — part of the game's simulation assemblies (managed code for Cities: Skylines 2).
Namespace:
Game.Simulation

Type:
class

Base:
GameSystemBase

Summary:
System that finds and processes attendees for calendar events. It runs on a fixed interval (16 frames), iterates households, decides which households will attend events (especially "couple" type events), enqueues attendance work and then processes that queue to create CoordinatedMeeting entities and optional journal data. Uses Unity DOTS ECS patterns (IJobChunk, IJob, NativeQueue, EntityCommandBuffer) and Burst where appropriate. Handles removal of FindingEventParticipants once an event has aged past a threshold.


Fields

  • private const uint UPDATE_INTERVAL = 16u
    System update interval in simulation frames. The system returns this value from GetUpdateInterval to run every 16 frames.

  • private SimulationSystem m_SimulationSystem
    Reference to the SimulationSystem used to read the current simulation frame index.

  • private EndFrameBarrier m_EndFrameBarrier
    Barrier system used to create an EntityCommandBuffer for producing entity changes (meetings, journal data) at end-of-frame.

  • private EntityQuery m_EventQuery
    Query selecting CalendarEvent entities that are currently finding participants (has CalendarEvent & FindingEventParticipants, excludes Deleted/Temp).

  • private EntityQuery m_HouseholdQuery
    Query selecting Households that can be considered for attendance (includes UpdateFrame and HouseholdCitizen buffers; excludes AttendingEvent and Deleted).

  • private NativeQueue<Attend> m_AttendQueue
    Concurrent queue used by the ConsiderAttendanceJob to enqueue Attend items for the AttendJob to consume.

  • private EntityArchetype m_MeetingArchetype
    Archetype used to create CoordinatedMeeting entities and associated buffers/components.

  • private EntityArchetype m_JournalDataArchetype
    Archetype used to create AddEventJournalData entities for event journaling.

  • private TypeHandle __TypeHandle
    Generated container holding the various Entity/Component/Buffer type handles used for job scheduling.

Properties

  • None (this system exposes no public properties).

Constructors

  • public FindEventAttendantsSystem()
    Default constructor (preserved). Initialization of the system is done in OnCreate.

Methods

  • public override int GetUpdateInterval(SystemUpdatePhase phase)
    Returns the update interval for the system. This system returns 16, meaning it runs every 16 simulation frames.

  • protected override void OnCreate()
    Initializes queries, allocates the NativeQueue, sets up archetypes and subsystem references (SimulationSystem, EndFrameBarrier). Calls RequireForUpdate(m_EventQuery) so the system only runs when there are relevant event entities.

  • protected override void OnDestroy()
    Disposes of the NativeQueue and performs cleanup.

  • protected override void OnUpdate()
    Main update flow: computes an update frame with interval, schedules ConsiderAttendanceJob (IJobChunk) to inspect households and enqueue attendance for eligible events, then schedules AttendJob (IJob) to consume the queue and create CoordinatedMeeting entities / journal data. Uses m_EndFrameBarrier.EntityCommandBuffer and adds job dependencies to the barrier.

  • protected override void OnCreateForCompiler()
    Compiler-time helper that assigns entity/component handles; used by generated code paths.

  • private void __AssignQueries(ref SystemState state)
    Generated helper for query assignment (stubbed/disposed in this compiled form).

Inner job types (summarized):

  • ConsiderAttendanceJob : IJobChunk
    Burst-compiled chunk job. Runs over household chunks on the configured update frame index. For each household chunk:
  • Builds a temporary list of calendar event entities that target couples (EventTargetType.Couple) and are eligible.
  • For each household in the chunk, counts adult vs child citizens and skips households that don't meet constraints.
  • Uses randomness and CalendarEventData.m_AffectedProbability to decide if the household attends an event. When attending:
    • Enqueues an Attend { m_Event, m_Participant } into the NativeQueue (AsParallelWriter).
    • Adds an AttendingEvent component to the household (via parallel EntityCommandBuffer).
  • Uses RandomSeed.Next() to create per-chunk Unity.Mathematics.Random.

  • AttendJob : IJob
    Burst-compiled single-threaded job that consumes the Attend NativeQueue:

  • For each dequeued Attend item:
    • Validates the event has a PrefabRef and that the prefab includes HaveCoordinatedMeetingData.
    • Creates a CoordinatedMeeting entity with PrefabRef and CoordinatedMeeting component (phase 0, status Waiting).
    • If the event's CalendarEventData.m_RandomTargetType == EventTargetType.Couple and the participant has a HouseholdCitizen buffer, adds household members to the event's TargetElement buffer and to the CoordinatedMeetingAttendee buffer on the new meeting entity.
    • Adds journal data (AddEventJournalData) if attendees were added.
  • After draining the queue, iterates the list of event entities and removes FindingEventParticipants for events that are older than 240 frames past their Duration.m_StartFrame.

Notes on Burst/ECS usage: - Both jobs are decorated as BurstCompile for performance. - ConsiderAttendanceJob is scheduled via JobChunkExtensions.ScheduleParallel to iterate households in parallel. - AttendJob runs as an IJob after the chunk job completes and uses a single-threaded EntityCommandBuffer to create meeting entities and buffers. - The system uses entity lookup/access utilities (ComponentLookup/BufferLookup/BufferTypeHandle/SharedComponentTypeHandle) via the generated __TypeHandle.

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    // Typical initialization inside the system (this system creates an attendee queue):
    m_AttendQueue = new NativeQueue<Attend>(Allocator.Persistent);

    // Set up queries and archetypes as needed (simplified):
    m_EventQuery = GetEntityQuery(ComponentType.ReadWrite<Game.Events.CalendarEvent>(),
                                  ComponentType.ReadWrite<FindingEventParticipants>(),
                                  ComponentType.Exclude<Deleted>(),
                                  ComponentType.Exclude<Temp>());

    m_MeetingArchetype = EntityManager.CreateArchetype(
        ComponentType.ReadWrite<CoordinatedMeeting>(),
        ComponentType.ReadWrite<CoordinatedMeetingAttendee>(),
        ComponentType.ReadWrite<PrefabRef>(),
        ComponentType.ReadWrite<Created>());
}

If you want, I can also produce a brief diagram of the job flow (ConsiderAttendanceJob -> NativeQueue -> AttendJob) or extract exact component definitions referenced by this system (e.g., CoordinatedMeeting, AttendingEvent, CalendarEventData) into additional documentation sections.