Save Sync¶
Save sync keeps your game saves in sync between multiple devices through your RomM server. Play a game on your Steam Deck, then continue where you left off on your HTPC — your saves travel with you.
How It Works¶
The plugin uploads and downloads your RetroArch game saves to and from your RomM server. When you start a game, the plugin checks if the server has a newer save and downloads it. When you stop playing, it uploads your updated save.
Important: Save sync runs in Game Mode only, but there it covers every way a game can start: the Play button on the game detail page syncs directly, and a launch that skips the plugin's UI (for example a
steam://rungameiddeep link) is caught by the plugin's launch gate and synced before the game starts. In Desktop Mode the plugin is not loaded at all, so nothing syncs there — no pre-launch download, no post-exit upload. Changes made in Desktop Mode are picked up the next time you sync in Game Mode, which may surface a conflict.
Sync uses a newest-wins model with a hash-divergence guard:
- The plugin asks the RomM server for the saves in your active slot for the game and picks the newest (highest
updated_at). - If the server tracks your device as up-to-date and your local file matches the recorded baseline, there's nothing to do.
- If another device pushed a newer save and your local file is unchanged, the new server save is downloaded silently.
- If you played offline and your local file changed, your save is pushed back to the server.
- A conflict modal only appears if both sides changed since the last sync — the plugin won't silently overwrite either version.
This is the same model used by the official RomM clients (Argosy and Grout). It keeps cross-device save sync simple: one timeline per slot, newest wins.
Saves are per version¶
When a game has several versions — a (USA) dump and a (Europe) one, a (Rev 1), and
so on — each version has its own saves, on RomM and on disk. Automatic sync only ever touches the active version
(the one currently bound to the shortcut). Switching versions never copies, moves, or deletes a save.
That means an inactive version's local saves simply wait: if you switch away from a downloaded version whose saves were never uploaded, those saves stay on disk untouched and resume syncing the moment you switch back to that version. The plugin warns you before you leave such a version and shows a reminder banner on the Saves tab so the saves aren't forgotten (see Managing Games → Versions). Nothing is lost — the saves just don't sync while their version is inactive.
The reminder never tells you to switch back to a retained version that the current version-list check positively confirmed is no longer available on RomM. Such a row may still keep its local files and saves, but it cannot be selected; the Saves tab skips it and continues looking for drift on later live inactive versions.
Important: Use Your Own RomM Account¶
Save files in RomM are tied to the authenticated user account. If multiple people share the same RomM account, their saves will overwrite each other. Each person should have their own RomM account with their own credentials configured in the plugin.
Supported Systems¶
Save sync works on the per-game save files RetroArch writes for the systems RetroDECK supports. Standard cartridge saves (SRAM) sync automatically; several systems also sync their own formats — RTC, EEPROM, and console-specific backup RAM — so it is not limited to a single file type. Exactly what syncs varies by system: for the current per-system breakdown of what carries across devices today and what's planned, see the save sync support matrix.
Standalone emulator saves (PCSX2, DuckStation, Dolphin, PPSSPP, melonDS, etc.) are not yet supported and are planned for a future update.
Settings¶
Open Save Sync from the main QAM page to configure sync behavior.
Auto Sync¶
- Sync before launch (default: on) — runs sync when a game starts, whether via the Play button or the launch gate. If the server is unreachable, the game launches with whatever local save exists.
- Sync after exit (default: on) — runs sync after closing a game. A toast confirms what moved and which way — "Saves uploaded to RomM", "Saves downloaded from RomM", or "Saves synced with RomM (1 up, 2 down)" when a run went both ways; a sync that transferred nothing shows no toast. If the sync fails, the toast names the actual cause (see Offline Behavior) instead of a generic message.
When saves conflict¶
The plugin uses a single, automatic resolution policy:
- Newest server save in your slot wins by default. If your local save hasn't changed since the last successful sync, the server version is downloaded silently.
- Your local edits push automatically when the server still considers your device up-to-date — for example, you played offline and no other device synced in the meantime.
- A conflict modal appears only when both sides changed since the last sync. You pick which version to keep.
Tap Sync All Saves Now to sync saves for all installed ROMs at once. This is useful for:
- Bulk backup before uninstalling ROMs
- Catching up after a period of offline play
- Verifying that all saves are in sync
This only covers games you've already set up save sync for (games whose save slot you've confirmed). Games you haven't configured yet are left untouched, so a stale local save can't accidentally overwrite newer progress from another device.
Resolving Conflicts¶
When both your local save and the server save have changed since the last sync, a modal appears with both versions.
Each side shows:
- File size
- Modified / uploaded timestamp
Three actions:
- Keep Local — uploads your local save to the server, overwriting the server version.
- Use Server — downloads the server save and overwrites your local file.
- Cancel — dismisses the modal without changing anything. The conflict will reappear on the next sync as long as both sides still differ. If another device pushes an update in the meantime, the situation may resolve automatically (your unchanged local file gets the new version) and the modal won't reappear.
The modal blocks the Play action until you choose. If a post-exit sync detects a conflict you'll see a toast — the modal opens the next time you tap Play, where it blocks launch until resolved. There is no longer a separate "pending conflicts" list on the settings page.
Copying a Save to Another Slot¶
On the SAVES tab, most save rows carry a Copy to slot… button — the active slot's current save, its Previous Versions, and the saves listed under any other slot (including the read-only Manual archive — saves uploaded to RomM without a slot). Tap it to copy that save into another slot:
- Pick an existing slot, or type a name to create a new one.
- The copy is not a move — the original save stays where it is. Delete it from the RomM web app later if you want it gone.
- The slot you copy into becomes the game's active slot, with the copied save as its current save.
- If that save's content is already in the destination slot, nothing is copied — you're told it's already there
(shown as
#<id>).
Common uses: promote a save from the Manual archive into a named slot, or bring a save from one slot onto another so you can continue it there.
The button is unavailable while RomM is offline. If the game's current slot has an unresolved conflict, resolve it first (you'll be prompted). If the destination slot has newer changes from another device, sync that slot first, then copy again.
A game whose save the plugin does not sync is refused here too, and so are switching its slot and restoring an older version — for example a memory card every game shares (standalone PCSX2's, even though the plugin knows its folder), a save written into the game file itself, or saves written beside it; the message says why.
Core Switch Warning¶
When you switch the emulator core for a game (e.g., from mGBA to gpSP for GBA), the plugin detects the change and shows a warning before launching. This is because some cores use incompatible save formats — launching with a different core may overwrite your existing save with data the previous core can't read.
The warning shows which core you're switching from and to. You can:
- Continue — launch with the new core (your save may be overwritten)
- Cancel — go back and switch the core back before launching
A per-game core applies for any ROM filename — the plugin bakes the chosen core into the game's launch command rather than relying on RetroDECK's gamelist lookup. See Changing the Active Core for how per-game and per-platform cores work.
Which cores are compatible?¶
Most cores for the same system produce compatible .srm saves because the save format is defined by the original
hardware, not the emulator. However, there are exceptions:
| System | Cores | Compatible? | Notes |
|---|---|---|---|
| SNES | Snes9x, Supafaust, bsnes | Yes | All dump raw cartridge SRAM identically |
| PSX | Beetle PSX, PCSX ReARMed | Generally yes | Both use RetroArch's .srm memory card convention, but verify after switching — historical edge cases exist with memory card handling |
| N64 | Mupen64Plus, ParaLLEl | Generally yes | ParaLLEl-N64 is based on Mupen64Plus-next and shares save logic; save-type auto-detection can occasionally mismatch between cores |
| GBA | mGBA, VBA-M | Generally yes | Minor edge cases with save type detection |
| GBA | mGBA ↔ gpSP | No | gpSP uses different save type detection; may corrupt saves |
| NDS | MelonDS ↔ DeSmuME | No | Completely different save formats |
If in doubt, don't switch cores mid-playthrough. Before switching, back up your
.srmfile — copy it somewhere safe (e.g. asaves-backup/folder). If the new core loads your save correctly, you can delete the backup. If it doesn't, you can restore the backup and switch the core back.
Offline Behavior¶
If the RomM server is unreachable when a sync is attempted:
- Before launch: the game starts normally with your local save (a toast notification informs you).
- After exit: the upload is skipped. Your local save is untouched, and the next sync attempt produces the same outcome — typically pushing your changes once the server is reachable again.
- No save data is ever lost due to a failed sync.
The slot list comes from the server, so while RomM is unreachable the SAVES tab has no confirmed slot to show — and it names none rather than guessing. Your locally tracked save files are still listed, just not filed under a slot panel, and the offline banner at the top of the tab explains why slot switching is unavailable. The slots, and the active one among them, reappear as soon as the server is reachable again.
The sync status recovers with them. While RomM is unreachable the tab shows "Server unreachable" where the sync state would be, and the per-file rows are missing the parts that only the server can answer — when the save was last updated, which save is on the server, and which device synced last. Once the server is reachable again the tab re-reads all of it and fills those rows in, with the game's page still open. You do not have to leave the page and come back.
Below those files the tab shows the slots as RomM last reported them, with the one that was active then marked — dimmed, not pressable, and introduced by a line saying the save counts and times are from that last contact rather than from now. It is there so an offline tab shows what the device knows instead of an empty space; nothing in it can be expanded or activated, and creating a slot still needs the server. A game you have never set up a slot for has no such history to show, so its tab stays as described above.
"Server offline" is reported only for a genuine reachability failure (the server can't be reached or times out). A sync that fails for another reason — for example an expired or revoked login token, or an SSL certificate problem — shows that specific reason instead (such as "Authentication failed — check your username and password"), so a working server is never mislabelled as offline. That includes the case where RomM answers that it no longer has something the plugin asked about: if the game was deleted and re-added on the server (which gives it a new id), or the RomM database was wiped and this device's registration went with it, the server is answering perfectly well. You'll see a message naming what's missing rather than "RomM is offline", and the offline badge stays clear. This applies to both surfaces: the warning shown before launch and the "after exit" toast both name the actual cause rather than a generic "failed to sync" message. When more than one save file fails in the same sync, the toast shows the first file's reason followed by a "(+N more)" count so the message stays short. If you see an authentication message, re-enter your server URL and sign in again in the plugin settings.
One more thing "Server offline" is never used for: syncs run one at a time on your Deck, so if you exit two games within moments of each other, the second one's sync waits for the first. If that wait runs long the second sync is skipped, and it says so — "Another save sync was still running — saves will sync next time". Your local save is untouched and is picked up by the next launch or by a manual Sync All Saves Now; nothing about your server is wrong.
After a failed sync the game-detail save panel reflects the honest state right away: a file whose upload failed shows a yellow Local changes badge (not a green "synced"), and its "Last synced" line keeps the time of the last successful sync — a green checkmark appears only once a sync actually succeeds. A separate "Checked" line shows when the plugin last attempted a sync, so a recent failed attempt and the last good sync are both visible.
Sync Disabled for This Device on the Server¶
RomM lets you turn save sync off for a specific device in its own device settings (on the RomM web UI). If you disable sync for this device there, the plugin stops syncing that device's saves and tells you so — a manual sync reports "Save sync is disabled for this device on the RomM server", and the after-exit toast says the same. Your local saves are left untouched, and the game still launches normally (before-launch sync just skips). Re-enable sync for the device in RomM to resume. This is separate from the plugin's own Save Sync toggle in the QAM — either one being off stops syncing.
Playtime Tracking¶
The plugin tracks playtime per game. Session start and end times are recorded, and time the device spent suspended (asleep) during a session is excluded, so a game left running overnight in sleep does not inflate its playtime. Playtime is displayed on the game detail page next to the save sync status.
Each finished session is sent to RomM's built-in play-session store, so your last_played time shows correctly in the
RomM web UI. This is separate from save sync — playtime is recorded for every game on every exit, even when save
sync is off. If RomM is unreachable, the session is queued locally and uploaded automatically the next time you launch a
game or reconnect (nothing is lost).
The displayed playtime refreshes live: when you finish a session the PLAYTIME value updates on the same detail page without needing to navigate away and back. Opening a game's detail page also reconciles playtime with RomM — if you played the same game on another device, that device's play is folded in (the total only ever goes up, never backwards) and shown as soon as the page loads. Cross-device reconcile needs a RomM server version that grants the play-session read scope and a fresh sign-in; until then the displayed value is your local total. After upgrading, sign in again to enable cross-device playtime — the plugin shows a banner in the QAM panel prompting this whenever your saved login predates the play-session read scope. When RomM is unreachable the displayed value stays on your local total.
The LAST PLAYED date on the detail page comes from this same cross-device history, so it stays correct after you move to a new device — where Steam would otherwise reset it and show every game as just played. Until the server has a recorded session for a game (or while RomM is unreachable), the date falls back to Steam's own last-played value.
Steam also tracks playtime natively for non-Steam shortcuts, so you'll see playtime in the standard Steam UI as well.
Upgrading from an older version: earlier releases stored playtime in a hidden RomM note named
romm-sync:playtime. The plugin no longer uses these notes and starts fresh with the native store — your local total is preserved and keeps showing until the server re-accumulates. The old notes are left on the server, harmless; you can delete them yourself from RomM if you like.
Save File Location¶
Save files live where the emulator itself keeps them. The plugin does not work that folder out on its own: it asks, for each game and for the emulator that game launches with, where that emulator reads and writes the save — the same answer that says which files the save consists of. On a stock RetroDECK install that is typically:
- Internal SSD:
~/retrodeck/saves/{system}/{rom_name}.srm - SD card:
/run/media/deck/Emulation/retrodeck/saves/{system}/{rom_name}.srm
Some cores keep their saves in a folder of their own below that — the 3DO core, for example, writes to
saves/3do/opera/per_game — and the plugin now looks there, because that is where the answer points. That has not yet
been observed on a device.
RetroArch Save Sorting¶
RetroArch's two "Sort Saves into Folders" settings (Settings > Saving) decide which folder a game's save goes into. Save sync follows whichever combination you use — none of them is required:
| Content Directory | Core Name | Save path |
|---|---|---|
| ON | OFF | saves/gba/game.srm |
| OFF | ON | saves/mGBA/game.srm |
| ON | ON | saves/gba/mGBA/game.srm |
| OFF | OFF | saves/game.srm (flat) |
On a fresh RetroDECK install the first row is what you have.
When you change the sorting¶
RetroArch does not move existing saves when you change these settings, so after a change your saves sit in a folder it no longer reads. The plugin notices the next time it touches that game's saves — at launch, when the server can be reached; at exit, when Sync after exit is on; when you sync the game by hand; when the game page shows its saves; before a slot switch, a restore of an older version, a copy to another slot or a conflict resolution; before Delete Local Saves; when Library › Platforms counts a platform's save files as you pick it, or before its Delete N save files; or, for games whose save slot you have set up, when you use Sync All Saves Now — and moves that game's save files into the new folder first. There is nothing to confirm and no notice to act on; each game follows on its own.
Following a game's saves into the new folder is part of save sync: with save sync off, neither happens. A sorting change made while it is off is followed once save sync is on again, the next time the plugin touches that game's saves — for a game whose save folder the plugin had already noted before the change. It notes every installed game's folder once, on the first start of this version, and each game's again whenever it follows it; a game it had never noted starts from where RetroArch looks now. While a RetroDECK home migration is waiting or running, nothing is followed: those files are the migration's to move.
If the new folder already holds a file with the same name, nothing is overwritten: the older of the two copies is moved
into a .romm-backup folder beside it, and the newer one is kept where RetroArch looks.
Saves written next to the game file¶
When a game's saves are written beside the game file instead of in the saves folder — usually because RetroArch's
Write Saves to Content Directory is on — save sync stays off for that game. The game still launches, and the game
page says why its saves are not synced. Turning that setting on moves no save into the game's folder, and turning it
back off finds the saves where they were. A save the emulator writes into the game file itself (an Amiga .adf, an
Atari ST .st) is a different case, and syncing that game by hand says so.
Updating from a version with the save-sorting migration¶
Earlier versions asked you to migrate save files in Settings after a sorting change. If you changed the sorting and had not run that migration yet when you updated, the plugin cannot tell where those saves were: it starts from where RetroArch looks now. A game whose save is on your RomM server gets it back at its next sync, downloaded into the new folder. A save that exists only on this device stays in the old folder — move it into the new folder yourself, or set the sorting back to what it was before.
RomM Version Compatibility¶
The plugin requires RomM >= 5.3.0. Pre-release builds whose numeric core is above that floor pass — for example
5.3.1-beta or 5.4.0-alpha.1. Tags at the exact floor (5.3.0-beta.1, 5.3.0-alpha.1) are rejected because they
rank below the 5.3.0 release. Servers below 5.3.0 are rejected at connection time with a full error page in both the
QAM panel and the game detail view. The plugin uses server-side device tracking, content hashing, save slots, and
device_syncs for conflict detection. Save sync is built on RomM's Device Sync, which arrived in RomM 4.9.0. Nothing
the plugin does needs a newer server than that yet; the minimum is 5.3.0 so that coming updates can use what that
release added without having to raise it first.
For technical details on how save sync works internally (three-way conflict detection, state schema, session detection), see the Save File Sync Architecture technical reference.
Previous: RetroDECK Path Migration | Next: Troubleshooting