From-scratch reimplementation of the Sword of the Stars (2006) engine. Clean-room; engine code only — bring your own game copy. Planning/RE evidence live in sots-re.
Find a file
alex 00e9266476 tests: ratchet the opaque ITEM COUNT, not the percentage; census baseline 538
The coverage ratchet reads `pct >= 99.99`, and with the last carried bodies
typed it cannot usefully be raised: the only opaque items left are the MT19937
block's two in every save, so the number is 2/items and it still ranges from
99.99400 on a 532 KB save to 99.99746 on a 1.17 MB one.  Moving the bar to
99.995 would fail a save that types perfectly and pass a save twice its size
that had picked up a whole new opaque body.  A percentage ratchet on a
fixed-size debt is a ratchet on save size.

So the percentage stays where it is and a stronger line goes beside it: the
opaque set must be exactly the two RNG items.  That breaks on the save that has
the new body, and `opaque_by_tag` names it.

test_domains: 43 saves give 755 fields observed, 538 varying, 217 constant,
against a baseline of 490 measured at 22 saves.  Nineteen of the new fields are
the bodies typed in the previous commit and only two of them (FTPShID,
FTPDesID) have ever been seen to move -- which is why the constants grew faster
than the varying fields, and is worth leaving visible.
2026-09-09 10:03:59 -04:00
cmake m0: binkw32 proxy shim, minhook, trace hook on Application::Initialize; build/deploy tooling 2026-09-07 17:22:15 -04:00
docs rng: model chance(), the only entry point that can cost zero words 2026-09-08 22:32:14 -04:00
include/generated shim: aivisit, the fleet-assignment visit-order log (lane BU) 2026-09-09 03:10:52 -04:00
src stream: the name-gen used-slot pair, and the Sprj and FTPnts bodies 2026-09-09 10:03:50 -04:00
tests tests: ratchet the opaque ITEM COUNT, not the percentage; census baseline 538 2026-09-09 10:03:59 -04:00
third_party mars/vfs: gob ZIP reader + native override, miniz 3.1.2; oracle-verified 8352+2035 entries 2026-09-07 17:40:51 -04:00
tools shim: fix cbpin's wrapped header and six unnamed hooks; add a config check 2026-09-09 02:01:58 -04:00
.gitignore init commit 2026-09-07 17:07:54 -04:00
CMakeLists.txt shim: aivisit, the fleet-assignment visit-order log (lane BU) 2026-09-09 03:10:52 -04:00
CMakePresets.json m0: binkw32 proxy shim, minhook, trace hook on Application::Initialize; build/deploy tooling 2026-09-07 17:22:15 -04:00
CONTRIBUTING.md CONTRIBUTING: note uv tool install cmake as the local workaround 2026-09-08 09:07:47 -04:00
LICENSE init commit 2026-09-07 17:07:54 -04:00
README.md src/app: the standalone -- load a save, run a turn, write a save 2026-09-08 10:35:45 -04:00

sots-engine

A from-scratch, functional reimplementation of the engine behind Sword of the Stars (2006). Not a byte-for-byte decompilation: behavior-equivalent code, built up one verified piece at a time (OpenRCT2-style) until the tree can build the whole application on its own.

Bring your own game. This repository contains engine code only. Game data, assets, saves, and the original binaries are never included; tests and tools read an owner-supplied copy via $SOTS_DATA_DIR. See CONTRIBUTING.md for the clean-room rules.

Status

Phase 2. M0 done — the shim frontend (src/shim/, a proxy binkw32.dll the original game loads) builds, deploys, hooks, and logs from a real game launch. Engine code accrues under src/mars/ and src/game/; each module is oracle-verified against the owner's game data before merge:

  • mars/parse — brace-block + .effect readers (1,531/1,531 files agree with the reference)
  • mars/text — flat key/value tables, id manifests, CSV (64/64 files agree)
  • game/sim — strategic formulas (economy, research, colonies, movement) as pure functions; 356 hand-computed checks
  • mars/vfs — .gob (ZIP) archive reader + loose-file override; entry counts and bytes verified against unzip
  • mars/stream — the game's self-describing save/serialization format (reader, writer, typed shapes) + gzip; three real saves round-trip byte-identical
  • mars/rng — MT19937 with save-state load/store; layout confirmed against real saves, draw mappings read off the binary (docs/mars-rng.md)
  • game/data — typed catalogs (weapons, ship sections, turrets, id registries, tech tree, strings) with cross-reference checks; 229k values agree with the reference
  • game/design — ship-design assembly/fit/tech-gating rules and derived stats; validates all 127 stock designs from real saves
  • app — the standalone: sots_turn loads a save, runs one strategic turn over the published phase order of all three turn drivers, and writes a save. 14 of the 44 turn-driver phases are modelled; every phase that is not appears in the run log as a named no-op. How far it is from the byte-match, and what stands in the way, is in docs/S-standalone.md

Build: cmake --preset host && cmake --build --preset host && ctest --preset host (Linux); tools/sync-build.sh cross-builds the shim on the lab box and stages it for deployment.

Layout (grows with the work)

  • src/shim/ — binkw32 proxy + hooks + old-vs-new compare harness (frontend #1)
  • src/mars/, src/game/ — the engine and game reimplementation (accruing)
  • src/app/ — the standalone turn driver (frontend #2): load a save, run a turn, write a save
  • include/generated/sots_addresses.h — binary facts (RVAs/prototypes), generated from the RE repo
  • tests/ — host tests; real-data tests skip unless $SOTS_DATA_DIR is set
  • tools/ — build (MinGW i686 cross) and deploy scripts

Planning, findings, and verification evidence are tracked in the private RE repo (sots-re).