Skip to content

Game.EventJournalSystem

Assembly: Assembly-CSharp.dll
Namespace: Game.Events

Type: class

Base: GameSystemBase, IEventJournalSystem

Summary:
EventJournalSystem is an ECS-managed system responsible for tracking in-game "event journals" (ongoing/pending/completed world events) in Cities: Skylines 2. It monitors newly started journals, removed/deleted event entities, per-journal city-effect tracking and ad-hoc event data changes. The system uses multiple Burst-compiled IJobChunk jobs to efficiently process large numbers of journal entities: StartedEventsJob, DeletedEventsJob, TrackCityEffectsJob, TrackDataJob and CheckJournalTrackingEndJob. It exposes a persistent NativeList (eventJournal) representing active journal entities, and provides callbacks for when journal data or entries change.


Fields

  • private EntityQuery m_StartedJournalQuery
    Tracks journal entities that have EventJournalEntry and are either Created or pending (EventJournalPending). Used to find newly started journals to initialize and enqueue.

  • private EntityQuery m_DeletedEventQuery
    Query for JournalEvent entities that have been Deleted — used to clear references in journals when events are removed.

  • private EntityQuery m_JournalDataEventQuery
    Query for AddEventJournalData components (events that add tracked data to journals). Used by TrackDataJob.

  • private EntityQuery m_ActiveJournalEffectQuery
    Query for EventJournalCityEffect buffers on active journals (excludes pending/completed). Used to check and update tracked city-effect values.

  • private EntityQuery m_JournalEventPrefabQuery
    Query for EventPrefab + PrefabData to enumerate available event prefabs (used by the eventPrefabs property).

  • private EntityQuery m_LoadedJournalQuery
    Query for EventJournalEntry components on loaded journals (used on load to rebuild sorted eventJournal list).

  • private ISimulationSystem m_SimulationSystem
    Cached reference to the Simulation system (used for frameIndex when starting events).

  • private IBudgetSystem m_BudgetSystem
    Cached reference to the Budget system (used to compute some city-effect values).

  • private ICityServiceBudgetSystem m_CityServiceBudgetSystem
    Cached reference to the City Service Budget system (used to compute city-effect values).

  • private CitySystem m_CitySystem
    Cached CitySystem reference (used to read Population/Tourism components on the city entity).

  • private ModificationBarrier5 m_ModificationBarrier
    Barrier used to create an EntityCommandBuffer.ParallelWriter for structural changes performed by jobs.

  • private NativeQueue<Entity> m_Started
    Queue used by StartedEventsJob to enqueue entities that have started so the main system can add them to eventJournal on the main thread.

  • private NativeQueue<Entity> m_Changed
    Queue used by jobs (TrackCityEffectsJob, TrackDataJob, etc.) to record journal entities whose data changed and notify listeners on the main thread.

  • private NativeArray<int> m_CityEffects
    Array used to hold snapshot values for city-wide properties (happiness, tax income, trade worth, tourists, etc.) that are applied to EventJournalCityEffect entries when journals start or are tracked.

  • private TypeHandle __TypeHandle
    Internal structure holding cached Entity/Component/Buffer type handles and lookups for job scheduling (assigned in OnCreateForCompiler).

Properties

  • public NativeList<Entity> eventJournal { get; private set; }
    A persistent NativeList of journal entities maintained in start-order (sorted by start frame on load). Represents active/loaded event journals that UI or other systems can iterate.

  • public Action<Entity> eventEventDataChanged { get; set; }
    Callback invoked when a journal's tracked data or city-effect values change. The callback receives the journal entity whose data changed.

  • public Action eventEntryAdded { get; set; }
    Callback invoked when a new journal entry is added (i.e., when a journal is started and moved into the eventJournal list).

  • public IEnumerable<JournalEventComponent> eventPrefabs { get; }
    Enumerable that yields JournalEventComponent instances from the EventPrefab prefabs available in the world (uses PrefabSystem and m_JournalEventPrefabQuery).

Constructors

  • public EventJournalSystem()
    Default constructor (system is registered and created by the world). The heavy initialization is performed in OnCreate.

