EOS Integration KitAlpha
v5.0.1

Player Data Storage

Save and load player-specific data like save games, settings, and progress to the cloud

Player Data Storage lets you save player-specific data to the cloud. Data syncs across devices automatically when players log in.

Player Data Storage is per-user. Each player can only access their own data. For shared game data, use Title Storage.

Storage limit is 400MB per player. Files are encrypted and only accessible by the owning player.

Write File

Save data to the cloud. Creates the file if it doesn't exist, or overwrites if it does.

Write User File node
Copy and paste into Unreal Engine Blueprint editor
  • Filename: Name of the file to write
  • File Data: Raw bytes to save

Use the Save Game to Bytes helper to convert a SaveGame object to bytes.

#include "EIKCore/Public/Interfaces/IEIKUserFile.h"

void UMyClass::SavePlayerData(const TArray<uint8>& Data)
{
    TSharedPtr<IEIKUserFile> UserFile = GetUserFileInterface();
    if (!UserFile.IsValid()) return;

    FEIKWriteUserFileParams Params;
    Params.Filename = TEXT("savegame.sav");
    Params.Contents = Data;

    UserFile->WriteFile(0, Params,
        FEIKAsyncCallback<void>::CreateLambda(
            [](const TEIKAsyncResult<void>& Result)
            {
                if (Result.IsSuccessful())
                {
                    UE_LOG(LogTemp, Log, TEXT("File saved to cloud"));
                }
            }));
}
#include "Online/OnlineServices.h"
#include "Online/UserFile.h"

using namespace UE::Online;

void UMyClass::SavePlayerData(const TArray<uint8>& Data)
{
    IOnlineServicesPtr Services = GetServices(EOnlineServices::Epic);
    IUserFilePtr UserFile = Services->GetUserFileInterface();

    FUserFileWriteFile::Params Params;
    Params.LocalAccountId = GetLocalAccountId();
    Params.Filename = TEXT("savegame.sav");
    Params.FileContents = MakeShared<TArray<uint8>>(Data);

    UserFile->WriteFile(MoveTemp(Params))
        .OnComplete([](const TOnlineResult<FUserFileWriteFile>& Result)
        {
            if (Result.IsOk())
            {
                UE_LOG(LogTemp, Log, TEXT("File saved to cloud"));
            }
        });
}
#include "OnlineSubsystem.h"
#include "Interfaces/OnlineUserCloudInterface.h"

void UMyClass::SavePlayerData(const TArray<uint8>& Data)
{
    IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get(FName(TEXT("EIK")));
    IOnlineUserCloudPtr UserCloud = OnlineSub->GetUserCloudInterface();
    FUniqueNetIdPtr UserId = OnlineSub->GetIdentityInterface()->GetUniquePlayerId(0);

    TArray<uint8> FileData = Data;
    UserCloud->WriteUserFile(*UserId, TEXT("savegame.sav"), FileData);

    UserCloud->AddOnWriteUserFileCompleteDelegate_Handle(
        FOnWriteUserFileCompleteDelegate::CreateLambda(
            [](bool bWasSuccessful, const FUniqueNetId& UserId, const FString& FileName)
            {
                if (bWasSuccessful)
                {
                    UE_LOG(LogTemp, Log, TEXT("File saved: %s"), *FileName);
                }
            }));
}

Read File

Load data from the cloud.

Read User File node
Copy and paste into Unreal Engine Blueprint editor
  • Filename: Name of the file to read
  • File Data (output): Raw bytes loaded from cloud

Use the Bytes to Save Game helper to convert bytes back to a SaveGame object.

void UMyClass::LoadPlayerData()
{
    TSharedPtr<IEIKUserFile> UserFile = GetUserFileInterface();

    FEIKReadUserFileParams Params;
    Params.Filename = TEXT("savegame.sav");

    UserFile->ReadFile(0, Params,
        FEIKAsyncCallback<FEIKReadUserFileResult>::CreateLambda(
            [this](const TEIKAsyncResult<FEIKReadUserFileResult>& Result)
            {
                if (Result.IsSuccessful())
                {
                    const TArray<uint8>& Data = Result.GetValue().FileContents.Data;
                    // Process loaded data
                }
            }));
}
void UMyClass::LoadPlayerData()
{
    IUserFilePtr UserFile = GetUserFileInterface();

    FUserFileReadFile::Params Params;
    Params.LocalAccountId = GetLocalAccountId();
    Params.Filename = TEXT("savegame.sav");

    UserFile->ReadFile(MoveTemp(Params))
        .OnComplete([this](const TOnlineResult<FUserFileReadFile>& Result)
        {
            if (Result.IsOk())
            {
                const TArray<uint8>& Data = *Result.GetOkValue().FileContents;
                // Process loaded data
            }
        });
}
void UMyClass::LoadPlayerData()
{
    IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get(FName(TEXT("EIK")));
    IOnlineUserCloudPtr UserCloud = OnlineSub->GetUserCloudInterface();
    FUniqueNetIdPtr UserId = OnlineSub->GetIdentityInterface()->GetUniquePlayerId(0);

    UserCloud->ReadUserFile(*UserId, TEXT("savegame.sav"));

    UserCloud->AddOnReadUserFileCompleteDelegate_Handle(
        FOnReadUserFileCompleteDelegate::CreateLambda(
            [this, UserCloud, UserId](bool bWasSuccessful, const FUniqueNetId& Id, const FString& FileName)
            {
                if (bWasSuccessful)
                {
                    TArray<uint8> FileData;
                    UserCloud->GetFileContents(*UserId, FileName, FileData);
                    // Process loaded data
                }
            }));
}

Enumerate Files

List all cloud files for the player.

Enumerate User Files node
Copy and paste into Unreal Engine Blueprint editor

Returns an array of file metadata including filename, size, and last modified time.

void UMyClass::ListCloudFiles()
{
    TSharedPtr<IEIKUserFile> UserFile = GetUserFileInterface();

    FEIKEnumerateUserFilesParams Params;

    UserFile->EnumerateFiles(0, Params,
        FEIKAsyncCallback<FEIKEnumerateUserFilesResult>::CreateLambda(
            [](const TEIKAsyncResult<FEIKEnumerateUserFilesResult>& Result)
            {
                if (Result.IsSuccessful())
                {
                    for (const FEIKUserFileMetadata& File : Result.GetValue().Files)
                    {
                        UE_LOG(LogTemp, Log, TEXT("%s (%lld bytes)"),
                            *File.Filename, File.FileSizeBytes);
                    }
                }
            }));
}
void UMyClass::ListCloudFiles()
{
    IUserFilePtr UserFile = GetUserFileInterface();

    FUserFileEnumerateFiles::Params Params;
    Params.LocalAccountId = GetLocalAccountId();

    UserFile->EnumerateFiles(MoveTemp(Params))
        .OnComplete([](const TOnlineResult<FUserFileEnumerateFiles>& Result)
        {
            if (Result.IsOk())
            {
                UE_LOG(LogTemp, Log, TEXT("Files enumerated"));
            }
        });
}
void UMyClass::ListCloudFiles()
{
    IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get(FName(TEXT("EIK")));
    IOnlineUserCloudPtr UserCloud = OnlineSub->GetUserCloudInterface();
    FUniqueNetIdPtr UserId = OnlineSub->GetIdentityInterface()->GetUniquePlayerId(0);

    UserCloud->EnumerateUserFiles(*UserId);

    UserCloud->AddOnEnumerateUserFilesCompleteDelegate_Handle(
        FOnEnumerateUserFilesCompleteDelegate::CreateLambda(
            [UserCloud, UserId](bool bWasSuccessful, const FUniqueNetId& Id)
            {
                if (bWasSuccessful)
                {
                    TArray<FCloudFileHeader> Files;
                    UserCloud->GetUserFileList(*UserId, Files);

                    for (const FCloudFileHeader& File : Files)
                    {
                        UE_LOG(LogTemp, Log, TEXT("%s (%d bytes)"),
                            *File.FileName, File.FileSize);
                    }
                }
            }));
}

Delete File

Remove a file from cloud storage.

Delete User File node
Copy and paste into Unreal Engine Blueprint editor
  • Filename: Name of the file to delete
void UMyClass::DeleteCloudFile(const FString& Filename)
{
    TSharedPtr<IEIKUserFile> UserFile = GetUserFileInterface();

    FEIKDeleteUserFileParams Params;
    Params.Filename = Filename;

    UserFile->DeleteFile(0, Params,
        FEIKAsyncCallback<void>::CreateLambda(
            [Filename](const TEIKAsyncResult<void>& Result)
            {
                if (Result.IsSuccessful())
                {
                    UE_LOG(LogTemp, Log, TEXT("Deleted: %s"), *Filename);
                }
            }));
}
void UMyClass::DeleteCloudFile(const FString& Filename)
{
    IUserFilePtr UserFile = GetUserFileInterface();

    FUserFileDeleteFile::Params Params;
    Params.LocalAccountId = GetLocalAccountId();
    Params.Filename = Filename;

    UserFile->DeleteFile(MoveTemp(Params))
        .OnComplete([](const TOnlineResult<FUserFileDeleteFile>& Result) {});
}
void UMyClass::DeleteCloudFile(const FString& Filename)
{
    IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get(FName(TEXT("EIK")));
    IOnlineUserCloudPtr UserCloud = OnlineSub->GetUserCloudInterface();
    FUniqueNetIdPtr UserId = OnlineSub->GetIdentityInterface()->GetUniquePlayerId(0);

    UserCloud->DeleteUserFile(*UserId, Filename, true, true);
}

Helper Functions

The EIK User File Library provides utilities for working with cloud files:

FunctionDescription
SaveGameToBytesConvert USaveGame to byte array
BytesToSaveGameConvert byte array back to USaveGame
StringToBytesConvert FString to byte array
BytesToStringConvert byte array to FString
JsonStringToBytesConvert JSON string to bytes
BytesToJsonStringConvert bytes to JSON string
IsValidCloudFilenameCheck if filename is valid for cloud storage

Working with SaveGame Objects

SaveGame to Bytes conversion
Copy and paste into Unreal Engine Blueprint editor
  1. Create your SaveGame object
  2. Use Save Game to Bytes to convert it
  3. Pass the bytes to Write User File

To load:

  1. Use Read User File to get bytes
  2. Use Bytes to Save Game to convert back
  3. Cast to your SaveGame class
// Save
USaveGame* SaveGame = UGameplayStatics::CreateSaveGameObject(UMySaveGame::StaticClass());
TArray<uint8> Bytes;
UGameplayStatics::SaveGameToMemory(SaveGame, Bytes);
// Write Bytes to cloud...

// Load
// Read Bytes from cloud...
USaveGame* LoadedGame = UGameplayStatics::LoadGameFromMemory(Bytes);
UMySaveGame* MySave = Cast<UMySaveGame>(LoadedGame);

On this page