Commit graph

27 commits

Author SHA1 Message Date
alex
f965c8c769 lane S: std::string is 0x1c binary-wide; ObservedTech element fully mapped
Settles the 0x18-vs-0x1c contradiction lane X raised. 0x1c is right, everywhere,
and there is exactly one std::string instantiation in this binary:
_Bx@0, _Mysize@0x10, _Myres@0x14, _Alval@0x18.

ObservedTech+0x24 is that string's trailing empty-allocator word, not the
unaccounted data field it was read as. Three complete enumerations of the element
each skip it: ObservedTech::Write 0x00817cf0, the ctor 0x008562a0, and the copy
ctor inlined at 0x0079a184. Generalised with a new scanner, tools/strfootprint.py,
which recovers every (base, disp, tag) handed to the Mars::Stream string helpers:
65 std::string members off a non-stack base across every serializer in the exe,
ZERO with a sibling member inside the 0x1c span, and 51 of the 52 measurable
inter-member gaps exactly 0x1c. Corroborated by the vector<string> walk stride
(add esi,0x1c @0x00699c29), PostEvent's by-value strings at [ebp+8]/[ebp+0x24]
with RET 0x4c, and MoraleEvent 0x50 = name@0x34 + 0x1c.

Blast radius: zero recovered struct tables were wrong. Every string-bearing layout
already used 0x1c spans and 0x1c gaps -- ServerPlayer::pswd @0x2dc..0x2f7, the row
flagged for re-checking, included. Only prose carried the 0x18 number: the
loader-prototypes conventions line, the GlobalConst_ParseString prototype, and the
ObservedTech element table. struct-recovery S0 additionally had _Mysize/_Myres
transposed (size@0x14, res@0x18) while every table in the same file used the
correct offsets; fixed.

ObservedTech's four on-disk fields are now mapped rather than guessed, by reading
the serializer as lane X suggested: +0x04 uint16 otnF, +0x06 uint16 otnL, +0x08
bool odet (ONE BYTE, WriteBool), +0x0c std::string otch (0x1c), +0x28 int owith
= 0x2c exactly. That matches save_reader.py's on-disk order already. Game::
ObservedWeapon (0x00817bc0/0x00817b10) is the same element with tag owep.

Oracles unaffected and re-run: save_reader 36/36 and --strict exit 0 on all three
real saves; state_checksum 38 tests OK, coverage PROVED byte-for-byte on turn1 and
turn3. sots-engine wip/strings 32d3e36 syncs the header and corrects two stale
"unpinned" comments: clean_room_check OK, host ctest 33/33.

Standing rule this produced: never size a struct member from the offsets the code
touches. This build's STL puts the empty allocator LAST in both string (0x1c) and
vector (0x10), and an empty allocator is never loaded or stored, so a touch-scan
undercounts by exactly 4 every time. Size from an enumeration instead.
2026-09-08 05:09:33 -04:00
alex
6600382e12 b3 static findings: rng draw mapping, NextInt inclusive, float32 odds; address contract +17 2026-09-07 23:14:51 -04:00
alex
f146a7616a m2 code merged (VM window pending); record the 3-word vector struct hazard 2026-09-07 22:43:05 -04:00
alex
fa47bcdd6f correct the rng float-parity note: float10 is the x86 return ABI, not evidence of extended-precision math 2026-09-07 22:29:34 -04:00
alex
cea76e2771 rng: verify Seed/Twist/NextFloat signatures; lazy twist confirmed; flag x87 float-parity risk 2026-09-07 22:28:56 -04:00
alex
de7a2bef04 tech effects (196-entry TechId table, OnTechResearched), 8 formula gaps answered, std::string settled 2026-09-07 22:05:49 -04:00
alex
5d877d373b 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
alex
436a51fa04 save-reader: real tag names (byte-confirmed), 36 tests, strict 3/3 2026-09-07 17:56:59 -04:00
alex
c61a35f1e8 board: game/data verified; allows default resolved 2026-09-07 17:56:07 -04:00
alex
1eb967756b verified: End-Turn oracle byte-identical cross-process; stream tag corrections 2026-09-07 17:46:20 -04:00
alex
078dbbbcc7 loader prototypes M1-M4 + app spine signatures; address contract 80 entries; first-wins parity bug logged 2026-09-07 17:45:24 -04:00
alex
4547f6c8fe verify: compare harness (trace format, tracecmp, replay, oracle bridge); board catch-up; sim formula gaps 2026-09-07 17:28:37 -04:00
alex
5614940650 p2-m0 evidence: shim log + menu screenshot; Initialize signature caution 2026-09-07 17:22:21 -04:00
alex
2d298b1e98 phase 2: address contract + generator, turn-internals filed, M0-M4 rows; sibling repo sots-engine 2026-09-07 17:08:40 -04:00
alex
daea98feba verify: ship-design rules + validator, 127/127 stock designs pass; species index order decoded 2026-09-07 16:45:25 -04:00
alex
f644b83581 battle-load: profile filed, bug parked; sampler + resume recipe kept 2026-09-07 16:43:14 -04:00
alex
426df0232a verified: save_reader strict-clean on 3 real saves; all core layouts confirmed; SAVE_FORMAT confirmed 2026-09-07 16:39:41 -04:00
alex
a1852bbf5b objects: save-schema gaps resolved from serializers; StrategyServer complete 2026-09-07 16:24:54 -04:00
alex
afbfdf5ce8 verified: real saves parse; ServerPlayer/StarFleet/StarShip confirmed, ServerSystem conditional gaps listed; game-run recipe 2026-09-07 16:09:28 -04:00
alex
15ecd22aa6 verify: Streamable save reader + writer stub + tests + SAVE_FORMAT 2026-09-07 15:55:27 -04:00
alex
bb01d8e655 control-flow: full app/turn spine with addresses; types written into Ghidra; threads cleared for battle-load 2026-09-07 15:55:02 -04:00
alex
fc1d703ce7 objects: ServerPlayer/ServerSystem/StarFleet/StarShip member layouts via save-name xrefs; stream API 2026-09-07 15:24:18 -04:00
alex
7139dee219 verify: mars data parsers proven 100% on 1595 files; catalogs; tech-tree graph 2026-09-07 15:22:55 -04:00
alex
9378cec2fa ui/flow: 36-screen catalog, turn state machine; screens are C++ not data 2026-09-07 15:18:14 -04:00
alex
3bdc83fe29 recon: RTTI hierarchy + vftables, affinity pin has no topology branch, save-struct reference 2026-09-07 15:01:50 -04:00
alex
994b182f7a strings/config: battle-load smoking gun (affinity), lockstep sim, net map, Mods override 2026-09-07 14:58:36 -04:00
alex
9ad30bffce scaffold RE campaign: board, backlog, findings template, verify tree 2026-09-07 14:40:44 -04:00