Files
core2026/docs/architecture/legacy-scenarios.md
T

112 lines
4.0 KiB
Markdown

# 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
1. Server reset/init calls `ResetHelper::buildScenario()`.
2. `Scenario` loads `scenario_{id}.json` and merges defaults (`default.json`).
3. `Scenario::buildConf()` generates runtime constants:
- `d_setting/GameConst.php` from `GameConstBase + scenario.const/map/stat`
- `d_setting/CityConst.php` from `scenario/map/{mapName}.php`
- `d_setting/GameUnitConst.php` from `scenario/unit/{unitSet}.php`
4. `Scenario::build()` inserts nations, generals, and events into DB and runs
`initialEvents` immediately.
`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`, `iconPath`
- `stat`: default stat totals and bounds
- `map`: `mapName`, `unitSet`, `scenarioEffect`
- `const`: overrides for `GameConst` (commands, items, limits, etc.)
- `nation`, `diplomacy`
- `general`, `general_ex`, `general_neutral`
- `events`, `initialEvents`
- `ignoreDefaultEvents` (skip `GameConst::$defaultInitialEvents/$defaultEvents`)
Notes:
- A few files still use `initialActions` or `defaultInitialEvents` keys. The
engine currently reads `initialEvents` only.
- `general` rows use the tuple format from `Scenario::generateGeneral()`:
`affinity, name, picture, nationName, city, leadership, strength, intel,
officerLevel, birth, death, ego, char, text`.
## How Scenario Chooses Commands and Effects
Scenario config influences runtime rules via `GameConst` and `ScenarioEffect`:
- `const.availableGeneralCommand` / `const.availableChiefCommand` define the
commands that appear in UI and can be executed.
- `const.availableSpecialDomestic/War`, `const.availablePersonality`,
`const.allItems`, `const.availableNationType` control selectable traits/items.
- `map.scenarioEffect` or `const.scenarioEffect` sets
`GameConst::$scenarioEffect`, which is injected into each `General` as an
`iAction` (`General::getActionList()`).
- `const.availableInstantAction` merges into
`GameConst::$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_clean`
- `cr`
- `chess`
- `pokemon_v1`
- `ludo_rathowm`
Unit sets (`scenario/unit/*.php`):
- `che` (default)
- `che_except_siege`
- `cr`
- `basic`
- `siegetank`
- `event_more_crewtype`
- `ludo_rathowm`
Scenario effects (`sammo/ActionScenarioEffect/*`):
- `event_StrongAttacker`
- `event_UnlimitedDefenceThresholdChange`
- `event_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.