Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functionality to symlink save data from another game's prefix, a few games would benefit from this #217

Merged

Conversation

UsernamesAreNotMyThing
Copy link
Contributor

@UsernamesAreNotMyThing UsernamesAreNotMyThing commented Jan 25, 2025

Some games have functionality that is dependent on having save data for another game, which works fine on Windows, but needs workarounds on Proton due to how it handles stuff that is stored in the user folder rather than the game's own steamapps/common folder (usually under Documents or My Games). This leads to the game not detecting the save data for the other game despite it being there, because it's in a different prefix.

This pull request adds a new function for util that can be used to automate a symlinking workaround to accomplish this.

This will only work if you have the other game installed from Steam.

How this works

  1. Reads Steam's steamapps/libraryfolders.vdf file to find locations of known library folders.
  2. Iterates through each of the library folders to determine if it can find a compatdata/(APPID) folder in it.
  3. If it finds one, it will create a symlink in the current game's prefix to point to the location in the found prefix, at the location the game expects to find the save data folder for the other game.

Games impacted

  • Final Fantasy VII Rebirth: Has bonus content (or something, I don't know what) for players with save data from FF7 Remake Intergrade, which would be found in the documents folder.
  • Horizon Zero Dawn Remastered: Allows playing saves from the original Complete Edition, which are stored in the documents folder.
  • Metaphor ReFantazio: Allows continuing from saves made in its demo, which uses a different ID and thus a different prefix.
  • Octopath Traveler 2: Same as above.
  • Utawarerumono (Utawarerumono: Prelude to the Fallen and Utawarerumono: Mask of Truth)

How to use the Function

def import_saves_folder(from_appid: int, relative_path: str)

Parameters:

  • from_appid: The Steam app id for the game whose save data is desired in the prefix for the game you're trying to play.
  • relative_path: The location in the drive_c/users/steamuser folder where the game expects the save data for the other game to be. You can find this by looking up the game on PC Gaming Wiki.
    This function will have to be used in the fix scripts for each of the games that need it.

@UsernamesAreNotMyThing UsernamesAreNotMyThing changed the title Add functionality to import save data from another game's prefix, a few games will benefit from this Add functionality to symlink save data from another game's prefix, a few games would benefit from this Jan 26, 2025
@UsernamesAreNotMyThing UsernamesAreNotMyThing marked this pull request as ready for review January 30, 2025 00:01
@R1kaB3rN
Copy link
Member

R1kaB3rN commented Feb 3, 2025

I think this would be useful and I’ve also considered supporting this in the past. Utawarerumono is another title that would benefit from this. I’m just not sure if this would be the appropriate project for it since some may not be broken in Proton, and we would need to add a note in the umu-database that the entry is related to this feature.

Up until now though, I don’t know why Valve has intentionally not decided to handle this longstanding issue themselves. If there’s an upstream issue that answers that question, I would be interested.

@R1kaB3rN
Copy link
Member

R1kaB3rN commented Feb 6, 2025

Will review the implementation in a bit. For now, please address the lint errors. You can do this by running ruff check and ruff format on util.py and the game fixes.

`relative_location` → `relative_path`
Removed some no longer needed imports.
@UsernamesAreNotMyThing
Copy link
Contributor Author

For now, please address the lint errors. You can do this by running ruff check and ruff format on util.py and the game fixes.

I don't know what that is, I'm just editing files one at a time in a browser. I see the error in the Checks section, but I'm not sure how to fix that one or why it's being flagged.

@GloriousEggroll GloriousEggroll merged commit b263f43 into Open-Wine-Components:master Feb 7, 2025
1 of 2 checks passed
@termdisc
Copy link

The "Games impacted" section refers to Metaphor, but I couldn't find the corresponding 2679460.py file for the fix. I would like to see how save files are managed when the folder would typically be shared in a Windows deployment. In the case of Metaphor, both the demo and full game store to AppData/Roaming/SEGA/METAPHOR/Steam/{64BitSteamID}

I am looking into this in context of Octopath Traveler 2 as well. Both the demo and full game store to Documents/My Games/Octopath_Traveler2/Steam/{64BitSteamID}/SaveGames/, but the demo stores files as *_Trial.sav which are then read in by the full game.

My interpretation of the added code is that the whole folder referenced in the script is symlinked into the current game, but this wouldn't work out very well when the folder is the same such as in the cases of Metaphor and Octopath Traveler 2, especially if the game had already created the save folder and stored some data into it already.

I was working on 1971650.py until I came across this potential issue. Any guidance or suggestions would be appreciated. Thanks.

"""Octopath Traveler 2"""

from protonfixes import util


def main() -> None:
    """Links demo saves to be imported into the full game"""
    util.import_saves_folder(2203230, 'Documents/My Games/Octopath_Traveler2')

@UsernamesAreNotMyThing
Copy link
Contributor Author

The "Games impacted" section refers to Metaphor, but I couldn't find the corresponding 2679460.py file for the fix.

The workaround for that game has not been implemented yet, largely because I don't know the app ID for the demo.

My interpretation of the added code is that the whole folder referenced in the script is symlinked into the current game, but this wouldn't work out very well when the folder is the same such as in the cases of Metaphor and Octopath Traveler 2, especially if the game had already created the save folder and stored some data into it already.

That's actually a really good point, I have definitely overlooked that possibility.

To get around this, I've made a new pull request (#227) to add a new parameter for import_saves_folder for this use case. When used that way, it will copy files from the folder in the demo's prefix instead of symlinking them, which also has the benefit of not losing the files if the demo's prefix is deleted. Files that have the same name as a file in the full game's folder will be skipped.

Due to how I implemented that (it's not recursive), if it gets merged, a better path to use for Octopath Traveler 2 would be

f'Documents/My Games/Octopath_Traveler2/Steam/{get_steam_account_id()}/SaveGames'

Note that the pull request also adds the get_steam_account_id() function, because the Steam client doesn't offer the ID as an environment variable, and it looks like it would be useful for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants