136 lines
6.2 KiB
Markdown
136 lines
6.2 KiB
Markdown
# Legacy Engine Execution Flow
|
|
|
|
This document summarizes how the legacy engine advances turns and executes
|
|
commands. It focuses on the execution pipeline, RNG seeding, and state writes
|
|
based on `legacy/hwe/sammo/API/Global/ExecuteEngine.php`,
|
|
`legacy/hwe/sammo/TurnExecutionHelper.php`, and `legacy/hwe/sammo/Command/BaseCommand.php`.
|
|
|
|
## Entry Point: ExecuteEngine API
|
|
|
|
- Endpoint: `legacy/hwe/sammo/API/Global/ExecuteEngine.php`
|
|
- Session: no session required (`NO_SESSION`)
|
|
- Optional `serverID` guard via `UniqueConst::$serverID`
|
|
- Calls `TurnExecutionHelper::executeAllCommand($updated, $locked)`
|
|
- Returns `{ updated, locked, lastExecuted }`
|
|
|
|
## Global Turn Loop (`TurnExecutionHelper::executeAllCommand`)
|
|
|
|
1. **Time gate**
|
|
- If `now < game_env.turntime`, return without executing.
|
|
2. **Locking**
|
|
- `tryLock()` on `plock` row (`type='GAME'`).
|
|
- If locked or `isunited` in `2|3`, return (frozen state).
|
|
3. **Pre-turn maintenance**
|
|
- Cache game env, `checkDelay()`, `updateOnline()`, `CheckOverhead()`.
|
|
4. **Catch-up monthly loop**
|
|
- Compute `prevTurn = cutTurn(turntime, turnterm)` and `nextTurn = addTurn(prevTurn)`.
|
|
- While `nextTurn <= now`:
|
|
- `executeGeneralCommandUntil(nextTurn, limitActionTime, year, month)`
|
|
- `updateTraffic()`
|
|
- Monthly pipeline:
|
|
- `runEventHandler(PreMonth)`
|
|
- `preUpdateMonthly()`
|
|
- `turnDate(nextTurn)`
|
|
- `checkStatistic()` (only if `month == 1`)
|
|
- `runEventHandler(Month)`
|
|
- `postUpdateMonthly($monthlyRng)`
|
|
- Advance `prevTurn`, `nextTurn`, update `game_env.turntime`.
|
|
5. **Current partial month**
|
|
- `turnDate(prevTurn)`
|
|
- `executeGeneralCommandUntil(now, limitActionTime, year, month)`
|
|
6. **Post-turn maintenance**
|
|
- `processTournament()`
|
|
- `processAuction()`
|
|
- Reset cache, `unlock()`.
|
|
|
|
`limitActionTime` is derived from `max_execution_time` (roughly 2/3 of the
|
|
configured limit). If time runs out mid-loop, it returns early and keeps
|
|
`game_env.turntime` at the most recent executed value.
|
|
|
|
## Per-General Execution (`executeGeneralCommandUntil`)
|
|
|
|
For each general with `turntime < targetDate` (ordered by `turntime, no`):
|
|
|
|
1. **Load state**
|
|
- `General::createObjFromDB()` and `KVStorage` for `game_env`.
|
|
2. **Nation command (if officer_level >= 5)**
|
|
- Pull `nation_turn` row for `turn_idx = 0`.
|
|
- Build `NationCommand` with `LastTurn` stored in `nation_env`.
|
|
3. **AI/autorun**
|
|
- NPCs (`npc >= 2`) or players past `autorun_limit` use `GeneralAI`.
|
|
- AI can replace both nation and general commands.
|
|
4. **Preprocess triggers**
|
|
- RNG seed: `hiddenSeed + 'preprocess' + year + month + generalID`.
|
|
- `preprocessCommand()` merges action triggers + `che_부상경감`, `che_병력군량소모`.
|
|
5. **Blocked users**
|
|
- `processBlocked()` consumes `killturn` and logs if `block >= 2`.
|
|
6. **Execute nation command**
|
|
- RNG seed: `hiddenSeed + 'nationCommand' + year + month + generalID + commandKey`.
|
|
- `processNationCommand()` checks conditions, term stack, `run()`.
|
|
- If `run()` fails and `getAlternativeCommand()` exists, it retries.
|
|
- Updates `nation_env` with `LastTurn` result.
|
|
7. **Execute general command**
|
|
- Load from `general_turn` (`turn_idx = 0`), default to `휴식`.
|
|
- RNG seed: `hiddenSeed + 'generalCommand' + year + month + generalID + commandKey`.
|
|
- `processCommand()` checks conditions, term stack, `run()`.
|
|
- Updates `killturn` based on NPC status, autorun, or `휴식`.
|
|
8. **Queue maintenance & turntime**
|
|
- `pullNationCommand()` / `pullGeneralCommand()` advance queues.
|
|
- `updateTurnTime()` handles deletion/retirement and sets next `turntime`.
|
|
- Persist via `General::applyDB()`.
|
|
9. **LastTurn persistence**
|
|
- General `LastTurn` lives in `general.last_turn` JSON.
|
|
- Nation `LastTurn` is stored in `nation_env` under `turn_last_{officer_level}`.
|
|
- `LastTurn.term` only advances when the same command + arg repeats across turns.
|
|
|
|
## Command Semantics (BaseCommand)
|
|
|
|
- **Constraints**: permission/min/full conditions are evaluated via
|
|
`Constraint::testAll()` with `general/city/nation/dest*` context.
|
|
- **Pre-turn requirement**: `getPreReqTurn()` uses `LastTurn` to accumulate
|
|
term stack (`addTermStack()`), logging "수행중" until the term completes.
|
|
- **Post-turn requirement**: `getPostReqTurn()` uses `next_execute` storage
|
|
(general: `next_execute`, nation: `nation_env`) to block early execution.
|
|
- **Run flow**: `run($rng)` returns `true` when completed; `false` can chain to
|
|
`getAlternativeCommand()`.
|
|
|
|
## Turntime & Lifecycle (`updateTurnTime`)
|
|
|
|
- **Inactivity**: if `killturn <= 0`:
|
|
- NPC-owned characters can detach (owner -> NPC) if `deadyear` not reached.
|
|
- Otherwise the general is deleted (`kill()`).
|
|
- **Retirement**: if `age >= retirementYear` and not NPC, `CheckHall()` and
|
|
`rebirth()` are invoked.
|
|
- **Scheduling**: next `turntime` is `addTurn(current, turnterm)` with
|
|
optional `nextTurnTimeBase` override (aux var).
|
|
|
|
## killturn, block, autorun
|
|
|
|
- `killturn` acts as an inactivity counter; it is reset to `game_env.killturn`
|
|
when a non-rest player action completes, and decremented for NPCs, autorun,
|
|
rest commands, or block states.
|
|
- `block >= 2` forces `killturn` decrement and logs a block message.
|
|
- When `killturn <= 0`, the general is converted to NPC (owner removed) or
|
|
deleted depending on NPC type and `deadyear`.
|
|
- `autorun_limit` is stored in general `aux` and used to decide AI takeover.
|
|
|
|
## Deterministic RNG Seeds
|
|
|
|
RNG uses `LiteHashDRBG` with `UniqueConst::$hiddenSeed`:
|
|
|
|
- Preprocess: `('preprocess', year, month, generalID)`
|
|
- Nation command: `('nationCommand', year, month, generalID, commandKey)`
|
|
- General command: `('generalCommand', year, month, generalID, commandKey)`
|
|
- Monthly: `('monthly', year, month)`
|
|
|
|
These seeds make command outcomes and monthly updates reproducible for
|
|
validation.
|
|
|
|
## Open Questions / Follow-ups
|
|
|
|
- `preUpdateMonthly()`, `postUpdateMonthly()`, `turnDate()`, `checkStatistic()`
|
|
are defined outside this flow; see `legacy/hwe/func_time_event.php` for
|
|
economic updates and population calculations.
|
|
- `updateTraffic()`, `checkDelay()`, `updateOnline()` logic lives in
|
|
`legacy/hwe/func.php` and related utility files.
|