Skip to main content

Cloud Save

Last updated on

Overview

AccelByte Cloud's Cloud Save service stores arbitrary data in JSON format. With Cloud Save, you can store, retrieve, update, and delete any data from your game. Game data can be stored in one of two types of records:

  • Game Records which store game data such as event configurations and themes.

  • Player Records which store player records such as saved game data.

Permissions

Permissions are used to grant access to specific resources within our services. Make sure your account has the following permissions before you attempt to manage cloud save in the Admin Portal. For a full list of permissions that impact Cloud Save, see the Profile, Stats & Cloud Save tab of the permissions reference.

UsageResourceAction
Save namespace level recordADMIN:NAMESPACE:{namespace}:CLOUDSAVE:RECORDCreate
Save or replace game recordADMIN:NAMESPACE:{namespace}:CLOUDSAVE:RECORDUpdate
Purge all records under the given keyADMIN:NAMESPACE:{namespace}:CLOUDSAVE:RECORDCreate, Delete
Retrieve list of records key by namespaceADMIN:NAMESPACE:{namespace}:CLOUDSAVE:RECORDRead
Retrieve a record value by its keyADMIN:NAMESPACE:{namespace}:CLOUDSAVE:RECORDRead
Save or modify public player recordsADMIN:NAMESPACE:{namespace}:USER:*:PUBLIC:CLOUDSAVE:RECORDUpdate
Save or modify private player recordsNAMESPACE:{namespace}:USER:{userId}:CLOUDSAVE:RECORDUpdate

Permissions work slightly differently depending on whether they are assigned to IAM Clients or Roles assigned to users. For more information, read the Authentication and Authorization documentation.

Metadata

Metadata allows admins and players to define the behavior of the Cloud Save records. Record metadata is defined in the request body with the field name __META. Metadata is assigned with a default value if not otherwise defined.

  • Write Permission (set_by)

    This metadata indicates which party modified the record. This metadata is available in the admin endpoint only. The value options are:

    • Server: the record can only be modified by the server.

    • Client: the record can be modified by both clients and the server. This is the default value.

      Write permission behavior metrics on the Game Record:

      AdminPlayer
      ServerModify, ReadRead
      ClientModify, ReadModify, Read

      Write permission behavior metrics on the Player Record:

      AdminPlayer
      Record OwnerOther Players
      ServerModify--
      ClientModifyModify-
  • Is Public Record (is_public)

    This metadata indicates whether the record is public or not and is available in both admin and public endpoints. The value options are:

    • True: meaning that the record is a public record.

    • False: meaning that the record is a private record. This is the default value.

      Is Public Record behavior metrics on the Player Record:

      AdminPlayer
      Record OwnerOther Players
      FalseReadRead-
      TrueReadReadRead

Manage Cloud Saves in the Admin Portal

Create a New Game Record

  1. In the Game Management section of the Admin Portal, go to the Cloud Save menu and select Game Records.

  2. On the Cloud Save page, click the Create Game Record button.

  3. The Add Record form will appear. Fill in the required fields.

    • Input the Game Record Key using the appropriate format.

    • Select the Write Permission from the dropdown menu. See Metadata for a full list of the available options.

    • Input the JSON Configuration.

    Once completed, click the Add button and the new record will be added to the list.

Update a Record

Game Record

To update a Game Record, go to the Game Records page, choose the record you want to update, and select View.

  • In the Record Detail window, go to the JSON Configuration section and click Edit. Input the updated record information and click Save.

Player Record

To update a Player Record, go to the Player Record page, choose the record you want to update, and select View.

  • In the Record Detail window, go to the JSON Configuration section and click Edit. Input the updated record information and click Save.

    A confirmation will appear. Click Save to complete your update.

Integrate Your Game with Cloud Save at the User Level

Create a New Record

This example shows you how to store user data inside the graphicQuality key using the SaveUserRecord() function. Please note that if the key already exists, the new record will be appended to the existing record.

FString Key = FString("graphicQuality");

