Skip to content

Mac: keep game saves safe when the game library moves, a copy fails, or the drive is HFS+ - #1118

Open
MartinMajewski wants to merge 1 commit into
LNPANDY:mainfrom
MartinMajewski:fix/library-save-followup
Open

MartinMajewski wants to merge 1 commit into
LNPANDY:mainfrom
MartinMajewski:fix/library-save-followup

Conversation

@MartinMajewski

@MartinMajewski MartinMajewski commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

Fix or feature

  • Fix
  • Feature

What and why

Problem. The library folder patch, now 0031-mac-library-folder.patch (0010 and 0112 from #920 and #1097, squashed together) keeps a game's save in ~/Library when its game library is on a drive that can't hold saves. @thehobbit85's review of #920 found three cases where it still loses progress, and the fixes for them never reached main, because #920 was closed before I could push them.

Cause. 0031 only copies a save into an empty folder, so an older copy can win after a library moves between drives. Its copy doesn't report failures, so the game can start on half a save. And HFS+ doesn't report the clone and swap bits, so 0031 treats it as able to hold saves.

Change. New patch 0046-mac-launcher-bring-the-last-played-save-along-al.patch on top of 0031, in dm/mac/launcher.c:

  • The launcher records the folder it last started the game from (save-location in the game's Application Support folder). When that changes, it brings the whole save along. Without a record, the library's save counts as current.
  • The copy is all or nothing: it goes into <save>.migrating and is renamed into place only when every file arrived. An older save in the destination is kept as <save>.replaced-<time>. If the copy fails, an alert says why, the game doesn't start, and the next start tries again.
  • When a volume doesn't report the clone and swap bits, the filesystem type from statfs decides, and only APFS keeps saves next to the game.

Two things main gained since #920 are covered too. The device save (<save>_device) moves together with the save. And a save folder the launcher passes in DM_SAVE (the per-game and global save folders from #1097) is used as it is, and only recorded.

Checked

  • Tests: python3 tools/engine.py check passes (on 0c078130). python3 -m unittest test_nsp_mac_app in engine/dm/tools/tests passes, 83 tests. frontend/ and frontend-qt/ aren't changed.
  • Test for a fix: six new or changed tests in test_nsp_mac_app.App, and each one fails on the old 0112 behavior that 0031 still has:
    • test_library_folder_on_hfs: a library on an HFS+ disk image
    • test_library_save_beats_older_home_save: a newer library save wins over an older ~/Library copy
    • test_library_back_on_apfs: progress made in ~/Library, device save included, follows the library to APFS
    • test_library_save_copy_fails: a copy cut short by a file-size limit doesn't start the game, and the next start finishes it
    • test_library_save_chosen_by_the_front_end: DM_SAVE from the launch environment is used and recorded
    • test_library_folder_on_apfs: now also checks the record
  • Run on a device or Mac: Mac Studio, M4 Max, macOS 27.2. On the earlier base, Link's Awakening (01006BB00C6F0000, 1.0.1) in an exFAT library started with this launcher on its ~/Library save, and recorded it. I didn't run it again on today's main.

Screenshots

None, no visible change in the launcher. The one new piece of UI is the game app's own alert when a save can't be copied.

Scope

  • No engine file (dm/, scripts/, docs/, ref/) is added to the repository: a change there is a patch in patches/ (a commit in engine/, then tools/engine.py export, and tools/engine.py check passes), with its Upstream-Status
  • A fix to the engine or a game profile also goes to seedds/nxnative as a PR in parallel. Not applicable: this patch fixes 0031, which only this fork has. Upstream's version of the feature is Mac app: a dataFolder key keeps a game's save, caches and log in one folder a front end chooses seedds/nxnative#460, so the patch says pending.
  • A change to a launcher view has before and after screenshots above. Not applicable, no launcher view changes.
  • No keys, game files or data extracted from a game in the change or the attachments

One thing I left out: VolumeSaves.holdsSaves in frontend/Sources/NXCore/SaveLocation.swift (from #1097) has the same HFS+ gap, so the launcher's save settings would show an HFS+ library as fine while the game falls back to ~/Library. I can add that in this PR or a separate one if you'd like.

🤖 Co-authored with Claude Code

@github-actions github-actions Bot added the patch-queue Changes the patch queue or the upstream pin label Nov 10, 2026
@MartinMajewski MartinMajewski changed the title Saves: fix the three ways patch 0112 still loses progress Mac: keep game saves safe when the game library moves, a copy fails, or the drive is HFS+ Nov 10, 2026
@LNPANDY

LNPANDY commented Nov 10, 2026

Copy link
Copy Markdown
Owner

Heads up @MartinMajewski: #1120 just merged into main and took slot 0123 (patches/0123-splatoon-raiders-shader-tables-are-split-again-w.patch). Please rebase onto main and renumber this patch to 0124-mac-launcher-bring-the-last-played-save-along-al.patch in patches/ and patches/series.

@MartinMajewski
MartinMajewski force-pushed the fix/library-save-followup branch from bef41e3 to cd1e556 Compare November 10, 2026 12:26
@MartinMajewski

Copy link
Copy Markdown
Contributor Author

Thanks for the heads-up, @LNPANDY. It's rebased onto the current main now, and the patch is renamed to 0124-mac-launcher-bring-the-last-played-save-along-al.patch in patches/ and patches/series. The patch queue check passes with all 88 patches, and the Mac app tests still pass on the new base.

🤖 Co-authored with Claude Code

…or the drive is HFS+

Patch 0031-mac-library-folder (0010 and 0112 from LNPANDY#920 and LNPANDY#1097, squashed) keeps a game's save in
~/Library when its game library is on a drive that can't hold saves.
The review of LNPANDY#920 found three cases where it still loses progress, and
the fixes never reached main. Patch 0046 adds them:

- The launcher records which folder it last started the game from and
  brings that whole save along when the folder changes, so an older
  copy no longer wins after a library moves between drives.
- The copy is all or nothing. An older save in the destination is kept
  aside, and a failed copy stops the launch with an alert and is tried
  again on the next start.
- HFS+, which doesn't report the clone and swap bits, now falls back
  as the README says.

The device save (<save>_device) moves with the save, and a save folder
the launcher passes in DM_SAVE is used as it is and recorded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MartinMajewski
MartinMajewski force-pushed the fix/library-save-followup branch from c53429b to c938615 Compare November 13, 2026 12:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

patch-queue Changes the patch queue or the upstream pin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants