Handling of multiple libraries
What's your idea?
I'm not sure exactly how this would be implemented, but I figured I'd start by logging something and brainstorming more about it.
My situation is that I have two computers I game on. My Steam Deck and my desktop. Both have multiple libraries.
- My Steam Deck has
/home/deck/.local/share/Steamas well as a library on two different SDCards, which are occasionally swapped. Either/run/media/Aor/run/media/B. - On the desktop, I have
/home/vividboarder/.local/share/Steamas well as one in/media/vividboarder/wdblack.
The different home dirs is no problem since it can be trivially handled with a redirect. The complication is that for one system, a game may be installed on the home directory, and on another installed on an external library.
So if I back up from one and go to restore on another, it writes to a new directory where the game isn't. If I then backup again, it will overwrite the files in my backup with the files from the other library location.
The only way that I can think to manage this currently is with adding redirects for paths that are unique to each client and each game.
Resolving this doesn't seem trivial though. I could think something along the lines of giving each root a name in the configuration and then, backing up with paths relative to the containing root. Then, when restoring roots can be matched based on library type (Eg. Steam), or, if there are multiple, a user can switch the root.
In this way I could backup files on my deck relative to /home/deck/.local/share/Steam and it would only include the path inside the library. On my desktop, it would, by default, map to my home dir, but I could then select an alternative Steam root with the actual install. I suppose if the game is found in a scan, it could also auto-select that root.
Anyway, this is a lot, but I figured I'd put it out there. You may have already considered and rejected relative paths before.
Hi! Yeah, Ludusavi doesn't have a good way of handling this right now. It would be a little better if you could define redirects only for specific games, but it would still be tedious and error-prone. I'll have to think about this.
Yea, game specific redirects would be tough. What do you think about relative paths and named roots? That avoids some of the redirect logic complexity.
I'm imagining something like this:
Steam Deck roots:
- Name: Internal, Type: Steam, Path:
/home/deck/.local/share/Steam - Name: SDA, Type: Steam, Path
/run/media/A - Name: SDB, Type: Steam, Path
/run/media/B
Desktop roots;
- Name: Primary, Type: Steam, Path
/home/vividboarder/.local/share/Steam - Name: External, Type: Steam, Path
/mnt/wdblack/SteamLibrary
If I scan for a game on my Steam Deck, it might find it at /run/media/A/MyGameSaves.
It stores the following:
- In repository, path to files:
{root:Steam}/MyGameSaves/file. The placeholder indicates that it should match a Steam root. - In local config section for the game
root: Internal
When I try to restore on my desktop, it could look for exsting saves in each root, but if not found it defaults to the first root in my list.
- In local config, sets the config for the game to:
root: Primary - When restoring, restores to
/home/vividboarder/.local/share/Steam/MyGameSaves/fileafter expanding a the root value.
I'm modestly experienced in Rust, so I'll probably try to hack at this at some point, but I wanted to try to brainstorm first and gauge your interest.
I'm modestly experienced in Rust, so I'll probably try to hack at this at some point, but I wanted to try to brainstorm first and gauge your interest.
I appreciate that 🎉 I'm definitely open to ideas here, as long as we can cover all the edge cases.
In local config section for the game
root: Internal
With this approach, it would need to be associated with each file path, not at the game level, since you could have two roots of the same kind with different copies of the same game. I don't think you can get Steam to install multiple copies, but you can certainly do it with DRM-free games, something like:
/games/GOG/Some Game/games/GOG (modded)/Some Game
You could store something like this in the backup:
files:
"/games/GOG/Some Game/save1":
root: foo
"/games/GOG (modded)/Some Game/save1":
root: bar
roots:
foo:
path: /games/GOG
kind: gog
bar:
path: /games/GOG (modded)
kind: gog
That would also degrade gracefully for older Ludusavi versions, since they could just ignore the root field and use the path as-is. It would still be oriented towards absolute paths (which I think is important as a default behavior), but makes the root info available for postprocessing.
The root IDs (foo, bar) could be auto-generated based on the root's values. That should also work even if you configure identical roots, since they'd get the same ID. The backup should be self-contained here so that it's not dependent on your current system's Ludusavi config.
Also, one edge case to keep in mind is that the roots section won't necessarily match your Ludusavi config exactly, since you can define roots using globs that then get expanded into multiple "real" roots.
When I try to restore on my desktop, it could look for exsting saves in each root, but if not found it defaults to the first root in my list.
I'd definitely want this to be opt-in, with the default being the current behavior. For example, if you reinstall your OS, you may want to put everything back to the original locations even if they don't exist yet.
With this approach, it would need to be associated with each file path, not at the game level, since you could have two roots of the same kind with different copies of the same game. I don't think you can get Steam to install multiple copies, but you can certainly do it with DRM-free games, something like:
That's interesting. I haven't encountered that. If I had multiple installs of a game, however, I'd want to manage them as two separate "Games". Like, if it finds "Some Game" in "Root A" and then "Some Game" in "Root B", rather than just having "Some Game" with all the files merged together, it would be easier to manage if I had "Some Game (A)" and "Some Game (B)". That would also do away with the need to map at file level.
Hmm... Actually, while I still think for this example that'd be preferable, there are probably some examples where files exist in different root locations anyway. Like in my Wine Prefix and in my home dir for a single game. Not sure if that's actually true though. I definitely did that manually so I could sync saves and installed mods (those are sometimes tightly coupled).
I'll have to think on that a bit more. My worry is that doing it by file will be hard to manage. I guess maybe less so since there is a "tree" view so you could swap at the base of a tree.
That would also degrade gracefully for older Ludusavi versions, since they could just ignore the root field and use the path as-is.
I imagine it's important to you to have some form of compatibility between versions, but I'm wondering how much you care about this. Since installation is via GH releases or repos that are very easy to update (not like waiting on an Ubuntu LTS), it should be fairly easy for folks to upgrade. Backwards compatibility would still be important to facilitate the upgrade, however forward compatibility may not be.
I'd definitely want this to be opt-in, with the default being the current behavior. For example, if you reinstall your OS, you may want to put everything back to the original locations even if they don't exist yet.
Yea, I think defaulting to the original behavior makes sense, and could still work with relative paths as long as it either detects a root (even if empty) or you manually add a non-existent root.
there are probably some examples where files exist in different root locations anyway
Yeah, this could happen in cases like:
- (root + special folder) The Steam version of Alan Wake stores saves in the Steam root's
userdata, but the GOG version stores saves in%USERPROFILE%\Documents\Remedy\AlanWake_GOG_Version. Ludusavi wouldn't know whether or not the files in Documents are related to the files in the Steam root. - (root + root) This case would be rarer, but it could happen if you have a root for an alternative home folder or OS drive.
Backwards compatibility would still be important to facilitate the upgrade, however forward compatibility may not be.
I'm mainly thinking about potential accidents where someone is using Rclone or Syncthing, and they update Ludusavi on one system, but forget to update on another system. Also, although I wouldn't recommend it for most use cases, there are some tools/scripts that read mapping.yaml directly (like https://github.com/jose-l-martins/GSM-to-Ludusavi-converter), so I'd like to avoid any breakages there unless truly necessary.
Just writing to express my interest in this feature. I previously had SyncThing set up for similar functionality, but manually finding each save location was tiresome. Ludisavi is effortless on both my Steam Deck and Windows PC, but getting both to play nicely with each other when save locations differ doesn't seem possible currently.
Hi @mtkennerly I was going to open a new ticket with exactly this request (but search brought me here), since I also have a Steam Deck (in which some games are in the internal directory and others on the SD card), and when restoring them in the desktop I also have to toggle around with the redirects, given that the tool doesn't know how to deal with this.
My suggestion (to keep it simple for the users) would be something like this:
- Allow the creation of backup profiles. a. The redirects are not dealt on the the settings, but on the profiles itself. b. Each profile has the current implementation of the redirects (the ones we use right now) which can be used for different games. c. Profiles could allow the user to also set the path of a current prefix. (This would help with games that share the same prefix and would probably help with this situation I asked about before).
- When backing up/restoring, you have the default profile, and this could be changed to another one (only one could be the default).
- Given that we are now dealing with these profiles, each entry (game) could override the default (a dropdown in the GUI next to the game) with a different profile (this would solve the issue of instead the tool figuring out to where should it backup/restore, since the profile handles this).
Of course, this is just a suggestion, and I know it's a bit tricky given that it would probably mess a bit with the current code and the way it's implemented. But here are my 2 🪙.