Page 1 of 1

[Solved] Recommendation for SaveSystem setup (cloud saves & user specific saves)

Posted: Wed Jun 28, 2023 12:03 pm
by Jamez0r
Hey Tony, hope you're doing well! :)

Right now I'm using the Player Prefs Saved Game Data Storer. My publishing producer was just messaging me about setting up cloud saving on Epic Game store, which would seem to require using (some form of) Disk Saved Game Storer instead.

The documentation says that Disk Saved Game Storer "is supported on standalone builds", which I interpret as it not working with the Unity Editor itself.

I'd like to set things up (switch over) to the Disk Saved Game Storer, so that we can use Epic Game store's cloud save system, but also be able to continue saving/loading in the Unity Editor. Is there a recommended way of doing this? Maybe some custom code that checks if the game is being run in the Unity Editor, and to only use the Player Prefs Game Data Storer if so?

Thanks!

Re: Recommendation for SaveSystem setup

Posted: Wed Jun 28, 2023 1:03 pm
by Tony Li
Hi,

Disk Saved Game Data Storer works in the editor's play mode, too. But it writes to local disk files on the player's device.

If you want to do EGS cloud saves, make a subclass of SavedGameDataStorer and fill in the methods with the API calls to read/write to the cloud save system. Then add this subclass to the Save System in place of PlayerPrefsSavedGameDataStorer or DiskSavedGameDataStorer.

Re: Recommendation for SaveSystem setup

Posted: Wed Jun 28, 2023 2:11 pm
by Jamez0r
Tony Li wrote: Wed Jun 28, 2023 1:03 pm Hi,

Disk Saved Game Data Storer works in the editor's play mode, too. But it writes to local disk files on the player's device.

If you want to do EGS cloud saves, make a subclass of SavedGameDataStorer and fill in the methods with the API calls to read/write to the cloud save system. Then add this subclass to the Save System in place of PlayerPrefsSavedGameDataStorer or DiskSavedGameDataStorer.
Thanks as always for the quick response! Thats good to hear that the "Disk Saved Game Data Storer" will work! That'll be a quick and easy switcheroo.

In regards to the EGS cloud save - my producer seems to be insinuating that all she needs to know is which files should be included in the cloud save, and that she could set it up on her end (via Epic's developer website). Maybe that is a new/simpler way to do it? I'll get in touch with her and find out :)

Re: Recommendation for SaveSystem setup

Posted: Wed Jun 28, 2023 2:40 pm
by Tony Li
Sounds good. I haven't used EGS cloud save yet myself. I was assuming it was similar to cloud saves on consoles such as Xbox or Switch, which use platform-specific API calls.

Re: Recommendation for SaveSystem setup

Posted: Fri Jun 30, 2023 3:30 pm
by Jamez0r
Alrighty, I looked a bit more into this - both Steam and Epic Games have a "simple" way of setting up Cloud Saves without any code/API calls, where you log into the developer portal and tell it which files to synchronize:

Steam: https://partner.steamgames.com/doc/features/cloud
Note: This documentation includes what would need to be done to include Steam-user-specific subdirectories (the "Auto-Cloud special path values" section)

Epic Games: https://dev.epicgames.com/docs/epic-gam ... cloud-save
Note: This documentation does not include any info on EpicGames-user-specific subdirectories. But I did find this post where someone from Epic Games responded saying that it can be done but you have to contact their representative (lol...): https://eoshelp.epicgames.com/s/questio ... uage=en_US

I switched over to using a custom/extended version of DiskSavedGameDataStorer.

Here is my code, in case it can give anyone else a head-start on doing this. You'd obviously have to replace all the "BuildManager.Platformtype" stuff with your own code for checking what your build platform is:

Code: Select all

using PixelCrushers;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

/// <summary>
/// This extends the "Dialogue System For Unity" DiskSavedGameDataStorer to add additional platform-specific-user-specific save file storage location functionality.
/// </summary>
public class DiskSavedGameDataStorerCustom : DiskSavedGameDataStorer
{

    //Override GetBasePath() to add the platform-specific-user-specific subdirectory
    protected override string GetBasePath() {

        //Get the base path from parent class
        string buildPathString = base.GetBasePath();

        //Add platform specific subdirectory if it exists
        string platformSpecificSubDirectory = GetPlatformSpecificUniqueUserSubDirectory();
        if(string.IsNullOrWhiteSpace(platformSpecificSubDirectory) == false) {

            buildPathString = Path.Combine(buildPathString, platformSpecificSubDirectory);

            //Create unique user subdirectory folder if it doesn't exist
            if (Directory.Exists(buildPathString) == false) {
                try {
                    Directory.CreateDirectory(buildPathString);
                } catch (System.Exception e) {
                    Debug.LogError("Unable to create subdirectory: " + buildPathString);
                    throw e;
                }
            }
        }

        return buildPathString;
    }

    public string GetPlatformSpecificUniqueUserSubDirectory() {

        switch (BuildManager.instance.platformType) {
            case BuildManager.PlatformType.Steam:
                return Path.Combine("SaveDataSteamUsers",""+BuildManager.instance.steamManager.GetUsersSteamID_As_Ulong());
            case BuildManager.PlatformType.EpicGamesStore:
                return Path.Combine("SaveDataEpicGamesUsers", BuildManager.instance.epicGamesStoreManager.GetProductUserID());
            case BuildManager.PlatformType.GoG:
                //Assuming GoG doesn't have user-accounts like this?
                return "";
            case BuildManager.PlatformType.WindowsStore:
                //TBD
                return "";
            case BuildManager.PlatformType.XboxThirdGen:
            case BuildManager.PlatformType.XboxFourthGen:
            case BuildManager.PlatformType.PS4:
            case BuildManager.PlatformType.PS5:
            case BuildManager.PlatformType.Switch:
                //TBD
                return "";
            case BuildManager.PlatformType.None:
            default:
                return "";
        }
    }

}
So far I've only tested this on Steam, but it looks to be working. I had to add some code to create the user-specific subdirectory (if applicable).

So for steam the resulting file path for a save slot is: Application.persistentDataPath/SavedDataSteamUsers/<USER'S STEAM ID>/save_#.dat

One thing I did notice is that the game stutters for a moment when it initially has to create the unique subdirectory, which currently happens when the game is saved for the first time (I don't have too much experience with file/folder creation, so hopefully I'm doing it correctly). So I am thinking that when the game initially loads, I'll check if the unique user subdirectory exists and if not I'll create it then.

Re: Recommendation for SaveSystem setup

Posted: Fri Jun 30, 2023 3:34 pm
by Tony Li
Thanks for sharing all those tips!