feat(saves): lossless self-contained save JSON + dm2 dump path #311
No reviewers
Labels
No labels
area/ci-release
area/cli
area/docs
area/dungeon
area/ftl
area/graphics
area/gui
area/music
area/saves
area/tooling
port/amiga
port/dos
port/fm-towns
port/mac
port/pc98
port/sega-cd
priority/high
priority/low
priority/medium
type/bug
type/chore
type/docs
type/feature
type/research
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
jqueuniet/dm2-tools!311
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/save-json-self-contained"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements lossless, round-trippable save JSON for Dungeon Master II savegames — the self-contained variant (Plan 1 of 2, issue #308). Foundation for the future web save editor (#301) and GUI editors (#303).
What this adds
dm2-saves::jsonmodule — a DTO-based JSON layer (SaveDump) that serialises a parsedSaveFileto human-readable JSON and reconstructs it byte-for-byte. DTOs are hand-shaped because the wire types can't derive serde directly (FileHeader/ByteOrderlack serde; several byte blobs exceed serde's 32-element array limit).SaveDump::gameplay_only(&save, variant)— lossy human-readable view (no reload).SaveDump::self_contained(&save, variant)— gameplay + all structural sections + the full suppression bitstream (base64). Reconstructs with no external files.SaveDump::reconstruct_self_contained()— rebuilds the original bytes; re-encodes gameplay phases 1–2 over the embedded bitstream and splices the phase-3–7 tail verbatim.dm2 dumpsave path — default emits gameplay-only JSON;--self-containedemits the lossless self-contained form. No external files needed in either mode.Editability model
gameplay(SGB, globals, champions, effects, timers) is editable and engine-safe.record_streamstays opaque inside the embedded bitstream here — promoting it to field-editable is the field-driven "full" variant (Plan 2), out of scope for this PR.Losslessness
A byte-exact round-trip gate (
tests/json_roundtrip.rs) runs the full public path (parse → self_contained → to_pretty_json → deserialize → reconstruct_self_contained) and asserts byte-identity over real fixtures in both byte orders — all 6 DOS-EN slots (Little, incl. the nonstandardSKSAVE4/5.DAT) and every Mac-US fixture (Big).Verification
cargo fmt --all -- --check,cargo clippy --workspace --all-targets -- -D warnings,cargo build --workspace --locked,cargo doc --workspace --no-deps --locked, andcargo test --workspaceall pass.