TSharedPtr<FJsonObject> RecordRequest = MakeShareable(new FJsonObject);
// 0 Low Quality, 1 Medium Quality, 2 High Quality
RecordRequest->SetNumberField(FString("textures"), 2);
RecordRequest->SetNumberField(FString("shadow"), 1);
RecordRequest->SetNumberField(FString("lighting"), 0);
RecordRequest->SetNumberField(FString("post-processing"), 2);

FRegistry::CloudSave.SaveUserRecord(Key, *RecordRequest, false, FVoidHandler::CreateLambda([]()
{
// Do something if SaveUserRecord has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString ErrorMessage)
{
// Do something if SaveUserRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error SaveUserRecord, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Retrieve a User Record

User data stored in a private record can be retrieved using the GetUserRecord() function.

FString Key = FString("graphicQuality");

FRegistry::CloudSave.GetUserRecord(Key, THandler<FAccelByteModelsUserRecord>::CreateLambda([](const FAccelByteModelsUserRecord& Result)
{
// Do something if GetUserRecord has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if GetUserRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error GetUserRecord, Error Code: %d Error Message %s"), ErrorCode, *ErrorMessage);
}));

Retrieve a Public User Record

A public user record can be retrieved by another user. To get another user's public records, you can use the GetPublicUserRecord() function.

FString Key = FString("playerStatus");
FString UserId = FString("SomeUserId");

FRegistry::CloudSave.GetPublicUserRecord(Key, UserId, THandler<FAccelByteModelsUserRecord>::CreateLambda([](const FAccelByteModelsUserRecord& Result)
{
// Do something if GetPublicUserRecord has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if GetPublicUserRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error GetPublicUserRecord, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Replace a User Record

You can update data using the ReplaceUserRecord() function, even when the data does not exist. If the data does not exist, it will be created based on the data in the update. This data can be stored either publicly or privately.

FString Key = FString("graphicQuality");

TSharedPtr<FJsonObject> RecordRequest = MakeShareable(new FJsonObject);
RecordRequest->SetNumberField(FString("textures"), 2);
RecordRequest->SetNumberField(FString("shadow"), 1);
RecordRequest->SetNumberField(FString("lighting"), 0);
RecordRequest->SetNumberField(FString("post-processing"), 1);

FRegistry::CloudSave.ReplaceUserRecord(Key, *RecordRequest, false, FVoidHandler::CreateLambda([]()
{
// Do something if ReplaceUserRecord has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if ReplaceUserRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error ReplaceUserRecord, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Replace User Records Concurrently

This feature will send an error message when a client tries to submit changes to a user record that has been changed at the same time by another client to ensure that edits to user records made concurrently aren't overwritten. There are two possible implementations of this feature: Manual and Automatic:

Manual

The manual implementation will return the error ErrorCode.PlayerRecordPreconditionFailed in Unity or ErrorCodes::PlayerRecordPreconditionFailedException in Unreal Engine if the record has been changed since it was retrieved by the client. You'll need to input the last updated time of the record, which can be found using the GetUserRecord function.

FString Key = FString("playerEquipments");

FRegistry::CloudSave.GetUserRecord(Key, THandler<FAccelByteModelsUserRecord>::CreateLambda([&](const FAccelByteModelsUserRecord& Result)
{
TSharedPtr<FJsonObject> RecordRequest = MakeShareable(new FJsonObject);
RecordRequest->SetNumberField(FString("armor"), 3);
RecordRequest->SetNumberField(FString("weapon"), 4);
RecordRequest->SetNumberField(FString("ring"), 2);
RecordRequest->SetNumberField(FString("wing"), 1);
RecordRequest->SetNumberField(FString("mount"), 3);

FRegistry::CloudSave.ReplaceUserRecordCheckLatest(Key, Result.UpdatedAt, *RecordRequest, FVoidHandler::CreateLambda([]()
{
// Do something if ReplaceUserRecordCheckLatest has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if ReplaceUserRecordCheckLatest has an error
UE_LOG(LogTemp, Log, TEXT("Error ReplaceUserRecordCheckLatest, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if GetUserRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error GetUserRecord, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Automatic

The automatic implementation will retrieve the latest update for you. You can set it as your custom modifier, which compares records that are submitted at almost the same time. When the request is submitted again, the new custom modifier will decide which record will be submitted and which record will need to be reviewed and submitted again.

int32 TryAttempt = 7;
FString Key = FString("playerEquipments");
TSharedPtr<FJsonObject> RecordRequest = MakeShareable(new FJsonObject);
RecordRequest->SetNumberField(FString("armor"), 4);
RecordRequest->SetNumberField(FString("weapon"), 2);
RecordRequest->SetNumberField(FString("ring"), 1);
RecordRequest->SetNumberField(FString("wing"), 3);
RecordRequest->SetNumberField(FString("mount"), 2);

TBaseDelegate<FJsonObject, FJsonObject> PayloadModifier = TBaseDelegate<FJsonObject, FJsonObject>::CreateLambda([RecordRequest](FJsonObject LatestRecord)
{
for (auto Item : RecordRequest->Values)
{
FString Value;
if (Item.Value->TryGetString(Value))
{
LatestRecord.SetStringField(Item.Key, Value);
}
}
return LatestRecord;
});

FRegistry::CloudSave.ReplaceUserRecordCheckLatest(TryAttempt, Key, *RecordRequest, PayloadModifier, FVoidHandler::CreateLambda([]()
{
// Do something if ReplaceUserRecordCheckLatest has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if ReplaceUserRecordCheckLatest has an error
UE_LOG(LogTemp, Log, TEXT("Error ReplaceUserRecordCheckLatest, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Delete a User Record

Use the DeleteUserRecord() function to delete a record.

FString Key = FString("graphicQuality");

FRegistry::CloudSave.DeleteUserRecord(Key, FVoidHandler::CreateLambda([]()
{
// Do something if DeleteUserRecord has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if DeleteUserRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error DeleteUserRecord, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Integrate Your Game with Cloud Save at the Namespace Level

Create a New Game Record

To create a new record, use the SaveGameRecord() function. Please note that if the key already exists, the new record will be appended to the existing record.

FString Key = FString("gameMode");
TSharedPtr<FJsonObject> RecordRequest = MakeShareable(new FJsonObject);
RecordRequest->SetNumberField(FString("1v1"), 0);
RecordRequest->SetNumberField(FString("2v2"), 1);
RecordRequest->SetNumberField(FString("3v3"), 2);
RecordRequest->SetNumberField(FString("4v4"), 3);

FRegistry::CloudSave.SaveGameRecord(Key, *RecordRequest, FVoidHandler::CreateLambda([]()
{
// Do something if SaveGameRecord has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if SaveGameRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error SaveGameRecord, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Retrieve Game Record

Game data can be retrieved using the GetGameRecord() function.

FString Key = FString("gameMode");

FRegistry::CloudSave.GetGameRecord(Key, THandler<FAccelByteModelsGameRecord>::CreateLambda([](const FAccelByteModelsGameRecord& Result)
{
// Do something if GetGameRecord has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if GetGameRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error GetGameRecord, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Replace a Game Record

You can update game data using the ReplaceGameRecord() function, even when the data does not exist. If the data does not exist, it will be created based on the data in the update. And if the data exists, it will replace all the data in the update.

FString Key = FString("gameMode");
TSharedPtr<FJsonObject> RecordRequest = MakeShareable(new FJsonObject);
RecordRequest->SetNumberField(FString("1v1"), 0);
RecordRequest->SetNumberField(FString("2v2"), 1);
RecordRequest->SetNumberField(FString("3v3"), 2);
RecordRequest->SetNumberField(FString("4v4"), 3);

FRegistry::CloudSave.ReplaceGameRecord(Key, *RecordRequest, FVoidHandler::CreateLambda([]()
{
// Do something if ReplaceGameRecord has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if ReplaceGameRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error ReplaceGameRecord, Error Code: %d, Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Replace Game Records Concurrently

Just like user records, you can use this function to avoid overwriting the changes made by other users in the middle of your changes. There are both manual and automatic methods to replace game records concurrently.

Manual

The manual method will be successful only if there are no other updates on record, but will return an ErrorCode.GameRecordPreconditionFailed in Unity or ErrorCodes::PlayerRecordPreconditionFailedException error for Unreal Engine when the record has been changed since you retrieved it. You'll need to input the timestamp of the record's last update, which you can get from GetGameRecord.

FString Key = FString("gameMode");

FRegistry::CloudSave.GetGameRecord(Key, THandler<FAccelByteModelsGameRecord>::CreateLambda([&](const FAccelByteModelsGameRecord& Result)
{
TSharedPtr<FJsonObject> RecordRequest = MakeShareable(new FJsonObject);
RecordRequest->SetNumberField(FString("1v1"), 4);
RecordRequest->SetNumberField(FString("2v2"), 3);
RecordRequest->SetNumberField(FString("3v3"), 2);
RecordRequest->SetNumberField(FString("4v4"), 1);
RecordRequest->SetNumberField(FString("5v5"), 0);

FRegistry::CloudSave.ReplaceGameRecordCheckLatest(Key, Result.UpdatedAt, *RecordRequest, FVoidHandler::CreateLambda([]()
{
// Do something if ReplaceGameRecordCheckLatest has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if ReplaceGameRecordCheckLatest has an error
UE_LOG(LogTemp, Log, TEXT("Error ReplaceGameRecordCheckLatest, Error Code: %d, Error Message: %s"), ErrorCode, *ErrorMessage);
}));
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if GetGameRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error GetGameRecord, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Automatic

The automatic method will get the latest update for you, put it on your custom modifier, and then make the request again. In the custom modifier, you can compare the latest record with your local record to see what changes have been made.

int32 TryAttempt = 7;
FString Key = FString("gameMode");
TSharedPtr<FJsonObject> RecordRequest = MakeShareable(new FJsonObject);
RecordRequest->SetNumberField(FString("1v1"), 0);
RecordRequest->SetNumberField(FString("2v2"), 1);
RecordRequest->SetNumberField(FString("3v3"), 2);
RecordRequest->SetNumberField(FString("4v4"), 3);
RecordRequest->SetNumberField(FString("5v5"), 4);

TBaseDelegate<FJsonObject, FJsonObject> PayloadModifier = TBaseDelegate<FJsonObject, FJsonObject>::CreateLambda([RecordRequest](FJsonObject LatestRecord)
{
for (auto Item : RecordRequest->Values)
{
FString Value;
if (Item.Value->TryGetString(Value))
{
LatestRecord.SetStringField(Item.Key, Value);
}
}
return LatestRecord;
});

FRegistry::CloudSave.ReplaceGameRecordCheckLatest(TryAttempt, Key, *RecordRequest, PayloadModifier, FVoidHandler::CreateLambda([]()
{
// Do something if ReplaceGameRecordCheckLatest has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if ReplaceGameRecordCheckLatest has an error
UE_LOG(LogTemp, Log, TEXT("Error ReplaceGameRecordCheckLatest, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));
;

Delete a Game Record

Use the DeleteGameRecord() function to delete game data.

FString Key = FString("gameMode");

FRegistry::CloudSave.DeleteGameRecord(Key, FVoidHandler::CreateLambda([]()
{
// Do something if DeleteGameRecord has been successuful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if DeleteGameRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error DeleteGameRecord, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Integrate Your Game Server with Cloud Save

In this section, you will learn how to modify games and user records in the Game Server.

Create a User Record

You can create a record for the targeted user or game configuration. If the record already exists, this action will merge the records with the following conditions:

  • If the field name already exists, the value will be replaced.

  • If the field name does not exist, it will append the field and its value.

User Record

You can create a user record using the following function.


FString Key = FString("playerEqupments");
FString UserId = FString("SomeUserId");
TSharedPtr<FJsonObject> RecordRequest = MakeShareable(new FJsonObject);
RecordRequest->SetNumberField(FString("armor"), 1);
RecordRequest->SetNumberField(FString("weapon"), 2);
RecordRequest->SetNumberField(FString("ring"), 3);
RecordRequest->SetNumberField(FString("wing"), 1);
RecordRequest->SetNumberField(FString("mount"), 2);

FRegistry::ServerCloudSave.SaveUserRecord(Key, UserId, *RecordRequest, false, FVoidHandler::CreateLambda([]()
{
// Do something if SaveUserRecord has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if SaveUserRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error SaveUserRecord, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Game Record

You can create a game record using the following function.

FString Key = FString("npcLocation");
TSharedPtr<FJsonObject> RecordRequest = MakeShareable(new FJsonObject);
RecordRequest->SetStringField(FString("npc1"), FString("X=125;Y=256;Z=125"));
RecordRequest->SetStringField(FString("npc2"), FString("X=115,Y=225,Z=120"));

FRegistry::ServerCloudSave.SaveGameRecord(Key, *RecordRequest, FVoidHandler::CreateLambda([]()
{
// Do something if SaveGameRecord has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if SaveGameRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error SaveGameRecord, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Retrieve a Record

You can retrieve a specific game or user record.

User Record

You can retrieve a user record using the following function.

FString UserId = FString("SomeUserId");
FString Key = FString("playerEquipments");

FRegistry::ServerCloudSave.GetUserRecord(UserId, Key, THandler<FAccelByteModelsUserRecord>::CreateLambda([](const FAccelByteModelsUserRecord& Result)
{
// Do something if GetUserRecord has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if GetUserRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error GetUserRecord, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Game Record

You can retrieve a game record using the following function.

FString Key = FString("npcLocation");

FRegistry::ServerCloudSave.GetGameRecord(Key, THandler<FAccelByteModelsGameRecord>::CreateLambda([](const FAccelByteModelsGameRecord& Result)
{
// Do something if GetGameRecord has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if GetGameRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error GetGameRecord, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Retrieve a Public User Record

Retrieve the specified public user's record. You need to input a User ID to get the specific public user record.

FString Key = FString("playerEquipments");
FString UserId = FString("SomeUserId");

FRegistry::ServerCloudSave.GetPublicUserRecord(Key, UserId, THandler<FAccelByteModelsUserRecord>::CreateLambda([](const FAccelByteModelsUserRecord& Result)
{
// Do something if GetPublicUserRecord has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if GetPublicUserRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error GetPublicUserRecord, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Retrieve All Game Records

You can retrieve all the list of game records using the following function.

FRegistry::ServerCloudSave.RetrieveGameRecordsKey(THandler<FAccelByteModelsPaginatedRecordsKey>::CreateLambda([](const FAccelByteModelsPaginatedRecordsKey& Result)
{
// Do something if RetrieveGameRecordsKey has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if RetrieveGameRecordsKey has an error
UE_LOG(LogTemp, Log, TEXT("Error RetrieveGameRecordsKey, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Replace a Record

This function can overwrite an existing user's or game record if it exists. If the record does not exist, it will create a new record.

User Record

You can replace a user record using the following function.

FString UserId = FString("SomeUserId");
FString Key = FString ("playerEquipments");
TSharedPtr<FJsonObject> RecordRequest = MakeShareable(new FJsonObject);
RecordRequest->SetNumberField(FString("armor"), 5);
RecordRequest->SetNumberField(FString("weapon"), 2);
RecordRequest->SetNumberField(FString("ring"), 1);
RecordRequest->SetNumberField(FString("wing"), 3);
RecordRequest->SetNumberField(FString("mount"), 2);

FRegistry::ServerCloudSave.ReplaceUserRecord(UserId, Key, *RecordRequest, false, FVoidHandler::CreateLambda([]()
{
// Do something if ReplaceUserRecord has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if ReplaceUserRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error ReplaceUserRecord, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Game Record

You can replace a game record using the following function.

FString Key = FString("npcLocation");
TSharedPtr<FJsonObject> RecordRequest = MakeShareable(new FJsonObject);
RecordRequest->SetStringField(FString("npc1"), FString("X=125;Y=120;Z=100"));
RecordRequest->SetStringField(FString("npc2"), FString("X=75;Y=175;Z=225"));

FRegistry::ServerCloudSave.ReplaceGameRecord(Key, *RecordRequest, FVoidHandler::CreateLambda([]()
{
// Do something if ReplaceGameRecord has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if ReplaceGameRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error ReplaceGameRecord, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Delete a Record

This function can erase the specified record.User Record

You can delete a user record using the following function.

FString UserId = FString("SomeUserId");
FString Key = FString("playerEquipments");

FRegistry::ServerCloudSave.DeleteUserRecord(Key, UserId, false, FVoidHandler::CreateLambda([]()
{
// Do something if DeleteUserRecord has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if DeleteUserRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error DeleteUserRecord, Error Code: %d Error Message: %s"), ErrorCode, *ErrorMessage);
}));

Game Record

You can delete a game record using the following function.

FString Key = FString("npcLocation");

FRegistry::ServerCloudSave.DeleteGameRecord(Key, FVoidHandler::CreateLambda([]()
{
// Do something if DeleteGameRecord has been successful
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if DeleteGameRecord has an error
UE_LOG(LogTemp, Log, TEXT("Error DeleteGameRecord, Error Code: %d Error Message: %s"), ErrorMessage, *ErrorMessage);
}));

Connect Custom Services to Cloud Save using the Server SDKs

SDK Initialization

Before using the Cloud Save service from the SDK, you will need to initialize your server-side SDK to ensure you are authorized and able to perform create, read, update, and delete actions.

Golang SDK Initialization

Before using the Cloud Save service from the Golang SDK, you will need to initialize the SDK by following the steps below:


cloudsaveService := &cloudsave.CloudsaveService{
Client: factory.NewCloudsaveClient(&repository.ConfigRepositoryImpl{}),
TokenRepository: &repository.TokenRepositoryImpl{},
}

Once completed, you can use the Golang SDK to create, read, update, or delete Cloud Saves from your serverless app.

Python SDK Initialization

Before using the Cloud Save service from the Python SDK, you will need to initialize the SDK by following the steps below:

Once completed, you can use the Python SDK to create, read, update, or delete Cloud Saves from your serverless app.

.NET (C#) SDK Initialization

Before using the Cloud Save service, you will need to set some permissions. Use the following .NET namespaces:

using AccelByte.Sdk.Api.Cloudsave.Model;
using AccelByte.Sdk.Api.Cloudsave.Operation;
using AccelByte.Sdk.Api.Cloudsave.Wrapper;

Java SDK Initialization

Before using the Cloud Save service, you will need to set some permissions. Initialize the PublicGameRecord wrapper from the Cloud Save service using the following code:

PublicGameRecord wPublicGameRecord = new PublicGameRecord(sdk);

Once completed, you can use the SDK to create, read, update, or delete cloud saves.

Create a Game Record

Use the following function to create a game record:

err := cloudsaveService.PostGameRecordHandlerV1(input)
if err != nil {
return err
}
return nil

Update a Game Record

Use the following function to update a game record:

err := cloudsaveService.GetGameRecordHandlerV1(input)
if err != nil {
return err
}
return nil

Delete a Game Record

Use the following function to delete a game record:

err := cloudsaveService.DeleteGameRecordHandlerV1(input)
if err != nil {
return err
}
return nil

Retrieve a Game Record

Use the following function to retrieve a game record:

gameRecords, err := cloudsaveService.GetGameRecordHandlerV1(input)
if err != nil {
return err
}
return nil