lane O: 7 purpose-built saves - issued turn commands, node routes, research-roll-pending
Produces the game states several board rows were blocked on, and reads each one back out of the save before claiming it. - CD/TurnCommands_v5 decoded: three saves with issued orders (research target, research boost, build orders, system rates, colonize, fleet move). Layout in SAVE_FORMAT.md section 11; ids cross-checked against the same file's Sys/Flt. - Waypoint type 3 (NodeRoute) now has 16 instances in one save and the player's own fleet is a mover in two. Type 2 is shown NOT to be produced by a Move order for either node-drive race (Zuul and Human both emit type 3). - research_roll_pending true at load in two saves; the ProcessTurn gate constant at 0x00a2c788 is a float 0.5, so the flag survives into ProcessResearch only while progress/cost <= 0.5 at the start of the turn. - Budget tail: construction and a large maintenance are live; Nexp is empty in all 11 saves and the 1.8 UI has no expense slider, so slot 12 looks dead. VM140 restored to the original 8-file SavedGames set (autosaves byte-identical) and left at the main menu; VM140 row set FREE.
This commit is contained in:
parent
648e9aae77
commit
9de77f7e5e
10 changed files with 73 additions and 8 deletions
File diff suppressed because one or more lines are too long
12
ghidra/addresses.d/lane-o.json
Normal file
12
ghidra/addresses.d/lane-o.json
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"entries": [
|
||||
{
|
||||
"name": "ResearchRollProgressThreshold",
|
||||
"addr": "0x00a2c788",
|
||||
"convention": "data",
|
||||
"prototype": "const float 0.5f -- the progress-ratio threshold in ServerPlayer::ProcessTurn's `ResT != NULL && ResErrRoll != 0 && CONST < progressRatio` gate (events.md §3, window 0x008915ec-0x00891624). Read out of dumps/sots.exe: .rdata bytes at 0x00a2c788 are 00 00 00 3f (float 0.5); the following word 0x00a2c78c is float 100.0, so this is a float32, NOT the double an 8-byte read would suggest (that reads as 5.28e13). CONSEQUENCE, measured on the live game: ResErrRoll survives into ProcessResearch only while progress/cost <= 0.5 at the START of the turn, so the OnTechResearched draw (0x0088df20) can fire only when a single turn supplies more than half the target tech's remaining cost. See the board's `research_roll_pending save` row",
|
||||
"status": "verified",
|
||||
"source": "lane O 2026-09-08, PE section walk of dumps/sots.exe + turn-by-turn observation on VM140 (verify/results/saves/zuul-turn1[5-7]-*.sav)"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
verify/results/saves/human-turn2-orders.sav
Normal file
BIN
verify/results/saves/human-turn2-orders.sav
Normal file
Binary file not shown.
BIN
verify/results/saves/human-turn3-noderoute.sav
Normal file
BIN
verify/results/saves/human-turn3-noderoute.sav
Normal file
Binary file not shown.
BIN
verify/results/saves/zuul-turn15-orders.sav
Normal file
BIN
verify/results/saves/zuul-turn15-orders.sav
Normal file
Binary file not shown.
BIN
verify/results/saves/zuul-turn16-noderoute.sav
Normal file
BIN
verify/results/saves/zuul-turn16-noderoute.sav
Normal file
Binary file not shown.
BIN
verify/results/saves/zuul-turn17-orders2.sav
Normal file
BIN
verify/results/saves/zuul-turn17-orders2.sav
Normal file
Binary file not shown.
BIN
verify/results/saves/zuul-turn17-rollpending.sav
Normal file
BIN
verify/results/saves/zuul-turn17-rollpending.sav
Normal file
Binary file not shown.
BIN
verify/results/saves/zuul-turn23-fleet23.sav
Normal file
BIN
verify/results/saves/zuul-turn23-fleet23.sav
Normal file
Binary file not shown.
|
|
@ -268,3 +268,56 @@ resyncs / 0 hint-failures; the info count drops from 257/259/259 to 197 on turn1
|
|||
60/62/62 `otnF` "read positionally" notes are gone, and every remaining info is a `"."`
|
||||
item. `test_save_reader.py::TagNameCorrectionsTest` pins each correction and fails a
|
||||
frame that uses the old spelling.
|
||||
|
||||
## 11. `CD` `Player.<id>.TurnCommands_v5` — the issued-order block (lane O, 2026-09-08)
|
||||
|
||||
Until now every save in the corpus carried the **same** empty `TurnCommands_v5` frame, so the
|
||||
block looked structureless. `state_checksum --tree --depth 1` makes that concrete: `CD[0]` is
|
||||
`3df7d93164fb1d7d`, **35 leaves / 122 B**, byte-for-byte identical in `turn1/2/3-state.sav`,
|
||||
`zuul-turn5-species5.sav` and `human-turn3-noderoute.sav`. Saves made **after issuing orders and
|
||||
before End Turn** grow it (all five below are `--strict` clean and `coverage: PROVED`):
|
||||
|
||||
| save | CD[0] | orders issued that turn |
|
||||
|---|---|---|
|
||||
| any no-orders save | 35 leaves / 122 B | — |
|
||||
| `human-turn2-orders.sav` | 41 / 143 B | 1 fleet move |
|
||||
| `zuul-turn15-orders.sav` | 61 / 226 B | research target + research boost + 5 build + 1 fleet move |
|
||||
| `zuul-turn17-orders2.sav` | 129 / 498 B | 20 build + 1 system-rates + 1 colonize (3 ships) |
|
||||
|
||||
Body, as read off `zuul-turn15-orders.sav` / `zuul-turn17-orders2.sav` (all items `"."`-tagged,
|
||||
so this is a positional record, not a named one):
|
||||
|
||||
```
|
||||
int playerId (16 = the human player's PID; matches CDT's "Player.00000016.…")
|
||||
bool ? (True in every sample, orders or not)
|
||||
float researchRate (0.25 default -> 0.97 after the empire Savings/Research slider)
|
||||
bool hasResearchTargetCmd ; if set, int techId follows (191 = WEP_GrnLas)
|
||||
bool hasResearchBoostCmd ; if set, int money follows (216383 -- exactly the
|
||||
Imperial Savings delta the boost produced)
|
||||
float ? (0.9992… when a research command is present, absent otherwise)
|
||||
bool x3 = False (three further command-present flags, never seen set)
|
||||
int x2 = 0
|
||||
int nBuildOrders ; nBuildOrders x { int ordinal; int designId; int systemId; int 0 }
|
||||
(ordinal is the running build-queue index, not 0-based per turn;
|
||||
designId 608 = DE Colonizer, 576 = DE Armor; systemId 384 = the
|
||||
home system that owns the queue)
|
||||
int 0
|
||||
int nSystemRateCmds ; n x { int systemId; frame { float SRs; float SRt; float SRsc;
|
||||
float SRtf; float SRi; float SRoh; int SRnr } }
|
||||
(SRsc = 1.0 is the Planetary Budget slider pushed fully to
|
||||
Construction; this is the only NAMED sub-frame in the block)
|
||||
int 0
|
||||
int nColonizeOrders ; n x { int shipId; int 1 }
|
||||
int nFleetMoveOrders ; n x { int fleetId; int 1; int destSystemId; int 0 }
|
||||
… trailing zero words (the unused command lists) to the frame END
|
||||
```
|
||||
|
||||
Cross-checks that pin the decode: `384`/`432` resolve to `Sys` **Gallandro**/**Octans** in the
|
||||
same file, `688` to the `Flt` the UI showed as *Alpha Fleet* with `Dest: Octans`, and `216383` is
|
||||
the exact `Imperial Savings` drop the Boost Research panel caused. **The commands are pending, not
|
||||
applied**: in `zuul-turn15-orders.sav` the `ServerPlayer` still reads `ResRate 0.25`, `ResTNm ''`,
|
||||
`Sav 2,902,722` while the block already carries rate 0.97 and the boost — the block is the
|
||||
client→server queue that `ProcessTurn` drains.
|
||||
|
||||
Not observed (the flags/lists that stayed zero in every sample): the three unset command-present
|
||||
bools, and every list beyond the five above.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue