board: lanes A2 and D2 - alliance rule, ModCount rule, ship designs do have a serializer
This commit is contained in:
parent
ab79e16843
commit
90fba303ac
1 changed files with 8 additions and 0 deletions
|
|
@ -224,3 +224,11 @@ Status flow: `backlog → in-progress → mapped → verified` (or `blocked`).
|
|||
| multiplayer revival plan, ranked | subsystems | mapped | high | 90% | 2026-09-08 | TIER 0 (hours): VPN/LAN + manual join, NO SERVER AT ALL. TIER 1 (afternoon): availability responder, specified BYTE-FOR-BYTE - request `09 00 00 00 00 "swordots" 00`, reply `FE FD 09 00 00 00 00` - and LIKELY A NO-OP, because the check FAILS OPEN on DNS failure (socket == -1 returns GSIACAvailable); MATCHINGSERVICE_UNSUPPORTED was GameSpy's KILL-SWITCH, not self-detection. TIER 3 COLLAPSES TO CONFIGURATION, NOT CODE: OpenSpy and UniSpyServer both implement the exact service set and both already ship the swordots row; adding a title is one DB row plus SyncToRedis. CAVEATS, STATED: swordots is SEEDED not on OpenSpy's 132-title tested list; the public openspy.net availability responder returns "available" for ANY gamename so it PROVES NOTHING - self-host; the seeded row says queryport 6500 while SOTS reports on 3369; and its keylist omits SOTS's 16 custom QR2 keys (slot0..7, numslots, mapshape, numsys, turn, scenario, settings, slot_, ranks - ids 50-65, recovered here). 333networks RULED OUT: GameSpy v0 only, no SB v2/NatNeg/peerchat |
|
||||
| two clients on ONE guest: /concurrent | meta | verified | high | 100% | 2026-09-08 | THE GAME SHIPS THE TWO-INSTANCE SWITCH. WinMain compares argv against `/concurrent` on ERROR_ALREADY_EXISTS and CONTINUES on a match - so `/concurrent /join 127.0.0.1:3369` gives two clients on one guest, NO CLONED VM NEEDED. Address parsing is DOTTED-QUAD ONLY (`localhost` is rejected). Full switch list: /join, /concurrent, /startup:, /motd_, /tell |
|
||||
| CORRECTIONS from lane G2 | meta | verified | high | 100% | 2026-09-08 | ui-screen-map.md corrected in place on two counts: there are 13 NETERROR_* strings and NONE IS CD-KEY (the "21 incl. 6 CD-key" and "CD-key strings survive" claims were WRONG), and the "2017 build knows GameSpy is dead" inference is replaced with the FAIL-OPEN finding. Also: **SOTS1's backend died December 2012, not the May 2014 general shutdown** - its agreement ran through Lighthouse Interactive |
|
||||
| alliance mask rule + ModCount writers | control-flow | verified | high | 95% | 2026-09-08 | Lane A2. THE ALLIANCE RULE, byte for byte at 0x007dc871-0x007dc8c7: `rec->almem = 0; rec->almem |= 1<<i; if (p->ALid != -1) rec->almem |= p->AL;` - THREE SEPARATE STORES with the record pointer reloaded before each, which is what makes the term an OR and is INVISIBLE IN ANY SUMMARY. The shift count is the LOOP COUNTER, so the bit is the vector position, not PlyrIdx. Measured against bytes the game wrote: 11 saves, 80 player-records, **560 fields, 0 mismatches** (was 480/6). ITS FALSIFIER FIRED AND WAS THE MODEL, NOT A MISS: all 8 almem on turn1-state are 0 because FinalizeTurnRecords ALSO RUNS ON LOAD and the load path never runs the spine, so every save's earliest archived turn carries a zero mask - true on all 11 - and the engine states it as a POSITIVE prediction (spineRan) so all 80 records compare. MODCOUNT: StrategyServer::Write tags both words itself, so S+0x8 IS ModCount and S+0xc is Frame; RTTI explains the two bases (Game::StrategySim is a base sub-object at offset 4). **29 writer sites**, each with the base PROVED a StrategySim by an independent fingerprint: 20 command handlers bumping UNCONDITIONALLY ON ENTRY BEFORE VALIDATION, 6 more inlined in ApplyTurnCommandBatch, the two turn drivers, and the abandon/chaos check (gated on Abdn, false on all 28 systems of all 11 saves) |
|
||||
| ModCount is NOT derivable from a pre-turn save | verify | verified | high | 100% | 2026-09-08 | THE RULE: ΔModCount = 2 + one per command applied out of every player's TurnCommands block (+ one per abandoned system). That is why the delta is not a function of the board - human-turn2->3 is 28 and zuul-turn16->17 is 16 on IDENTICAL 28-system/7-player boards. And the TurnCommands block in turn1/2/3-state is the EMPTY 35-item block, so the 10 non-driver bumps were issued AFTER the autosave. **ModCount cannot be derived from the pre-turn save**, S00+T00 are all the standalone can produce, and IT IS THE WRONG LEAF TO CHASE BEFORE THE AI. Independently confirms lane Q's block layout: the flush walks a vector<TurnCommands> at S+0x174 with stride 0x1b4 (last list at 0x1a8, stride 0xc) |
|
||||
| A2 reported what the corpus CANNOT separate | verify | verified | high | 100% | 2026-09-08 | Rule 15, applied without prompting. THREE parts of the alliance rule this corpus cannot distinguish: every player has PlyrIdx == i (0 of 80 records differ), every observed AL already contains its own member's bit, and AL == 0 exactly when ALid == -1. So `1<<i` vs `1<<PlyrIdx`, the OR vs an assignment, and the ALid guard vs an `AL != 0` guard are INSTRUCTION-STREAM READINGS ONLY. A unit test pins all three with the separating inputs no save provides, and the corpus test PRINTS THAT IT COULD NOT SEPARATE THEM |
|
||||
| T36 cost measured: net positive on BOTH pairs now | verify | mapped | high | 100% | 2026-09-08 | Default run UNCHANGED at closed 5 / regressed 0 - S04 writes no save leaf of its own, the mask reaches the wire only through T36 which stays blocked. What moved is T36's COST: the 8 almem regressions are GONE, and the remainder is exactly inc x3 + sav x3 (the budget) plus 3 census leaves (lane D2's). T36 now closes ALL 24 /Sim/turnstats leaves on the reference pair, so it becomes a clean +24 the moment those two land. CORRECTION to lane Y: "which way the net falls depends on the save" is NO LONGER TRUE - --commit-blocked is now net positive on BOTH pairs (+20, +2). It stays blocked anyway, because 9 leaves would be CONFIDENTLY WRONG |
|
||||
| ship designs DO have a serializer - misattributed address | objects | verified | high | 100% | 2026-09-08 | Lane D2 overturns lane D's finding. **Game::ShipDesign::Write exists at 0x008325e0 and makes four stream calls.** The published "ShipDesign::Write (0x008747a0) makes no stream call at all" was A MISATTRIBUTED ADDRESS, not a fact about the class - lane V2's inversion is decisive: `vtable_map.py who 0x008747a0` says it is IN NO VFTABLE, and its body pops a parser stack. WHY THE SWEEP MISSED IT: RTTI shows Game::ShipDesign : Game::ShipDesignDef, Mars::IStreamable, ... and **ShipDesignDef is the base and is NOT itself IStreamable** - it declares its own three virtuals in a different order; ShipDesign overrides all three and the IStreamable sub-object at +0x9c holds three ADJUSTOR THUNKS back to the primary vftable. A slot-indexed sweep finds the thunk. THE *Impl RULE WITH A TWIST WORTH RECORDING: the concrete serializer can be a DERIVED CLASS, not a separate Impl - lane V2's "check the shape, do not assume it" was right |
|
||||
| ship design: three sections, not five | objects | verified | high | 100% | 2026-09-08 | THREE CORRECTIONS FORCED. (1) THREE sections, not five - the campaign's "slots 3-4 reserved" was save_reader.py's trailing Rest("sections") sweeping Dtc/Dwgv into the section list and stock_designs.py decoding them as empty slots. **RULE 8 EXACTLY: reader and consumer agreed and were both wrong.** Two independent enumerations say three (straight-line writer; ctor eh_vector_constructor_iterator(this+0x24, 0x28, 3) closing at 0x9c = sizeof(ShipDesignDef)). (2) DWep/Dwgv are BOOLS, byte-indistinguishable at a 4-char tag - same class as odet. (3) Offset order != write order: array [+0x24,+0x4c,+0x74] = mission, command, engine; WIRE = command, mission, engine. Oracles fixed openly (rule 12): save_reader.py 49/49, stock_designs.json regenerated with the diff ONLY raw_slots 5->3 and dWep int->bool across all 127 designs, design rules still 32/32 and 127/127 |
|
||||
| hull size and the 0x400 flag | objects | verified | high | 90% | 2026-09-08 | **0x400 = defence_platform**, read off the .shipsection parser's own bit setter at 0x005749b7 directly after the strcmp against the literal; the design's word is the OR across its <=3 sections. **NOT lane B5's 0x400** - that is a FLEET flag, on the wire as FtFlg (turn1-state fleet 0 has FtFlg 1024). Different word, different object. HULL SIZE = section_class via ParseShipClassName 0x0056e1c0, _stricmp against Destroyer/Cruiser/Dreadnought -> 0/1/2; absent or unrecognised -> **0 WITH A LOG LINE, NOT AN ERROR** (16 shipped sections have no section_class); ASSIGNMENT NOT MAX - last resolved section in MEMORY ORDER wins. Both live on ShipDesign, NEITHER ON THE WIRE, both rebuilt by UpdateDerivedStats. Independent corroboration: the same bit picks default hull health (500/3000/15000 without, 100/500/1000 with) - platforms, not ships. CENSUS VERIFIED: 11 saves, 503 designs, 480 leaves, 0 mismatched, computed TWICE independently (Python off save_reader, C++ off the engine's shapes reader - they DISAGREE about section count and still agree on all 480) |
|
||||
| census coverage: 3 of 6 leaves UNEXERCISED | verify | backlog | — | 0% | 2026-09-08 | Rule 15 again, unprompted. Only 32 of 480 census leaves are NONZERO: cls0 shpt 18, cls0 satt 3, cls1 shpt 0, cls1 satt 0, cls2 shpt 11, cls2 satt 0. **Three of the six census leaves are UNEXERCISED, NOT VERIFIED** - no cruiser of any kind and no DN platform in the corpus. ONE SAVE WITH A CRUISER CLOSES TWO OF THEM. Also 0 ships with an unresolvable design, 0 unclassifiable designs, 0 designs where first- and last-resolved section disagree on hull size |
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue