Contents
TutorialUnity

Install The Unity SDK And Save Your First Game Data

Install the Persistly Unity package, configure PersistlyGameSaves, load local data, save one game data, and force a cloud sync.

Unity integrations should start with the PersistlyGameSaves facade. For a one-save game, use SaveDataAsync and LoadDataAsync; the SDK stores that data in the default autosave slot. Add named slots later when you need manual saves or multiple slots.

Install The Package

Open Unity Package Manager:

txt
Window -> Package Manager -> Add package from git URL
https://github.com/Persistly/persistly-sdk-unity.git

Then import the SDK namespace:

c#
using Persistly.Unity;

Configure The SDK

Configure once during boot or before the first save operation:

c#
await PersistlyGameSaves.ConfigureAsync(new PersistlyGameSavesSettings("ps_test_replace_me")
{
    PlayerRef = "player-184",
    Store = new FilePersistlyGameSavesStore(Application.persistentDataPath),
});

Use a stage ps_test_ key while building. Use a production ps_live_ key only in release builds.

PlayerRef is optional bookkeeping for your own systems. It is not a password, account lookup key, recovery code, or proof of account ownership.

Load Before Gameplay

Try local load first:

c#
var loaded = await PersistlyGameSaves.Shared.LoadDataAsync<PlayerState>();

if (loaded.Data != null)
{
    StartGameFromState(loaded.Data);
}
else
{
    StartNewGame();
}

This lets the game start even when the network is unavailable.

Save The First Game Data

Save one serializable data object:

c#
await PersistlyGameSaves.Shared.SaveDataAsync(new PlayerState
{
    Level = 1,
    Coins = 50,
    Checkpoint = "forest-gate",
});

SaveDataAsync writes locally first. It does not need a network request, and it uses PersistlyGameSaves.DefaultSlotKey, which is autosave.

Sync At Safe Moments

Force sync while testing:

c#
var sync = await PersistlyGameSaves.Shared.ForceSyncDataAsync();

For normal gameplay, call sync on controlled lifecycle moments:

c#
private async void OnApplicationPause(bool paused)
{
    if (paused)
    {
        await PersistlyGameSaves.Shared.ForceSyncDataAsync();
    }
}

Do not rely only on OnApplicationQuit; platforms can terminate quickly.

Add SlotInfo For Menus

Use slotInfo JSON for slot-select screens, save-slot lists, and support context:

c#
await PersistlyGameSaves.Shared.SaveDataAsync(
    data,
    new PersistlySaveSlotOptions
    {
        SlotInfoJson = "{\"characterName\":\"Ayla\",\"className\":\"Mage\",\"level\":9}",
    });

Keep real gameplay data in the typed data object. Keep display/search fields in slotInfo.

Multiple Slots

Use one slot key per slot or manual save:

c#
await PersistlyGameSaves.Shared.SaveSlotAsync("warrior", warriorState);
await PersistlyGameSaves.Shared.SaveSlotAsync("mage", mageState);

Use stable slot keys so the slot-select screen can load the same logical save each time.

For conflict recovery in a one-save game, hand off to your conflict UI before choosing a branch:

c#
var sync = await PersistlyGameSaves.Shared.ForceSyncDataAsync();

if (sync.Status == PersistlySlotStatus.Conflict)
{
    ShowConflictRecovery();
    return;
}

After the player chooses, use AcceptCloudDataAsync, OverwriteCloudDataAsync, or KeepLocalDataForLaterAsync.

What To Test Next

  • Enter play mode, save, stop, and load again.
  • Disable network and confirm local save still works.
  • Re-enable network and call ForceSyncDataAsync.
  • Add a second slot for another slot.
  • Add conflict recovery before cross-device release testing.