Import cartridge .sav files with verified structure, checksums and clock (Closes #44)

Savegames → Import backup now reads an English Crystal .sav (from an
emulator, a cartridge dump or the 3DS Virtual Console's sav.dat) and
converts it into a native save after a preview.

- world/cartridge-save.ts: picks the copy TryLoadSaveFile would load
  (check values and checksums of the main copy, else the backup), reads
  the saved WRAM block, the numbered boxes, mail backups, Hall of Fame and
  Battle Tower by PRET labels (SRAM, SAVE_BLOCK in the profile, checked by
  check:reference with the SAV constants), engine flags via EngineFlags,
  scenes via MapScenes, and the map's objects and masks.
- Clock: an emulator MBC3 footer plus the time since it was written,
  FixDays/FixTime with wStart*, mapped to the minute and weekday offsets;
  without one, the device's time and the saved wCurDay. Day countdowns
  move with the day difference.
- Refused with the reason: unported maps, the Bug-Catching Contest, a
  Battle Tower challenge, characters outside the naming screen.
- Names keep <PK>/<MN> as ᴾᴷ/ᴹᴺ (one character, one tile); trainer names
  accept the naming screen's alphabet; boxed Eggs validate; native states
  up to 256 kB load (a full PC exceeded 64 kB).
- Tests: the committed debug saves, layout offsets against the symbols,
  backup fallback, clock footers, day counters, refusals, slot session
  and the Savegames flow in Chromium and WebKit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
kawaandClaude Opus 5.5 committed 2026-10-17 12:03:01 +02:00
1 parent 87b05b45f4
commit 592ca43a40
20 files changed
+1821 -40

No files matched your search

+1 -1
View File
@@ -49,7 +49,7 @@ Open the printed local URL and select your uncompressed **English US/Europe revi
Use onscreen controls, or focus the game screen and use arrows to move, **X** to interact and **X / Z** to continue dialogue. **Settings** changes these keys, the text size and the sound volume for this browser. In choices, **Up / Down** change the answer, **X** confirms and **Z** answers No. Games save every 10 seconds and when paused, each into its own save. Switching apps pauses play. Download a backup before clearing browser data.
Native saves are separate from emulator snapshots and cartridge `.sav` files. Each save keeps its newest and previous write; if the newest was interrupted or damaged, the previous one loads and nothing is overwritten. The single save of earlier versions becomes "Save 1" the first time this version opens it. Saves and backups from a newer version are kept as they are and refused, never rewritten. Saving during a scene keeps the progress from before it, so the scene replays after loading. The time you give Oak is kept as an offset from the device clock (the steppers start at the device's time), and the weekday you give Mom as an offset from that clock's weekday. The tile counter measures in-game movement, not real-world steps.
Native saves are separate from emulator snapshots and cartridge `.sav` files, but Savegames → Import backup also reads a `.sav` of the English Crystal (from an emulator, a cartridge dump or the 3DS Virtual Console's `sav.dat`) and converts it into a new save after a preview. The cartridge's checksums decide which of its two copies is read, as the game would. With an emulator clock footer (VBA-M, mGBA, BGB, SameBoy), the game clock carries on from the cartridge's; otherwise it follows the device and the day continues from the save. Saves made in an area the port has not opened yet, during the Bug-Catching Contest or in a Battle Tower challenge are refused with the reason. Each save keeps its newest and previous write; if the newest was interrupted or damaged, the previous one loads and nothing is overwritten. The single save of earlier versions becomes "Save 1" the first time this version opens it. Saves and backups from a newer version are kept as they are and refused, never rewritten. Saving during a scene keeps the progress from before it, so the scene replays after loading. The time you give Oak is kept as an offset from the device clock (the steppers start at the device's time), and the weekday you give Mom as an offset from that clock's weekday. The tile counter measures in-game movement, not real-world steps.
## Reference emulator