EventManager

Overview

Central orchestrator for event selection and dispatch. Loads standard, chained, and dated events from Resources/ folders, keeps a static registry of Regions, and opens the UI when an event is picked. Supports peeking the next event, forcing an event for a region, and certainty-weighted selection.

Serialized References

  • UI: EventPanelUI panelUI
  • Atoms: FloatVariable personalityMobster, FloatVariable personalityScheming, FloatVariable personalitySubterfuge, FloatVariable eventCertainty
  • Events: VoidEvent longTickEvent, VoidEvent rerollEvent, RegionEvent forceEvent, ChairmanEventEvent openEventCanvas, ChainedEventInfoEvent chainEventPooled

Static Data

  • static List<ChairmanEvent> events
  • static List<Region> regions
  • static string eventDataPath = "Events\", chainEventDataPath = "ChainedEvents\", datedEventDataPath = "DatedEvents\"

Runtime State

  • bool storeNextEvent — when true, the next selected event is stored instead of shown
  • ChairmanEvent storedEvent — last stored event (for preview UI)
  • ChairmanEvent lastEvent — to avoid immediate repeats
  • Pools: List<ChainedEventInfo>, List<DatedChairmanEvent>, List<ChairmanChainEvent>

Lifecycle

  • Awake(): LoadEvents(), clear storedEvent, register handlers for longTickEvent/rerollEventProcessEvents, forceEventForceEvent, chainEventPooledPoolChainedEvent.
  • OnDestroy(): unregister.
  • Tick(): ProcessDatedEvents() each frame/tick.

Public API

  • List<Region> GetRegions(), List<ChairmanEvent> GetEvents()
  • static int GetEventIndex(ChairmanEvent e) — index within events (for localization keys)
  • ChairmanEvent FindChainEvent(string title)
  • void ProcessEvents() — main selection pipeline
  • void ForceEvent(Region targetRegion) — pick and open an event for the given region
  • void RegisterRegion(Region r), void UnregisterRegion(Region r) (static)

Selection Pipeline (ProcessEvents)

  1. Stored event path: if storedEvent!=null, raise openEventCanvas with it and clear stored unless storeNextEvent remains true.
  2. Chained events: ProcessChainedEvents() may fire one immediately (probabilistic pool).
  3. Pick a region: SelectRandomValidRegion() among those with Presence and Control < 1.
  4. Filter candidates:
    • Remove lastEvent (no instant repeats).
    • By infrastructure: drop events whose RequiresLab/Route is unmet (RegionLab and RouteCount>0).
    • By nature: weighted by region severities × personality atoms.
    • By severity: threshold against the target’s Police/Cartel/average severity.
    • By effect validity: panelUI.ValidateButton must pass for response 0 and 1.
  5. Select one: SelectWeightedRandomEvent() using eventCertainty:
    • If eventCertainty >= 1: choose events at the maximum minSeverity per nature.
    • Else: compute weights w = exp(-alpha * (severity - minSeverity)) with alpha = c/(1-c), sample by cumulative weight.
  6. Dispatch: set TargetRegion, update lastEvent, and either store it (if peeking) or raise openEventCanvas.

Chained & Dated

  • ProcessChainedEvents(): rolls poolChance against pooled entries; looks up by title and raises immediately (honors storeNextEvent). Pool entry is removed on fire.
  • ProcessDatedEvents(): when triggerDate == GameDateDisplay.CurrentDate and chance passes, finds the target region by name and raises the dated event.

Loading

  • Reads JSON TextAssets from Resources/Events, Resources/ChainedEvents, and Resources/DatedEvents. ChairmanChainEvent with chainStart=true goes into the main events list; others into a separate chained list.

Notes

  • The personality filter method exists but is disabled by default in the pipeline.
  • BaseLocID used by ChairmanEvent depends on the order of events at runtime—keep resource load order stable for localization.