5.1 KiB
Legacy Scenario System
This document explains how scenarios are loaded and how they define the active
rule set, commands, and effects. Core references include
legacy/hwe/sammo/Scenario.php, legacy/hwe/sammo/ResetHelper.php, and
legacy/hwe/sammo/GameConstBase.php.
Scenario Loading Flow
- Server reset/init calls
ResetHelper::buildScenario(). Scenarioloadsscenario_{id}.jsonand merges defaults (default.json).Scenario::buildConf()generates runtime constants:d_setting/GameConst.phpfromGameConstBase + scenario.const/map/statd_setting/CityConst.phpfromscenario/map/{mapName}.phpd_setting/GameUnitConst.phpfromscenario/unit/{unitSet}.php
Scenario::build()inserts nations, generals, and events into DB and runsinitialEventsimmediately.
Scenario::getAllScenarios() is used for listing scenarios without fully
building them (lazy init).
Scenario JSON Structure (Observed)
Common top-level keys (see legacy/hwe/scenario/frame.json and actual
scenario_*.json files):
title,startYear,history,iconPathstat: default stat totals and boundsmap:mapName,unitSet,scenarioEffectconst: overrides forGameConst(commands, items, limits, etc.)nation,diplomacygeneral,general_ex,general_neutralevents,initialEventsignoreDefaultEvents(skipGameConst::$defaultInitialEvents/$defaultEvents)
Notes:
- A few files still use
initialActionsordefaultInitialEventskeys. The engine currently readsinitialEventsonly. generalrows use the tuple format fromScenario::generateGeneral():affinity, name, picture, nationName, city, leadership, strength, intel, officerLevel, birth, death, ego, char, text.
General Icon Paths
Scenario general rows store an explicit path relative to /image/icons.
New shared portraits use 장수/<general-name>.<extension>; scenario-specific
portraits keep their existing directory such as 걸그룹/ or 롤시나리오/.
This makes active and delayed generals persist the same path without requiring
the legacy image service's runtime list.json lookup.
resources/general-icons.json records the canonical general name, current
path, retained numeric legacy aliases, and source image. The numeric files in
the image repository remain compatibility aliases for deployed legacy
versions. Run the following from a core2026 checkout whenever scenarios or
portrait assets change:
pnpm manage:general-icons --image-root /path/to/image --write
pnpm manage:general-icons --image-root /path/to/image
The first command synchronizes canonical aliases and scenario paths. The second
is a read-only drift and file-content check. Missing source images stay listed
under the catalog's unresolved field and resolve to default.jpg when they
were an explicit numeric reference.
How Scenario Chooses Commands and Effects
Scenario config influences runtime rules via GameConst and ScenarioEffect:
const.availableGeneralCommand/const.availableChiefCommanddefine the commands that appear in UI and can be executed.const.availableSpecialDomestic/War,const.availablePersonality,const.allItems,const.availableNationTypecontrol selectable traits/items.map.scenarioEffectorconst.scenarioEffectsetsGameConst::$scenarioEffect, which is injected into eachGeneralas aniAction(General::getActionList()).const.availableInstantActionmerges intoGameConst::$availableInstantAction.
Because GameConst is generated from scenario data, a scenario can swap
available commands or replace the action pool entirely.
Command Prefix Conventions
Prefixes are used to separate rule packs and assets:
che_: default rule set (base commands, specials, items, nation types).cr_: alternate rule set used by specific scenarios (e.g.scenario_910).event_: scenario-specific extensions (research, extra unit sets, or special effects).
Example: scenario_910.json uses mapName=cr and unitSet=cr and overrides
availableGeneralCommand/availableChiefCommand to include cr_건국,
cr_맹훈련, and cr_인구이동 alongside che_ commands.
Scenario Environment Variants (Current Repo)
These are the map/unit/effect variants referenced by existing scenario files.
Defaults are mapName=che and unitSet=che when not specified.
Map sets (scenario/map/*.php):
che(default)miniche,miniche_b,miniche_cleancrchesspokemon_v1ludo_rathowm
Unit sets (scenario/unit/*.php):
che(default)che_except_siegecrbasicsiegetankevent_more_crewtypeludo_rathowm
Scenario effects (sammo/ActionScenarioEffect/*):
event_StrongAttackerevent_UnlimitedDefenceThresholdChangeevent_MoreEffect
Event Targets
Scenario events are stored in the event table and executed via
TurnExecutionHelper::runEventHandler() using EventTarget values:
PRE_MONTH, MONTH, OCCUPY_CITY, DESTROY_NATION, UNITED.
Most scenario JSON uses lowercase targets (e.g. "month"). The DB enum uses
uppercase values but is case-insensitive, so lowercase targets still match.