Compare commits

..

No commits in common. "feaa70e15e08218e2c27b4129235dff7b7b2828c" and "fdea0fde081fa4ca251e7b45c5bb7f3b01bb6db8" have entirely different histories.

11 changed files with 16 additions and 2010 deletions

View file

@ -1,16 +1,16 @@
# SotS RE campaign — coverage dashboard # SotS RE campaign — coverage dashboard
Generated 2026-09-09 14:24 UTC · `sots-re` @ d9b06ca,2026-09-09 · `sots-engine` @ 7741d42,2026-09-09 (252 commits) · regenerate with `tools/dashboard.py` Generated 2026-09-09 14:13 UTC · `sots-re` @ d4e9b58,2026-09-09 · `sots-engine` @ 52db23c,2026-09-09 (250 commits) · regenerate with `tools/dashboard.py`
> **North star:** A functional reimplementation of the engine — behavior-equivalent, NOT byte-for-byte > **North star:** A functional reimplementation of the engine — behavior-equivalent, NOT byte-for-byte
## 1. Map coverage (campaign/board.md) ## 1. Map coverage (campaign/board.md)
454 targets · mapped-or-better **405/454** `[█████████░] 89%` · verified **362/454** `[████████░░] 80%` 453 targets · mapped-or-better **404/453** `[█████████░] 89%` · verified **361/453** `[████████░░] 80%`
| Status | Count | % | | Status | Count | % |
|---|---:|---:| |---|---:|---:|
| verified | 362 | 80% | | verified | 361 | 80% |
| mapped | 43 | 9% | | mapped | 43 | 9% |
| in-progress | 5 | 1% | | in-progress | 5 | 1% |
| backlog | 41 | 9% | | backlog | 41 | 9% |
@ -21,7 +21,7 @@ Generated 2026-09-09 14:24 UTC · `sots-re` @ d9b06ca,2026-09-09 · `sots-engine
| objects | 46 | 6 | 0 | 3 | 1 | 56 | | objects | 46 | 6 | 0 | 3 | 1 | 56 |
| control-flow | 41 | 2 | 1 | 0 | 0 | 44 | | control-flow | 41 | 2 | 1 | 0 | 0 | 44 |
| subsystems | 4 | 8 | 0 | 2 | 1 | 15 | | subsystems | 4 | 8 | 0 | 2 | 1 | 15 |
| engine | 34 | 1 | 0 | 0 | 0 | 35 | | engine | 33 | 1 | 0 | 0 | 0 | 34 |
| verify | 106 | 15 | 3 | 35 | 0 | 159 | | verify | 106 | 15 | 3 | 35 | 0 | 159 |
| phase2 | 15 | 3 | 1 | 0 | 0 | 20 | | phase2 | 15 | 3 | 1 | 0 | 0 | 20 |
| meta | 95 | 6 | 0 | 1 | 0 | 102 | | meta | 95 | 6 | 0 | 1 | 0 | 102 |
@ -31,7 +31,7 @@ Generated 2026-09-09 14:24 UTC · `sots-re` @ d9b06ca,2026-09-09 · `sots-engine
- RTTI type descriptors: **1,924** (`Game::` 1,404, `Mars::` 194; serializable types 179) - RTTI type descriptors: **1,924** (`Game::` 1,404, `Mars::` 194; serializable types 179)
- Classes with recovered member layouts: **384** / 1,598 named classes `[██░░░░░░░░] 24%` — `objects/layouts.json` (serializer recovery) plus classes recovered by hand in `struct-recovery.md` + `schema-gaps-resolved.md`. Note 179 types are *serializable*; the recovery also reaches non-serializable ones, so this is not a subset of that - Classes with recovered member layouts: **384** / 1,598 named classes `[██░░░░░░░░] 24%` — `objects/layouts.json` (serializer recovery) plus classes recovered by hand in `struct-recovery.md` + `schema-gaps-resolved.md`. Note 179 types are *serializable*; the recovery also reaches non-serializable ones, so this is not a subset of that
- Functions: **41,411** (parsed from `01-fingerprint.md`); named/annotated in the **address contract** (`ghidra/addresses.json`, not Ghidra's full rename count): **1320**, verified **1187** `[█████████░] 90%` - Functions: **41,411** (parsed from `01-fingerprint.md`); named/annotated in the **address contract** (`ghidra/addresses.json`, not Ghidra's full rename count): **1310**, verified **1179** `[█████████░] 90%`
## 3. Data layer ## 3. Data layer
@ -46,7 +46,7 @@ Generated 2026-09-09 14:24 UTC · `sots-re` @ d9b06ca,2026-09-09 · `sots-engine
| Module | LOC | Test files | Checks | Wired | Doc | | Module | LOC | Test files | Checks | Wired | Doc |
|---|---:|---:|---:|---|---| |---|---:|---:|---:|---|---|
| `app` | 5,092 | 9 | 207 | yes | N-output-term.md | | `app` | 4,838 | 9 | 207 | yes | N-output-term.md |
| `game/ai` | 2,138 | 8 | 322 | yes | L4-ai-orders.md | | `game/ai` | 2,138 | 8 | 322 | yes | L4-ai-orders.md |
| `game/combat` | 582 | 2 | 34 | yes | L2-predictions.md | | `game/combat` | 582 | 2 | 34 | yes | L2-predictions.md |
| `game/config` | 558 | 4 | 131 | yes | M1.md | | `game/config` | 558 | 4 | 131 | yes | M1.md |
@ -55,7 +55,7 @@ Generated 2026-09-09 14:24 UTC · `sots-re` @ d9b06ca,2026-09-09 · `sots-engine
| `game/effects` | 973 | 3 | 231 | yes | game-effects.md | | `game/effects` | 973 | 3 | 231 | yes | game-effects.md |
| `game/events` | 558 | 3 | 152 | yes | E-events.md | | `game/events` | 558 | 3 | 152 | yes | E-events.md |
| `game/nav` | 581 | 2 | 113 | yes | — | | `game/nav` | 581 | 2 | 113 | yes | — |
| `game/sim` | 4,918 | 15 | 1086 | yes | game-sim.md | | `game/sim` | 4,780 | 14 | 1038 | yes | game-sim.md |
| `mars/parse` | 875 | 12 | 277 | yes | mars-parse.md | | `mars/parse` | 875 | 12 | 277 | yes | mars-parse.md |
| `mars/rng` | 273 | 0 | 0 | yes | mars-rng.md | | `mars/rng` | 273 | 0 | 0 | yes | mars-rng.md |
| `mars/stream` | 6,021 | 8 | 331 | yes | mars-stream.md | | `mars/stream` | 6,021 | 8 | 331 | yes | mars-stream.md |
@ -64,9 +64,9 @@ Generated 2026-09-09 14:24 UTC · `sots-re` @ d9b06ca,2026-09-09 · `sots-engine
| `shim` | 16,777 | 0 | 0 | direct (WIN32) | H-probes.md | | `shim` | 16,777 | 0 | 0 | direct (WIN32) | H-probes.md |
| `shim/hooks` | 13,658 | 0 | 0 | direct (WIN32) | L1-predictions.md | | `shim/hooks` | 13,658 | 0 | 0 | direct (WIN32) | L1-predictions.md |
| `shim/trace` | 2,258 | 9 | 273 | direct (WIN32) | shim-trace.md | | `shim/trace` | 2,258 | 9 | 273 | direct (WIN32) | shim-trace.md |
| **total** | **60,226** | **123** | **4307** | | | | **total** | **59,834** | **122** | **4259** | | |
Board `engine:` rows: verified **34**, mapped 1, in flight 0 (of 35) — verified & merged `[██████████] 97%` Board `engine:` rows: verified **33**, mapped 1, in flight 0 (of 34) — verified & merged `[██████████] 97%`
## 5. Phase 2 milestones ## 5. Phase 2 milestones
@ -133,11 +133,11 @@ Most recent open:
## 9. Delta since previous dashboard ## 9. Delta since previous dashboard
- verified targets: 361 → 362 (+1) · mapped-or-better: 404 → 405 (+1) - verified targets: 356 → 361 (+5) · mapped-or-better: 399 → 404 (+5)
- engine LOC: 59,834 → 60,226 (+392) · test files: 122 → 123 (+1) · checks: 4,259 → 4,307 (+48) - engine LOC: 59,514 → 59,834 (+320) · test files: 122 → 122 (+0) · checks: 4,257 → 4,259 (+2)
- addresses verified: 1,179 → 1,187 (+8) · recovered layouts: 384 → 384 (+0) · open questions: 26 → 26 (+0) - addresses verified: 1,167 → 1,179 (+12) · recovered layouts: 384 → 384 (+0) · open questions: 26 → 26 (+0)
- standalone leaves closed: 45 → 45 (+0) · leaves still diverging: 63 → 63 (+0) - standalone leaves closed: 45 → 45 (+0) · leaves still diverging: 63 → 63 (+0)
--- ---
warnings: board.md line 459: unknown status 'open' for '**A replace of `ProcessResearch` is gated on `ServerPlayer::OnTechResearched`, and partly on a policy question**'; board.md: unknown types engine + gate, subsystems, tooling; mars-rng.md: no oracle total row parsed; mars-stream.md: no oracle total row parsed; mars-vfs.md: no oracle total row parsed warnings: board.md line 459: unknown status 'open' for '**A replace of `ProcessResearch` is gated on `ServerPlayer::OnTechResearched`, and partly on a policy question**'; board.md: unknown types engine + gate, subsystems, tooling; mars-rng.md: no oracle total row parsed; mars-stream.md: no oracle total row parsed; mars-vfs.md: no oracle total row parsed
<!-- dashboard-metrics {"verified": 362, "mapped_plus": 405, "targets": 454, "loc": 60226, "tests": 123, "checks": 4307, "addr_verified": 1187, "addr_total": 1320, "layouts": 384, "open_q": 26, "sa_closed": 45, "sa_left": 63} --> <!-- dashboard-metrics {"verified": 361, "mapped_plus": 404, "targets": 453, "loc": 59834, "tests": 122, "checks": 4259, "addr_verified": 1179, "addr_total": 1310, "layouts": 384, "open_q": 26, "sa_closed": 45, "sa_left": 63} -->

File diff suppressed because one or more lines are too long

View file

@ -1,132 +0,0 @@
# The route classifier under a hook — `game/nav` from `modelled` to `compared`
Lane DN, 2026-09-09. Guest **VM146** (`sots-re-win10-146`), build box CT111, own build dir
`/srv/re-lab/build/sots-engine-dn`, own worktree `sots-engine` branch `wip/dn`.
**Hold announced:** VM146 only, for the duration of this lane. VM140 is the exclusive reference
guest and was not touched; VM141 (lane CZ) and VM145 (lane CR) are held by other lanes and were
not touched. VM146 is released restored and hash-verified at the end of this document.
`game/nav` is the campaign's largest **`modelled`** module by span of behaviour and it had never
executed under an instrument. `tools/displacement.py` records it as
> offline vs 58 waypoints / 46 flight plans across 11 saves, 0 failures
> — *never instrumented; not one leg has executed under a hook*
and `path-solver.md` closes with the same sentence from the other side: *"the classifier's rules
are read instruction by instruction … and **not one leg of it has ever been observed executing
under an instrument**."* This lane executes it.
---
## 0. The entry point is a real function, so the hook is on the classifier itself
The brief allowed for the classifier being inlined into its caller, in which case the honest hook
would have been on the enclosing function comparing its *output*. **It is not inlined.**
`path-solver.md` §0.1/§1.1/§2 read it from the instruction stream:
| | |
|---|---|
| `StarFleet_ClassifyLeg` | `0x00703730`, **thiscall**, `ret 0x14`, six arguments, real body `0x00703730..0x00703bc9` then 6 × `int3` to the next function start |
| callers | `PathSolver` `0x007066c0` at two sites (the pre-flight probe and the per-leg loop), and `MoveFleet`'s multi-waypoint continuation at `0x7da5c6` / `0x7da5da` |
| output surface | the **return value** (the waypoint kind), `*flagsOut` (the flag word), and the route record's three written words at `routeOut+4..+0xf`. Nothing else. |
So the comparison surface is the classifier's own three outputs plus its return value, and there
is no unit boundary invented here that the binary does not have. `PathSolver` is hooked too, but
**trace only** — see §1.3.
---
## 1. Predictions (committed before the compare run, rule 2)
This section is committed in its own commit, before the instrumented build ran once.
### 1.1 The workload, and why it reaches two route classes
Save `ar-oracle-A-pre.sav` (`15b99255…`), turn 38, players: **Human ×2** (net 16 = the human seat,
496), **Tarkas ×2** (32, 512), **NPC ×4** (528–576). `DriveTypeOfSpecies` maps Human → 3,
Tarkas → 1, NPC → 0, so *three* drive classes are present before the AI does anything.
Procedure, fixed and replayed identically in every run:
1. load (SavedGames reset to exactly one file, row 1), lobby, `Launch`;
2. `Move`, order **Delta Fleet → Isis**. The game answers with its own prompt —
*"Delta Fleet does not have the range to reach Isis using nodes. Do you want to plot a
sublight course?"* — and `OK` commits it. **This is the sublight-crawl class.**
3. `Move`, order **Delta Fleet → Venkman**. Hover reads *"Range: 6.0 / ETA: 2 Turns"*, there is no
prompt, the order is committed straight away. **This is the node-route class.**
4. `End Turn`.
The hover readout named the class before either click, exactly as the campaign's guest notes say:
Venkman `ETA: 2 Turns` (node), Isis `ETA: 50 Turns` in red (sublight); Nu Ophiuchi `4 Turns`,
Kua'Taak `47`, Kam'Tara `53`, Kao'Lolto `50`, Ko'Kotan `47`. The state was **built deliberately**
from that readout rather than hoped for.
### 1.2 Falsifiable predictions
> **P1 — call count from the two player orders: 8.** Each accepted order costs **two**
> `PathSolver` calls (the UI's dry run `FUN_005e6d50`, then the server's `OrderFleetMove`), and
> each `PathSolver` call on a one-destination list costs **two** `ClassifyLeg` calls (the
> pre-flight probe against `MinRange`, then the loop leg). Two orders × 2 × 2 = **8**, with
> **4** `PathSolver` records. `count` is 1 on all four and the leading-destination drop does
> **not** fire (neither destination is the fleet or the fleet's own system).
> *Falsified by:* a different multiple of 2 — most likely because hovering also runs the dry run,
> which would add calls in pairs and is worth knowing either way.
>
> **P2 — the Isis leg raises `0x002`, not `0x020`.** The game's own prompt says the fleet cannot
> reach Isis **"using nodes"**, which is `errBits` seeded at `0x00703a0d` and ORed at
> `0x00703b10`: a node line **exists** and is beyond the fuel budget. So on that call
> `line_found >= 0`, the returned kind is **0**, and the flag word is `0x002`.
> *Falsified by:* `line_found == -1` on that call, which would make the flag `0x020` and the
> prompt string generic rather than diagnostic.
>
> **P3 — the Venkman leg returns kind 3 with a live route.** `line_found >= 0`, return value 3,
> `nrp == line_found`, `nrf ==` Epsilon Eridani's network id, `nrt ==` Venkman's, flags `0`.
>
> **P4 — no Human or Zuul call returns 1, 2 or 6; no Tarkas call returns 3; every Tarkas call
> leaves the route record at `{-1,0,0}` and performs no range check.** This is
> `DriveTypeOfSpecies` and step E of the decision order, live. The record carries the original's
> own `StarFleet_GetDriveType` next to the species, so the table is checkable rather than assumed.
>
> **P5 — `can_bore == 0` on every call, so the bore arm is reached 0 times.** No Zuul player, and
> the `0x20000` capability is the Zuul node cruiser. This is the declared gap that makes itself
> inert, and the trace proves it instead of the brief asserting it (rule 28 practice 1).
>
> **P6 — `gate_cap == 0` on every call, so no call returns kind 4 or 5 and flag `0x004` never
> appears.** Every player in every corpus save has `NGts == 0`. Kinds 4 and 5 stay at **zero
> observations** and this lane says so rather than quietly counting a clean sheet as coverage.
>
> **P7 — 0 divergences, and the reason is the narrowings already in the module.** The `MoveFleet`
> lane's eight live divergences were all float32 narrowings; `game/nav` already carries the five
> of `LegLength` and the unstored `r*r` of `LegInRange`. I predict the compare comes back clean,
> and I predict that a *boundary* fuel case is the only thing in this subsystem that could
> break it — which this workload is not built to hit.
> *Falsification shapes, each with a distinct symptom:*
> * kind differs on a Tarkas/NPC call → the drive table is wrong (visible directly against
> `drive_orig`);
> * flags differ on `0x001` / `0x800` → the pending-action-mask split is wrong;
> * flags differ between `0x002` and `0x020` → `LegInRange` disagrees off a boundary, i.e. the
> range or the tank-capacity input is wrong, not the arithmetic;
> * `nrf` / `nrt` differ → the origin/destination identification in the node arm is wrong;
> * the `fleet` guard fires → the classifier writes the moving fleet and the module's purity
> claim is false.
>
> **P8 — neutrality holds.** The compare run's `(Autosave EndTurn)` and `(Autosave)` are
> byte-identical to the control's. If they are not, every number in this lane is void (rule 19).
>
> **P9 — at least 8 distinct input states.** A count of calls is not coverage (rule 23); this is
> the number the verdict has to stand on.
### 1.3 What is deliberately not compared
* **`PathSolver` is `trace` only, and its `ours` throws if anyone sets it to `compare`.** The plan
needs the fleet's effective range, which comes from `FUN_00705d60`'s tanker-redistribution fold
— a function `path-solver.md` §9 explicitly did not read. A hook that returned "no plan" there
would print a green verdict over a missing input, which is rule 1's failure mode.
* **`nrp` on an existing line is an input, not a result.** The single-hop answer is taken from the
original's own `NodeGraph_FindNodeLine` **before the original runs** (afterwards it could return
a line the original itself had just bored). Its agreement is therefore not evidence; the kind,
the flags and `nrf`/`nrt` are.
* **Three input gaps, counted per call rather than argued away:** the intercept solve for a
destination fleet already on a node leg (`intercept_gap`), the node bore (`bore_arm`), and the
unread friendliness test `FUN_00817890` on the point↔system arms (`friendly_recon`).

File diff suppressed because one or more lines are too long

View file

@ -1,87 +0,0 @@
{ "entries": [
{ "name": "MapObject_off_Id",
"offset": "0x00000004",
"convention": "offset",
"prototype": "int Id -- the network handle of a map object. This is what OrderFleetMove writes into Waypoint.Wpt(+0x4) (dests[i]->+0x4) and what ClassifyLeg writes into the route record's nrf/nrt, which is why nrt == Wpt on every type-3 waypoint in the corpus",
"status": "verified",
"source": "findings/subsystems/path-solver.md" },
{ "name": "MapObject_off_Kind",
"offset": "0x00000014",
"convention": "offset",
"prototype": "int Kind -- the map object's shape tag: 0 system, 1 fleet, 2 deep-space point. Read by MapObject_GetOwner 0x0071e280, MapObject_AsSystem 0x0071e340, StarFleet_GetLocationIfNode 0x006fe300, PathSolver's refuel test and ClassifyLeg's endpoint classification, so the three values are established from four independent sites",
"status": "verified",
"source": "findings/subsystems/path-solver.md" },
{ "name": "MapObject_off_Pos",
"offset": "0x00000018",
"convention": "offset",
"prototype": "float Pos[3] at +0x18/+0x1c/+0x20 -- the position every leg length and every range check reads. PathSolver's inlined Mars_Vec3_Length loads exactly these three slots (fld [edi+0x18] / +0x1c / +0x20 at 0x00706844)",
"status": "verified",
"source": "findings/subsystems/path-solver.md" },
{ "name": "MapObject_off_PointVisibleMask",
"offset": "0x0000008c",
"convention": "offset",
"prototype": "uint per-player bitmask on a kind-2 (deep-space point) object; bit PlyrIdx set = the point is visible to that player. The first of the two masks ClassifyLeg tests before raising 0x400; either mask alone permits the move, and a species-4 fleet bypasses both",
"status": "verified",
"source": "findings/subsystems/path-solver.md" },
{ "name": "MapObject_off_PointKnownMask",
"offset": "0x00000090",
"convention": "offset",
"prototype": "uint per-player bitmask on a kind-2 (deep-space point) object; the second of the pair at +0x8c/+0x90. Set = the point is known to that player",
"status": "verified",
"source": "findings/subsystems/path-solver.md" },
{ "name": "ServerSystem_off_GFlags",
"offset": "0x000000dc",
"convention": "offset",
"prototype": "uint GFlags -- the PER-PLAYER GATE MASK, read as (GFlags >> p->PlyrIdx(+0x28)) & 1 by ServerSystem_HasGate 0x00744010. combat-retreat-pipeline.md lists +0xdc only as 'a second presence source (not read here)'; the whole waypoint-type-4/5 branch of ClassifyLeg is built on it",
"status": "verified",
"source": "findings/subsystems/path-solver.md" },
{ "name": "ServerPlayer_off_NGts",
"offset": "0x00000144",
"convention": "offset",
"prototype": "int NGts -- the player's gate count. Multiplied by PrGtTrf(+0x148) to give the gate-traffic capacity (ServerPlayer_GateTrafficCapacity 0x0080dc50), which GTraf(+0x14c) plus the moving fleet's own int16 cost is tested against. NGts == 0 on every player of every corpus save, so waypoint kinds 4 and 5 have never been produced",
"status": "verified",
"source": "findings/subsystems/path-solver.md" },
{ "name": "NodeRoute_off_PathIndex",
"offset": "0x00000004",
"convention": "offset",
"prototype": "int nrp -- the node line's path index inside a NodeRoute {vptr, nrp@+4, nrf@+8, nrt@+0xc}, sizeof 0x10. Constructed to -1 by NodeRoute_Construct 0x006e1b20; ClassifyLeg leaves -1 for a freshly bored line or a point endpoint and writes FindNodeLine's entry->+0x8 otherwise. Copied to Waypoint+0x10 by FlightPlan_Waypoint_Set 0x007006e0",
"status": "verified",
"source": "findings/subsystems/path-solver.md" },
{ "name": "NodeRoute_off_FromId",
"offset": "0x00000008",
"convention": "offset",
"prototype": "int nrf -- the leg ORIGIN object's network id (origin->+0x4), written only when the leg's kind is 3. Copied to Waypoint+0x14. Chains across a multi-hop plan: nrf[0] == FlightPlan.pnd and nrf[i+1] == nrt[i], checked green on 46 of 46 corpus flight plans",
"status": "verified",
"source": "findings/subsystems/path-solver.md" },
{ "name": "NodeRoute_off_ToId",
"offset": "0x0000000c",
"convention": "offset",
"prototype": "int nrt -- the leg DESTINATION object's network id (dest->+0x4), written only when the leg's kind is 3. Copied to Waypoint+0x18, and equal to that waypoint's own Wpt(+0x4) on all 58 corpus waypoints",
"status": "verified",
"source": "findings/subsystems/path-solver.md" },
{ "name": "NodeRoute_sizeof",
"offset": "0x00000010",
"convention": "offset",
"prototype": "sizeof(NodeRoute) -- {vptr, int nrp, int nrf, int nrt}. Pinned by PathSolver's routesOut stride (add esi,0x10 at 0x007068b2) and by the Waypoint layout {vptr, Wpt@+4, Tp@+8, NodeRoute@+0xc} summing to the 0x1c stride",
"status": "verified",
"source": "findings/subsystems/path-solver.md" },
{ "name": "Galaxy_vft_off_GetNodeGraph",
"offset": "0x00000004",
"convention": "offset",
"prototype": "byte offset of vtable slot 1 on the object at StarFleet+0x10 (the 'galaxy'). ClassifyLeg's node-route branch obtains the node-line graph with `(fleet->galaxy(+0x10))->vft[1]()` at 0x00703a14 -- a thiscall through slot 1, taking no stack arguments and returning the NodeGraph* that NodeGraph_FindNodeLine 0x006e4eb0 is called on. Lane P2 left this indirect edge unresolved by static reading; lane DN resolves it dynamically instead, by making the same call from the hook",
"status": "verified",
"source": "findings/subsystems/nav-classifier-live.md" }
] }

View file

@ -1,84 +0,0 @@
{
"entries": [
{
"name": "RecordObservedDesignsSweep",
"addr": "0x007c2350",
"convention": "thiscall",
"prototype": "void __thiscall Game::StrategyServer::RecordObservedDesigns() -- TAIL PHASE 34 (called at 0x007d98aa from OnAllCombatDone_Tail 0x007d92a0; also from BuildTurnEvents 0x007db780 at 0x007dbc98 and from LoadGame 0x007dd530 at 0x007ddc2b). 222 bytes. Triple loop: for each player p in Players (this+0x54/0x58), for each fleet f in Fleets (this+0x64/0x68), for each ship sh in f->ships (f+0xa4/0xa8) -- so the recorder is called once per SHIP, not once per design, and the repetition is load-bearing because the recorder moves a re-observed record to the back of the list. TWO GATES: `p->PlyrIdx(+0x28) >= 15` skips the player (0x007c23bf `cmp eax,0xf; jge`), and `((sh->+0x54 >> (2*PlyrIdx)) & 3) != 3` skips the ship (0x007c23c4-0x007c23d6, `lea ecx,[eax+eax]; mov eax,3; shl eax,cl; and eax,[edx+0x54]; shr eax,cl; cmp eax,3`). Ship+0x54 is a TWO-BIT-PER-PLAYER visibility word and is NOT serialised -- the ship's on-disk field list runs +0x4c Dep, +0x4d Atq, +0x5c LCT with 0x54 and 0x58 absent. Then `RecordObservedDesign(p, sh->design(+0x14))` at 0x007c23e2",
"status": "verified",
"source": "findings/subsystems/t34-observed-designs.md (lane DT, 2026-09-09, own disassembly pass over dumps/sots.exe with tools/x86disp.py)"
},
{
"name": "RecordObservedDesign",
"addr": "0x007be340",
"convention": "thiscall",
"prototype": "void __thiscall Game::StrategyServer::RecordObservedDesign(Game::ServerPlayer* observer, Game::Design* design) -- RET 8. Four early returns: null observer, null design, `design->owner(+0x130)->+0xfb != 0 && ->+0xfc == 0` (0x007be389/0x007be392 -- NPC and RebAI, so a design owned by an NPC that is not a rebel AI is never observed by anyone), `!0x0080baf0(design)` (0x007be3a1) and `0x00813ab0(design, 0x400, 0)` (0x007be3b7, a design flag test). DEDUP ON odid ALONE: linear scan of observer->odes (+0x254/+0x258) comparing element+0x8, stride 0x10 (0x007be3c4-0x007be3ef). MISS -> ObservedDesign ctor 0x0080da30 on the stack, push_back 0x00799d80, then otnF/otnL = server->turn(+0xc) as WORDS at +0x4/+0x6, odid = design->+0xa0->+0x4 at +0x8, opid = owner->+0x4 at +0xc; if the owner is not the observer, the design id is also appended to a per-player vector at server->+0x284 + 0x10*observer->PlyrIdx. HIT -> the element's four fields are COPIED OUT, the element is ERASED (vector::erase 0x00795c40) and a copy is PUSHED ON THE BACK (0x007be618-0x007be66d): a re-observation is a MOVE-TO-BACK, not an in-place update, so the list is in last-observation order and otnF survives. Both paths then set back->+0x6 = turn. Finally the TRIM at 0x007be67f: walk from the last element to the first, count elements whose opid equals this design's owner id, keep the first 20 (`cmp [ebp-0x10],0x14; jge erase`) and erase the rest -- a CAP OF 20 RECORDS PER DESIGN OWNER, applied after EVERY record call, not once per sweep. Tail: three set builders feed the tech and weapon lists -- 0x00862c90 and 0x008629b0 into RecordObservedTech 0x007ba1a0 (at 0x007be4e1 and 0x007be535), 0x008626a0 into RecordObservedWeapon 0x007be1b0 (at 0x007be591)",
"status": "verified",
"source": "findings/subsystems/t34-observed-designs.md (lane DT, 2026-09-09)"
},
{
"name": "RecordObservedWeapon",
"addr": "0x007be1b0",
"convention": "thiscall",
"prototype": "void __thiscall Game::StrategyServer::RecordObservedWeapon(Game::ServerPlayer* observer, Game::ServerPlayer* designOwner, <weapon>) -- the owep sibling of RecordObservedTech 0x007ba1a0 (lane X). Its single call site is RecordObservedDesign+0x251 (0x007be591), fed from the design's weapon set built by 0x008626a0. Named from that call site and from ObservedWeapon::Write 0x00817bc0; its body is NOT read",
"status": "hypothesis",
"source": "findings/subsystems/t34-observed-designs.md (lane DT, 2026-09-09) -- call-site attribution only"
},
{
"name": "vector_ObservedDesign_push_back",
"addr": "0x00799d80",
"convention": "thiscall",
"prototype": "void __thiscall std::vector<Game::ObservedDesign>::push_back(const ObservedDesign&) -- both call sites are inside RecordObservedDesign with ecx = ServerPlayer+0x254 (0x007be40b append, 0x007be65c move-to-back)",
"status": "verified",
"source": "findings/subsystems/t34-observed-designs.md (lane DT, 2026-09-09)"
},
{
"name": "vector_ObservedDesign_erase",
"addr": "0x00795c40",
"convention": "thiscall",
"prototype": "iterator __thiscall std::vector<Game::ObservedDesign>::erase(iterator) -- called at 0x007be64d with ecx = ServerPlayer+0x254, on the move-to-back path only. The trim at the end of RecordObservedDesign does its own inline element shift (0x007be7de, four moves of 0x10 bytes per element) rather than calling this",
"status": "verified",
"source": "findings/subsystems/t34-observed-designs.md (lane DT, 2026-09-09)"
},
{
"name": "ObservedDesign_ctor",
"addr": "0x0080da30",
"convention": "thiscall",
"prototype": "Game::ObservedDesign::ObservedDesign() -- called at 0x007be3f8 on a stack temporary that is immediately pushed back. Writes the vptr 0x00a23c64 (the same constant the move-to-back path stores into its stack copy at 0x007be62e)",
"status": "verified",
"source": "findings/subsystems/t34-observed-designs.md (lane DT, 2026-09-09)"
},
{
"name": "ObservedDesign_sizeof",
"convention": "constant",
"prototype": "sizeof(Game::ObservedDesign) = 0x10 (16). Measured three ways inside RecordObservedDesign: the dedup scan advances `add eax,0x10` (0x007be3e6), the trim indexes `shl edx,4` / `sar eax,4` (0x007be6a1, 0x007be692) and the erase shift steps 0x10 per element (0x007be7fc). Layout {vptr @+0x0, uint16 otnF @+0x4, uint16 otnL @+0x6, int odid @+0x8, int opid @+0xc} -- fully accounted, no padding slack. That is the wire record otnF otnL odid opid plus the vptr, and it is the SMALL sibling of Game::ObservedTech (0x2c), whose extra 0x1c is the embedded tech-name std::string",
"status": "verified",
"source": "findings/subsystems/t34-observed-designs.md (lane DT, 2026-09-09); cf. findings/subsystems/observedtech-append.md",
"offset": "0x10"
},
{
"name": "ObservedDesign_vftable",
"addr": "0x00a23c64",
"convention": "data",
"prototype": "Game::ObservedDesign vftable. Stored at +0x0 by ObservedDesign_ctor 0x0080da30 and written directly into the stack copy on RecordObservedDesign's move-to-back path (0x007be62e `mov [ebp-0x50], 0xa23c64`)",
"status": "verified",
"source": "findings/subsystems/t34-observed-designs.md (lane DT, 2026-09-09)"
},
{
"name": "ServerPlayer_off_ObservedDesigns",
"convention": "offset",
"prototype": "std::vector<Game::ObservedDesign> Game::ServerPlayer::odes at +0x254 (_Myfirst +0x254, _Mylast +0x258, _Myend +0x25c, _Alval +0x260). Already in objects/layouts as the odes vector; recorded here with its WRITER, which was not previously attributed: RecordObservedDesign 0x007be340 is the only function that appends to, erases from or trims it. Its sibling ServerPlayer_off_ObservedTechs is +0x274 (lane X)",
"status": "verified",
"source": "findings/subsystems/t34-observed-designs.md (lane DT, 2026-09-09)",
"offset": "0x254"
},
{
"name": "ServerPlayer_off_IsNPC",
"convention": "offset",
"prototype": "bool Game::ServerPlayer::NPC at +0xfb. Read by RecordObservedDesign at 0x007be389 as the first half of the observability guard `if (owner->+0xfb && !owner->+0xfc) return`. The identification is by ADJACENCY, not by a direct read: lane T pinned RebAI at +0xfc (ProcessTurn phase 8, 0x00891517), and the wire writes Elim, NPC, RebAI, ReqCL consecutively, so +0xfb is NPC. CORROBORATED BY THE WHOLE CORPUS: every observation record in every save names a design owned by one of the two non-NPC empires, and the four NPC factions' 26 designs appear in nobody's list; and removing the guard from the reimplementation regresses the canonical pair by 9 leaves (four spurious records for the NPC 'Alien Menace') while costing nothing on the rich turn",
"status": "hypothesis",
"source": "findings/subsystems/t34-observed-designs.md (lane DT, 2026-09-09) -- adjacency plus a corpus-wide and a differential check, not a direct read of the writer",
"offset": "0xfb"
}
]
}

View file

@ -1,65 +0,0 @@
A 4d8ea15bd6ddfe746f97c45b37bdcc8f /tmp/claude-1000/-home-alex/ec8e34f8-af37-4ef2-a309-ed6a15293097/scratchpad/dt/out/canon-after.sav
B e9c161e311f8ef8fad6f1aa1903dcf3f /home/alex/sots-re/verify/results/saves/turn3-state.sav
policy: floats=bits mask=none reader=74fd562c75e2679e
DIVERGED: 61 leaf difference(s)
/Summary/Checksum: -1205790620 -> -769976634
/Sim/NMnx: 109 -> 111
/Sim/FleetIDs[]: removed [1744], added [34, 1776] (7 -> 8 entries)
/Sim/ShipIDs[]: removed [], added [1760] (16 -> 17 entries)
/Sim/RNG/.: '<raw 2503 B ef4d678696ed4c53>' -> '<raw 2503 B a80459bfd63a006b>'
/Sim/cmbtid: 2 -> 3
/Sim/turnstats/history/hist[0]/stats[2]: only-in-B
/Sim/turnstats/history/hist[1]/stats[2]: only-in-B
/Sim/turnstats/history/hist[2]/stats[2]: only-in-B
/Sim/turnstats/history/hist[3]/stats[2]: only-in-B
/Sim/turnstats/history/hist[4]/stats[2]: only-in-B
/Sim/turnstats/history/hist[5]/stats[2]: only-in-B
/Sim/turnstats/history/hist[6]/stats[2]: only-in-B
/Sim/turnstats/history/hist[7]/stats[2]: only-in-B
/Sim/players/Player[16 "re"]/Events/EvNxID: 2 -> 3
/Sim/players/Player[16 "re"]/Events/Events/.[EvTurn=3]: only-in-B
/Sim/players/Player[16 "re"]/Events/Events/.[0]: 1 -> 2
/Sim/players/Player[16 "re"]/BnkPr: -789323 -> -791290
/Sim/players/Player[32 "Fane Lao"]/TechTree/TResDone[106]: 2879 -> 5768
/Sim/players/Player[32 "Fane Lao"]/TechTree/Tbd[106]: 1 -> 2
/Sim/players/Player[32 "Fane Lao"]/Sav: 142379 -> 135486
/Sim/players/Player[32 "Fane Lao"]/Maint: 500 -> 1000
/Sim/players/Player[32 "Fane Lao"]/Events/EvNxID: 2 -> 4
/Sim/players/Player[32 "Fane Lao"]/Events/Events/.[EvTurn=3]: only-in-B
/Sim/players/Player[32 "Fane Lao"]/Events/Events/.[0]: 1 -> 2
/Sim/players/Player[32 "Fane Lao"]/FNG/FNGNum: 1 -> 3
/Sim/players/Player[32 "Fane Lao"]/PvSav: 92651 -> 80751
/Sim/players/Player[32 "Fane Lao"]/BnkPr: -898837 -> -901002
/Sim/players/Player[32 "Fane Lao"]/ShipRecs/srb[0]: 1 -> 2
/Sim/players/Player[32 "Fane Lao"]/ShipRecs/sri[0]: 1 -> 2
/Sim/players/Player[32 "Fane Lao"]/ShipRecs/srb[3]: 1 -> 2
/Sim/players/Player[32 "Fane Lao"]/ShipRecs/sri[3]: 1 -> 2
/Sim/players/Player[32 "Fane Lao"]/lboid: 1 -> 2
/Sim/systems/Sys[64 "Hyperion"]/rcex: 65536 -> 0
/Sim/systems/Sys[64 "Hyperion"]/TShn: 2 -> 3
/Sim/systems/Sys[112 "Gamma Cephei"]/PvPop2/PopG/PopC: 500000000 -> 520000000
/Sim/systems/Sys[112 "Gamma Cephei"]/RepCur: 336360.0 -> 336840.0 [15360 ulp]
/Sim/systems/Sys[112 "Gamma Cephei"]/RepMax: 336360.0 -> 336840.0 [15360 ulp]
/Sim/systems/Sys[112 "Gamma Cephei"]/TShn: 2 -> 3
/Sim/systems/Sys[224 "Spica"]/TShn: 2 -> 3
/Sim/systems/Sys[288 "Ke'Dolarra"]/PvPop2/PopG/PopC: 500000000 -> 520000000
/Sim/systems/Sys[288 "Ke'Dolarra"]/RepCur: 370000.0 -> 370520.0 [16640 ulp]
/Sim/systems/Sys[288 "Ke'Dolarra"]/RepMax: 370000.0 -> 370520.0 [16640 ulp]
/Sim/systems/Sys[288 "Ke'Dolarra"]/DefF: 1744 -> 1776
/Sim/systems/Sys[288 "Ke'Dolarra"]/Flt: 1744 -> 1776
/Sim/systems/Sys[288 "Ke'Dolarra"]/TShn: 2 -> 3
/Sim/systems/Sys[304 "Koa’Vo"]/rcex: 268435456 -> 0
/Sim/systems/Sys[304 "Koa’Vo"]/TShn: 2 -> 3
/Sim/systems/Sys[336 "Kaa’Vaalu"]/rcex: 65536 -> 0
/Sim/systems/Sys[336 "Kaa’Vaalu"]/TShn: 2 -> 3
/Sim/systems/Sys[400 "Markab"]/rcex: 65536 -> 0
/Sim/systems/Sys[400 "Markab"]/TShn: 2 -> 3
/Sim/systems/Sys[448 "Kea’Pono"]/rcex: 65536 -> 0
/Sim/systems/Sys[448 "Kea’Pono"]/TShn[0]: 2 -> 3
/Sim/systems/Sys[448 "Kea’Pono"]/TShn[1]: 2 -> 3
/Sim/systems/Sys[480 "Ko'Rorkor"]/rcex: 65536 -> 0
/Sim/systems/Sys[480 "Ko'Rorkor"]/TShn: 2 -> 3
/Sim/NumFlts: 7 -> 8
/Sim/fleets/Flt[1744 "Alpha Fleet"]: only-in-A
/Sim/fleets/Flt[34 "Beta Fleet"]: only-in-B
/Sim/fleets/Flt[1776 "Gamma Fleet"]: only-in-B

View file

@ -1,66 +0,0 @@
A d9b659d5413715b463f418f06ef23942 /tmp/claude-1000/-home-alex/ec8e34f8-af37-4ef2-a309-ed6a15293097/scratchpad/dt/out/canon-before.sav
B e9c161e311f8ef8fad6f1aa1903dcf3f /home/alex/sots-re/verify/results/saves/turn3-state.sav
policy: floats=bits mask=none reader=74fd562c75e2679e
DIVERGED: 62 leaf difference(s)
/Summary/Checksum: -1205790620 -> -769976634
/Sim/NMnx: 109 -> 111
/Sim/FleetIDs[]: removed [1744], added [34, 1776] (7 -> 8 entries)
/Sim/ShipIDs[]: removed [], added [1760] (16 -> 17 entries)
/Sim/RNG/.: '<raw 2503 B ef4d678696ed4c53>' -> '<raw 2503 B a80459bfd63a006b>'
/Sim/cmbtid: 2 -> 3
/Sim/turnstats/history/hist[0]/stats[2]: only-in-B
/Sim/turnstats/history/hist[1]/stats[2]: only-in-B
/Sim/turnstats/history/hist[2]/stats[2]: only-in-B
/Sim/turnstats/history/hist[3]/stats[2]: only-in-B
/Sim/turnstats/history/hist[4]/stats[2]: only-in-B
/Sim/turnstats/history/hist[5]/stats[2]: only-in-B
/Sim/turnstats/history/hist[6]/stats[2]: only-in-B
/Sim/turnstats/history/hist[7]/stats[2]: only-in-B
/Sim/players/Player[16 "re"]/Events/EvNxID: 2 -> 3
/Sim/players/Player[16 "re"]/Events/Events/.[EvTurn=3]: only-in-B
/Sim/players/Player[16 "re"]/Events/Events/.[0]: 1 -> 2
/Sim/players/Player[16 "re"]/BnkPr: -789323 -> -791290
/Sim/players/Player[32 "Fane Lao"]/TechTree/TResDone[106]: 2879 -> 5768
/Sim/players/Player[32 "Fane Lao"]/TechTree/Tbd[106]: 1 -> 2
/Sim/players/Player[32 "Fane Lao"]/Sav: 142379 -> 135486
/Sim/players/Player[32 "Fane Lao"]/Maint: 500 -> 1000
/Sim/players/Player[32 "Fane Lao"]/Events/EvNxID: 2 -> 4
/Sim/players/Player[32 "Fane Lao"]/Events/Events/.[EvTurn=3]: only-in-B
/Sim/players/Player[32 "Fane Lao"]/Events/Events/.[0]: 1 -> 2
/Sim/players/Player[32 "Fane Lao"]/FNG/FNGNum: 1 -> 3
/Sim/players/Player[32 "Fane Lao"]/PvSav: 92651 -> 80751
/Sim/players/Player[32 "Fane Lao"]/BnkPr: -898837 -> -901002
/Sim/players/Player[32 "Fane Lao"]/ShipRecs/srb[0]: 1 -> 2
/Sim/players/Player[32 "Fane Lao"]/ShipRecs/sri[0]: 1 -> 2
/Sim/players/Player[32 "Fane Lao"]/ShipRecs/srb[3]: 1 -> 2
/Sim/players/Player[32 "Fane Lao"]/ShipRecs/sri[3]: 1 -> 2
/Sim/players/Player[32 "Fane Lao"]/lboid: 1 -> 2
/Sim/players/Player[32 "Fane Lao"]/odes/.[1]/otnL: 2 -> 3
/Sim/systems/Sys[64 "Hyperion"]/rcex: 65536 -> 0
/Sim/systems/Sys[64 "Hyperion"]/TShn: 2 -> 3
/Sim/systems/Sys[112 "Gamma Cephei"]/PvPop2/PopG/PopC: 500000000 -> 520000000
/Sim/systems/Sys[112 "Gamma Cephei"]/RepCur: 336360.0 -> 336840.0 [15360 ulp]
/Sim/systems/Sys[112 "Gamma Cephei"]/RepMax: 336360.0 -> 336840.0 [15360 ulp]
/Sim/systems/Sys[112 "Gamma Cephei"]/TShn: 2 -> 3
/Sim/systems/Sys[224 "Spica"]/TShn: 2 -> 3
/Sim/systems/Sys[288 "Ke'Dolarra"]/PvPop2/PopG/PopC: 500000000 -> 520000000
/Sim/systems/Sys[288 "Ke'Dolarra"]/RepCur: 370000.0 -> 370520.0 [16640 ulp]
/Sim/systems/Sys[288 "Ke'Dolarra"]/RepMax: 370000.0 -> 370520.0 [16640 ulp]
/Sim/systems/Sys[288 "Ke'Dolarra"]/DefF: 1744 -> 1776
/Sim/systems/Sys[288 "Ke'Dolarra"]/Flt: 1744 -> 1776
/Sim/systems/Sys[288 "Ke'Dolarra"]/TShn: 2 -> 3
/Sim/systems/Sys[304 "Koa’Vo"]/rcex: 268435456 -> 0
/Sim/systems/Sys[304 "Koa’Vo"]/TShn: 2 -> 3
/Sim/systems/Sys[336 "Kaa’Vaalu"]/rcex: 65536 -> 0
/Sim/systems/Sys[336 "Kaa’Vaalu"]/TShn: 2 -> 3
/Sim/systems/Sys[400 "Markab"]/rcex: 65536 -> 0
/Sim/systems/Sys[400 "Markab"]/TShn: 2 -> 3
/Sim/systems/Sys[448 "Kea’Pono"]/rcex: 65536 -> 0
/Sim/systems/Sys[448 "Kea’Pono"]/TShn[0]: 2 -> 3
/Sim/systems/Sys[448 "Kea’Pono"]/TShn[1]: 2 -> 3
/Sim/systems/Sys[480 "Ko'Rorkor"]/rcex: 65536 -> 0
/Sim/systems/Sys[480 "Ko'Rorkor"]/TShn: 2 -> 3
/Sim/NumFlts: 7 -> 8
/Sim/fleets/Flt[1744 "Alpha Fleet"]: only-in-A
/Sim/fleets/Flt[34 "Beta Fleet"]: only-in-B
/Sim/fleets/Flt[1776 "Gamma Fleet"]: only-in-B

View file

@ -1,45 +0,0 @@
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[2]/odid: 546 -> 1106
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[3]/odid: 770 -> 1042
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[4]/otnF: 28 -> 27
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[4]/odid: 1106 -> 226
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[5]/odid: 1042 -> 818
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[6]/odid: 226 -> 978
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[7]/odid: 818 -> 1202
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[8]/otnF: 28 -> 5
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[8]/odid: 978 -> 130
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[9]/odid: 1202 -> 1442
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[10]/otnF: 5 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[10]/odid: 130 -> 1506
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[11]/odid: 1442 -> 194
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[12]/odid: 1506 -> 1490
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[13]/odid: 962 -> 1826
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[14]/odid: 194 -> 386
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[15]/odid: 1490 -> 1474
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[16]/odid: 386 -> 1250
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[17]/odid: 1250 -> 1522
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[18]/otnF: 28 -> 27
/Sim/players/Player[32 "The Eternal Empire"]/odes/.[18]/odid: 1474 -> 962
/Sim/players/Player[32 "The Eternal Empire"]/owep/.[1]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/owep/.[2]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/owep/.[3]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/owep/.[4]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/owep/.[5]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[43]: only-in-B
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[0]: 42 -> 43
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[2]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[5]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[13]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[14]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[15]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[16]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[20]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[22]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[24]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[27]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[28]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[30]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[31]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[32]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[33]/otnL: 15 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[35]/otnL: 27 -> 28
/Sim/players/Player[32 "The Eternal Empire"]/otch/.[36]/otnL: 27 -> 28

View file

@ -1,205 +0,0 @@
load: /home/alex/sots-re/verify/results/saves/ad-turn27-two-raiders.sav
1052300 inflated bytes, 0 error(s), 1 warning(s)
turn 27, frame 27, modCount 1428, 8 player(s), 28 system(s), 54 fleet(s)
data: /tmp/claude-1000/-home-alex/ec8e34f8-af37-4ef2-a309-ed6a15293097/scratchpad/sotsdata -- 885 section(s) over 7 race(s), 5196 string(s), 46 load problem(s)
turn-commands: verify/results/turncommands/br2-turn27-deep.tcb -- 8 block(s), 3 seed(s)
source: BR2-deep-aiorders.txt
input: ad-turn27-two-raiders.sav
batch: seq=2 n=8
note: the load-time batch is excluded; this is the End-Turn submission
turn commands: 8 block(s), 4 submitting, 85 command(s)
ModCount bumps charged 70
applied 4 transcribed 0 declined 36 incomplete 45
leaves written by commands 0
step blk player cost disposition command
6 1 32 1 incomplete list 5 system rates [0]
the capture does not carry all eight fields of the rates frame
6 1 32 1 incomplete list 5 system rates [1]
the capture does not carry all eight fields of the rates frame
6 1 32 1 incomplete list 5 system rates [2]
the capture does not carry all eight fields of the rates frame
6 1 32 1 incomplete list 5 system rates [3]
the capture does not carry all eight fields of the rates frame
6 1 32 1 incomplete list 5 system rates [4]
the capture does not carry all eight fields of the rates frame
6 1 32 1 incomplete list 5 system rates [5]
the capture does not carry all eight fields of the rates frame
6 1 32 1 incomplete list 5 system rates [6]
the capture does not carry all eight fields of the rates frame
6 1 32 1 incomplete list 5 system rates [7]
the capture does not carry all eight fields of the rates frame
6 1 32 1 incomplete list 5 system rates [8]
the capture does not carry all eight fields of the rates frame
6 1 32 1 incomplete list 5 system rates [9]
the capture does not carry all eight fields of the rates frame
6 1 32 1 incomplete list 5 system rates [10]
the capture does not carry all eight fields of the rates frame
6 1 32 1 incomplete list 5 system rates [11]
the capture does not carry all eight fields of the rates frame
6 1 32 1 incomplete list 5 system rates [12]
the capture does not carry all eight fields of the rates frame
6 1 32 1 incomplete list 5 system rates [13]
the capture does not carry all eight fields of the rates frame
6 1 32 1 incomplete list 5 system rates [14]
the capture does not carry all eight fields of the rates frame
7 1 32 0 incomplete list 23 population [0]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
7 1 32 0 incomplete list 23 population [1]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
7 1 32 0 incomplete list 23 population [2]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
7 1 32 0 incomplete list 23 population [3]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
7 1 32 0 incomplete list 23 population [4]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
7 1 32 0 incomplete list 23 population [5]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
7 1 32 0 incomplete list 23 population [6]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
7 1 32 0 incomplete list 23 population [7]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
7 1 32 0 incomplete list 23 population [8]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
7 1 32 0 incomplete list 23 population [9]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
7 1 32 0 incomplete list 23 population [10]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
7 1 32 0 incomplete list 23 population [11]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
7 1 32 0 incomplete list 23 population [12]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
7 1 32 0 incomplete list 23 population [13]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
7 1 32 0 incomplete list 23 population [14]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
9 0 16 1 applied gate loop A (group5, research target, research rate) / research rate
the empire research/savings slider; the applier is a small handler and only this field write is modelled from it
9 1 32 1 applied gate loop A (group5, research target, research rate) / research rate
the empire research/savings slider; the applier is a small handler and only this field write is modelled from it
9 2 496 1 applied gate loop A (group5, research target, research rate) / research rate
the empire research/savings slider; the applier is a small handler and only this field write is modelled from it
9 3 512 1 applied gate loop A (group5, research target, research rate) / research rate
the empire research/savings slider; the applier is a small handler and only this field write is modelled from it
10 1 32 1 incomplete list 1 new designs [0]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
10 1 32 1 incomplete list 1 new designs [1]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
10 1 32 1 incomplete list 1 new designs [2]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
12 1 32 1 declined list 3 build orders [0]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
12 1 32 1 declined list 3 build orders [1]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
12 1 32 1 declined list 3 build orders [2]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
12 1 32 1 declined list 3 build orders [3]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
12 1 32 1 declined list 3 build orders [4]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
12 1 32 1 declined list 3 build orders [5]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
12 1 32 1 declined list 3 build orders [6]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
12 1 32 1 declined list 3 build orders [7]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
12 1 32 1 declined list 3 build orders [8]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
12 1 32 1 declined list 3 build orders [9]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
12 1 32 1 declined list 3 build orders [10]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
12 1 32 1 declined list 3 build orders [11]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
12 1 32 1 declined list 3 build orders [12]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
12 1 32 1 declined list 3 build orders [13]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
12 1 32 1 declined list 3 build orders [14]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
12 1 32 1 declined list 3 build orders [15]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
12 1 32 1 declined list 3 build orders [16]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
12 1 32 1 declined list 3 build orders [17]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
12 1 32 1 declined list 3 build orders [18]
ship construction: no phase in this engine builds a ship, so the build queue's ordinal, the maintenance charge, the savings debit and the hull's id allocation all have no model
17 1 32 1 declined list 10 [0]
an unnamed command; its three words fit 'assign these ships to this fleet at this system' and that reading has never been tested
17 1 32 1 declined list 10 [1]
an unnamed command; its three words fit 'assign these ships to this fleet at this system' and that reading has never been tested
17 1 32 1 declined list 10 [2]
an unnamed command; its three words fit 'assign these ships to this fleet at this system' and that reading has never been tested
17 1 32 1 declined list 10 [3]
an unnamed command; its three words fit 'assign these ships to this fleet at this system' and that reading has never been tested
18 1 32 1 incomplete list 12 fleet layouts [0]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
18 1 32 1 incomplete list 12 fleet layouts [1]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
18 1 32 1 incomplete list 12 fleet layouts [2]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
18 1 32 1 incomplete list 12 fleet layouts [3]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
18 1 32 1 incomplete list 12 fleet layouts [4]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
18 1 32 1 incomplete list 12 fleet layouts [5]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
18 1 32 1 incomplete list 12 fleet layouts [6]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
18 1 32 1 incomplete list 12 fleet layouts [7]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
18 1 32 1 incomplete list 12 fleet layouts [8]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
18 1 32 1 incomplete list 12 fleet layouts [9]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
18 1 32 1 incomplete list 12 fleet layouts [10]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
18 1 32 1 incomplete list 12 fleet layouts [11]
the capture recorded this element's presence but not all of its payload; the command is counted and deliberately not applied
20 1 32 1 declined list 14 fleet tasks [0]
a fleet task keyed on (fleet, mode); the two modes' effects are unread, and the fleet it names is the client-allocated one from list 8
20 1 32 1 declined list 14 fleet tasks [1]
a fleet task keyed on (fleet, mode); the two modes' effects are unread, and the fleet it names is the client-allocated one from list 8
20 1 32 1 declined list 14 fleet tasks [2]
a fleet task keyed on (fleet, mode); the two modes' effects are unread, and the fleet it names is the client-allocated one from list 8
20 1 32 1 declined list 14 fleet tasks [3]
a fleet task keyed on (fleet, mode); the two modes' effects are unread, and the fleet it names is the client-allocated one from list 8
20 1 32 1 declined list 14 fleet tasks [4]
a fleet task keyed on (fleet, mode); the two modes' effects are unread, and the fleet it names is the client-allocated one from list 8
20 1 32 1 declined list 14 fleet tasks [5]
a fleet task keyed on (fleet, mode); the two modes' effects are unread, and the fleet it names is the client-allocated one from list 8
20 1 32 1 declined list 14 fleet tasks [6]
a fleet task keyed on (fleet, mode); the two modes' effects are unread, and the fleet it names is the client-allocated one from list 8
20 1 32 1 declined list 14 fleet tasks [7]
a fleet task keyed on (fleet, mode); the two modes' effects are unread, and the fleet it names is the client-allocated one from list 8
23 1 32 1 declined list 7 colonize [0]
colonisation from a named colony ship: the colony formulas exist but the ship-to-planet resolution the command relies on does not
23 1 32 1 declined list 7 colonize [1]
colonisation from a named colony ship: the colony formulas exist but the ship-to-planet resolution the command relies on does not
24 1 32 1 declined list 8 fleet moves [0]
the order names a fleet the input save does not contain -- the client allocates the fleet object AND its id before it submits, and that allocator is unread, so applying a route would move a fleet that does not exist
24 1 32 1 declined list 8 fleet moves [1]
the order names a fleet the input save does not contain -- the client allocates the fleet object AND its id before it submits, and that allocator is unread, so applying a route would move a fleet that does not exist
24 1 32 1 declined list 8 fleet moves [2]
the order names a fleet the input save does not contain -- the client allocates the fleet object AND its id before it submits, and that allocator is unread, so applying a route would move a fleet that does not exist
phases
turn drivers (the milestone's denominator): 16 of 44 modelled, 12 committed
verified 0 implemented 4 partial 8 blocked 4 stub 28
post-combat tail (written to the autosave, tracked separately): 7 of 37 modelled
verified 0 implemented 1 partial 5 blocked 1 stub 30
this run
leaves written 135
leaves NOT written by a blocked phase 119
generator words consumed 16 (state loaded, left untouched)
generator words NOT accounted (never netted off the above):
- encounter detection draws one unit value and one bounded integer per turn on every turn measured (2 words), with no derived rule behind the count -- its bound is the product of the contact and detector counts, so it is left unmodelled
- two draws are downstream of the budget's research allocation -- ProcessResearch's completion Chance and the tech-effect callback's own roll (0 or 1 word each). The allocation needs ComputeBudget's per-system money, which is ComputeOutput with the system's OWN rate sliders; the max-income form of that money is now modelled and self-checked (see T31), but it is NOT the one this path takes
- a successful raid roll may draw one further word to pick its target; no roll succeeded on any measured turn, so the cost of a success is 0 or 1 and undetermined
! the generator advanced during this run but the save keeps its original state (--commit-rng to write it)
! the modelled words are a LOWER BOUND on the turn's cost, so a committed generator is short by the unaccounted sites below and its drawn VALUES are not the game's
wrote /tmp/claude-1000/-home-alex/ec8e34f8-af37-4ef2-a309-ed6a15293097/scratchpad/dt/out/dt-r1-deep.sav (100615 bytes gzipped, 1052288 inflated)

File diff suppressed because it is too large Load diff