4.2 KiB
Legacy Event System
This document summarizes how the legacy event system executes scenario- and
turn-based events, and how static event hooks are wired into commands. Primary
references include legacy/hwe/sammo/TurnExecutionHelper.php,
legacy/hwe/sammo/Event/*, and legacy/hwe/sammo/StaticEventHandler.php.
Entry Points
TurnExecutionHelper::runEventHandler(EventTarget $eventTarget)- Loads
eventtable rows by target and priority, evaluates conditions, and runs actions.
- Loads
StaticEventHandler::handleEvent(...)- Invoked by many commands and API handlers to run per-action static hooks.
Event Table Schema
event rows are stored in the legacy DB schema (legacy/hwe/sql/schema.sql):
id: auto-increment primary keytarget: enum ofPRE_MONTH,MONTH,OCCUPY_CITY,DESTROY_NATION,UNITEDpriority: higher first (default 1000)condition: JSON array (condition DSL)action: JSON array (action DSL)
Indexes: (target, priority, id) for dispatch ordering. Both condition and
action are JSON-validated by DB constraints.
Event Table Dispatch
runEventHandler() drives the dynamic event pipeline:
- Query
eventrows withtarget = {PRE_MONTH|MONTH|OCCUPY_CITY|DESTROY_NATION|UNITED}(ordered bypriority DESC, id ASC). - Decode
conditionandactionJSON. - Build a
Event\EventHandlerwith condition + action lists. - Execute
tryRunEvent($env)where$envisgame_envKV storage pluscurrentEventID.
Events are used inside the monthly pipeline and in special moments like
city occupation (EventTarget::OCCUPY_CITY, called by some commands).
Condition and Action DSL
Event\Condition::build() and Event\Action::build() decode JSON arrays into
class instances:
-
Condition
- Supports logic combinators (
and,or,xor,not) viaEvent\Condition\Logic. - Built-in condition types include:
Date,DateRelative,IntervalRemainNationConstBool
- Conditions return
{ value, chain }for tracing.
- Supports logic combinators (
-
Action
- Actions are classes under
Event/Action/withrun(array $env). - The dispatcher instantiates them from
actionarrays like['ProcessIncome', 'gold'].
- Actions are classes under
Common Event Actions (Examples)
These are the action modules observed in the legacy tree:
- Economy & upkeep:
ProcessIncome,ProcessSemiAnnual,ProcessWarIncome - World state:
UpdateCitySupply,UpdateNationLevel,RandomizeCityTradeRate - NPC/Invader flow:
RaiseInvader,RaiseNPCNation,ProvideNPCTroopLeader - Betting & unique items:
OpenNationBetting,FinishNationBetting,LostUniqueItem,MergeInheritPointRank - Event lifecycle:
DeleteEvent,NoticeToHistoryLog
All action execution uses the event environment (year, month, startyear,
turnterm, etc.) coming from game_env.
Static Events (Command Hooks)
Static events are hooks triggered directly by commands/APIs:
StaticEventHandler::handleEvent()looks up handler names fromGameConst::$staticEventHandlers[$eventType].- Handlers live under
legacy/hwe/sammo/StaticEvent/and implementBaseStaticEvent::run(). - These hooks are used to extend command behavior without modifying the command code itself (e.g., troop join/exit side effects).
Static Handler Map Sources
GameConst::$staticEventHandlers defaults to an empty array in
legacy/hwe/sammo/GameConstBase.php. Scenario JSON can override it:
legacy/hwe/scenario/scenario_911.json(only observed override in repo)sammo\\API\\Troop\\JoinTroop→event_부대탑승즉시이동sammo\\Command\\Nation\\che_발령→event_부대발령즉시집합
Static handler names should map to classes in legacy/hwe/sammo/StaticEvent/
(class name matches handler key).
RNG Notes
Dynamic event actions can use deterministic RNG by constructing
LiteHashDRBG with UniqueConst::$hiddenSeed and an event-specific tag.
Examples include RandomizeCityTradeRate and UpdateNationLevel.
Open Questions / Follow-ups
Event\Engineis a stub with a TODO; it is not currently used in the main turn pipeline.- Verify whether any runtime code injects additional static handlers beyond scenario JSON overrides.