The corpus went 11 -> 19 saves and named coverage fell to 97.6% against a 99.99
bar. Rule 27 says type the content. Typed, all from the recovered wire schema
plus the records the new trade/spy saves finally carry:
Game::CombatPlayerReport the <rest:prep> tail -- ncls run of six per ship
class, nsec run of two per section, ndam, srep
Game::CombatShipReport srep elements (caps2 is an i64; dami/damt f32)
Game::TacReport TRnc is a COUNT and TRships/TRsats/TRshipsL are one
loop body, INTERLEAVED on the wire -- not three
trailing runs. Two lanes could not settle this
because TRnc was 0 in every save until tonight.
Game::TacReportEvents TRby / TRto
Game::FleetLayout Lay: a FieldTemplate frame then a count and its ids
Game::TradeRoute rt -- a container write with NO count word, read as
an uncounted run keyed on the tag
Game::ServerTradeSector::FreighterWarning fwarn elements
Game::SpyCraft spy elements
Game::WeaponGroups Dwg, and Game::GunBankSelection under it
Corrections found on the way, both silent until a shape was bound to the table:
* Game::CombatReport: auto and cdst are BOOLs, dur/cdt/cdi are FLOATS. All
five were ints here. Four are 0/1 everywhere so the bytes never moved; cdt
is not, and was being read as 1070805848 instead of 1.598.
* Game::CombatWeaponReport: the damage quartet is flat and dami/damt are
floats. The old shape reached them through obj_flex, modelling a nested
`dams` frame the binary does not write. That also made CoverageArchive
charge one phantom typed item per weapon report -- exactly 8/13/21/32 on the
four affected saves -- so the pre-fix coverage figures were slightly
optimistic as well as too low.
FTPnts stays carried: it is the one item the recovery itself marks unresolved,
its count is 0 in every save, and element framing is a property of the helper --
the SysMem / mts / nalat trap. The workload that settles it is a save with a
stored fleet tactical formation.
Named coverage, per save, before -> after:
human-turn5-traderoutes 99.0003% -> 99.9951%
human-turn8-traderoutes 98.6349% -> 99.9955%
human-turn11-spytechs 97.6382% -> 99.9959%
human-turn15-spyprogram 96.9412% -> 99.9964%
the other 16 saves unchanged, 99.9940-99.9953%
corpus 99.5021% -> 99.9949%
All 20 saves are above the ratchet; the only opaque items left anywhere are the
two of the RNG blob. 14 new shapes bound to the wire schema, every one a full
match: 100 shapes, 966 items, 0 MISMATCH. ctest 58/58 over all 20 saves, both
round trips byte-identical, 0 errors and 0 warnings.
|
||
|---|---|---|
| cmake | ||
| docs | ||
| include/generated | ||
| src | ||
| tests | ||
| third_party | ||
| tools | ||
| .gitignore | ||
| CMakeLists.txt | ||
| CMakePresets.json | ||
| CONTRIBUTING.md | ||
| LICENSE | ||
| README.md | ||
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 +.effectreaders (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 checksmars/vfs—.gob(ZIP) archive reader + loose-file override; entry counts and bytes verified againstunzipmars/stream— the game's self-describing save/serialization format (reader, writer, typed shapes) + gzip; three real saves round-trip byte-identicalmars/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 referencegame/design— ship-design assembly/fit/tech-gating rules and derived stats; validates all 127 stock designs from real savesapp— the standalone:sots_turnloads 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 indocs/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 saveinclude/generated/sots_addresses.h— binary facts (RVAs/prototypes), generated from the RE repotests/— host tests; real-data tests skip unless$SOTS_DATA_DIRis settools/— build (MinGW i686 cross) and deploy scripts
Planning, findings, and verification evidence are tracked in the private RE repo (sots-re).