# Campaign board Status flow: `backlog → in-progress → mapped → verified` (or `blocked`). `verified` requires re-verifier evidence. Maintained by **re-quartermaster**. | Target | Type | Status | Conf | Coverage | Updated | Notes | | --- | --- | --- | --- | --- | --- | --- | | RTTI class inventory | meta | mapped | high | 100% | 2026-09-07 | `findings/objects/00-inventory.md` — 1924 types, engine=Mars | | `.gob` format | subsystem | mapped | high | 100% | 2026-09-07 | renamed uncompressed ZIP (community-known) | | `Mars::AppStartup` (entry) | control-flow | mapped | high | 100% | 2026-09-07 | entry 0x00925794 -> WinMain 0x0089dd30 -> DemoApp ctor 0x0089c950 -> Mars::Application::Initialize 0x008a0e50 (config/affinity, D3D9, window, sound thread, OnStartup -> net thread). findings/control-flow/turn-spine.md | | main loop / tick dispatch | control-flow | mapped | high | 90% | 2026-09-07 | Application::Run 0x0089f5b0: FrameTimer, PanelManager, DemoApp::OnUpdate 0x00898800 / OnTick 0x0089a640 / OnRender 0x00899210. Turn pipeline: EndTurn 0x00783be0 -> BeginProcessTurn 0x007d98e0 -> StrategyServer::ProcessTurn 0x007dc6c0 -> RunCombatRound 0x007cbe80 -> SETurnResults -> ResumePlaying 0x007ddc90. Lockstep on every machine | | `Game::ClientPlayer` / `AIPlayer` | object | verified | high | 100% | 2026-09-07 | ServerPlayer confirmed strict vs real saves (turns 1-3) | | `Game::StarSystem` | object | verified | high | 100% | 2026-09-07 | ServerSystem confirmed strict vs real saves; NVO.indi unconditional; haltv bool; cp1252 names | | `Game::Planet` / `DOPlanet` | object | mapped | high | 100% | 2026-09-07 | Planet : Actor is a RENDER actor, not streamed; all colony state is in ServerSystem (+PlayerView in NVs map) | | `Game::ShipDesignDef` / `DesignList` | object | verified | high | 90% | 2026-09-07 | engine game/design merged: rules + stats in C++; 127/127, 197/197 DOpts, gating 121/127 (hidden riders warn), oracle-identical incl. 9,673 stats; 43 unit tests | | `Game::FleetLayout` | object | verified | high | 100% | 2026-09-07 | StarFleet/StarShip confirmed strict vs real saves; PrisonerHold PrNSp gated on PrMax>0 | | Mars entity chain | object | mapped | high | 100% | 2026-09-07 | EntityBase@0x00a36fd0 (10) -> PhysicalEntity@0x00a3710c (12) -> TargetableEntity -> Actor@0x009e2114 (36); mixins RigidBody/Body/NetworkObject/HandleObject/IScriptable | | `Game::GameCombatSim` + `CombatCommand*` | subsystem | backlog | — | 0% | 2026-09-07 | tactical combat (~40 command types) | | D3D9 device init | subsystem | backlog | — | 0% | 2026-09-07 | `Mars::DrawDevice`/`Camera` → Direct3DCreate9/CreateDevice | | `Mars::Buffer::gobio` | subsystem | in-progress | — | 0% | 2026-09-07 | .gob I/O; anchors the verify/ parser | | serializable-types vs save structs | verify | mapped | high | 100% | 2026-09-07 | findings/objects/save-editor-structs.md (~130 structs, exact order); verifier: cross-check vs binary next | | battle-load path | subsystem | mapped | med | 60% | 2026-09-07 | mitigation = affinity pin FUN_0089ee70; sim+load on main thread; see thread-contention row (parked) | | class hierarchy + key vftables | meta | mapped | high | 100% | 2026-09-07 | findings/objects/ghidra-recon.md - RTTI Base_Class_Array read directly; vftables for 8 core classes | | data-model (.gob data files) | subsystem | mapped | high | 100% | 2026-09-07 | findings/subsystems/data-model.md - tech/weapons/sections/races/AI all data-driven | | string / config intel | meta | mapped | high | 100% | 2026-09-07 | findings/subsystems/strings-and-config.md | | Mars brace-block parser | subsystem | verified | high | 100% | 2026-09-07 | verify/parsers/ (mars_data, flat_kv, manifest, effect_txt, verify.py): 1595/1595 files parse, 0 dangling cross-links; catalogs in verify/results/data-catalogs/ | | networking (SNM/FNM + GameSpy) | subsystem | backlog | — | 0% | 2026-09-07 | ~60 SNM strategy msgs, FNM file-xfer/host-migration; lockstep sim | | battle-load: thread contention | subsystem | blocked | med | 60% | 2026-09-07 | PARKED (not on reimpl critical path). Profile: findings/subsystems/battle-load-profile.md. Combat not reached (no ships/range/encounters); audio thread inert w/o audio device; candidate = TryEnterCriticalSection->Sleep(1000) job poll @0x0071ea60 + 15.6ms timer. Resume recipe + tools in verify/harness/profiling/ | | UI screen & flow map | meta | mapped | high | 100% | 2026-09-07 | findings/subsystems/ui-screen-map.md - 36 screens; screens are C++ on Mars controls (NOT data); turn state machine recovered | | `Game::StrategyServer` (sim block) | object | verified | high | 100% | 2026-09-07 | full member table (47 rows) confirmed vs real saves under strict parse incl. ID lists, GOWinPly, invasions, zdsc pairs, SvSctOb (present in all 3 saves) | | stream primitive API | subsystem | mapped | high | 100% | 2026-09-07 | IStreamable vft: +0x18 string, +0x1c bool, +0x20 float, +0x24 int, +0x28 nested, +0x30 raw; FUN_00816490 = NetworkObject handle id | | real save for verification | verify | verified | high | 100% | 2026-09-07 | 6 saves, 3 distinct turn states in verify/results/saves/ (byte-deterministic per state). Game runs on VM140 via DXVK 3.1 + lavapipe; recipe findings/subsystems/running-the-game.md | | save_reader.py | verify | verified | high | 100% | 2026-09-07 | --strict exit 0 on all 3 real saves; 0 resyncs / 0 hint-failures; only raw = RNG blob (2503 B). 29 tests. SAVE_FORMAT.md confirmed | | Ghidra type write-back | meta | verified | high | 100% | 2026-09-07 | structs saved in project (ServerSystem 87f, ServerPlayer 110f, StarFleet, StarShip, StrategyServer partial, 22 nested); 52 serializers + primitives + ~60 spine fns renamed; decompile shows field names | | strategic turn internals (economy/research/colony/movement/diplomacy) | subsystem | mapped | high | 90% | 2026-09-07 | findings/subsystems/strategic-turn-internals.md: budget/RP/trade/bankruptcy formulas, research rolls (unlisted race=1.0, Zuul x2), colony growth, movement, RNG=MT19937; ~600 g_KEY labels in Ghidra | | P2-M0 shim bootstrap | phase2 | verified | high | 100% | 2026-09-07 | sots-engine 5f5bc41: proxy binkw32.dll (66 exports identical), MinHook, asm-stub trace hook on Application::Initialize; menu reached; evidence verify/results/shim/. Initialize signature unverified -> asm stubs only | | P2-M1 flat-KV config loader | phase2 | verified | high | 100% | 2026-09-08 | LIVE: GlobalConsts::LoadFile hooked; trace 19 calls/1088 regions (tracecmp 0); compare 19/19, 0 divergences; REPLACE loaded all 19 files and End-Turn autosaves hashed exactly to the oracle; offline replay 0. 3 extra parsers found (string/vec3/rect), pi/180 is a double. sots-engine 8b231c0, docs/M1.md; traces verify/traces/m1-* | | P2-M2 manifest/id registry | phase2 | in-progress | med | 70% | 2026-09-08 | CODE-COMPLETE (engine 81218c7): hooks on WeaponDictionary::Init + SectionDictionary ctor (verified thiscall; added CallConv::Thiscall to the Hook template), manifest_loader + MSVC sort replica; ctest 26/26, cross-build staged /srv/re-lab/shim/dist-m2. Scout trace on the live game proved 123 weapon ids exact, dict sorted by _stricmp on name, 885 sections, 10 dangling ids absent. NEEDS ~20min VM window for golden/compare/replace | | P2-M3 Mars brace-block parser | phase2 | backlog | — | 0% | 2026-09-07 | Mars::Script pull tokenizer (Open 0x008cd7d0, ReadToken 0x008cd2f0, Next 0x008cd3e0, SkipBlock 0x008cd4b0); whitespace-only delimiting, quotes " ' ` no escapes, EOF ends, stray } ignored, LAST PAIR W/O TRAILING NEWLINE DROPPED; consumers = _stricmp if/else chains (WeaponDef::ParseScript 0x00599070, SectionDef::ParseScript 0x005744e0, MasterTechTree::ParseTech 0x0058b050). .effect = Mars::TextFileStream (Open 0x008cfb90) | | P2-M4 gobio VFS read | phase2 | backlog | — | 0% | 2026-09-07 | choke point: bool __cdecl gobio::ReadFile(const char*, IBuffer**) 0x008d5140; FileSystemSet ctor 0x008d6d60 pushes NativeFileSystem(".") FIRST then sots.ini [Modules] Mount (fallback sots.gob, sots_local_en.gob); zip lookup case+slash-insensitive 0x008d4a50 -> matches mars/vfs NativeFirst | | loader prototypes (Ghidra) | meta | verified | high | 100% | 2026-09-07 | findings/subsystems/loader-prototypes.md: 80 entries (79 verified) in ghidra/addresses.json; Initialize = bool(this, AppStartup*) RET 4 (M0 crash explained); 93 fns renamed + 9 structs in Ghidra | | compare harness | verify | mapped | high | 100% | 2026-09-07 | verify/harness/compare/: TRACE_FORMAT.md, tracecmp.py, replay, oracle bridge | | engine: mars/parse | engine | verified | high | 100% | 2026-09-07 | sots-engine: brace-block + .effect readers; oracle 1531/1531; cross-compiles i686; wired into host+shim builds | | engine: mars/text | engine | verified | high | 100% | 2026-09-07 | flat-kv, id-manifest, csv; oracle 64/64 (Strings.csv 5722 rows); ctest green | | engine: game/sim formulas | engine | verified | high | 100% | 2026-09-08 | sim-pin merged: all 5 low-confidence formulas pinned (3.3 on protection limit, old-state bankruptcy decisions, hazard curve, money tail, pop bonus); tests 356->466; + game/effects (196 TechIds, 44 typed effects, 254 checks) | | engine: mars/stream + rng | engine | verified | high | 100% | 2026-09-07 | merging: 100% exact dump agreement on 3 saves; typed shapes round-trip byte-identical whole file; RNG = seed(RSeed)+2 twists confirmed; 4 tag-name fixes for SAVE_FORMAT | | engine: game/data catalogs | engine | verified | high | 100% | 2026-09-07 | merged: WeaponDef/ShipSectionDef/TurretTable/IdRegistry/TechTree/StringTable + cross_check; oracle 229,042 values 0 diffs; crosslink set reproduced exactly; 34 malformed shipped tokens pinned | | engine: mars/vfs (gob) | engine | verified | high | 100% | 2026-09-07 | merged: ZIP reader + native override; 8352+2035 entries = unzip -l; all 10268 files CRC-clean; byte-equal spot checks; ctest 11/11 | | determinism oracle | verify | verified | high | 100% | 2026-09-07 | BYTE-IDENTICAL across 5 runs incl. cross-process: (Autosave).sav 978041ac…, (Autosave EndTurn).sav bb4fd9ac…; gzip MTIME=0; only loaded-post-turn re-save differs (Player.Status 4->0, Summary.Checksum). findings/subsystems/determinism-oracle.md | | engine: shim trace/compare emitter | engine | verified | high | 100% | 2026-09-07 | merged (sots-engine 9e110b4): emitter byte-exact vs mkfixture, tracer, snapshot/diff, Hook; ctest 18/18; tracecmp exits 0/1/2 as specified; shim links | | engine parity: first-wins keys + tokenizer rules | engine | verified | high | 100% | 2026-09-07 | merged: Mars::Script tokenizer rules, first-wins keys, trailing-pair drop in mars/parse+mars/text AND Python oracle; oracles 1531/1531, 64/64; only real-data effects: 2 dropped trailing pairs (engine uses defaults), systemnames.txt nesting | | save-format tag corrections | verify | verified | high | 100% | 2026-09-07 | byte-confirmed at offsets (otnF x62, nextid, FAIDes/DHide/DWep/DName x43, ords, wpts, paths); reader A()-matches them; 36 tests; strict 3/3, infos 259->197; SAVE_FORMAT §10 changelog | | tech effects (code-defined) | subsystem | mapped | high | 90% | 2026-09-07 | findings/subsystems/tech-effects.md: g_TechIdNames 196 @0x009ff9e4 (TechId=10000+i), effects in ServerPlayer::OnTechResearched 0x00891790; SpeciesDef table 0x00b10a00; 36 strategic / ~45 gates / ~115 none. Feeds game/sim + game/data | | strategic formula gaps | subsystem | verified | high | 100% | 2026-09-07 | findings/subsystems/formula-gaps.md: all 8 answered with code (bankruptcy 3.3 on BnkPr, linear hazard, money tail, pbon, slider, [6] net, no speed clamp, decay hits current) | | engine: game/design | engine | verified | high | 100% | 2026-09-07 | merged; see ShipDesignDef row | | P2-B1 ComputeBudget (behavioral) | phase2 | verified | high | 90% | 2026-09-08 | LIVE + GREEN: 4,623 calls traced, 4,437 compared 0 divergences (all 8 End-Turn calls identical on 22 slots), REPLACE fed the game its budget for a full turn and the End-Turn oracle reproduced byte-for-byte. Corrections: out-param is int[22] not int[25] (next 3 words are a std::vector); researchMoneyKept only charged with a research target (real bug). Coverage: 8 slots verified on varied values, 8 slots always 0 in this save (expenses/aid/debt tail UNTESTED), 6 are inputs by construction | | P2-B2 OnTechResearched (behavioral) | phase2 | in-progress | — | 0% | 2026-09-08 | offline lane (no VM): hook ServerPlayer::OnTechResearched vs src/game/effects; per-field regions; static-first per B3's lesson. Builds /srv/re-lab/build/sots-engine-b2, stages dist-b2. Coverage risk: few/no tech completions in the reference End Turn -> host tests over the whole effects table | | P2-B3 ProcessResearch (behavioral, RNG) | phase2 | in-progress | med | 70% | 2026-09-08 | CODE-COMPLETE (engine 3ebc8bf), dist-b3 staged. Static analysis found 5 REAL BUGS in our code: draw = y/(2^32-1) not y*2^-32 (constant 1/4294967295; compare could NOT have caught this - 0 decision flips in 1e6); NextInt is [0,n] INCLUSIVE by pointer; spend has no floor at 0; odds/roll/ratio are float32 not double; decay constants are widened float literals. ProcessResearch arg2 = the RNG object. ctest 26/26. NEEDS VM window (queued behind M2) | | RNG signatures (Ghidra) | meta | verified | high | 100% | 2026-09-08 | Seed/Twist/NextFloat verified (own pass) + NextInt pinned by B3: [0,n] inclusive, bound by pointer. Draw mapping = y/(2^32-1). Lazy twist, left@+0x9c4. Open: x87 precision-control mode at runtime (instrumented - hook logs fpu_cw) | | engine: game/effects | engine | verified | high | 100% | 2026-09-08 | merged: TechId enum (196 slots @10000+i), 44 ids with typed strategic effects, species flag bits, ApplyTechEffect; 254 checks | | VM140 exclusivity (lab rule) | meta | verified | high | 100% | 2026-09-08 | one agent at a time deploys/relaunches; interleaved deploys silently corrupt compares. Holder: M2 (running its window). QUEUE: B3, then B2. Non-holders build in /srv/re-lab/build/sots-engine-, stage dist-, deploy to C:\SOTS\shimdist- | | Zuul double-roll (behavioural) | verify | backlog | — | 0% | 2026-09-08 | the reference save may have no species-5 player; if so the Zuul double roll is verified only by disassembly. Needs one extra compare from a Zuul save | | budget tail coverage (expenses/aid/debt) | verify | backlog | — | 0% | 2026-09-08 | 8 ComputeBudget slots were always 0 in ref-turn2 (no sliders, no aid, no debt, no handicap). Need a save with expense sliders, a debtor and a research-aid treaty to exercise ExpenseTotal + the aid/bonus tail | | hook GetDifficultyMods | meta | backlog | — | 0% | 2026-09-08 | B1 derived the two difficulty rows from trace values (AI maintenance divisor 3, research x1.5) instead of snapshotting them; hook it properly so they stop being constants |