diff --git a/campaign/board.md b/campaign/board.md index 8306f18..091e8a1 100644 --- a/campaign/board.md +++ b/campaign/board.md @@ -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<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 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<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 |