AP: P's three draws are two species branches - 0x00840a3c fires, 0x0088dc43 fires, the deploy NextFloat measured
From as-turn15-spydeployed.sav, 11 End Turns under probes=8. Detection at Frame 22, P at Frame 25: 0x00840a3c 1 call / 1 word, the first firing of any of P's sites. 0x00840929 and 0x008409c7 are the MORRIGI branch and cannot be reached in a Human game - correcting every inventory that lists them as three sites behind one gate. The counter-mission roll 0x0088dc43 fires from Frame 19 (corpus was 0 of 22) and the deploy NextFloat 0x0078c97f is measured with cbh reproducing lane AS's value bit for bit. Species table decoded, which also names AS's 0.75f as Zuul and 0.5f as Morrigi. Two corrections to lane AG 3.2 (CnTrd is the target's; ncp is a scalar counter). PB4 was wrong and is named: the trade-raid roll entered the tail at Frame 20, re-confirming lane AD's per-fleet model. Control pair disagrees (three outcomes in six processes) - not a calibration pair - and probes=8 is byte-identical to a control over 44,438 leaves. Exposure fields recorded per turn: saturated on this map.
This commit is contained in:
parent
e923d2928c
commit
2ac52350f0
11 changed files with 982 additions and 0 deletions
|
|
@ -299,3 +299,655 @@ From `as-turn14-predeploy.sav`, one Deploy Spy order, one End Turn, `probes=8`:
|
|||
---
|
||||
|
||||
*(End of the pre-registered section. Everything below is measurement.)*
|
||||
|
||||
---
|
||||
|
||||
## 4. What was run
|
||||
|
||||
Shim build **`ap-989c692-20260909T0425Z`**, cross-built on CT111 in this lane's own directory
|
||||
`/srv/re-lab/build/sots-engine-ap` after `rm -rf` of the whole tree, from a lane-private
|
||||
`git worktree` at `~/sots-engine-ap` with no local `build*` shipped (rules 21 and 24). `binkw32.dll`
|
||||
sha256 `ae084ed4774caf24ea7927fcb012d1999633f10556c7c99f0209f66067416a17`. Staged to
|
||||
`/srv/re-lab/shim/dist-ap`, deployed to `C:\SOTS\shimdist-ap` on VM144. **This lane wrote no engine
|
||||
code**; `shim.cfg.hp8` and `shim.cfg.hoff` were used unmodified.
|
||||
|
||||
| run | config | input | End Turns | purpose |
|
||||
|---|---|---|---|---|
|
||||
| **W** | `shim.cfg.hp8` (`probes=8`) | `MyGameas1spydep.sav` (Frame 15) | **11** (15 → 26) | target 1 |
|
||||
| **D** | `shim.cfg.hp8` | `MyGameas1predeploy.sav` (Frame 14) + one `Deploy Spy` order | 1 | target 2 |
|
||||
| **OA / OB** | `shim.cfg.hoff` | `MyGameas1spydep.sav` | 1 each, two fresh processes | control (§7) |
|
||||
|
||||
**Instrument armed and verified from `shim.log`, not assumed** (rule 1). Both instrumented runs:
|
||||
seven `drawsite:` detours `create=MH_OK enable=MH_OK`; `config: probes=8 -> 8 lane-H entry probes`
|
||||
and all eight `create=MH_OK enable=MH_OK`; **zero** `COVERAGE:` lines; **zero**
|
||||
`config: ignoring unknown key` lines; `draw_site_overflow = 0` on every turn. Probe indices 8–11
|
||||
report **NOT INSTALLED**, never 0. The one `MH_ERROR_ALREADY_CREATED` line is the `fpu` module
|
||||
losing the race for `BeginProcessTurn` to the ledger; it is present verbatim in lanes AC, AD, AR and
|
||||
AS's logs, so this is the same instrument those lanes ran.
|
||||
|
||||
**`probes=11` was not used anywhere in this lane.** No number here is comparable to lane AC's turn
|
||||
totals.
|
||||
|
||||
### 4.1 The wait cost eleven minutes, not an evening
|
||||
|
||||
The brief budgeted "~20 End Turns, expensive in wall-clock". On this state an End Turn under
|
||||
`probes=8` completes in **6 seconds**; the eleven turns took **11 minutes** including the load. The
|
||||
expensive part is the launch (~2 min through the intro movies) and the load (~3 min). Turn 27 hit a
|
||||
Von Neumann encounter dialog at Rigel and the driver stopped on it exactly as designed; by then the
|
||||
question was answered and the run was ended there rather than clicked through.
|
||||
|
||||
The driver is worth carrying forward: a scheduled task (`SOTSAP`) running an in-guest loop that
|
||||
clicks End Turn, then **polls the autosave's mtime** — never a button colour, which is lane AS's
|
||||
lesson — snapshots `(Autosave).sav` per turn, and stops on the first stall with a screenshot. It is
|
||||
left at `C:\SOTS\ui\ap\ap_loop.ps1`.
|
||||
|
||||
---
|
||||
|
||||
## 5. Target 1 — the wait, measured turn by turn
|
||||
|
||||
Detection landed on **Frame 22**, seven turns in. `P` therefore ran on **Frame 25**.
|
||||
|
||||
### 5.1 The per-turn ledger
|
||||
|
||||
Every row is `draw_sites` at the post-turn autosave marker, which the shim resets at the pre-turn
|
||||
marker — so these are **per-turn** figures, not cumulative.
|
||||
|
||||
| Frame | `0x00887c8a` spy 13 | `0x0088dc43` spy 14 | `0x00840a3c` `P` B1 | `0x00820e1d` trade raid | tail bracket | probe `vslot13` | probe `Slot13RngCallee` |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| 16 | **1** | — | — | — | **1** | 1 | 0 |
|
||||
| 17 | **1** | — | — | — | **1** | 1 | 0 |
|
||||
| 18 | **1** | — | — | — | **1** | 1 | 0 |
|
||||
| 19 | **1** | **1** ← first ever | — | — | **2** | 1 | 0 |
|
||||
| 20 | **1** | **1** | — | 2 | **4** | 1 | 0 |
|
||||
| 21 | **1** | **1** | — | 4 | **6** | 1 | 0 |
|
||||
| **22** | **1** ← succeeds, `sdet := 22` | **1** | — | 7 | **9** | 1 | 0 |
|
||||
| 23 | **—** | **1** | — | 7 | **8** | **1** | 0 |
|
||||
| 24 | **—** | **1** | — | 8 | **9** | **1** | 0 |
|
||||
| **25** | **—** | **—** | **1** ← first ever | 7 | **8** | **1** | **1** ← first ever |
|
||||
| 26 | — | — | — | 8 | **8** | 1 | 0 |
|
||||
|
||||
Every cell is `calls = words`, `no_draw_calls = 0`, `strategic = true`. **The tail bracket equals the
|
||||
sum of its rows on all eleven turns: residual 0 every turn**, and `draw_site_overflow = 0`.
|
||||
|
||||
Three lines of that table are the lane:
|
||||
|
||||
> **Frame 25:** `entry = Chance`, `ret_rva = 0x0044_0a41` (VA `0x00840a41`, the instruction after
|
||||
> `call 0x8e6dd0` at `0x00840a3c`), `calls = 1`, `words = 1`, `no_draw_calls = 0`,
|
||||
> `strategic = true`. **`0x00840a3c` had never fired in this campaign.**
|
||||
>
|
||||
> **Frames 23 and 24:** no row at `0x0048_7c8f` at all, while the entry probe on
|
||||
> `ServerSpyManager::vslot13` reads **1** on both. That is "entered and gated", not "did not run" —
|
||||
> rule 28 practice 1, in a third distinct arm of the same function.
|
||||
>
|
||||
> **Frame 25, the probe column:** `Game::SpyManager::Slot13RngCallee 0x008408e0` reads **1**. Lane AS
|
||||
> demonstrated that this probe's **zero** said nothing about the subtree. This is the other half:
|
||||
> the same probe, on the one turn the callee is actually entered, reads one.
|
||||
|
||||
### 5.2 `0x00840929` and `0x008409c7` did not fire, and could not have
|
||||
|
||||
Neither site appears in any of the eleven turns, including Frame 25 — the one turn `P` ran. **PA1
|
||||
held.** The reason is not a state we failed to build: `P`'s first instruction pair is
|
||||
`cmp [spyOwner+0x5c], 6` / `jne`, the spy's owner is player 16 `re` with `Species = 0` (Human), and
|
||||
the launch card confirms it in the UI. Branch A is a **Morrigi-only** path.
|
||||
|
||||
> The brief that created this lane, lane AS's §6, board row 207 and lane AG's §6 all list
|
||||
> `0x00840929` / `0x008409c7` / `0x00840a3c` as three sites behind one gate. They are **two
|
||||
> mutually exclusive branches selected by species**, and no workload can fire more than one of them
|
||||
> per call. To reach the other two, a lane must play a **Morrigi** empire, deploy a spy, and lose it.
|
||||
|
||||
### 5.3 `sdo` — the accumulator, exact to the float32
|
||||
|
||||
Read from the eleven autosaves. Prediction PB1 was `sdo(f) = 0.0084 × (f − 14)` as a float32.
|
||||
|
||||
| Frame | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| `sdo` | 0.016800 | 0.025200 | 0.033600 | 0.042000 | 0.050400 | 0.058800 | 0.067200 | 0.067200 | 0.067200 |
|
||||
| bits | `3c89a027` | `3cce703a` | `3d09a027` | `3d2c0831` | `3d4e703b` | `3d70d845` | `3d89a027` | frozen | frozen |
|
||||
|
||||
Seven consecutive exact steps of 0.0084, then **frozen** the moment `sdet` stamps — because branch D
|
||||
is the only writer of `sdo` and `sdet != -1` skips it. The freeze is a second, save-side proof that
|
||||
the branch stopped running on Frames 23 and 24, independent of the ledger's zero.
|
||||
|
||||
Lane AS measured two points of this line (0 → 0.0084 → 0.0168) and derived the rest. **Nine points
|
||||
now lie on it**, and `countC` stayed at 2 for the whole window, so `sdo`'s per-turn increment is a
|
||||
constant on this state rather than a fitted one.
|
||||
|
||||
### 5.4 The counter-mission machine, measured for the first time
|
||||
|
||||
`0x0088dc43` (lane AG §3.2) had **corpus count 0 of 22** and had never fired. It fires here from
|
||||
Frame 19, one call and one word per turn, and the save-side state machine is fully visible:
|
||||
|
||||
| Frame | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| `spyon` | **32** | 32 | 32 | 32 | 32 | 32 | 32 | — |
|
||||
| `cm` | **1** | 1 | **2** | 2 | **3** | 3 | **4** | — |
|
||||
| `cmo` | 0.2 | 0.4 | 0.2 | 0.4 | 0.2 | 0.4 | 0.2 | — |
|
||||
| `ncp` | 0 | 0 | **1** | 1 | **2** | 2 | **3** | — |
|
||||
| words at `0x0088dc43` | **0** | 1 | 1 | 1 | 1 | 1 | 1 | **0** |
|
||||
|
||||
Everything AG decoded statically is confirmed, and four things are added:
|
||||
|
||||
1. **The bootstrap turn costs nothing.** Frame 18 is `Frame − tdep == 3`; `vslot14` sets `spyon`,
|
||||
runs the stage machine `cm: 0 → 1` and `cmo := 0.2f`, and **does not draw**. The first draw is
|
||||
Frame 19. PB3 predicted exactly this and it held.
|
||||
2. **`cmo` steps by `0.2f` on failure and resets to `0.2f` on success**, as decoded. The stage
|
||||
advanced on Frames 20, 22 and 24 — always on the second try, at `p = 0.4`. Six rolls, three
|
||||
successes; expectation at (0.2, 0.4) alternating is 2.4. Consistent, not validated.
|
||||
3. **`ncp` is a scalar counter of completed stages, not a container.** It is a plain `int` item in
|
||||
the stream and it increments by exactly 1 on each stage completion (0,0,1,1,2,2,3), in lock-step
|
||||
with `cm`. AG's decode reads the `cm == 0` branch as gated on "`ncp` non-empty"; that gate was
|
||||
**never reached** here, because `cm` never returned to 0 before the spy was destroyed. It stays a
|
||||
rule-6 hypothesis — and a sharper one now that `ncp`'s values are known.
|
||||
4. **The `CnTrd` the stage machine consults is the TARGET's, not the spy owner's.** AG's caution to
|
||||
lane AS was that a spy program run without FTL Economics takes the `1 → 3` arm. This run took
|
||||
`1 → 2`, and in the save **my player (16) has `CnTrd = False` while Kepler's owner (32) has
|
||||
`CnTrd = True`**. So `owner->+0xff` at that branch is the **victim** empire's FTL Economics. The
|
||||
caution as written would have mispredicted this run.
|
||||
|
||||
`cm`, `cmo`, `spyon` and `ncp` are four of the 234 fields the value-domain census lists as having
|
||||
only ever held one value. **All four are now off zero**, with a measured trajectory each.
|
||||
|
||||
### 5.5 The spy is destroyed at `sdet + 3`, and `vslot13` does it
|
||||
|
||||
`nspy` goes **1 → 0** between the Frame-24 and Frame-25 autosaves, `spies2` at Kepler returns to
|
||||
`count = 0`, and the `spymgr` record loses its only `spy` child. That is `vslot13`'s drain loop at
|
||||
`0x00887eb0` calling manager vtable slot 10 `0x00838480`, which calls `ServerSystem::RemoveSpy
|
||||
0x0074f550`. **PA4 held.**
|
||||
|
||||
It also settles the ordering question in §1.4 behaviourally: `0x0088dc43` costs **0** on Frame 25
|
||||
although `vslot14`'s entry probe still reads 1. Phase 23 destroys the spy before phase 33 walks the
|
||||
list.
|
||||
|
||||
---
|
||||
|
||||
## 6. Target 2 — `0x0078c97f`, the site in no inventory, measured
|
||||
|
||||
Run D: `MyGameas1predeploy.sav` (Frame 14) in a fresh process under `probes=8`; Kepler selected on
|
||||
the map; `Special → Deploy Spy → OK`; one End Turn.
|
||||
|
||||
```
|
||||
draw_sites, post-turn autosave marker, the row verbatim:
|
||||
|
||||
entry = NextFloat
|
||||
ret_rva = 0x0038_c984 (VA 0x0078c984 -- after `call 0x47d830` at 0x0078c97f)
|
||||
calls = 1
|
||||
words = 1
|
||||
no_draw_calls = 0
|
||||
strategic = true
|
||||
|
||||
boundary ledger, same turn:
|
||||
|
||||
BeginProcessTurn 326 -> 326 0
|
||||
ProcessTurn 326 -> 344 18 <-- the deploy draw is in here
|
||||
OnAllCombatDone_Tail 344 -> 345 1 <-- the first detection roll, sdo = 0.0084
|
||||
Autosave 345 -> 345 0
|
||||
```
|
||||
|
||||
**PC1, PC2 and PC3 all held exactly.** The site fires once per applied `SHIPACTION_DEPLOYSPY`
|
||||
command, for one word, on the strategic generator, inside the `ProcessTurn` bracket — and the same
|
||||
turn's tail costs exactly 1, because `ApplyAllTurnCommands` runs before `OnAllCombatDone_Tail` and
|
||||
the freshly deployed spy is immediately eligible for its first detection roll.
|
||||
|
||||
It appears in **no other turn of this lane**: eleven turns of run W carry no row at `0x0038c984`.
|
||||
That is the stream predicate showing its shape — the site's cost is not a function of the save at
|
||||
all, it is a function of what the player ordered.
|
||||
|
||||
### 6.1 The sharpest prediction held: the deploy draw is reproducible across processes
|
||||
|
||||
**PC4.** Lane AS's `as-turn15-spydeployed.sav` was written by a different process, on a different
|
||||
day, from a different build. This lane's Frame-15 autosave was written by run D.
|
||||
|
||||
```
|
||||
lane AS spy.cbh = 5.033599376678467 (float32 0x40A11333)
|
||||
lane AP spy.cbh = 5.033599376678467 identical
|
||||
cbh / 2pi = 0.8011222000
|
||||
```
|
||||
|
||||
The same input state plus the same order drew the same word, in two processes separated by hours and
|
||||
by a rebuild. Together with `deat = 400`, `tdep = 15`, `sdo = 0.0084`, `sdet = -1` and `spies2 = [1]`
|
||||
at Kepler reproducing exactly (**PC5**), this says the **strategic** generator's consumption up to
|
||||
`ApplyAllTurnCommands` is deterministic given the save — the per-process AI client seed does not
|
||||
reach it. It is a much stronger statement than a whole-file hash comparison, because it isolates one
|
||||
word to one site.
|
||||
|
||||
### 6.2 A correction to lane AS's reading of the same bytes
|
||||
|
||||
AS gives the site as `cbh = NextFloat() * 2*pi`. The value is right; the expression is the
|
||||
campaign's standard range idiom with `LO` supplied by an `fldz`:
|
||||
|
||||
```
|
||||
0078c984 fld qword [0x009e21b0] ; HI = 6.2831854820251465
|
||||
0078c98a fldz ; LO = 0.0
|
||||
0078c994 fsub st(1),st ; HI - LO
|
||||
0078c99b fmulp st(1),st ; (HI - LO) * r
|
||||
0078c99d fstp [ebp+8] ; through a FLOAT32 temp
|
||||
0078c9a0 fadd [ebp+8] ; LO + that
|
||||
```
|
||||
|
||||
so it is `lerp(0.0, 2*pi, r)` **rounded to float32 mid-expression**, not a `double` multiply. A
|
||||
reimplementation that computes `r * 6.2831854820251465` in double and stores at the end can differ in
|
||||
the last bit.
|
||||
|
||||
The other half of the sequence is worth writing down because it reads wrong at first glance:
|
||||
|
||||
```
|
||||
0078c998 push ecx ; reserve DeploySpy's SECOND argument slot
|
||||
0078c9a9 fstp [esp] ; slot := the angle
|
||||
0078c9ac call 0x0080c860 ; __thiscall getter, `mov eax,[ecx+0xa8]; ret` -- NO stack args,
|
||||
; so it leaves the angle slot untouched. eax = the spy's id.
|
||||
0078c9ba push eax ; the FIRST argument
|
||||
0078c9bb call edx ; ServerSpyManager::DeploySpy(spyId, angle)
|
||||
```
|
||||
|
||||
`0x0080c860` looks like it consumes the float and does not; the compiler built the argument list out
|
||||
of order and called a zero-argument getter across the half-built frame. **`DeploySpy` takes two
|
||||
arguments**, and `0x008874b0 fld [ebp+0xc]` / `0x008874c0 fstp [esi+0x18]` is where `cbh` is
|
||||
written. Lane AS's *"`spy->cbh (+0x18) := <the float argument>`"* is exactly right; this only names
|
||||
which argument and shows why an eye following `eax` misses it.
|
||||
|
||||
---
|
||||
|
||||
## 7. The control — a truthful non-pair, and the exposure predicate checked against it
|
||||
|
||||
Two fresh `hooks=off` processes (**OA**, **OB**) on the same input, one End Turn each, plus this
|
||||
lane's instrumented run **W** and lane AS's three runs from the day before. Six processes, one
|
||||
input, one End Turn.
|
||||
|
||||
### 7.1 The hashes
|
||||
|
||||
```
|
||||
input MyGameas1spydep.sav 854a10fa1ea602f0f7909f9bf9154942e56ea5fa1db4cce47d6d32bf53952e08
|
||||
```
|
||||
|
||||
| run | lane | config | pre-turn `(Autosave EndTurn).sav` | post-turn `(Autosave).sav` | size |
|
||||
|---|---|---|---|---|---|
|
||||
| A | AS | `hoff` | `98e45d3745b91450…` | `262f8bda97c9511d…` | 77,685 |
|
||||
| B | AS | `hoff` | `98e45d3745b91450…` | `e34775a757e6fb3d…` | 77,649 |
|
||||
| M | AS | `probes=8` | `98e45d3745b91450…` | `262f8bda97c9511d…` | 77,685 |
|
||||
| **W** | **AP** | `probes=8` | — | **`262f8bda97c9511d…`** | 77,685 |
|
||||
| **OA** | **AP** | `hoff` | **`98e45d3745b91450…`** | **`e296394f578b3a56…`** | 77,677 |
|
||||
| **OB** | **AP** | `hoff` | *(§7.4)* | *(§7.4)* | |
|
||||
|
||||
**The pre-turn save is byte-identical across four processes, two lanes and two builds** — including
|
||||
this lane's own, which is not lane AS's binary. That is the strongest statement available about the
|
||||
input, and it is what makes the post-turn comparison meaningful.
|
||||
|
||||
**The post-turn saves are not.** Five processes have produced **three** distinct outcomes:
|
||||
`262f8bda` (three times: AS's A, AS's M, this lane's W), `e34775a7` (once: AS's B), `e296394f`
|
||||
(once: this lane's OA).
|
||||
|
||||
> **This is not a calibration pair and must not enter `determinism-hashes.txt`.** Said in advance as
|
||||
> PD3, and it is the honest verdict rather than a post-hoc excuse.
|
||||
|
||||
### 7.2 What varies, localised by sub-tree
|
||||
|
||||
`state_checksum --no-audit --floats bits --mask none`, OA against W:
|
||||
|
||||
```
|
||||
DIVERGED: 15 leaf difference(s)
|
||||
/Summary/Checksum 985948923 -> 985948837
|
||||
/Sim/turnstats/history/hist[1]/stats[15]/tch 45 -> 46
|
||||
/Sim/players/Player[32 "Revenge Fleet"]/TechTree/St[60] 3 -> 2
|
||||
/Sim/players/Player[32 "Revenge Fleet"]/TechTree/TResDone[60] 22469 -> 0
|
||||
/Sim/players/Player[32 "Revenge Fleet"]/TechTree/Tbd[60] 2 -> 1
|
||||
/Sim/players/Player[32 "Revenge Fleet"]/TechTree/St[64] 2 -> 4
|
||||
/Sim/players/Player[32 "Revenge Fleet"]/TechTree/TResDone[64] 0 -> 22469
|
||||
/Sim/players/Player[32 "Revenge Fleet"]/TechTree/TAcq[64] -1 -> 16
|
||||
/Sim/players/Player[32 "Revenge Fleet"]/TechTree/TiAcq[64] -1 -> 45
|
||||
/Sim/players/Player[32]/Events/…/EvDsc 'Research Over Budget' -> 'Research Complete'
|
||||
/Sim/players/Player[32]/Events/…/EvMsg 'Research for Micro-Fusion Drives has gone overbudget.'
|
||||
-> 'Tech Overthrusting has been acquired'
|
||||
/Sim/players/Player[32]/Events/…/EvImg 'EVENT_RESEARCH_OVERBUDGET' -> 'EVENT_RESEARCH_COMPLETE'
|
||||
/Sim/players/Player[32 "Revenge Fleet"]/ResTNm 'DRV_McroFus' -> ''
|
||||
/Sim/players/Player[32 "Revenge Fleet"]/otch/.[34] only-in-B
|
||||
/Sim/players/Player[32 "Revenge Fleet"]/otch/.[0] 33 -> 34
|
||||
```
|
||||
|
||||
**And the sub-tree digests say which halves of the save are affected**, which is the form the claim
|
||||
should take (PD4):
|
||||
|
||||
| sub-tree | OA | W | |
|
||||
|---|---|---|---|
|
||||
| `Sim/spymgr` | `9c3f224cf954aa54` | `9c3f224cf954aa54` | **identical** |
|
||||
| `Sim/systems` | `3227b08124339fe2` | `3227b08124339fe2` | **identical** |
|
||||
| `Sim/fleets` | `26a640cdfc597869` | `26a640cdfc597869` | **identical** |
|
||||
| `Sim/trdmgr` | `ed99071bdc121694` | `ed99071bdc121694` | **identical** |
|
||||
| `Sim/players` | `2d1c0cad92679606` | `46ddf6778ef36e0b` | differs |
|
||||
| `Summary` | `66db5e1055c9fe37` | `cb8a4c8e22480af0` | differs (the derived checksum) |
|
||||
|
||||
> **Every leaf this lane's numbers depend on reproduces across the pair. `spymgr` — the spy's
|
||||
> `deat`, `sdet`, `sdo`, `cm`, `cmo`, `ncp`, `cbh` — is byte-identical between an instrumented run
|
||||
> and an un-instrumented one, as is every system's `spies2`.** What does not reproduce is one AI
|
||||
> empire's research pick and the two derived values downstream of it.
|
||||
|
||||
**Three distinct picks across five processes** is worth stating plainly, because it is the first
|
||||
time this outcome set has been sampled more than twice: A/M/W completed `Overthrusting` (tech 64),
|
||||
B was part-way through `DRV_NodFoc`, OA went over budget on `DRV_McroFus`. AS observed A and M
|
||||
agreeing and correctly flagged it as a `1/k` coincidence rather than evidence about the instrument.
|
||||
With five samples the set has at least three members and the modal outcome took 3 of 5 — so the
|
||||
coincidence AS refused to lean on was about a 1-in-3 event, not a 1-in-2 one, and refusing to lean
|
||||
on it was right.
|
||||
|
||||
### 7.3 The seed-exposure predicate, checked (rule 26 corollary (c))
|
||||
|
||||
The coordinator's instruction is to record the exposure fields next to every control hash. Here they
|
||||
are for the **pre-turn** save of the control pair, and for every turn this lane played, so the
|
||||
predicate can be checked rather than asserted. `Species = 4` (NPC) players are omitted; they never
|
||||
decide. Net ids: player 16 is `re` (human), 32 is `Revenge Fleet` (the AI), 48 is `Spengler`.
|
||||
|
||||
| pre-turn save | Frame | Player[32] `ResTNm` | `NDes` | `NOwn` | ships | exposure |
|
||||
|---|---|---|---|---|---|---|
|
||||
| `as-turn14-predeploy` | 14 | **`''`** | 15 | 10 | 146 | **pick** |
|
||||
| **`as-turn15-spydeployed`** (the control input) | **15** | **`''`** | **15** | **10** | **146→148** | **pick + colonise + 2 ships** |
|
||||
| `w-16` | 16 | `''` | 15 | 11 | 157 | pick + 9 ships |
|
||||
| `w-17` | 17 | `''` | 16 | 12 | 161 | pick + design + colonise + 4 ships |
|
||||
| `w-18` | 18 | `''` | 20 | 12 | 169 | pick + 4 designs + 8 ships |
|
||||
| `w-19` | 19 | `''` | 20 | 12 | 181 | pick + 12 ships |
|
||||
| `w-20` | 20 | `'WEP_AmWhd'` | 20 | 12 | 185 | 4 ships |
|
||||
| `w-21` | 21 | `'WEP_AmWhd'` | 23 | 12 | 201 | 3 designs + 16 ships |
|
||||
| `w-22` | 22 | `'WEP_AmWhd'` | 27 | 12 | 218 | 4 designs + 17 ships |
|
||||
| `w-23` | 23 | `'WEP_AmWhd'` | 27 | 12 | 236 | 18 ships |
|
||||
| `w-24` | 24 | `'WEP_AmWhd'` | 27 | 14 | 235 | colonise ×2 |
|
||||
| `w-25` | 25 | `''` | 28 | 15 | 244 | pick + design + colonise + 9 ships |
|
||||
| `w-26` | 26 | `''` | 28 | 15 | 251 | pick + 7 ships |
|
||||
|
||||
**The predicate held, and it held in its strong direction.** The control input carries
|
||||
`Player[32].ResTNm == ''` — a pick turn — and the control varied, in exactly the research-pick leaves
|
||||
the predicate names and nothing else. Two independent lanes have now produced that signature on this
|
||||
input.
|
||||
|
||||
**And the state says something the predicate did not anticipate: on this map exposure is
|
||||
*saturated*.** Every one of the thirteen pre-turn states above carries at least one exposure
|
||||
signature; nine of thirteen carry a research pick, and every single turn adds ships. There is **no
|
||||
quiet turn anywhere in this lineage** to attempt an agreeing control on — so no rung-A oracle pair is
|
||||
obtainable from `as-turn15-spydeployed.sav` at any horizon by waiting, and a lane that wants one on
|
||||
this map must pin the client seeds instead. That is a fact about a 2-empire game where the AI runs a
|
||||
146 → 251-ship war economy, and it is the opposite end of the same axis from lane AR's quiet
|
||||
turns 38–39.
|
||||
|
||||
**One nuance that cuts against a naive reading of the predicate.** Exposure is necessary for
|
||||
variation, not sufficient *per process pair*: W (`probes=8`) and AS's A and M (two different
|
||||
configurations, two different builds, three different processes) landed on the **same** post-turn
|
||||
bytes on this exposed pick turn. A single agreeing pair on an exposed turn therefore proves nothing —
|
||||
which is rule 26's original point, now with a measured outcome-set size behind it.
|
||||
|
||||
### 7.4 OB, and the verdict
|
||||
|
||||
```
|
||||
OB (Autosave EndTurn).sav 98e45d3745b914506fc4c409ad5a5ad0938a2003ab4c845421a99a8065149c3a 76,706
|
||||
OB (Autosave).sav 262f8bda97c9511d8d2b41e6a8a0582d6f5364c2b01b1caf99e639d0e4f53ebe 77,685
|
||||
```
|
||||
|
||||
* **OA ≠ OB.** The two `hooks=off` processes of *this* lane's own control disagree, in **15 leaves,
|
||||
all of them** `Player[32]`'s research pick plus `/Summary/Checksum` and the `turnstats` `tch` cell.
|
||||
Nothing of my empire, the spy, `deat`, `sdet`, `sdo`, `cm`, `cmo`, `ncp`, `spies2`, the systems,
|
||||
the fleets or `trdmgr` moved between them.
|
||||
* **OB is byte-identical to W**, the instrumented run: `state_checksum` prints **IDENTICAL** over
|
||||
**44,438 leaves**. Both are `fc85c4228b9973fa159c1ed6aa851ae0`.
|
||||
|
||||
So the honest three-part statement, which is all the evidence supports:
|
||||
|
||||
1. **Not a calibration pair.** Two fresh un-instrumented processes on this input do not agree, so
|
||||
nothing here may enter `determinism-hashes.txt` as a rung-A pair. **PD1 and PD3 held.**
|
||||
2. **The instrument is neutral on everything this lane measured.** `probes=8` reproduced an
|
||||
un-instrumented run leaf for leaf, and the sub-trees carrying the spy state are identical across
|
||||
all three of this lane's processes. **PD4 held.** That is a stronger neutrality statement than
|
||||
lane AS could make, because AS's instrumented run agreed with only one of two controls; here it
|
||||
agrees with one control *exactly and completely* while the two controls differ from each other in
|
||||
a leaf class the instrument provably does not touch.
|
||||
3. **The divergence is the known one, and it was predicted.** **PD2 held**, and it held with the
|
||||
pre-turn exposure fields recorded in advance (§7.3) rather than diagnosed afterwards.
|
||||
|
||||
**A note for whoever certifies pairs.** Lane AS reported A ≠ B and called the class "one AI player's
|
||||
research pick plus the derived checksum". Two more processes, taken independently, land in the same
|
||||
class and add a third member to the outcome set. That is a second lane reproducing the *class* while
|
||||
failing to reproduce the *value* — which is exactly what a per-process seed feeding a small
|
||||
discrete choice should look like, and it is now measured rather than asserted.
|
||||
|
||||
---
|
||||
|
||||
## 8. Predictions scored — including the one that was wrong
|
||||
|
||||
| | prediction | verdict |
|
||||
|---|---|---|
|
||||
| **PA1** | `P` reaches at most one draw site per call, selected by `Species == 6`; only `0x00840a3c` from this save | **HELD.** No row at `0x0044092e` or `0x004409cc` on any of the twelve measured turns, including the turn `P` ran |
|
||||
| **PA2** | species table `0 Human … 4 _NPC, 5 Zuul, 6 Morrigi`; `0.75f` is Zuul, `0.5f` is Morrigi | **HELD** (corpus-wide; the launch card independently shows `re` = Human) |
|
||||
| **PA3** | `0x00840a3c` is `Chance` on a widened `0.25f` | **HELD** — `0x009e5ac0` is `00 00 80 3e` |
|
||||
| **PA4** | the spy is destroyed at the end of `vslot13` on the `P` turn | **HELD** — `nspy` 1 → 0, `spies2` emptied, no `spy` record at Frame 25 |
|
||||
| **PB1** | `sdo(f) = 0.0084 × (f − 14)` exactly, until detection | **HELD** — seven exact float32 steps, then frozen |
|
||||
| **PB2** | tail costs 1 on Frames 16, 17, 18 | **HELD** |
|
||||
| **PB3** | `0x0088dc43` first fires on Frame 19; Frame 18 bootstraps without drawing | **HELD exactly** |
|
||||
| **PB4** | **the tail costs 2 words/turn from Frame 19** | **WRONG.** It costs 2 on Frame 19 and then 4, 6, 9, 8, 9, 8, 8 |
|
||||
| **PB5** | `cm`, `spyon` move on Frame 18; `cmo` steps by `0.2f` | **HELD** |
|
||||
| **PB6** | on the detection turn `vslot13` still costs 1 and `sdet := T` | **HELD** — Frame 22 |
|
||||
| **PB7** | `vslot13` costs **zero** on `T+1`, `T+2` while still being entered | **HELD** — Frames 23, 24: no row, probe reads 1 |
|
||||
| **PB8** | `T+3`: one row at `0x0044_0a41`, 1/1/0/strategic; no `0x0048_7c8f`; `vslot14` contributes 0 | **HELD in all three parts** |
|
||||
| **PB9** | the `Slot13RngCallee` probe reads 1 on `T+3` | **HELD** — its first non-zero in the campaign |
|
||||
| **PB10** | 11 % by +4, 43 % by +10, 70 % by +15, 87 % by +20 | **not tested.** Detection landed at +7, where the model says 26 %. One sample is consistent with the model and does not test it |
|
||||
| **PB11** | residual 0 on every turn | **HELD** on all eleven turns of W and on run D |
|
||||
| **PB12** | the +20 tail case | **not reached** |
|
||||
| **PC1** | `0x0038c984`, `NextFloat`, 1/1/0, strategic | **HELD exactly** |
|
||||
| **PC2** | in the `ProcessTurn` bracket | **HELD** |
|
||||
| **PC3** | the same turn's tail costs exactly 1 | **HELD** |
|
||||
| **PC4** | `cbh` reproduces `5.033599376678467` exactly | **HELD** |
|
||||
| **PC5** | `spies2` 0 → `[1]`, `deat` → 400, `tdep := 15`, `sdo := 0.0084` | **HELD** |
|
||||
| **PD1** | the control pair's pre-turn saves agree, post-turn saves differ | **HELD** |
|
||||
| **PD2** | the divergence is one AI's research pick + checksum + `tch`, and nothing of mine | **HELD** — 15 leaves, localised |
|
||||
| **PD3** | not a calibration pair; must not enter `determinism-hashes.txt` | **HELD**, and stated in advance |
|
||||
| **PD4** | the sub-trees this lane's numbers depend on reproduce | **HELD** — `spymgr`, `systems`, `fleets`, `trdmgr` digests identical; and W is byte-identical to OB over 44,438 leaves |
|
||||
|
||||
### 8.1 PB4, the one that was wrong, and why it was wrong
|
||||
|
||||
I predicted the **tail bracket** would cost 2 words per turn from Frame 19, on the reasoning that
|
||||
`vslot13` contributes 1 and `vslot14` contributes 1. Both halves of that were right on every single
|
||||
turn. The prediction was still wrong, because **the tail has a third contributor and I treated it as
|
||||
a constant zero.**
|
||||
|
||||
```
|
||||
Frame 16 17 18 19 20 21 22 23 24 25 26
|
||||
vslot13 1 1 1 1 1 1 1 0 0 0 0 <- predicted exactly
|
||||
vslot14 0 0 0 1 1 1 1 1 1 0 0 <- predicted exactly
|
||||
0x00820e1d 0 0 0 0 2 4 7 7 8 7 8 <- NOT PREDICTED
|
||||
tail bracket 1 1 1 2 4 6 9 8 9 8 8
|
||||
```
|
||||
|
||||
`0x00820e1d` is the **trade-raid roll** in `TradeManager::Slot13RngCalleeA` — lane AC's site, priced
|
||||
per fleet by lane AD. It was at zero on Frames 16–19 and entered the tail on Frame 20, growing to 8.
|
||||
That is the AI's raider fleets arriving on trade-sector nodes as its navy went from 157 to 251
|
||||
ships: **`calls == words == the number of qualifying fleets`, exactly lane AD's per-fleet model**,
|
||||
now reproduced on a different map, a different lineage and an AI-owned fleet rather than a
|
||||
player-owned one. AD measured 2; this run measured 2, 4, 7, 7, 8, 7, 8 on seven consecutive turns.
|
||||
|
||||
The lesson is rule 20's, in the direction nobody watches: I checked that my *sites* were priced, and
|
||||
then quoted a *bracket* total as if the bracket contained only my sites. A bracket is a sum over
|
||||
subsystems, and predicting one requires predicting all of them. The correct form of PB4 was "the
|
||||
**spy** contribution to the tail is 2 words per turn from Frame 19", which is what was measured and
|
||||
what should have been written.
|
||||
|
||||
**It is also the most useful failure available**, because a wrong bracket prediction that decomposes
|
||||
cleanly into "my model was right, an unmodelled neighbour moved" is a free confirmation of the
|
||||
neighbour's model. The residual was 0 on every turn, so nothing is unaccounted for.
|
||||
|
||||
---
|
||||
|
||||
## 9. Coverage — what this did not touch, said as loudly as what it did
|
||||
|
||||
* **`0x00840929` and `0x008409c7` remain unfired, and are now known to need a Morrigi empire.**
|
||||
That is a *stronger* negative than "not reached in the states measured": the gate is decoded, the
|
||||
branch was taken twelve times in the other direction, and the predicate is a single field on the
|
||||
spy's owner. **The workload that closes them, named from the failed conjunct:** a Morrigi
|
||||
single-player game, four spy techs, a spy deployed at a foreign colony with a belt, and ~7 turns of
|
||||
waiting. `0x008409c7` needs one more thing on top — the roll at `0x00840929` must *succeed* (75 %)
|
||||
**and** the candidate list must be non-empty, which needs a **third** non-eliminated empire that is
|
||||
neither the spy's owner nor the target's. This map has one (`Spengler`), so a 3-empire Morrigi game
|
||||
reaches both.
|
||||
* **`P` ran exactly once.** Everything about its cost is a single observation. The loop is over the
|
||||
spy vector, so two spies detected three turns apart should give two calls on different turns and
|
||||
two spies detected on the *same* turn should give two calls on one turn — **that is a reading, not
|
||||
a measurement** (rule 20: do not fit a constant to one observation).
|
||||
* **The `sdo` arithmetic is still validated only in its first and third terms.** `countA`, `countB`
|
||||
and the species multiplier were 0 / 0 / 1.0 for all eleven turns. `countC` held at 2 throughout,
|
||||
which is why the line is straight; nothing here identifies *what* `countC` counts, only that it did
|
||||
not change while one fleet of one ship sat at Kepler.
|
||||
* **The auto-detect arm `(TerrFl & 1) == 0` was never taken.** Lane AS flagged it as the most
|
||||
load-bearing unmeasured branch in the chain and it still is. Nothing in this lane touched it.
|
||||
* **The `ncp`-blocks-rebootstrap gate was never reached** (§5.4 item 3). `cm` never wrapped 4 → 0
|
||||
because the spy was destroyed at Frame 25 with `cm = 4`. Two more turns of survival would have
|
||||
tested it; a second spy deployed later than the first would too.
|
||||
* **`P`'s return value was not traced.** The Frame-25 roll's outcome (whether `re` was named in
|
||||
Kepler's `EVENT_SPY_DESTROYED` event, a 25 % chance) was not read out of the event text. The
|
||||
ledger prices the site; the semantics in §1.2 are from the instruction stream.
|
||||
* **One turn, one process for the eleven-turn series.** W is a single process. The control pair
|
||||
covers only its **first** turn. Frames 17–26 have no two-process control at all, and by §7.3 every
|
||||
one of them is an exposed turn, so they should not be assumed reproducible.
|
||||
* **Turn 27 was not played.** The driver stopped on a Von Neumann encounter dialog at Rigel, which is
|
||||
where the series ends. Nothing after Frame 26 is measured.
|
||||
* **`probes=11` was not used anywhere in this lane**, and no number here is comparable to lane AC's
|
||||
turn totals.
|
||||
* **No `Guard` region is declared by any hook in this family** — the same gap lanes Z, H, AS and AR
|
||||
reported. `undeclared = 0` in these traces is vacuous.
|
||||
* **The species table is read from the save's own `ISsp` list**, cross-checked on one Zuul save and
|
||||
one hook report. No Morrigi, Hiver, Liir or Tarka save exists in the corpus, so indices 1, 2, 3 and
|
||||
6 are named but not exercised.
|
||||
|
||||
---
|
||||
|
||||
## 10. Corrections to earlier findings (rule 11)
|
||||
|
||||
* **Lane AS §6, board row 207, lane AG §6 and this lane's own brief: "`P`'s three draws".**
|
||||
`0x00840929`, `0x008409c7` and `0x00840a3c` are **not three sites behind one gate**. They are two
|
||||
mutually exclusive branches selected by `spyOwner->Species == 6`, and no call can reach more than
|
||||
one of them. Every inventory that lists them as a group of three should say so. §1.2.
|
||||
* **Lane AG §3.2's caution to lane AS: "a spy program run without FTL Economics takes a different
|
||||
branch of the machine".** The `CnTrd` the stage machine consults at `cm 1 → 2/3` is the **target
|
||||
system owner's**, not the spy owner's. My empire has `CnTrd = False` and the machine still took the
|
||||
`1 → 2` arm, because Kepler's owner has `CnTrd = True`. §5.4 item 4.
|
||||
* **Lane AG §3.2's `ncp` reading.** `ncp` is a scalar `int` in the stream, and it behaves as a
|
||||
**counter of completed counter-mission stages** (0,0,1,1,2,2,3 in lock-step with `cm`). "Non-empty"
|
||||
is therefore `!= 0`, and the branch that consults it was never reached here. §5.4 item 3.
|
||||
* **Lane AS §1.4 / §6.1: "`cbh = NextFloat() * 2*pi`".** Correct in value; the code is
|
||||
`lerp(0.0, 2*pi, r)` with a float32 round in the middle, and the angle is `DeploySpy`'s **second**
|
||||
argument, set up before `0x0080c860` (a zero-argument getter) is called across the half-built
|
||||
frame. AS's "`spy->cbh := <the float argument>`" is right; §6.2 only names which argument.
|
||||
* **Lane AS §6's detection-probability table** (38 % / 65 % / 85 % at +10 / +15 / +20) is the right
|
||||
model evaluated one turn late. `AccumulateDetectionOdds` runs *before* the gate, so the roll on the
|
||||
End Turn producing Frame `f` uses `sdo = 0.0084 × (f − 14)`, not `0.0084 × (f − 15)`. The corrected
|
||||
figures are 43 % / 70 % / 87 %. Measured `sdo` (§5.3) settles it: the Frame-16 autosave already
|
||||
holds 0.0168, so the Frame-16 roll was at 0.0168.
|
||||
* **Lane AG's audit and lane V2's inventory have a column they need.** `0x0078c97f`'s predicate is
|
||||
*"a `SHIPACTION_DEPLOYSPY` command in this turn's command stream"*. It is now **measured**, so the
|
||||
gate-indexed audit's two cell kinds (a firing, or a save predicate) become three: a firing, a save
|
||||
predicate, or a **stream** predicate. This is the first entry in that column.
|
||||
|
||||
---
|
||||
|
||||
## 11. Artifacts
|
||||
|
||||
| what | where |
|
||||
|---|---|
|
||||
| the instrumented eleven-turn trace (per-turn `draw_sites` + `probe_entries` + brackets) | `verify/traces/ap-probes8-turn16-turn26.jsonl.gz` |
|
||||
| the deploy-turn trace | `verify/traces/ap-probes8-deploy-turn15.jsonl.gz` |
|
||||
| shim log for the eleven-turn run | `verify/results/shim/ap/ap-probes8-w.shim.log` |
|
||||
| shim log for the deploy run | `verify/results/shim/ap/ap-probes8-d.shim.log` |
|
||||
| **the detected-spy save** — first `sdet != -1`, first non-zero `cm`/`cmo`/`ncp`/`spyon` in the corpus | `verify/results/saves/ap-turn22-spydetected.sav` (83,188 B, `--strict` 0 errors / 0 warnings) |
|
||||
| **the post-`P` save** — the spy destroyed, `nspy` back to 0, `spies2` emptied | `verify/results/saves/ap-turn25-spydestroyed.sav` (84,487 B, `--strict` clean) |
|
||||
| the deploy run's Frame-15 autosave (`cbh` reproduced) | `verify/results/saves/ap-deploy-turn15.sav` |
|
||||
| the two control post-turn saves | `verify/results/saves/ap-oa-turn16.sav`, `ap-ob-turn16.sav` |
|
||||
| addresses this lane mints | `ghidra/addresses.d/ap.json` |
|
||||
| predictions, committed before the build | this file §0–§3, commit `f8ff1b6` |
|
||||
| instrument | `sots-engine` `src/shim/shim.cfg.hp8` and `shim.cfg.hoff`, **both unchanged** — this lane wrote no engine code |
|
||||
|
||||
### 11.1 The hashes, for the record
|
||||
|
||||
```
|
||||
input MyGameas1spydep.sav 854a10fa1ea602f0f7909f9bf9154942e56ea5fa1db4cce47d6d32bf53952e08
|
||||
A/B/M/OA/OB (Autosave EndTurn).sav 98e45d3745b914506fc4c409ad5a5ad0938a2003ab4c845421a99a8065149c3a
|
||||
W (probes=8) turn 16 262f8bda97c9511d8d2b41e6a8a0582d6f5364c2b01b1caf99e639d0e4f53ebe
|
||||
OB (hooks=off) turn 16 262f8bda97c9511d8d2b41e6a8a0582d6f5364c2b01b1caf99e639d0e4f53ebe
|
||||
OA (hooks=off) turn 16 e296394f578b3a5668e5934b9eec8d6c4638ca7411200078f97de1abd346f4c5
|
||||
turn 22 (detection) 91381bd7e722ac3847795a402d78ebb31d74dbb5d2909f33d243aec3ef8abaf8
|
||||
turn 25 (P ran; spy destroyed) 46380fcf4498d67507e4471eb9ee3762647c53ee5473be142fe5c34e37344bc3
|
||||
deploy run, turn 15 844f2b746060dc2c4e2099cdc6ceffd5f55ef858c9e347df28c8aca3041f7165
|
||||
shim binkw32.dll ap-989c692-… ae084ed4774caf24ea7927fcb012d1999633f10556c7c99f0209f66067416a17
|
||||
```
|
||||
|
||||
**None of these is a calibration pair.** §7.
|
||||
|
||||
---
|
||||
|
||||
## 12. VM144 as left
|
||||
|
||||
**Restored and verified by screenshot at the main menu**, profile `re`, 2026-09-09.
|
||||
|
||||
* `C:\SOTS\binkw32.dll` restored to lane L3's build from `C:\SOTS\shimdist-l3\binkw32.dll`
|
||||
(sha256 `479B8614D2417603…`, byte-identical to what this lane found in place).
|
||||
* `C:\SOTS\shim.cfg` restored from `C:\SOTS\ui\preAS-shim.cfg` (L3's `shim.cfg.l3probe`,
|
||||
`probes=11`).
|
||||
* The three autosaves restored **byte-identical** from `C:\SOTS\ui\preAS-SavedGames`
|
||||
(`1985E6F4…` / `24B2E072…` / `5EC80C1E…`). This lane's eleven turns had overwritten their contents;
|
||||
lane AS's snapshot is what made the restore possible and it is worth keeping.
|
||||
* `C:\SOTS\shim.trace.jsonl` and `shim.log` removed before the relaunch.
|
||||
|
||||
**`SavedGames` is still 15 files** — this lane added none and removed none, so **lane AS's row
|
||||
positions still hold**: `MyGameas1predeploy` at **(400, 347)**, `MyGameas1spydep` at **(400, 376)**,
|
||||
`OK` at (682, 624). Verified by screenshot twice this session. All fifteen files hash as AS left
|
||||
them.
|
||||
|
||||
Left in place, all harmless: `C:\SOTS\shimdist-ap\` (build `ap-989c692-20260909T0425Z`, 63 files),
|
||||
`C:\SOTS\ui\apgo.ps1`, `C:\SOTS\ui\aphash.ps1`, `C:\SOTS\ui\ap\` (the End-Turn driver, its per-turn
|
||||
saves and screenshots), and the scheduled task **`SOTSAP`**. `click_helper.ps1` was **not touched** —
|
||||
this lane needed no new verbs either.
|
||||
|
||||
### 12.1 Guest notes worth carrying forward
|
||||
|
||||
* **The End-Turn driver is the reusable part.** `C:\SOTS\ui\ap\ap_loop.ps1`, run through the
|
||||
`SOTSAP` scheduled task (an `InteractiveToken` clone of `SOTSUI`), reads `C:\SOTS\ui\ap\job.txt`
|
||||
(`turns=`, `tag=`, `first=`, `maxwait=`), clicks End Turn, **polls the autosave's mtime** until it
|
||||
moves, snapshots `(Autosave).sav` to `ap\saves\<tag>-<NN>.sav`, and **stops on the first stall with
|
||||
a screenshot**. Eleven turns cost 11 minutes unattended. Set `job.txt`, `schtasks /Run /TN SOTSAP`,
|
||||
then watch `ap\loop.log` from outside.
|
||||
* **Nine minutes of this lane went into a screenshot-lag artefact, and the lesson is general.**
|
||||
Four consecutive clicks appeared to select the wrong Load-dialog rows, which read exactly like a
|
||||
coordinate offset and nearly produced a "the click helper is 87 px out on this guest" note. It was
|
||||
not: the click task takes ~3 s to start and ~3 s to run, and a screenshot taken 4 s after
|
||||
`schtasks /Run` shows the state **before** the click. **Wait ≥ 9 s between triggering the click
|
||||
task and screenshotting.** Every documented coordinate on this guest is correct.
|
||||
* **The first click after `fg` is swallowed** by the focus activation. Send `fg`, then `move`, then
|
||||
`sleep`, then `click` — or spend a throwaway click.
|
||||
* **A `wheel` zoom on the star map separates systems that overlap at the default zoom.** Lane AS lost
|
||||
a run to Kepler and Midway sharing a hit test; six notches at the cluster centre and then eight more
|
||||
at the target spread them to ~120 px apart, and the labels render. No affine fit was needed.
|
||||
* **Selecting the system, not the fleet, is what enables `Special`.** With Kepler selected the left
|
||||
panel grows a `Fleets at Kepler` list and `Manage Fleets` / `Move` / `Special` light up;
|
||||
`Special → Deploy Spy` then opens a ship picker whose ship is already selected, so `OK` is the only
|
||||
further click. The whole deploy is four clicks once the right star is under the cursor.
|
||||
* **The pixel test for "is the main menu up" must sample the button, not its label.** (511, 536) is
|
||||
inside the white text of `Load Game` and reads ~(195,191,191) on a bright frame; (470, 530) is the
|
||||
button itself and reads (184, 0, 0). A test on the first point passes only by luck on a dark frame.
|
||||
* **An End Turn on this state costs 6 seconds** under `probes=8` with ~150–250 AI ships. The
|
||||
campaign's "30–45 s per End Turn" figure is from a different guest and a different config.
|
||||
* Turn 27 raised a **Von Neumann encounter at Rigel** ("No ships available", `Done` at (233, 673)).
|
||||
A driver that polls the autosave rather than the screen stalls on it cleanly instead of clicking
|
||||
through something it cannot see.
|
||||
|
||||
---
|
||||
|
||||
## Proposed board rows
|
||||
|
||||
New row:
|
||||
|
||||
```
|
||||
| THE SPY ATTRIBUTION ROLL FIRES - and P's "three draws" are TWO SPECIES BRANCHES, only one reachable per game | verify | verified | high | 100% | 2026-09-09 | **Lane AP, VM144, build `ap-989c692-20260909T0425Z`, `probes=8` (never 11), own build dir /srv/re-lab/build/sots-engine-ap rm -rf'd first.** Continues lane AS from `as-turn15-spydeployed.sav`: **11 End Turns, 6 SECONDS EACH** (the brief budgeted an evening; the cost is the launch and the load, not the turns). **DETECTION AT FRAME 22, `P` RAN AT FRAME 25.** `Mars::RNG::Chance` at **0x00840a3c** fired **1 call / 1 word / no_draw_calls=0 / strategic=true** at `ret_rva 0x00840a41` - a site that had never fired. **CORRECTION TO EVERY INVENTORY (row 207, lane AG 6, lane AS 6, and this lane's own brief): 0x00840929 / 0x008409c7 / 0x00840a3c ARE NOT THREE SITES BEHIND ONE GATE.** `SpyManager::Slot13RngCallee 0x008408e0` opens `cmp [spyOwner+0x5c], 6; jne` - `Species == 6` (MORRIGI) takes `Chance(0.75f)` at 0x00840929 and then `NextInt` at 0x008409c7 to blame a RANDOM THIRD EMPIRE (a false flag; the true owner is never named); every other species takes `Chance(0.25f)` at 0x00840a3c and on success returns the TRUE owner. **No call can reach more than one.** Species table decoded from the save's own ISsp list and cross-checked on lane V's Zuul save: **0 Human, 1 Hiver, 2 Tarkas, 3 Liir, 4 _NPC, 5 Zuul, 6 Morrigi** - which also NAMES lane AS's two unexplained multipliers in `AccumulateDetectionOdds` (0.75f = ZUUL, 0.5f = MORRIGI). Constants read as the four bytes (rule 23): 0x009e5ac0 = 0.25f, 0x009e5ac4 = 0.75f (the same word AS read as the Zuul multiplier). **0x008409c7 needs BOTH the 0.75f roll to succeed AND a third non-eliminated empire** that is neither the spy's owner nor the target's. **SECOND SITE CLOSED: 0x0088dc43** (the counter-mission roll, lane AG 3.2, corpus 0 of 22, never fired) fires 1 word/turn from **Frame 19**; the bootstrap turn (Frame == tdep+3) sets spyon/cm:=1/cmo:=0.2f and DRAWS NOTHING. `cm`, `cmo`, `spyon`, `ncp` - four of the value-domain census's 234 single-valued fields - are all OFF ZERO with a measured trajectory. **TWO CORRECTIONS TO AG 3.2:** the `CnTrd` the stage machine consults at cm 1->2/3 is the TARGET OWNER's not the spy owner's (my player has CnTrd=False and it still took 1->2, because Kepler's owner has CnTrd=True), and `ncp` is a SCALAR COUNTER of completed stages (0,0,1,1,2,2,3 in lock-step with cm), not a container. **THIRD SITE CLOSED: 0x0078c97f**, the deploy `NextFloat` in the SHIPACTION_DEPLOYSPY handler that is in NO inventory - 1 call / 1 word / strategic, in the **ProcessTurn** bracket, and **spy.cbh came out 5.033599376678467 BIT-IDENTICAL to lane AS's** from a different process, build and session. **Its predicate is on the COMMAND STREAM, and this is the first measured entry in a column the gate-indexed audit does not have.** THE POLARITY CASE, MEASURED: on Frames 23 and 24 (sdet+1, sdet+2) `vslot13` is ENTERED (probe = 1) and costs **ZERO** - a third arm of the same function, and `sdo` FREEZES at 0.0672 in the save, proving branch D stopped independently of the ledger. On Frame 25 the entry probe on `SpyManager::Slot13RngCallee 0x008408e0` reads **1** - ITS FIRST NON-ZERO EVER, the complement of lane AS's demonstration that its zero said nothing about the subtree. The spy is DESTROYED at the end of phase 23 on sdet+3 by manager vtable slot 10 `0x00838480` -> `ServerSystem::RemoveSpy`, so vslot14 costs 0 that turn: nspy 1->0, spies2 emptied. `sdo` measured on NINE points, exactly `0.0084*(f-14)` as float32 (`3c89a027 3cce703a 3d09a027 3d2c0831 3d4e703b 3d70d845 3d89a027`), which also corrects AS's detection-probability table by one turn: **43%/70%/87%** at +10/+15/+20, not 38/65/85. Residual **0 on all 12 measured turns**, overflow 0. **ONE PREDICTION WRONG AND NAMED: PB4** said the tail costs 2 words/turn from Frame 19; it costs 2,4,6,9,8,9,8,8 because the TRADE-RAID roll 0x00820e1d entered the tail at Frame 20 and grew 2,4,7,7,8,7,8 as the AI's navy went 157->251 ships - an independent live re-confirmation of lane AD's per-fleet model on a different map and an AI-owned fleet. The spy halves were predicted exactly; quoting a BRACKET total requires modelling every subsystem in it. Saves `ap-turn22-spydetected.sav`, `ap-turn25-spydestroyed.sav`, `ap-deploy-turn15.sav`; findings `findings/subsystems/spy-program-draws.md` |
|
||||
```
|
||||
|
||||
```
|
||||
| CONTROL ON as-turn15: THREE OUTCOMES IN SIX PROCESSES, and exposure is SATURATED on this map | verify | verified | high | 100% | 2026-09-09 | Lane AP, VM144. Two fresh `hooks=off` processes (OA, OB) on `MyGameas1spydep.sav` + 1 End Turn, added to lane AS's A/B/M and this lane's `probes=8` run W. **Pre-turn `(Autosave EndTurn).sav` is byte-identical across four processes, two lanes and TWO DIFFERENT BUILDS** (`98e45d3745b91450...`). Post-turn: **three distinct outcomes in six processes** - `262f8bda` x4 (AS's A and M, AP's W and OB), `e34775a7` x1 (AS's B), `e296394f` x1 (AP's OA). **OA != OB, so this is NOT a calibration pair and must not enter `determinism-hashes.txt`** - stated in advance as PD3. OA vs OB diverge in **15 leaves, ALL of them Player[32]'s research pick plus /Summary/Checksum and one turnstats `tch` cell**; three distinct picks were sampled (Overthrusting completed / DRV_NodFoc in progress / DRV_McroFus over budget). **`probes=8` IS BYTE-NEUTRAL, PROVEN PROPERLY THIS TIME: W is IDENTICAL to OB over 44,438 leaves** (`state_checksum --floats bits --mask none`), while the two un-instrumented controls differ from each other - so the instrument agrees exactly with a control in a leaf class it provably does not touch. Sub-tree digests: `Sim/spymgr`, `Sim/systems`, `Sim/fleets`, `Sim/trdmgr` all IDENTICAL across the pair; only `Sim/players` and the derived `Summary` move. **RULE 26(c) EXPOSURE FIELDS RECORDED NEXT TO THE HASHES** (coordinator's request): the control input carries `Player[32].ResTNm == ''` - a pick turn - and it varied in exactly the leaves the predicate names. **AND THE PREDICATE IS SATURATED ON THIS MAP: all 13 pre-turn states from Frame 14 to Frame 26 carry at least one exposure signature** (9 of 13 a research pick, every single one a batch of ship completions, four a design, four a colonisation; Player[32]'s navy goes 146 -> 251 ships in twelve turns). **There is NO quiet turn anywhere in this lineage**, so no rung-A pair is obtainable from `as-turn15-spydeployed.sav` by waiting - the opposite end of the axis from lane AR's turns 38-39, and a lane that wants a pair on this map must pin the client seeds. Counter-nuance: exposure is necessary for variation, not sufficient per pair - W, A and M (three processes, two configurations, two builds) landed on the SAME bytes on this exposed turn, so a single agreeing pair on an exposed turn proves nothing. Saves `ap-oa-turn16.sav`, `ap-ob-turn16.sav` |
|
||||
```
|
||||
|
||||
Edits to existing rows:
|
||||
|
||||
- **Row 62** (guest holders) — see §12.1 for the exact replacement text.
|
||||
- **Row 207** (V2's eight sites) — append: `CORRECTED AND ADVANCED 2026-09-09 by lane AP. 0x00840a3c FIRED (1 word, Frame sdet+3 from as-turn15-spydeployed.sav). 0x00840929 and 0x008409c7 are NOT two more sites behind the same gate - they are the MORRIGI branch of SpyManager::Slot13RngCallee (`cmp [spyOwner+0x5c],6`), mutually exclusive with 0x00840a3c, and unreachable in any Human/Hiver/Tarka/Liir/Zuul game. Closing them needs a MORRIGI empire (and, for 0x008409c7, a third surviving empire). Of V2's eight, only 0x0082cdb8 (trade 15) is now both reachable and unfired.`
|
||||
- **Row 418** (lane AS's detection-roll row) — append: `EXTENDED 2026-09-09 by lane AP: the roll fired on seven consecutive turns and SUCCEEDED on Frame 22; `sdo` is exactly 0.0084*(f-14) as float32 over NINE points and FREEZES the moment sdet stamps. AS's probability table is one turn late - the corrected figures are 43%/70%/87% at +10/+15/+20. AS's 0x0078c97f is now MEASURED (1 word, ProcessTurn bracket) and `cbh` reproduced bit-identically across processes and builds.`
|
||||
- **The `0x0088dc43` row of lane AG's audit (§3.2)** — `FIRED 2026-09-09 by lane AP, 1 word/turn from Frame 19 (= tdep + 4). The bootstrap turn draws nothing. TWO CORRECTIONS: the CnTrd consulted at cm 1->2/3 is the TARGET OWNER's, and `ncp` is a scalar counter of completed stages, not a container.`
|
||||
- **The gate-indexed audit's cell taxonomy** — `A THIRD CELL KIND EXISTS AND NOW HAS ITS FIRST MEASURED ENTRY: a STREAM predicate. 0x0078c97f fires once per SHIPACTION_DEPLOYSPY command applied; no predicate over the save can express it, and no call-graph sweep can find it (stack-built ship-action table, lane B6's class).`
|
||||
|
|
|
|||
69
ghidra/addresses.d/ap.json
Normal file
69
ghidra/addresses.d/ap.json
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
{
|
||||
"_note": "Lane AP (2026-09-09). The rest of the spy program's draw sites, read from the instruction stream of dumps/sots.exe (disassembled to the NEXT FUNCTION START, rule 17 -- no Ghidra size is used below) and then MEASURED live on VM144 under probes=8, build ap-989c692-20260909T0425Z. Evidence: findings/subsystems/spy-program-draws.md. The headline is that SpyManager_Slot13RngCallee 0x008408e0 (already named in lane-h.json, not re-minted here) contains TWO MUTUALLY EXCLUSIVE BRANCHES selected by the spy owner's Species, so its three draw sites can never all be reached: 0x00840929 + 0x008409c7 are Morrigi-only and 0x00840a3c is everyone else. NOT minted here because other fragments already have them: SpyManager_Slot13RngCallee 0x008408e0 (lane H), ServerSpyManager_vslot13 0x008877b0 and vslot14 0x0088db80 (lane V2), ServerSpyManager_DeploySpy 0x00887410 and ServerSystem_AddSpy/RemoveSpy (lane AS), Mars_RNG_NextFloat/NextInt/Chance (addresses.json).",
|
||||
"entries": [
|
||||
{
|
||||
"name": "SpyManager_ShipActionDeploySpyHandler",
|
||||
"addr": "0x0078c930",
|
||||
"convention": "__thiscall",
|
||||
"prototype": "bool (Game::StrategyServer* this, Game::Ship* ship) /* body 0x0078c930..0x0078c9e0 (next function start), `ret 4`. Entry of the STACK-BUILT SHIP-ACTION TABLE (lane B6's indirection class): no direct callers, no vtable slot, invisible to every call-graph sweep this campaign has run. One gate -- a 12-byte stack query object (vtable 0x00a09648) built at 0x0078c93d and asked about the ship at 0x0078c964; false => return with NO DRAW. Past it: `mov ecx,[esi+0x16c]; add ecx,4; call Mars_RNG_NextFloat` at 0x0078c97f -- ONE STRATEGIC-GENERATOR WORD PER APPLIED Deploy Spy ORDER, inside ApplyAllTurnCommands, i.e. the ProcessTurn bracket and NOT the tail's. The angle is lerp(0.0, 2*pi, r) computed through a FLOAT32 temp at [ebp+8] (fldz supplies LO; HI is the double 6.2831854820251465 at 0x009e21b0), stored to the stack slot pushed at 0x0078c998, which is DeploySpy's SECOND argument. 0x0080c860 is then called ACROSS that half-built frame and does not touch it. MEASURED lane AP 2026-09-09: 1 call / 1 word / no_draw_calls=0 / strategic=true at ret_rva 0x0078c984, and spy.cbh came out 5.033599376678467 -- BIT-IDENTICAL to lane AS's value from a different process, build and session, so this draw is reproducible from the save. ITS PREDICATE IS ON THE COMMAND STREAM, not on save fields: `a SHIPACTION_DEPLOYSPY command in this turn's command stream`. The gate-indexed audit has no column for that and should grow one */",
|
||||
"status": "verified",
|
||||
"source": "findings/subsystems/spy-program-draws.md (lane AP 2026-09-09)"
|
||||
},
|
||||
{
|
||||
"name": "Ship_GetAttachedSpyId",
|
||||
"addr": "0x0080c860",
|
||||
"convention": "__thiscall",
|
||||
"prototype": "int (Game::Ship* this) /* 7 bytes, complete: `mov eax,[ecx+0xa8]; ret`. A zero-argument getter for the ship's attached-spy id -- the same field ServerSpyManager_DeploySpy clears when it detaches the craft from its tender. Recorded because at its ONE call site (0x0078c9ac, in the SHIPACTION_DEPLOYSPY handler) it looks like it takes a float: the caller has already pushed DeploySpy's second argument and stored the deploy angle into it, and this call runs across that half-built frame without disturbing it. An eye following eax there misses where the angle goes */",
|
||||
"status": "verified",
|
||||
"source": "findings/subsystems/spy-program-draws.md (lane AP 2026-09-09)"
|
||||
},
|
||||
{
|
||||
"name": "SpyManager_DestroySpyById",
|
||||
"addr": "0x00838480",
|
||||
"convention": "__thiscall",
|
||||
"prototype": "void (Game::ServerSpyManager* this, int sid) /* Game::ServerSpyManager vftable 0x00a3073c SLOT 10. Looks the SpyCraft up by id through vtable slot 5, then: if spy->deat(+0x10) != 0, registry_lookup(server+0x84, deat) and ServerSystem_RemoveSpy 0x0074f550 on that system (which clears deat and erases sid from spies2); if spy->atto(+0xc) != 0, clear the tender's ship->[+0xa8] and spy->atto; erase the craft from the manager's vector at this+0x10 via 0x0059ec00; then the scalar deleting destructor with flag 1. CALLED FROM ServerSpyManager_vslot13's drain loop at 0x00887eb0, back to front over the local vector<int> of sids collected at 0x008878a1 -- so a spy detected on turn T is DESTROYED at the end of phase 23 on turn T+3, BEFORE vslot14 runs at phase 33. MEASURED lane AP 2026-09-09: nspy 1 -> 0 and spies2 emptied between the Frame-24 and Frame-25 autosaves, and 0x0088dc43 cost 0 on Frame 25 although vslot14 was still entered */",
|
||||
"status": "verified",
|
||||
"source": "findings/subsystems/spy-program-draws.md (lane AP 2026-09-09)"
|
||||
},
|
||||
{
|
||||
"name": "SpyManager_AttributionRoll_MorrigiBranch",
|
||||
"addr": "0x00840929",
|
||||
"convention": "site",
|
||||
"prototype": "/* NOT A FUNCTION -- the `call Mars_RNG_Chance 0x008e6dd0` at 0x00840929 inside SpyManager_Slot13RngCallee 0x008408e0, return address 0x0084092e. Reached ONLY when the destroyed spy's owner has ServerPlayer.Species (+0x5c) == 6, i.e. MORRIGI (species table read from the save's own ISsp list: 0 Human, 1 Hiver, 2 Tarkas, 3 Liir, 4 _NPC, 5 Zuul, 6 Morrigi). Probability is the WIDENED FLOAT at 0x009e5ac4 = 0.75f -- the same four bytes SpyCraft_AccumulateDetectionOdds uses as its species-5 multiplier. Generator: `mov ecx,[eax+0x16c]` -- the STRATEGIC generator OBJECT (not the +4 sub-object). One word at 0 < p < 1. On success the function walks StrategyServer+0x54..+0x58 collecting every player with [+0xfb]==0 and [+0xf8]==0 that is neither the spy's owner nor the target system's owner, and picks one -- a FALSE FLAG; the true owner is never returned for a Morrigi spy. UNFIRED: lane AP measured twelve turns including the one turn the function ran and this branch was never taken, because its Species was 0. THE WORKLOAD THAT CLOSES IT is a Morrigi empire, not a different save of a Human one */",
|
||||
"status": "verified",
|
||||
"source": "findings/subsystems/spy-program-draws.md (lane AP 2026-09-09)"
|
||||
},
|
||||
{
|
||||
"name": "SpyManager_AttributionRoll_MorrigiPick",
|
||||
"addr": "0x008409c7",
|
||||
"convention": "site",
|
||||
"prototype": "/* NOT A FUNCTION -- the `call Mars_RNG_NextInt 0x004271c0` at 0x008409c7 inside SpyManager_Slot13RngCallee 0x008408e0, return address 0x008409cc. Generator: `mov ecx,[...+0x16c]; add ecx,4` -- the +4 SUB-OBJECT. Bound is `count - 1` passed BY POINTER at [ebp+8] (inclusive), so the index is uniform over the candidate list. TWO conditions past the Morrigi branch: the 0.75f roll at 0x00840929 must SUCCEED, and the candidate list must be NON-EMPTY -- `cmp ecx,eax; je 0x840a07` at 0x008409ac returns NULL with no draw when it is empty, which needs a third non-eliminated empire that is neither the spy's owner nor the target's. UNFIRED for the same reason as 0x00840929 */",
|
||||
"status": "verified",
|
||||
"source": "findings/subsystems/spy-program-draws.md (lane AP 2026-09-09)"
|
||||
},
|
||||
{
|
||||
"name": "SpyManager_AttributionRoll_DefaultBranch",
|
||||
"addr": "0x00840a3c",
|
||||
"convention": "site",
|
||||
"prototype": "/* NOT A FUNCTION -- the `call Mars_RNG_Chance 0x008e6dd0` at 0x00840a3c inside SpyManager_Slot13RngCallee 0x008408e0, return address 0x00840a41. Taken for EVERY species except 6 (Morrigi), i.e. the `jne 0x840a29` at 0x00840910. Probability is the WIDENED FLOAT at 0x009e5ac0 = 0.25f. Generator: `mov ecx,[edx+0x16c]` -- the STRATEGIC generator object. One word. On success the function returns arg1, the spy's OWN owner: the victim correctly identifies who sent the spy, 25% of the time; otherwise NULL and the event names no empire. FIRED FOR THE FIRST TIME IN THIS CAMPAIGN, lane AP 2026-09-09: 1 call / 1 word / no_draw_calls=0 / strategic=true at ret_rva 0x00840a41, on the End Turn producing Frame sdet+3 (sdet=22, so Frame 25), from verify/results/saves/as-turn15-spydeployed.sav after seven End Turns. On that same turn the ENTRY PROBE on SpyManager_Slot13RngCallee 0x008408e0 read 1 -- its first non-zero ever, the complement of lane AS's demonstration that its zero said nothing about the subtree */",
|
||||
"status": "verified",
|
||||
"source": "findings/subsystems/spy-program-draws.md (lane AP 2026-09-09)"
|
||||
},
|
||||
{
|
||||
"name": "SpyManager_CounterMissionRollSite",
|
||||
"addr": "0x0088dc43",
|
||||
"convention": "site",
|
||||
"prototype": "/* NOT A FUNCTION -- the `call Mars_RNG_Chance 0x008e6dd0` at 0x0088dc43 inside ServerSpyManager_vslot14 0x0088db80 (phase 33), return address 0x0088dc48. Decoded statically by lane AG (gate-indexed-rng-audit.md 3.2) with CORPUS COUNT 0 OF 22; FIRED FOR THE FIRST TIME lane AP 2026-09-09, 1 call / 1 word / strategic=true on each of Frames 19..24. Probability is spy.cmo (+0x28). MEASURED BEHAVIOUR: the bootstrap turn (Frame == tdep + 3, here Frame 18) sets spyon, runs the stage machine cm 0 -> 1 and cmo := 0.2f and DOES NOT DRAW; from the next turn the site costs one word until cmo reaches 1.0. cmo steps +0.2f per failure and resets to 0.2f on success. TWO CORRECTIONS TO LANE AG 3.2: (a) the CnTrd (+0xff) the stage machine consults at cm 1 -> 2/3 is the TARGET SYSTEM OWNER's, not the spy owner's -- measured, my player has CnTrd=False and the machine still took 1 -> 2 because Kepler's owner has CnTrd=True; (b) `ncp` is a scalar int counter of COMPLETED counter-mission stages (measured 0,0,1,1,2,2,3 in lock-step with cm), so the cm==0 branch's `ncp non-empty` test is `ncp != 0` -- and that branch was never reached, because vslot13 destroyed the spy at cm==4 */",
|
||||
"status": "verified",
|
||||
"source": "findings/subsystems/spy-program-draws.md (lane AP 2026-09-09)"
|
||||
},
|
||||
{
|
||||
"name": "SpyManager_DeploySpyDrawSite",
|
||||
"addr": "0x0078c97f",
|
||||
"convention": "site",
|
||||
"prototype": "/* NOT A FUNCTION -- the `call Mars_RNG_NextFloat 0x0047d830` at 0x0078c97f inside SpyManager_ShipActionDeploySpyHandler 0x0078c930, return address 0x0078c984, ECX = GetGame()->RNG(+0x16c) + 4. ONE STRATEGIC-GENERATOR WORD PER APPLIED Deploy Spy ORDER, in the ProcessTurn bracket. Decoded but not measured by lane AS; MEASURED lane AP 2026-09-09 (1 call / 1 word / no_draw_calls=0 / strategic=true) and the resulting spy.cbh reproduced lane AS's 5.033599376678467 bit for bit across processes, builds and sessions. IN NO EARLIER INVENTORY -- not lane V2's eight, not lane I's 22, not lane AG's audit -- because it hangs off the stack-built ship-action table and leaves no static call edge. Its predicate is on the COMMAND STREAM, not on save fields */",
|
||||
"status": "verified",
|
||||
"source": "findings/subsystems/spy-program-draws.md (lane AP 2026-09-09)"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
verify/results/saves/ap-deploy-turn15.sav
Normal file
BIN
verify/results/saves/ap-deploy-turn15.sav
Normal file
Binary file not shown.
BIN
verify/results/saves/ap-oa-turn16.sav
Normal file
BIN
verify/results/saves/ap-oa-turn16.sav
Normal file
Binary file not shown.
BIN
verify/results/saves/ap-ob-turn16.sav
Normal file
BIN
verify/results/saves/ap-ob-turn16.sav
Normal file
Binary file not shown.
BIN
verify/results/saves/ap-turn22-spydetected.sav
Normal file
BIN
verify/results/saves/ap-turn22-spydetected.sav
Normal file
Binary file not shown.
BIN
verify/results/saves/ap-turn25-spydestroyed.sav
Normal file
BIN
verify/results/saves/ap-turn25-spydestroyed.sav
Normal file
Binary file not shown.
114
verify/results/shim/ap/ap-probes8-d.shim.log
Normal file
114
verify/results/shim/ap/ap-probes8-d.shim.log
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
00:48:28.253 [tid 10144] ==== sots-engine shim (binkw32 proxy) build ap-989c692-20260909T0425Z ====
|
||||
00:48:28.253 [tid 10144] exe: C:\SOTS\Sword of the Stars.exe
|
||||
00:48:28.253 [tid 10144] exe base=0x006b0000 (link-time image base 0x00400000, ASLR delta +2818048) pid=7108 shim=72b60000
|
||||
00:48:28.253 [tid 10144] addresses: Source: sots-re ghidra/addresses.json @ 48db3cc, generated 2026-09-08 by tools/gen_addresses.py
|
||||
00:48:28.268 [tid 10144] config: hooks=trace
|
||||
00:48:28.268 [tid 10144] config: hook.Shim::SelfTest::Fill=off
|
||||
00:48:28.268 [tid 10144] config: hook.Mars::GlobalConsts::LoadFile=off
|
||||
00:48:28.268 [tid 10144] config: hook.Game::WeaponDictionary::Init=off
|
||||
00:48:28.268 [tid 10144] config: hook.Game::SectionDictionary::SectionDictionary=off
|
||||
00:48:28.268 [tid 10144] config: hook.Game::ServerPlayer::ComputeBudget=off
|
||||
00:48:28.268 [tid 10144] config: hook.Game::TechTree::ProcessResearch=off
|
||||
00:48:28.268 [tid 10144] config: hook.Game::ServerPlayer::OnTechResearched=off
|
||||
00:48:28.268 [tid 10144] config: hook.Game::ServerSystem::ProcessTurn=off
|
||||
00:48:28.268 [tid 10144] config: hook.Game::ServerPlayer::ProcessTurn=off
|
||||
00:48:28.268 [tid 10144] config: hook.Game::ServerSystem::GroupOutput=off
|
||||
00:48:28.268 [tid 10144] config: hook.Game::ServerSystem::ComputeTotalOutput=off
|
||||
00:48:28.268 [tid 10144] config: hook.Game::StrategyServer::MoveFleet=off
|
||||
00:48:28.268 [tid 10144] config: hook.Game::StrategyServer::ProcessFleetMovement=off
|
||||
00:48:28.268 [tid 10144] config: hook.Game::StrategyHost::Autosave=trace
|
||||
00:48:28.268 [tid 10144] config: hook.Game::StrategyServer::ProcessTurn=trace
|
||||
00:48:28.268 [tid 10144] config: hook.Game::StrategyServer::OnAllCombatDone_Tail=trace
|
||||
00:48:28.268 [tid 10144] config: hook.Game::StrategyServer::ApplyEncounterResult=trace
|
||||
00:48:28.268 [tid 10144] config: hook.Game::StrategyServer::NodeLineDecay=trace
|
||||
00:48:28.268 [tid 10144] config: hook.Game::StrategyServer::ProcessNodeSpaceTravel=trace
|
||||
00:48:28.268 [tid 10144] config: hook.Game::EncounterDetect::AssignContacts=trace
|
||||
00:48:28.268 [tid 10144] config: hook.Game::EncounterDetect::ProcessTeamRecord=trace
|
||||
00:48:28.268 [tid 10144] config: fpu.sample_turn=off
|
||||
00:48:28.268 [tid 10144] config: fpu.sample_ticks=off
|
||||
00:48:28.268 [tid 10144] config: trace.inline_max=64
|
||||
00:48:28.268 [tid 10144] config: trace.path=C:\SOTS\shim.trace.jsonl
|
||||
00:48:28.268 [tid 10144] config: trace.flush=always
|
||||
00:48:28.268 [tid 10144] config: probes=8 -> 8 lane-H entry probes
|
||||
00:48:28.331 [tid 10144] trace: C:\SOTS\shim.trace.jsonl (default mode trace, inline_max 64, flush always)
|
||||
00:48:28.331 [tid 10144] hook: Mars_Application_Initialize rva=0x004a0e50 -> va=00b50e50
|
||||
00:48:28.331 [tid 10144] hook: MH_Initialize -> MH_OK
|
||||
00:48:28.331 [tid 10144] hook: MH_CreateHook -> MH_OK (trampoline=030e0fe0)
|
||||
00:48:28.346 [tid 10144] hook: MH_EnableHook -> MH_OK
|
||||
00:48:28.346 [tid 10144] cfg: GlobalConsts hook ready (scale constant 0.017453292519943295)
|
||||
00:48:28.346 [tid 10144] hook: Mars::GlobalConsts::LoadFile rva=0x004b73c0 mode=off (not installed)
|
||||
00:48:28.346 [tid 10144] dict: dictionaries hook ready (crt new=74c4232b delete=74c40174)
|
||||
00:48:28.346 [tid 10144] hook: Game::WeaponDictionary::Init rva=0x0019a4c0 mode=off (not installed)
|
||||
00:48:28.346 [tid 10144] hook: Game::SectionDictionary::SectionDictionary rva=0x00176f40 mode=off (not installed)
|
||||
00:48:28.346 [tid 10144] research: ProcessResearch hook ready (Cost=0082da00, node=0x34, rng=0x9cc, fpu_cw=0x027f)
|
||||
00:48:28.346 [tid 10144] hook: Game::TechTree::ProcessResearch rva=0x001876c0 mode=off (not installed)
|
||||
00:48:28.346 [tid 10144] techfx: OnTechResearched hook ready (regions=15, gate=0/0, fpu_cw=0x027f)
|
||||
00:48:28.346 [tid 10144] hook: Game::ServerPlayer::OnTechResearched rva=0x00491790 mode=off (not installed)
|
||||
00:48:28.346 [tid 10144] hook: Game::ServerPlayer::ComputeBudget rva=0x00463030 mode=off (not installed)
|
||||
00:48:28.346 [tid 10144] hook: Game::ServerSystem::ProcessTurn rva=0x003598e0 mode=off (not installed)
|
||||
00:48:28.346 [tid 10144] hook: Game::ServerSystem::GroupOutput rva=0x0034b7a0 mode=off (not installed)
|
||||
00:48:28.346 [tid 10144] hook: Game::ServerSystem::ComputeTotalOutput rva=0x00350480 mode=off (not installed)
|
||||
00:48:28.346 [tid 10144] player_turn: ServerPlayer::ProcessTurn hook armed (ratio helper at 0082e950)
|
||||
00:48:28.346 [tid 10144] hook: Game::ServerPlayer::ProcessTurn rva=0x00491340 mode=off (not installed)
|
||||
00:48:28.346 [tid 10144] hook: Game::StrategyServer::MoveFleet rva=0x003d9ee0 mode=off (not installed)
|
||||
00:48:28.346 [tid 10144] hook: Game::StrategyServer::ProcessFleetMovement rva=0x003da9a0 mode=off (not installed)
|
||||
00:48:28.346 [tid 10144] hook: Game::StrategyHost::Autosave rva=0x00495210 -> va=00b45210 MH_CreateHook -> MH_OK (trampoline=030e0fc0)
|
||||
00:48:28.362 [tid 10144] hook: Game::StrategyHost::Autosave MH_EnableHook -> MH_OK mode=trace
|
||||
00:48:28.362 [tid 10144] hook: Game::StrategyServer::ProcessTurn rva=0x003dc6c0 -> va=00a8c6c0 MH_CreateHook -> MH_OK (trampoline=030e0fa0)
|
||||
00:48:28.378 [tid 10144] hook: Game::StrategyServer::ProcessTurn MH_EnableHook -> MH_OK mode=trace
|
||||
00:48:28.378 [tid 10144] hook: Game::StrategyServer::OnAllCombatDone_Tail rva=0x003d92a0 -> va=00a892a0 MH_CreateHook -> MH_OK (trampoline=030e0f80)
|
||||
00:48:28.393 [tid 10144] hook: Game::StrategyServer::OnAllCombatDone_Tail MH_EnableHook -> MH_OK mode=trace
|
||||
00:48:28.393 [tid 10144] hook: Game::StrategyServer::ApplyEncounterResult rva=0x003d8920 -> va=00a88920 MH_CreateHook -> MH_OK (trampoline=030e0f60)
|
||||
00:48:28.409 [tid 10144] hook: Game::StrategyServer::ApplyEncounterResult MH_EnableHook -> MH_OK mode=trace
|
||||
00:48:28.409 [tid 10144] hook: Game::StrategyServer::NodeLineDecay rva=0x003ae010 -> va=00a5e010 MH_CreateHook -> MH_OK (trampoline=030e0f40)
|
||||
00:48:28.409 [tid 10144] hook: Game::StrategyServer::NodeLineDecay MH_EnableHook -> MH_OK mode=trace
|
||||
00:48:28.409 [tid 10144] hook: Game::StrategyServer::ProcessNodeSpaceTravel rva=0x003a0e20 -> va=00a50e20 MH_CreateHook -> MH_OK (trampoline=030e0f20)
|
||||
00:48:28.424 [tid 10144] hook: Game::StrategyServer::ProcessNodeSpaceTravel MH_EnableHook -> MH_OK mode=trace
|
||||
00:48:28.424 [tid 10144] hook: Game::EncounterDetect::AssignContacts rva=0x003aa240 -> va=00a5a240 MH_CreateHook -> MH_OK (trampoline=030e0f00)
|
||||
00:48:28.440 [tid 10144] hook: Game::EncounterDetect::AssignContacts MH_EnableHook -> MH_OK mode=trace
|
||||
00:48:28.440 [tid 10144] hook: Game::EncounterDetect::ProcessTeamRecord rva=0x003ca640 -> va=00a7a640 MH_CreateHook -> MH_OK (trampoline=030e0ee0)
|
||||
00:48:28.456 [tid 10144] hook: Game::EncounterDetect::ProcessTeamRecord MH_EnableHook -> MH_OK mode=trace
|
||||
00:48:28.456 [tid 10144] hook: Game::StrategyServer::BeginProcessTurn rva=0x003d98e0 -> va=00a898e0 MH_CreateHook -> MH_OK (trampoline=030e0ec0)
|
||||
00:48:28.471 [tid 10144] hook: Game::StrategyServer::BeginProcessTurn MH_EnableHook -> MH_OK mode=trace
|
||||
00:48:28.471 [tid 10144] hook: Game::SVSOSwarmQueen::OnTurnBegin rva=0x00129930 -> va=007d9930 MH_CreateHook -> MH_OK (trampoline=030e0ea0)
|
||||
00:48:28.487 [tid 10144] hook: Game::SVSOSwarmQueen::OnTurnBegin MH_EnableHook -> MH_OK mode=trace
|
||||
00:48:28.487 [tid 10144] hook: Game::SVSOSwarmQueen::RegisterHives rva=0x00127630 -> va=007d7630 MH_CreateHook -> MH_OK (trampoline=030e0e80)
|
||||
00:48:28.503 [tid 10144] hook: Game::SVSOSwarmQueen::RegisterHives MH_EnableHook -> MH_OK mode=trace
|
||||
00:48:28.503 [tid 10144] hook: Game::SVSOSwarmQueen::TickHives rva=0x00127770 -> va=007d7770 MH_CreateHook -> MH_OK (trampoline=030e0e60)
|
||||
00:48:28.518 [tid 10144] hook: Game::SVSOSwarmQueen::TickHives MH_EnableHook -> MH_OK mode=trace
|
||||
00:48:28.518 [tid 10144] hook: Game::SVSOSlaversRefuel::UpdateDifficultyTier rva=0x00115820 -> va=007c5820 MH_CreateHook -> MH_OK (trampoline=030e0e40)
|
||||
00:48:28.534 [tid 10144] hook: Game::SVSOSlaversRefuel::UpdateDifficultyTier MH_EnableHook -> MH_OK mode=trace
|
||||
00:48:28.534 [tid 10144] hook: Mars::RNG::Seed rva=0x0009fdf0 -> va=0074fdf0 MH_CreateHook -> MH_OK (trampoline=030e0e20)
|
||||
00:48:28.534 [tid 10144] hook: Mars::RNG::Seed MH_EnableHook -> MH_OK mode=trace
|
||||
00:48:28.534 [tid 10144] hook: Game::StrategyApp::RunAI rva=0x004706f0 -> va=00b206f0 MH_CreateHook -> MH_OK (trampoline=030e0e00)
|
||||
00:48:28.549 [tid 10144] hook: Game::StrategyApp::RunAI MH_EnableHook -> MH_OK mode=trace
|
||||
00:48:28.565 [tid 10144] drawsite: Mars::RNG::NextFloat rva=0x0007d830 -> va=0072d830 create=MH_OK enable=MH_OK
|
||||
00:48:28.581 [tid 10144] drawsite: Mars::RNG::NextInt rva=0x000271c0 -> va=006d71c0 create=MH_OK enable=MH_OK
|
||||
00:48:28.596 [tid 10144] drawsite: Mars::RNG::Chance rva=0x004e6dd0 -> va=00b96dd0 create=MH_OK enable=MH_OK
|
||||
00:48:28.612 [tid 10144] drawsite: Mars::RNG::NextUInt rva=0x000f7670 -> va=007a7670 create=MH_OK enable=MH_OK
|
||||
00:48:28.628 [tid 10144] drawsite: Mars::RNG::FloatRange rva=0x0007d8a0 -> va=0072d8a0 create=MH_OK enable=MH_OK
|
||||
00:48:28.628 [tid 10144] drawsite: Mars::RNG::IntRangeBell rva=0x004e6d80 -> va=00b96d80 create=MH_OK enable=MH_OK
|
||||
00:48:28.643 [tid 10144] drawsite: Mars::RNG::GaussianRange rva=0x004e6e30 -> va=00b96e30 create=MH_OK enable=MH_OK
|
||||
00:48:28.643 [tid 10144] probe: installing 8 of 12 (probes= in shim.cfg)
|
||||
00:48:28.659 [tid 10144] probe: Game::ServerSpyManager::vslot13 rva=0x004877b0 -> va=00b377b0 create=MH_OK enable=MH_OK
|
||||
00:48:28.674 [tid 10144] probe: Game::ServerSpyManager::vslot14 rva=0x0048db80 -> va=00b3db80 create=MH_OK enable=MH_OK
|
||||
00:48:28.690 [tid 10144] probe: Game::ServerTradeManagerImpl::vslot13 rva=0x0048ef80 -> va=00b3ef80 create=MH_OK enable=MH_OK
|
||||
00:48:28.706 [tid 10144] probe: Game::ServerTradeManagerImpl::vslot15 rva=0x0042cca0 -> va=00adcca0 create=MH_OK enable=MH_OK
|
||||
00:48:28.706 [tid 10144] probe: Game::SpyManager::Slot13RngCallee rva=0x004408e0 -> va=00af08e0 create=MH_OK enable=MH_OK
|
||||
00:48:28.721 [tid 10144] probe: Game::TradeManager::Slot13RngCalleeA rva=0x00420ca0 -> va=00ad0ca0 create=MH_OK enable=MH_OK
|
||||
00:48:28.737 [tid 10144] probe: Game::TradeManager::Slot13RngCalleeB rva=0x0048b440 -> va=00b3b440 create=MH_OK enable=MH_OK
|
||||
00:48:28.753 [tid 10144] probe: Game::ServerTradeManager::CreateRaidEncounter rva=0x004938a0 -> va=00b438a0 create=MH_OK enable=MH_OK
|
||||
00:48:28.753 [tid 10144] watch: disabled (watch=off)
|
||||
00:48:28.753 [tid 10144] aiorders: disabled (aiorders=off)
|
||||
00:48:28.753 [tid 10144] fpu: module init, entry cw=0x027f 53bit-double/nearest; force=off value=0x0000 sample_ticks=off
|
||||
00:48:28.753 [tid 10144] fpu: sample_turn=off (off releases StrategyServer::ProcessTurn for another hook)
|
||||
00:48:28.753 [tid 10144] fpu: StrategyClient::EndTurn rva=0x00383be0 -> va=00a33be0 MH_CreateHook -> MH_OK (trampoline=030e0c00)
|
||||
00:48:28.768 [tid 10144] fpu: StrategyClient::EndTurn MH_EnableHook -> MH_OK
|
||||
00:48:28.768 [tid 10144] fpu: StrategyServer::BeginProcessTurn rva=0x003d98e0 -> va=00a898e0 MH_CreateHook -> MH_ERROR_ALREADY_CREATED (trampoline=00000000)
|
||||
00:48:28.768 [tid 10144] fpu: StrategyServer::ProcessTurn rva=0x003dc6c0 not installed (sampler off)
|
||||
00:48:28.768 [tid 10144] fpu: DemoApp::OnTick rva=0x0049a640 not installed (sampler off)
|
||||
00:48:28.768 [tid 10144] selftest: Shim::SelfTest::Fill mode=off checksum=075ef0c3 records=0
|
||||
00:48:28.768 [tid 10144] Application::Initialize called (this=033a8128)
|
||||
00:59:06.468 [tid 10144] fpu: sample at StrategyClient::EndTurn (this=0d69f600): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:59:09.765 [tid 10144] fpu: sample at StrategyClient::EndTurn (this=330dbd58): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:59:09.827 [tid 10144] fpu: sample at StrategyClient::EndTurn (this=330e0628): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
147
verify/results/shim/ap/ap-probes8-w.shim.log
Normal file
147
verify/results/shim/ap/ap-probes8-w.shim.log
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
00:32:14.211 [tid 8036] ==== sots-engine shim (binkw32 proxy) build ap-989c692-20260909T0425Z ====
|
||||
00:32:14.211 [tid 8036] exe: C:\SOTS\Sword of the Stars.exe
|
||||
00:32:14.211 [tid 8036] exe base=0x006b0000 (link-time image base 0x00400000, ASLR delta +2818048) pid=8872 shim=72b60000
|
||||
00:32:14.211 [tid 8036] addresses: Source: sots-re ghidra/addresses.json @ 48db3cc, generated 2026-09-08 by tools/gen_addresses.py
|
||||
00:32:14.211 [tid 8036] config: hooks=trace
|
||||
00:32:14.211 [tid 8036] config: hook.Shim::SelfTest::Fill=off
|
||||
00:32:14.211 [tid 8036] config: hook.Mars::GlobalConsts::LoadFile=off
|
||||
00:32:14.211 [tid 8036] config: hook.Game::WeaponDictionary::Init=off
|
||||
00:32:14.211 [tid 8036] config: hook.Game::SectionDictionary::SectionDictionary=off
|
||||
00:32:14.211 [tid 8036] config: hook.Game::ServerPlayer::ComputeBudget=off
|
||||
00:32:14.211 [tid 8036] config: hook.Game::TechTree::ProcessResearch=off
|
||||
00:32:14.211 [tid 8036] config: hook.Game::ServerPlayer::OnTechResearched=off
|
||||
00:32:14.211 [tid 8036] config: hook.Game::ServerSystem::ProcessTurn=off
|
||||
00:32:14.211 [tid 8036] config: hook.Game::ServerPlayer::ProcessTurn=off
|
||||
00:32:14.211 [tid 8036] config: hook.Game::ServerSystem::GroupOutput=off
|
||||
00:32:14.211 [tid 8036] config: hook.Game::ServerSystem::ComputeTotalOutput=off
|
||||
00:32:14.211 [tid 8036] config: hook.Game::StrategyServer::MoveFleet=off
|
||||
00:32:14.211 [tid 8036] config: hook.Game::StrategyServer::ProcessFleetMovement=off
|
||||
00:32:14.211 [tid 8036] config: hook.Game::StrategyHost::Autosave=trace
|
||||
00:32:14.211 [tid 8036] config: hook.Game::StrategyServer::ProcessTurn=trace
|
||||
00:32:14.211 [tid 8036] config: hook.Game::StrategyServer::OnAllCombatDone_Tail=trace
|
||||
00:32:14.211 [tid 8036] config: hook.Game::StrategyServer::ApplyEncounterResult=trace
|
||||
00:32:14.211 [tid 8036] config: hook.Game::StrategyServer::NodeLineDecay=trace
|
||||
00:32:14.211 [tid 8036] config: hook.Game::StrategyServer::ProcessNodeSpaceTravel=trace
|
||||
00:32:14.211 [tid 8036] config: hook.Game::EncounterDetect::AssignContacts=trace
|
||||
00:32:14.211 [tid 8036] config: hook.Game::EncounterDetect::ProcessTeamRecord=trace
|
||||
00:32:14.211 [tid 8036] config: fpu.sample_turn=off
|
||||
00:32:14.211 [tid 8036] config: fpu.sample_ticks=off
|
||||
00:32:14.211 [tid 8036] config: trace.inline_max=64
|
||||
00:32:14.211 [tid 8036] config: trace.path=C:\SOTS\shim.trace.jsonl
|
||||
00:32:14.211 [tid 8036] config: trace.flush=always
|
||||
00:32:14.211 [tid 8036] config: probes=8 -> 8 lane-H entry probes
|
||||
00:32:14.274 [tid 8036] trace: C:\SOTS\shim.trace.jsonl (default mode trace, inline_max 64, flush always)
|
||||
00:32:14.274 [tid 8036] hook: Mars_Application_Initialize rva=0x004a0e50 -> va=00b50e50
|
||||
00:32:14.274 [tid 8036] hook: MH_Initialize -> MH_OK
|
||||
00:32:14.274 [tid 8036] hook: MH_CreateHook -> MH_OK (trampoline=013f0fe0)
|
||||
00:32:14.305 [tid 8036] hook: MH_EnableHook -> MH_OK
|
||||
00:32:14.305 [tid 8036] cfg: GlobalConsts hook ready (scale constant 0.017453292519943295)
|
||||
00:32:14.305 [tid 8036] hook: Mars::GlobalConsts::LoadFile rva=0x004b73c0 mode=off (not installed)
|
||||
00:32:14.305 [tid 8036] dict: dictionaries hook ready (crt new=74c4232b delete=74c40174)
|
||||
00:32:14.305 [tid 8036] hook: Game::WeaponDictionary::Init rva=0x0019a4c0 mode=off (not installed)
|
||||
00:32:14.305 [tid 8036] hook: Game::SectionDictionary::SectionDictionary rva=0x00176f40 mode=off (not installed)
|
||||
00:32:14.305 [tid 8036] research: ProcessResearch hook ready (Cost=0082da00, node=0x34, rng=0x9cc, fpu_cw=0x027f)
|
||||
00:32:14.305 [tid 8036] hook: Game::TechTree::ProcessResearch rva=0x001876c0 mode=off (not installed)
|
||||
00:32:14.305 [tid 8036] techfx: OnTechResearched hook ready (regions=15, gate=0/0, fpu_cw=0x027f)
|
||||
00:32:14.305 [tid 8036] hook: Game::ServerPlayer::OnTechResearched rva=0x00491790 mode=off (not installed)
|
||||
00:32:14.305 [tid 8036] hook: Game::ServerPlayer::ComputeBudget rva=0x00463030 mode=off (not installed)
|
||||
00:32:14.305 [tid 8036] hook: Game::ServerSystem::ProcessTurn rva=0x003598e0 mode=off (not installed)
|
||||
00:32:14.305 [tid 8036] hook: Game::ServerSystem::GroupOutput rva=0x0034b7a0 mode=off (not installed)
|
||||
00:32:14.305 [tid 8036] hook: Game::ServerSystem::ComputeTotalOutput rva=0x00350480 mode=off (not installed)
|
||||
00:32:14.305 [tid 8036] player_turn: ServerPlayer::ProcessTurn hook armed (ratio helper at 0082e950)
|
||||
00:32:14.305 [tid 8036] hook: Game::ServerPlayer::ProcessTurn rva=0x00491340 mode=off (not installed)
|
||||
00:32:14.305 [tid 8036] hook: Game::StrategyServer::MoveFleet rva=0x003d9ee0 mode=off (not installed)
|
||||
00:32:14.305 [tid 8036] hook: Game::StrategyServer::ProcessFleetMovement rva=0x003da9a0 mode=off (not installed)
|
||||
00:32:14.305 [tid 8036] hook: Game::StrategyHost::Autosave rva=0x00495210 -> va=00b45210 MH_CreateHook -> MH_OK (trampoline=013f0fc0)
|
||||
00:32:14.321 [tid 8036] hook: Game::StrategyHost::Autosave MH_EnableHook -> MH_OK mode=trace
|
||||
00:32:14.321 [tid 8036] hook: Game::StrategyServer::ProcessTurn rva=0x003dc6c0 -> va=00a8c6c0 MH_CreateHook -> MH_OK (trampoline=013f0fa0)
|
||||
00:32:14.336 [tid 8036] hook: Game::StrategyServer::ProcessTurn MH_EnableHook -> MH_OK mode=trace
|
||||
00:32:14.336 [tid 8036] hook: Game::StrategyServer::OnAllCombatDone_Tail rva=0x003d92a0 -> va=00a892a0 MH_CreateHook -> MH_OK (trampoline=013f0f80)
|
||||
00:32:14.336 [tid 8036] hook: Game::StrategyServer::OnAllCombatDone_Tail MH_EnableHook -> MH_OK mode=trace
|
||||
00:32:14.336 [tid 8036] hook: Game::StrategyServer::ApplyEncounterResult rva=0x003d8920 -> va=00a88920 MH_CreateHook -> MH_OK (trampoline=013f0f60)
|
||||
00:32:14.352 [tid 8036] hook: Game::StrategyServer::ApplyEncounterResult MH_EnableHook -> MH_OK mode=trace
|
||||
00:32:14.352 [tid 8036] hook: Game::StrategyServer::NodeLineDecay rva=0x003ae010 -> va=00a5e010 MH_CreateHook -> MH_OK (trampoline=013f0f40)
|
||||
00:32:14.367 [tid 8036] hook: Game::StrategyServer::NodeLineDecay MH_EnableHook -> MH_OK mode=trace
|
||||
00:32:14.367 [tid 8036] hook: Game::StrategyServer::ProcessNodeSpaceTravel rva=0x003a0e20 -> va=00a50e20 MH_CreateHook -> MH_OK (trampoline=013f0f20)
|
||||
00:32:14.383 [tid 8036] hook: Game::StrategyServer::ProcessNodeSpaceTravel MH_EnableHook -> MH_OK mode=trace
|
||||
00:32:14.383 [tid 8036] hook: Game::EncounterDetect::AssignContacts rva=0x003aa240 -> va=00a5a240 MH_CreateHook -> MH_OK (trampoline=013f0f00)
|
||||
00:32:14.399 [tid 8036] hook: Game::EncounterDetect::AssignContacts MH_EnableHook -> MH_OK mode=trace
|
||||
00:32:14.399 [tid 8036] hook: Game::EncounterDetect::ProcessTeamRecord rva=0x003ca640 -> va=00a7a640 MH_CreateHook -> MH_OK (trampoline=013f0ee0)
|
||||
00:32:14.414 [tid 8036] hook: Game::EncounterDetect::ProcessTeamRecord MH_EnableHook -> MH_OK mode=trace
|
||||
00:32:14.414 [tid 8036] hook: Game::StrategyServer::BeginProcessTurn rva=0x003d98e0 -> va=00a898e0 MH_CreateHook -> MH_OK (trampoline=013f0ec0)
|
||||
00:32:14.430 [tid 8036] hook: Game::StrategyServer::BeginProcessTurn MH_EnableHook -> MH_OK mode=trace
|
||||
00:32:14.430 [tid 8036] hook: Game::SVSOSwarmQueen::OnTurnBegin rva=0x00129930 -> va=007d9930 MH_CreateHook -> MH_OK (trampoline=013f0ea0)
|
||||
00:32:14.446 [tid 8036] hook: Game::SVSOSwarmQueen::OnTurnBegin MH_EnableHook -> MH_OK mode=trace
|
||||
00:32:14.446 [tid 8036] hook: Game::SVSOSwarmQueen::RegisterHives rva=0x00127630 -> va=007d7630 MH_CreateHook -> MH_OK (trampoline=013f0e80)
|
||||
00:32:14.461 [tid 8036] hook: Game::SVSOSwarmQueen::RegisterHives MH_EnableHook -> MH_OK mode=trace
|
||||
00:32:14.461 [tid 8036] hook: Game::SVSOSwarmQueen::TickHives rva=0x00127770 -> va=007d7770 MH_CreateHook -> MH_OK (trampoline=013f0e60)
|
||||
00:32:14.477 [tid 8036] hook: Game::SVSOSwarmQueen::TickHives MH_EnableHook -> MH_OK mode=trace
|
||||
00:32:14.477 [tid 8036] hook: Game::SVSOSlaversRefuel::UpdateDifficultyTier rva=0x00115820 -> va=007c5820 MH_CreateHook -> MH_OK (trampoline=013f0e40)
|
||||
00:32:14.492 [tid 8036] hook: Game::SVSOSlaversRefuel::UpdateDifficultyTier MH_EnableHook -> MH_OK mode=trace
|
||||
00:32:14.492 [tid 8036] hook: Mars::RNG::Seed rva=0x0009fdf0 -> va=0074fdf0 MH_CreateHook -> MH_OK (trampoline=013f0e20)
|
||||
00:32:14.508 [tid 8036] hook: Mars::RNG::Seed MH_EnableHook -> MH_OK mode=trace
|
||||
00:32:14.508 [tid 8036] hook: Game::StrategyApp::RunAI rva=0x004706f0 -> va=00b206f0 MH_CreateHook -> MH_OK (trampoline=013f0e00)
|
||||
00:32:14.524 [tid 8036] hook: Game::StrategyApp::RunAI MH_EnableHook -> MH_OK mode=trace
|
||||
00:32:14.524 [tid 8036] drawsite: Mars::RNG::NextFloat rva=0x0007d830 -> va=0072d830 create=MH_OK enable=MH_OK
|
||||
00:32:14.539 [tid 8036] drawsite: Mars::RNG::NextInt rva=0x000271c0 -> va=006d71c0 create=MH_OK enable=MH_OK
|
||||
00:32:14.555 [tid 8036] drawsite: Mars::RNG::Chance rva=0x004e6dd0 -> va=00b96dd0 create=MH_OK enable=MH_OK
|
||||
00:32:14.571 [tid 8036] drawsite: Mars::RNG::NextUInt rva=0x000f7670 -> va=007a7670 create=MH_OK enable=MH_OK
|
||||
00:32:14.586 [tid 8036] drawsite: Mars::RNG::FloatRange rva=0x0007d8a0 -> va=0072d8a0 create=MH_OK enable=MH_OK
|
||||
00:32:14.602 [tid 8036] drawsite: Mars::RNG::IntRangeBell rva=0x004e6d80 -> va=00b96d80 create=MH_OK enable=MH_OK
|
||||
00:32:14.617 [tid 8036] drawsite: Mars::RNG::GaussianRange rva=0x004e6e30 -> va=00b96e30 create=MH_OK enable=MH_OK
|
||||
00:32:14.617 [tid 8036] probe: installing 8 of 12 (probes= in shim.cfg)
|
||||
00:32:14.633 [tid 8036] probe: Game::ServerSpyManager::vslot13 rva=0x004877b0 -> va=00b377b0 create=MH_OK enable=MH_OK
|
||||
00:32:14.649 [tid 8036] probe: Game::ServerSpyManager::vslot14 rva=0x0048db80 -> va=00b3db80 create=MH_OK enable=MH_OK
|
||||
00:32:14.664 [tid 8036] probe: Game::ServerTradeManagerImpl::vslot13 rva=0x0048ef80 -> va=00b3ef80 create=MH_OK enable=MH_OK
|
||||
00:32:14.680 [tid 8036] probe: Game::ServerTradeManagerImpl::vslot15 rva=0x0042cca0 -> va=00adcca0 create=MH_OK enable=MH_OK
|
||||
00:32:14.696 [tid 8036] probe: Game::SpyManager::Slot13RngCallee rva=0x004408e0 -> va=00af08e0 create=MH_OK enable=MH_OK
|
||||
00:32:14.711 [tid 8036] probe: Game::TradeManager::Slot13RngCalleeA rva=0x00420ca0 -> va=00ad0ca0 create=MH_OK enable=MH_OK
|
||||
00:32:14.727 [tid 8036] probe: Game::TradeManager::Slot13RngCalleeB rva=0x0048b440 -> va=00b3b440 create=MH_OK enable=MH_OK
|
||||
00:32:14.742 [tid 8036] probe: Game::ServerTradeManager::CreateRaidEncounter rva=0x004938a0 -> va=00b438a0 create=MH_OK enable=MH_OK
|
||||
00:32:14.742 [tid 8036] watch: disabled (watch=off)
|
||||
00:32:14.742 [tid 8036] aiorders: disabled (aiorders=off)
|
||||
00:32:14.742 [tid 8036] fpu: module init, entry cw=0x027f 53bit-double/nearest; force=off value=0x0000 sample_ticks=off
|
||||
00:32:14.742 [tid 8036] fpu: sample_turn=off (off releases StrategyServer::ProcessTurn for another hook)
|
||||
00:32:14.742 [tid 8036] fpu: StrategyClient::EndTurn rva=0x00383be0 -> va=00a33be0 MH_CreateHook -> MH_OK (trampoline=013f0c00)
|
||||
00:32:14.758 [tid 8036] fpu: StrategyClient::EndTurn MH_EnableHook -> MH_OK
|
||||
00:32:14.758 [tid 8036] fpu: StrategyServer::BeginProcessTurn rva=0x003d98e0 -> va=00a898e0 MH_CreateHook -> MH_ERROR_ALREADY_CREATED (trampoline=00000000)
|
||||
00:32:14.758 [tid 8036] fpu: StrategyServer::ProcessTurn rva=0x003dc6c0 not installed (sampler off)
|
||||
00:32:14.758 [tid 8036] fpu: DemoApp::OnTick rva=0x0049a640 not installed (sampler off)
|
||||
00:32:14.758 [tid 8036] selftest: Shim::SelfTest::Fill mode=off checksum=075ef0c3 records=0
|
||||
00:32:14.758 [tid 8036] Application::Initialize called (this=03438128)
|
||||
00:40:12.096 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=0d67e8f0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:40:15.284 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e7ee0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:40:15.284 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e8d70): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:40:25.878 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=0d67e8f0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:40:29.081 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e7ee0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:40:29.096 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e8d70): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:40:39.299 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=0d67e8f0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:40:42.503 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e7ee0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:40:42.503 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e8d70): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:40:52.768 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=0d67e8f0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:40:55.956 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e7ee0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:40:55.971 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e8d70): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:41:06.237 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=0d67e8f0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:41:09.471 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e7ee0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:41:09.471 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e8d70): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:41:19.690 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=0d67e8f0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:41:22.893 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e7ee0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:41:22.893 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e8d70): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:41:33.096 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=0d67e8f0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:41:36.331 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e7ee0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:41:36.331 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e8d70): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:41:46.549 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=0d67e8f0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:41:49.799 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e7ee0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:41:49.799 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e8d70): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:42:00.018 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=0d67e8f0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:42:03.237 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e7ee0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:42:03.237 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e8d70): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:42:13.503 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=0d67e8f0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:42:16.706 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e7ee0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:42:16.706 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e8d70): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:42:26.956 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=0d67e8f0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:42:30.174 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e7ee0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:42:30.190 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e8d70): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:42:40.378 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=0d67e8f0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:42:43.549 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e7ee0): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
00:42:43.549 [tid 8036] fpu: sample at StrategyClient::EndTurn (this=341e8d70): cw=0x127f 53bit-double/nearest [no fpu.force configured]
|
||||
BIN
verify/traces/ap-probes8-deploy-turn15.jsonl.gz
Normal file
BIN
verify/traces/ap-probes8-deploy-turn15.jsonl.gz
Normal file
Binary file not shown.
BIN
verify/traces/ap-probes8-turn16-turn26.jsonl.gz
Normal file
BIN
verify/traces/ap-probes8-turn16-turn26.jsonl.gz
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue