Cloud Save
Overview
AccelByte Gaming Services (AGS) Starter Cloud Save is a service that stores arbitrary data in JSON format. With Cloud Save, you can store, retrieve, update, and delete any data from your game. The game data can be stored in one of two types of records:
- Game Records which store game data such as event configurations and themes, and
- Player Records which store player records such as saved game data.
Metadata
Metadata allows admins and players to define the behavior of theirCloud 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. There are several different types of metadata, including:
Write Permission (set_by) This metadata indicates which party modified the record and 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:
Admin Player Server Modify, Read Read Client Modify, Read Modify, Read Write permission behavior metrics on the Player Record:
Admin Player Record Owner Other Players Server Modify - - Client Modify Modify -
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:
Admin Player Record Owner Other Players False Read Read - True Read Read Read
Managing Your Game with Cloud Save in the Admin Portal
AGS Starter Admin Portal gives community managers and game admins an easy way to manage and integrate Cloud Save.
Create a New Game Record
Open your desired game title in the Admin Portal, expand the Game Management section, click the Cloud Save menu, and select Game Records.
On the Cloud Save page, select the Create Game Record button.
The Add Record form will appear. Fill in the required fields.
Input the game record Key using the appropriate format as explained below.
- Use only lowercase letters and numbers
- Only the hyphen (-) is allowed as a separator. It cannot appear twice in a row and cannot be used to start or end the key name
Input the JSON Configuration.
Once completed, click the Add 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 Records
To update a Player Record, go to the Player Records page, choose the record you want to update by inputting the correct User ID, 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 box will appear. Click Save to complete your update.
Integrating 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.
If the key already exists, the new record will be appended to the existing record.
- Unreal Engine
- Unity
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);
}));
string key = "graphicQuality";
Dictionary<string, object> recordRequest = new Dictionary<string, object>
{
// 0 Low Quality, 1 Medium Quality, 2 High Quality
{ "textures", 0 },
{ "shadow", 2 },
{ "lighting", 1 },
{ "post-processing", 2 }
};
AccelBytePlugin.GetCloudSave().SaveUserRecord(key, recordRequest, false, result =>
{
if (result.IsError)
{
// Do something if SaveUserRecord has an error
Debug.Log($"Error SaveUserRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if SaveUserRecord has been successful
}
});
Retrieve a User Record
User data stored in a private record can be retrieved using the GetUserRecord() function.
- Unreal Engine
- Unity
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);
}));
string key = "graphicQuality";
AccelBytePlugin.GetCloudSave().GetUserRecord(key, result =>
{
if (result.IsError)
{
// Do something if GetUserRecord has an error
Debug.Log($"Error GetUserRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if GetUserRecord has been successful
}
});
Retrieve a Public User Record
A public user record can be retrieved by another user. To get another user’s public records, use the GetPublicUserRecord() function.
- Unreal Engine
- Unity
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);
}));
string key = "playerStatus";
string userId = "SomeUserId";
AccelBytePlugin.GetCloudSave().GetPublicUserRecord(key, userid, result =>
{
if (result.IsError)
{
// Do something if GetPublicUserRecord has an error
Debug.Log($"Error GetPublicUserRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if GetPublicUserRecord has been successful
}
});
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 then be stored either publicly or privately.
- Unreal Engine
- Unity
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);
}));
string key = "graphicQuality";
Dictionary<string, object> recordRequest = new Dictionary<string, object>
{
{ "textures", 50 },
{ "shaodw", 25 },
{ "lighting", 20 },
{ "post-processing", 15 }
};
AccelBytePlugin.GetCloudSave().ReplaceUserRecord(key, recordRequest, false, result =>
{
if (result.IsError)
{
// Do somtehing if ReplaceUserRecord has an error
Debug.Log($"Error ReplaceUserRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if ReplaceUserRecord has been successful
}
});
Replace User Records Concurrently
To ensure that concurrent edits to user records aren’t overwritten, this feature gives the user an error if another client tries to submit changes to that same user record at the same time. There are two possible implementations of this feature: manual and automatic.
Manual
The manual implementation will return the error ErrorCodes::PlayerRecordPreconditionFailedException in Unreal Engine or ErrorCode.PlayerRecordPreconditionFailed in Unity 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.
- Unreal Engine
- Unity
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);
}));
string key = "playerEquipments";
AccelBytePlugin.GetCloudSave().GetUserRecord(key, result =>
{
if (result.IsError)
{
// Do something if GetUserRecord has an error
Debug.Log($"Error GetUserRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
Dictionary<string, object> recordRequest = new Dictionary<string, object>
{
{ "armor", 4 },
{ "weapon", 3 },
{ "ring", 2 },
{ "wing", 3 },
{ "mount", 2 }
};
AccelBytePlugin.GetCloudSave().ReplaceUserRecordCheckLatest(key, result.Value.updated_at, recordRequest, result =>
{
if (result.IsError)
{
// Do something if ReplaceUserRecordCheckLatest has an error
Debug.Log($"Error ReplaceUserRecordCheckLatest, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if ReplaceUserRecordCheckLatest has been successful
}
});
}
});
Automatic
Automatic implementation will retrieve the latest update for you. You can set this as your custom modifier, which compares records that are submitted at almost the same time. When a request is submitted again, the new custom modifier will decide which record will be accepted and which record will be rejected, updated, and require submitting again.
- Unreal Engine
- Unity
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);
}));
int tryAttempt = 7;
string key = "playerEquipments";
Dictionary<string, object> recordRequest = new Dictionary<string, object>
{
{ "armor", 4 },
{ "weapon", 2 },
{ "ring", 3 },
{ "wing", 2 },
{ "mount", 5 }
};
Dictionary<string, object> payloadModifier(Dictionary<string, object> latestRecord)
{
foreach (var item in recordRequest)
{
latestRecord.Add(item.Key, item.Value);
}
return latestRecord;
};
AccelBytePlugin.GetCloudSave().ReplaceUserRecordCheckLatest(tryAttempt, key, recordRequest, result =>
{
if (result.IsError)
{
// Do something if ReplaceUserRecordCheckLatest has an error
Debug.Log($"Error ReplaceUserRecordCheckLatest, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if ReplaceUserRecordCheckLatest has been successful
}
}, payloadModifier);
Delete a User Record
Use the DeleteUserRecord() function to delete a record.
- Unreal Engine
- Unity
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);
}));
string key = "graphicQuality";
AccelBytePlugin.GetCloudSave().DeleteUserRecord(key, result =>
{
if (result.IsError)
{
// Do something if DeleteUserRecord has an error
Debug.Log($"Error DeleteUserRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if DeleteUserRecord has been successful
}
});
Integrating Your Game with Cloud Save at the Title Level
Create a New Game Record
To create a new record, use the SaveGameRecord() function.
If the key already exists, the new record will be appended to the existing record.
- Unreal Engine
- Unity
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);
}));
string key = "gameMode";
Dictionary<string, object> recordRequest = new Dictionary<string, object>
{
{ "1v1", 0 },
{ "2v2", 1 },
{ "3v3", 2 },
{ "4v4", 3 }
};
AccelBytePlugin.GetCloudSave().SaveGameRecord(key, recordRequest, result =>
{
if (result.IsError)
{
// Do something if SaveGameRecord has an error
Debug.Log($"Error SaveGameRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if SaveGameRecord has been successful
}
});
Retrieve Game Record
Game data can be retrieved using the GetGameRecord() function.
- Unreal Engine
- Unity
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);
}));
string key = "gameMode";
AccelBytePlugin.GetCloudSave().GetGameRecord(key, result =>
{
if (result.IsError)
{
// Do something if GetGameRecord has an error
Debug.Log($"Error GetGameRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if GetGameRecord has been successful
}
});
Replace 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.
- Unreal Engine
- Unity
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);
}));
string key = "gameMode";
Dictionary<string, object> recordRequest = new Dictionary<string, object>
{
{ "1v1", 0 },
{ "2v2", 1 },
{ "3v3", 2 },
{ "4v4", 3 }
};
AccelBytePlugin.GetCloudSave().ReplaceGameRecord(key, recordRequest, result =>
{
if (result.IsError)
{
// Do something if ReplaceGameRecord has an error
Debug.Log($"Error ReplaceGameRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if ReplaceGameRecord has been successful
}
});
Replace Game Record 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 ErrorCodes::PlayerRecordPreconditionFailedException error for Unreal Engine or ErrorCode.GameRecordPreconditionFailed in Unity 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.
- Unreal Engine
- Unity
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);
}));
string key = "gameMode";
AccelBytePlugin.GetCloudSave().GetGameRecord(key, result =>
{
if (result.IsError)
{
// Do something if GetGameRecord has an error
Debug.Log($"Error GetGameRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
Dictionary<string, object> recordRequest = new Dictionary<string, object>
{
{ "1v1", 4 },
{ "2v2", 3 },
{ "3v3", 2 },
{ "2v2", 1 },
{ "1v1", 0 }
};
AccelBytePlugin.GetCloudSave().ReplaceGameRecordCheckLatest(key, result.Value.updated_at, recordRequest, result =>
{
if (result.IsError)
{
// Do something if ReplaceGameRecordCheckLatest has an error
Debug.Log($"Error ReplaceGameRecordCheckLatest, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if ReplaceGAmeRecordCheckLatest has been successful
}
});
}
});
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.
- Unreal Engine
- Unity
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);
}));
;
int tryAttempt = 7;
string key = "gameMode";
Dictionary<string, object> recordRequest = new Dictionary<string, object>
{
{ "1v1", 1 },
{ "2v2", 2 },
{ "3v3", 3 },
{ "4v4", 4 },
{ "5v5", 5 }
};
Dictionary<string, object> payloadModifier(Dictionary<string, object> latestRecord)
{
foreach (var item in recordRequest)
{
latestRecord.Add(item.Key, item.Value);
}
return latestRecord;
};
AccelBytePlugin.GetCloudSave().ReplaceGameRecordCheckLatest(tryAttempt, key, recordRequest, result =>
{
if (result.IsError)
{
// Do something if ReplaceGameRecordCheckLatest has an error
Debug.Log($"Error ReplaceGameRecordCheckLatest, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if ReplaceGameRecordCheckLatest has been successful
}
}, payloadModifier);
Delete Game Record
Use the DeleteGameRecord() function to delete game data.
- Unreal Engine
- Unity
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);
}));
string key = "gameMode";
AccelBytePlugin.GetCloudSave().DeleteGameRecord(key, result =>
{
if (result.IsError)
{
// Do something if DeleteGameRecord has an error
Debug.Log($"Error DeleteGameRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if DeleteGameRecord has been successful
}
});
Integrating Your Game Server with Cloud Save
Create a New Record
Create a new record for the targeted user or game. 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.
- Unreal Engine
- Unity
FString Key = FString("playerEquipments");
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);
}));
string userId = "SomeUserId";
string key = "playerEquipments";
Dictionary<string, object> recordRequest = new Dictionary<string, object>
{
{ "armor", 2 },
{ "weapon", 1 },
{ "ring", 3 },
{ "wing", 2 },
{ "mount", 5 }
};
AccelByteServerPlugin.GetCloudSave().SaveUserRecord(userId, key, recordRequest, result =>
{
if (result.IsError)
{
// Do something if SaveUserRecord has an error
Debug.Log($"Error SaveUserRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if SaveUserRecord has been successful
}
});
Game Record
You can create a game record using the following function.
- Unreal Engine
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
Retrieve the specified game or user’s record.
User Record
You can retrieve a user record using the following function.
- Unreal Engine
- Unity
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);
}));
string userId = "SomeUserId";
string key = "playerEquipments";
AccelByteServerPlugin.GetCloudSave().GetUserRecord(userid, key, result =>
{
if (result.IsError)
{
// Do something if GetUserRecord has an error
Debug.Log($"Error GetUserRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if GetUserRecord has been successful
}
});
Game Record
You can retrieve a game record using the following function.
- Unreal Engine
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.
- Unreal Engine
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.
- Unreal Engine
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.
- Unreal Engine
- Unity
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);
}));
string userId = "SomeUserId";
string key = "playerEquipments";
Dictionary<string, object> recordRequest = new Dictionary<string, object>
{
{ "armor", 2 },
{ "weapon", 1 },
{ "ring", 5 },
{ "wing", 2 },
{ "mount", 1 }
};
AccelByteServerPlugin.GetCloudSave().ReplaceUserRecord(userid, key, recordRequest, result =>
{
if (result.IsError)
{
// Do something if ReplaceUserRecord has an error
Debug.Log($"Error ReplaceUserRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if ReplaceUserRecord has been successful
}
});
Game Record
You can replace a game record using the following function.
- Unreal Engine
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.
- Unreal Engine
- Unity
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);
}));
string userId = "SomeUserId";
string key = "playerEquipments";
AccelByteServerPlugin.GetCloudSave().DeleteUserRecord(userId, key, result =>
{
if (result.IsError)
{
// Do something if DeleteUserRecord has an error
Debug.Log($"Error DeleteUserRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if DeleteUserRecord has been successful
}
});
Game Record
You can delete a game record using the following function.
- Unreal Engine
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);
}));
Integrating Your Game Server with Cloud Save
In this section, you will learn how to modify games and user records in the Game Server.
NOTE
You need to use a client token to call a Game Server.
Create a New Record
Create a new record for the targeted user or game. 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.
- Unreal Engine
- Unity
FString Key = FString("playerEquipments");
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);
}));
string userId = "SomeUserId";
string key = "playerEquipments";
Dictionary<string, object> recordRequest = new Dictionary<string, object>
{
{ "armor", 2 },
{ "weapon", 1 },
{ "ring", 3 },
{ "wing", 2 },
{ "mount", 5 }
};
AccelByteServerPlugin.GetCloudSave().SaveUserRecord(userId, key, recordRequest, result =>
{
if (result.IsError)
{
// Do something if SaveUserRecord has an error
Debug.Log($"Error SaveUserRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if SaveUserRecord has been successful
}
});
Game Record
You can create a game record using the following function.
- Unreal Engine
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
Retrieve the specified game or user’s record.
User Record
You can retrieve a user record using the following function.
- Unreal Engine
- Unity
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);
}));
string userId = "SomeUserId";
string key = "playerEquipments";
AccelByteServerPlugin.GetCloudSave().GetUserRecord(userid, key, result =>
{
if (result.IsError)
{
// Do something if GetUserRecord has an error
Debug.Log($"Error GetUserRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if GetUserRecord has been successful
}
});
Game Record
You can retrieve a game record using the following function.
- Unreal Engine
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.
- Unreal Engine
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.
- Unreal Engine
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.
- Unreal Engine
- Unity
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);
}));
string userId = "SomeUserId";
string key = "playerEquipments";
Dictionary<string, object> recordRequest = new Dictionary<string, object>
{
{ "armor", 2 },
{ "weapon", 1 },
{ "ring", 5 },
{ "wing", 2 },
{ "mount", 1 }
};
AccelByteServerPlugin.GetCloudSave().ReplaceUserRecord(userid, key, recordRequest, result =>
{
if (result.IsError)
{
// Do something if ReplaceUserRecord has an error
Debug.Log($"Error ReplaceUserRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if ReplaceUserRecord has been successful
}
});
Game Record
You can replace a game record using the following function.
- Unreal Engine
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 will delete the specified user record.
User Record
You can delete a user record using the following function.
- Unreal Engine
- Unity
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);
}));
string userId = "SomeUserId";
string key = "playerEquipments";
AccelByteServerPlugin.GetCloudSave().DeleteUserRecord(userId, key, result =>
{
if (result.IsError)
{
// Do something if DeleteUserRecord has an error
Debug.Log($"Error DeleteUserRecord, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
}
else
{
// Do something if DeleteUserRecord has been successful
}
});
Game Record
You can delete a game record using the following function.
- Unreal Engine
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);
}));