Adopt the engine-exact standalone-missile termination for Beta saves #257

Merged
jqueuniet merged 0 commits from refs/pull/257/head into main 2026-07-17 08:47:27 +02:00
jqueuniet commented 2026-07-17 08:42:53 +02:00 (Migrated from codeberg.org)

Re-tests the #169 standalone-missile termination discrepancy now that the Beta walk is bit-exact (#256), and resolves it: the Beta compensating model is gone, retail and Beta share the engine-exact model.

Background

For standalone (non-creature-possessed) type-14 missiles, the Beta path deliberately kept a chain-mode / persistent-flag "compensating" model that contradicted the disassembled Beta binary, because engine-exact semantics desynced DATA/SKSAVE0.DAT at the time (#169, 2026-07-06). That desync was measured while the three since-fixed Beta decode bugs (overlay masks, teleporter pair fold, map cap) were corrupting downstream bit positions.

What changed

  • The decoder and encoder standalone-missile arms drop the beta conditional: single-record sub-read/sub-write with the termination flag set, flag unconditionally cleared — matching the retail engine and the unpacked Fires.exe reader/writer (0x1eaa4/0x1eac6, 0x1de41/0x1de60).
  • The two compensating-model unit tests are replaced by engine-exact Beta expectations (a type-15 after a standalone missile parses/encodes as a full cloud under set_beta(true) too); the retail-shaped tests stay as the shared-path guard.
  • docs/formats/save-record-stream.md §"Standalone-missile termination" rewritten from open question to resolved, with the history and a fixture-coverage statement.

Evidence (all under the flip, local fixtures)

  • Beta suites green: all 9 slots land inside the final flush byte and field-round-trip byte-exactly; full crate 321 passed; 26 retail --ignored round-trip guards green (retail unchanged).
  • Slot-0 engine oracle trace: PERFECT MATCH, all 15,295 CHECKCODE-entry bit positions identical (temporary trace instrumentation, removed before commit as in #256).
  • Fixture census: slots 6/7/8 contain 4/6/6 standalone missiles (16 total), every one holding exactly a nested termination — a shape that consumes identical bits under both models; no slot's CHECKCODE stream contains any type-15 full cloud, so the model-distinguishing shape (flag persistence misparsing a later cloud) is never exercised. The docs state this explicitly: the flip rests on the binary evidence; the fixtures corroborate that it regresses nothing.

Notes for review

  • CI exercises none of the Beta assertions (fixtures are local-only, skip-on-missing), same as #256. Local gates: fmt / clippy -D warnings / full workspace tests / doc -D warnings all green.

Closes #169.

Re-tests the #169 standalone-missile termination discrepancy now that the Beta walk is bit-exact (#256), and resolves it: the Beta compensating model is gone, retail and Beta share the engine-exact model. ## Background For standalone (non-creature-possessed) type-14 missiles, the Beta path deliberately kept a chain-mode / persistent-flag "compensating" model that contradicted the disassembled Beta binary, because engine-exact semantics desynced `DATA/SKSAVE0.DAT` at the time (#169, 2026-07-06). That desync was measured while the three since-fixed Beta decode bugs (overlay masks, teleporter pair fold, map cap) were corrupting downstream bit positions. ## What changed - The decoder and encoder standalone-missile arms drop the `beta` conditional: single-record sub-read/sub-write with the termination flag set, flag unconditionally cleared — matching the retail engine and the unpacked `Fires.exe` reader/writer (`0x1eaa4`/`0x1eac6`, `0x1de41`/`0x1de60`). - The two compensating-model unit tests are replaced by engine-exact Beta expectations (a type-15 after a standalone missile parses/encodes as a full cloud under `set_beta(true)` too); the retail-shaped tests stay as the shared-path guard. - `docs/formats/save-record-stream.md` §"Standalone-missile termination" rewritten from open question to resolved, with the history and a fixture-coverage statement. ## Evidence (all under the flip, local fixtures) - Beta suites green: all 9 slots land inside the final flush byte and field-round-trip byte-exactly; full crate 321 passed; 26 retail `--ignored` round-trip guards green (retail unchanged). - Slot-0 engine oracle trace: PERFECT MATCH, all 15,295 CHECKCODE-entry bit positions identical (temporary trace instrumentation, removed before commit as in #256). - Fixture census: slots 6/7/8 contain 4/6/6 standalone missiles (16 total), every one holding exactly a nested termination — a shape that consumes identical bits under both models; no slot's CHECKCODE stream contains any type-15 full cloud, so the model-distinguishing shape (flag persistence misparsing a later cloud) is never exercised. The docs state this explicitly: the flip rests on the binary evidence; the fixtures corroborate that it regresses nothing. ## Notes for review - CI exercises none of the Beta assertions (fixtures are local-only, skip-on-missing), same as #256. Local gates: fmt / clippy `-D warnings` / full workspace tests / doc `-D warnings` all green. Closes #169.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
jqueuniet/dm2-tools!257
No description provided.