Files
core2026/docs/architecture/legacy-engine-general.md
T

104 lines
3.8 KiB
Markdown

# Legacy General Model and Action Stack
This document captures how `General` aggregates modifiers, computes stats, and
exposes trigger hooks. The main reference is `legacy/hwe/sammo/General.php`.
## Construction and Core State
- `General` builds from raw DB rows (general, city, nation, rank, access log).
- `last_turn` is parsed into `LastTurn`, and a separate `resultTurn` is
maintained for updates.
- `penalty` JSON is decoded into `PenaltyKey -> value` map.
- `aux` JSON is lazily decoded and only written when aux values change.
- Rank data is tracked with:
- `rankVarRead` (current read view)
- `rankVarIncrease` (increment queue)
- `rankVarSet` (explicit set queue)
## Action Objects (`iAction`)
`General` composes action sources into a single list:
1. Nation type (`buildNationTypeClass`)
2. Officer level (`TriggerOfficerLevel`)
3. Domestic special (`buildGeneralSpecialDomesticClass`)
4. War special (`buildGeneralSpecialWarClass`)
5. Personality (`buildPersonalityClass`)
6. Crew type (`GameUnitConst::byID`)
7. Inheritance buff (`TriggerInheritBuff`)
8. Scenario effect (`buildScenarioEffectClass`)
9. Items: horse / weapon / book / item (`buildItemClass`)
`getActionList()` returns this merged list and is the core entry point for
modifiers and triggers.
## Stat Computation
`getStatValue()` applies layered modifiers:
- Base stat from raw value
- Injury multiplier
- Cross-stat adjust (strength/intel + 1/4 of the other stat)
- Clamp to `GameConst::$maxLevel`
- `onCalcStat()` from every action object
- Cached by `(statName, injury, action, adjust)` tuple
Convenience wrappers:
- `getLeadership()`, `getStrength()`, `getIntel()`
## Turn Reservation and LastTurn
- `getReservedTurn(turnIdx)` reads from `general_turn`.
- When no entry exists, `buildGeneralCommandClass(null)` creates `휴식`.
- `LastTurn` holds `{ command, arg, term, seq }` and is used by
`BaseCommand::addTermStack()` to advance multi-turn commands.
- `applyDB()` persists updated fields and writes `last_turn` if it changed.
## Aux and Penalty Behavior
- `aux` is loaded on demand (`unpackAux()`), and `setAuxVar()` writes through to
`general.aux` only when values changed.
- Setting an aux value to `null` deletes the key from JSON.
- Command constraints that require aux values trigger `General::unpackAux()`
before evaluation.
- `penalty` is used in both `General` logic (AI and permission checks) and
API flows (messages, nation tools); runtime expiration is not automatic.
## Trigger and Modifier Hooks
`General` delegates calculations and trigger lists through action objects:
- Economy/strategy: `onCalcDomestic`, `onCalcStrategic`,
`onCalcNationalIncome`
- Combat modifiers: `onCalcStat`, `onCalcOpposeStat`, `getWarPowerMultiplier`
- Arbitrary actions: `onArbitraryAction` (used in city conquest)
Turn-prep triggers:
- `getPreTurnExecuteTriggerList()` merges trigger lists from every action
object. `TurnExecutionHelper::preprocessCommand()` adds
`che_부상경감` + `che_병력군량소모` on top.
Battle triggers:
- `getBattleInitSkillTriggerList()` merges per-action battle-init triggers.
- `getBattlePhaseSkillTriggerList()` includes base phase triggers:
- `che_필살시도`, `che_필살발동`
- `che_회피시도`, `che_회피발동`
- `che_계략시도`, `che_계략발동`, `che_계략실패`
- plus any action-specific additions.
## Rank and Access Log Updates
- `increaseRankVar()` / `setRankVar()` queue updates until `applyDB()`.
- `applyDB()` updates `general` and `rank_data`, then flushes logs.
- `checkStatChange()` uses `*_exp` thresholds to increase/decrease stats and
logs level changes.
## Open Questions / Follow-ups
- `PenaltyKey` effects and how penalties are applied are outside this file.
- `GeneralBase` and `LazyVarAndAuxUpdater` may contain additional state
conventions for new code to mirror.