Sword of the Stars (2006) reverse-engineering worklog. Infra docs live in trikilli services/re-lab.md.
Find a file
alex 746a6f29cb BP: probe 2 result - pinned seeds do NOT collapse a rich turn; the residue is one fleet-id transposition
P1 falsified. Two processes with identical pinned AI client seeds produced
different turn-28 autosaves from ad-turn27-two-raiders.sav, so a per-process
input other than the seed reaches a rich turn and C-exact is false on this
state. Resolution trigger, handed back rather than chased.

But the pin did almost all the work. AD's unpinned pair differed in 94 leaves
across designs, ship records, money, both build queues, ModCount, NumFlts,
DesignIDs[] and FleetIDs[]. This pinned pair differs in 35 of 61147, and all 35
are one transposition: fleets 1970 and 1986 exchange their entire contents.
Every decision leaf is identical.

The command block says the same from the input side. Runs L (unpinned) and A
(pinned to L's observed seeds) wrote BYTE-IDENTICAL autosaves, which gives a
noise mask no previous lane could build for this state; against it, A and B
differ in exactly three words - one fleet-move fleetId and two systemIds - and
list 10's fleet ids are in the same order in both. The id counter is
deterministic; what varies is which newly formed ship group each id lands on.

Also measured: the save has seven non-human players and the engine builds THREE
AI clients (RunAI fires 3x, ids 32/496/512); the four NPC factions get no client
and no seed.
2026-09-09 01:56:49 -04:00
campaign lane AP merged: P is two species branches not three sites; three gates closed; rule 23 gains predict-at-the-site 2026-09-09 01:36:22 -04:00
findings BP: probe 2 result - pinned seeds do NOT collapse a rich turn; the residue is one fleet-id transposition 2026-09-09 01:56:49 -04:00
ghidra AP: P's three draws are two species branches - 0x00840a3c fires, 0x0088dc43 fires, the deploy NextFloat measured 2026-09-09 01:33:23 -04:00
guides lane AP merged: P is two species branches not three sites; three gates closed; rule 23 gains predict-at-the-site 2026-09-09 01:36:22 -04:00
notes init commit 2026-09-07 12:31:56 -04:00
objects regenerate both headers (669 addresses); track objects/generated so the shared clone stops sitting dirty 2026-09-08 07:36:16 -04:00
scripts lane V2: vtable inversion — resolve indirect call edges image-wide 2026-09-08 12:05:05 -04:00
tools dashboard: value-domain line as the counterweight to the 99.99%-typed figure 2026-09-08 21:59:34 -04:00
verify BP: probe 2 result - pinned seeds do NOT collapse a rich turn; the residue is one fleet-id transposition 2026-09-09 01:56:49 -04:00
.gitignore lane D: automated struct recovery from the IStreamable serializers 2026-09-08 05:51:37 -04:00
README.md guides: RE how-to for 2000s MSVC/DX9 games (98 sources); queue replay-checksum, class recovery, apitrace/TTD 2026-09-07 18:05:58 -04:00

sots-re

Reverse-engineering worklog for Sword of the Stars (2006, SOTS1) — the 32-bit DX9 original + expansions. The nitty-gritty: static/dynamic analysis notes, Ghidra & ReVa scripts, function/struct maps, D3D9 call traces, decomp progress, findings.

Where this runs

Analysis lab on spicy (PVE, 192.168.3.201):

  • CT111 sots-re — Linux workspace: Ghidra + headless ReVa server, radare2/rizin/cutter, binwalk. Hosts the Samba share and this repo's working tree at /srv/re-lab/notes.
  • VM140 sots-re-win10 — Win10 runtime + dynamic analysis (x64dbg, Cheat Engine, RenderDoc/apitrace, DXVK→CPU-Vulkan for GPU-less rendering).

Infra (guests, storage, network, share, ReVa endpoint) is documented from the system-maintainer POV in trikilli → services/re-lab.md. This repo is everything else.

Layout

  • findings/ — the running findings log (append-only), one file per subsystem.
  • ghidra/ — exported scripts, data-type archives, struct definitions.
  • traces/ — D3D9 / Win32 API call captures + analysis.
  • scripts/ — helper tooling (loaders, extractors, parsers).
  • notes/ — session notes, scratch, hypotheses.

Ownership / legality

Game binaries come from the owner's own GOG/Steam copy. RE is for personal interoperability, bug-fixing, and preservation. Binaries themselves are not committed here (see .gitignore) — they live on the lab's Samba share /srv/re-lab/samples.

Campaign (how this repo is run)

A 4-agent crew (defined in ~/.claude/agents/re-*.md) runs the exploration: re-quartermaster (backlog + board) → re-analyst (maps via ReVa) → re-verifier (proves vs real data; old-vs-new differential once reimpl starts) → re-scribe (files the note, links it, commits).

  • campaign/board.md — live status board (start here).
  • Live tracking = Forgejo issues on alex/sots-re (labels status/* are the kanban columns; type/*, conf/*). campaign/board.md is the editable mirror — publish with scripts/forgejo_campaign.py bootstrap (needs FORGEJO_TOKEN).
  • campaign/backlog.md — prioritized target queue.
  • campaign/open-questions.md — unresolved threads.
  • findings/_template.md — the record format every finding follows.
  • findings/{objects,control-flow,subsystems}/ — the growing engine map.
  • verify/{parsers,traces,harness,results}/ — validation: struct parsers now, golden-trace replay + shim compare-mode for reimplementation.
  • ghidra/ — exported scripts + datatype archives.

Approach & north star: findings/00-strategy.md. Binary facts: findings/01-fingerprint.md.

Sibling repo

alex/sots-engine — the from-scratch engine source (clean-room, public-capable). This repo keeps the evidence + planning for both; binary facts cross over only via ghidra/addresses.json → tools/gen_addresses.py.

  • guides/re-windows-2000s-howto.md — annotated bibliography + how-to for RE of mid-2000s MSVC/DX9 Windows games, with our-experience call-outs.