Methods

  • protected override void OnCreate()
    Initializes all EntityQuery instances, resolves and caches system references (SimulationSystem, CitySystem, BudgetSystem, CityServiceBudgetSystem), creates the modification barrier and allocates persistent native containers (eventJournal NativeList, m_Started/m_Changed NativeQueues, m_CityEffects NativeArray). Marked with [Preserve] in the original to avoid stripping.

  • protected override void OnGameLoaded(Context serializationContext)
    Called when a saved game is loaded. Clears existing lists and rebuilds eventJournal sorted by start-frame (EventJournalEntry.m_StartFrame) so the UI shows events in chronological order.

  • protected override void OnDestroy()
    Disposes persistent native containers allocated in OnCreate (eventJournal, m_Changed, m_Started, m_CityEffects).

  • protected override void OnUpdate()
    Main per-frame logic that:

  • Dequeues m_Started and appends entities to eventJournal (invokes eventEntryAdded if any).
  • Dequeues m_Changed and invokes eventEventDataChanged for each changed journal.
  • Updates m_CityEffects from city systems (population/tourism/budgets) if relevant queries are non-empty.
  • Schedules Burst IJobChunk jobs conditionally:
    • StartedEventsJob: initializes started journals, sets start frame, removes pending tag, enqueues started entities (uses m_Started and modification barrier).
    • DeletedEventsJob: clears references to deleted JournalEvent entities in EventJournalEntry and marks journals completed if needed.
    • CheckJournalTrackingEndJob: checks special cases (e.g., fire) to mark journal tracking completed when conditions are met.
    • TrackCityEffectsJob: compares buffer of EventJournalCityEffect values to current city snapshot and enqueues changed journals.
    • TrackDataJob: processes AddEventJournalData components to add tracked counts to EventJournalData buffers and enqueue changes.
  • Adds job handles to the modification barrier where structural changes are made.

  • public EventJournalEntry GetInfo(Entity journalEntity)
    Returns EventJournalEntry component data for the given journal entity (reads from EntityManager).

  • public Entity GetPrefab(Entity journalEntity)
    Returns the prefab Entity referenced by the journal's PrefabRef component (m_Prefab).

  • public bool TryGetData(Entity journalEntity, out DynamicBuffer<EventJournalData> data)
    Attempts to get the EventJournalData dynamic buffer for the journal entity; returns true if present (buffer returned as read-only).

  • public bool TryGetCityEffects(Entity journalEntity, out DynamicBuffer<EventJournalCityEffect> data)
    Attempts to get the EventJournalCityEffect dynamic buffer for the journal entity; returns true if present (buffer returned as read-only).

  • protected override void OnCreateForCompiler()
    Internal initialization used by the generated code path to assign handles; calls __AssignQueries and assigns TypeHandle handles.

  • private void __AssignQueries(ref SystemState state)
    Internal helper used at compile-time in generated code (no-op in this handwritten listing; included for completeness).

Nested Job structs (Burst-compiled, IJobChunk): - StartedEventsJob
Initializes EventJournalCityEffect start values from m_CityEffects, removes EventJournalPending for entries ready to start and sets EventJournalEntry.m_StartFrame, then enqueues the started entity to m_Started. Uses ModificationBarrier command buffer for structural changes.

  • DeletedEventsJob
    For JournalEvent entities that were deleted, clears the Event reference inside the corresponding EventJournalEntry and adds EventJournalCompleted if the journal is not already completed.

  • TrackCityEffectsJob
    Iterates EventJournalCityEffect buffers for active journals and updates stored runtime values (m_Value) from the snapshot m_CityEffects; enqueues changed journals to m_Changes.

  • TrackDataJob
    Processes AddEventJournalData components (one-shot events that add tracked counts) by locating the associated journal entity (via JournalEvent lookup) and incrementing the appropriate EventJournalData entries. Enqueues changed journals.

  • CheckJournalTrackingEndJob
    Performs domain-specific checks (e.g., for Fire events) to determine whether a journal's tracked target elements have all finished (no OnFire), and marks journal completed via command buffer when done.


Usage Example

// Example: subscribing to journal notifications and reading journal info
[Preserve]
public class MyModSystem : GameSystemBase
{
    private EventJournalSystem _journalSystem;

    protected override void OnCreate()
    {
        base.OnCreate();
        _journalSystem = World.GetExistingSystemManaged<EventJournalSystem>();
        if (_journalSystem != null)
        {
            _journalSystem.eventEntryAdded += OnEventEntryAdded;
            _journalSystem.eventEventDataChanged += OnEventDataChanged;
        }
    }

    private void OnEventEntryAdded()
    {
        // Iterate the current event journal list
        foreach (var journalEntity in _journalSystem.eventJournal)
        {
            var info = _journalSystem.GetInfo(journalEntity);
            UnityEngine.Debug.Log($"Journal started: prefab={_journalSystem.GetPrefab(journalEntity)} startFrame={info.m_StartFrame}");
        }
    }

    private void OnEventDataChanged(Entity journalEntity)
    {
        UnityEngine.Debug.Log($"Data changed for journal: {journalEntity}");
        if (_journalSystem.TryGetData(journalEntity, out var data))
        {
            foreach (var d in data)
                UnityEngine.Debug.Log($"  Data type {d.m_Type}: {d.m_Value}");
        }
    }
}

Note: This system is tightly integrated with the game's ECS and other systems (SimulationSystem, CitySystem, Budget systems) and uses Burst-compiled jobs with EntityCommandBuffer for structural changes. Access to World/EntityManager and safe use of Native containers must follow Unity's ECS/job safety rules when used from mod code.