Ren'Py Copying and importing saves from season to season on Android

Perverteer

Peddler of Unspeakable Goods
Game Developer
Nov 19, 2017
515
2,968
My game has two seasons and uses a special end-of-season save file to import all of your choices into Season 2. This isn't much of a problem on Windows, Linux and macOS, but as of late, Android users have been complaining about being unable to transfer their save files. Android restricts access to the directories where Ren'Py writes the save games and third-party file managers are not, or no longer, able to access those folders either.

So I've trying to implement a solution, partly based on the work done here, without much success. I don't want the save files moved to a new location, just copied to /Documents/Renpy_Saves, where Season 2 can copy the special season save file. I have the save copying to /Documents/Renpy_Saves/com.perverteer.tftuv working, but I'm not able to then copy the files to the Season 2 save folder (/Documents/Renpy_Saves/com.perverteer.tftuv2). glob returns an empty list when listing the files in for some reason, so my guess is that it's a permission issue.

Could anybody who has more experience with Android perhaps help me with this? I'm now at a stage where it seems more feasible to buy a proper computer to play the game on for all the Android users reporting the same bug... :cautious:

From the aforementioned thread, I've copied the lib and rapt directories and the changes I made to the core Ren'Py files I've attached in a zip. The following is the code that runs in Season 2 in scripts.rpy and should copy or at least list the save files in /Documents/Renpy_Saves/com.perverteer.tftuv (but it doesn't and makes me shed big manly tears every time it fails):

Python:
init 0 python:
    import os
    import platform

    # Copy saves from Season 1 to Season 2
    if renpy.variant("android"):
        # Get name to current season (likely com.perverteer.tftuv2)
        currentSeason = os.path.basename(os.path.dirname(renpy.config.basedir))
        # Path to base save directory
        publicDir = os.environ['ANDROID_PUBLIC']

        previousSeasonPath = os.path.join(publicDir, "../../../../Documents/RenPy_Saves", "com.perverteer.tftuv")
        # seasonSaves = previousSeasonPath + "/Season*"
        seasonSaves = previousSeasonPath + "/*.save"

        # Path to saves in Android documents folder
        destinationDir = os.path.join(publicDir, "../../../../Documents/RenPy_Saves", currentSeason)

        print("Current Season: " + currentSeason)
        print("Public Dir: " + publicDir)
        print("Destination: " + destinationDir)
        print("Previous Season: " + previousSeasonPath)

        if os.path.exists(destinationDir):
            # Copy Season 1 save to save locations
            import glob
            from shutil import copy
            import __main__

            print(glob.glob(previousSeasonPath + "/Season*"))
            print(glob.glob(previousSeasonPath + "/*.save"))
            print(glob.glob(destinationDir + "/*save"))

            if os.path.exists(previousSeasonPath):            
                for saveFile in glob.glob(seasonSaves):
                    try:
                        print("Copying " + saveFile + " to " + destinationDir)
                        shutil.copy(saveFile, destinationDir)
                    except:
                        pass

                    try:
                        print("Copying " + saveFile + " to " + __main__.path_to_saves(renpy.config.gamedir))
                        shutil.copy(saveFile, __main__.path_to_saves(renpy.config.gamedir))
                    except:
                        pass
 

clowns234

Engaged Member
Game Developer
May 2, 2021
3,047
4,725
I don't have an answer to your specific question, but isn't passing data to other games what MultiPersistent("gameName") is for?
It stores game data in a common renpy folder in the roaming folder.
 

Perverteer

Peddler of Unspeakable Goods
Game Developer
Nov 19, 2017
515
2,968
Yes, it is, I use it for other purposes, but it doesn't work out of the box on Android without asking for write permissions, which in turn requires for custom changes to the Ren'Py SDK (the changes to lib and rapt I mentioned in the OP), which I've tried to avoid until now, because it makes updating the SDK a hassle.

The way Season 1 is currently set up isn't compatible with MultiPersistence either, in that case 12 episodes worth of variables would have to have been set in a MultiPersistent object.
 
  • Like
Reactions: clowns234