Integrate game session attributes
Overview
Game sessions with AccelByte Gaming Services (AGS) Session can contain session attributes that can be used for storing and reading data that is shared across members and dedicated servers (DS) that are used to host the game session. All game session members and DSes have read and write access to this data.
This article shows you how to store, read, and listen to notifications for session data updates through the AGS Game SDK. You will also find code snippets provided for the following topics:
- Storing session attribute
- Handling update conflicts
- Reading session attribute
- Listening to notifications on session data updates
Store session attribute
Storing session data requires developers to update the session with attributes. Attributes can also be filled on game session creation.
- OSS
- Unity
Session attributes in Unreal OSS are stored inside session settings, so you need to set the session attribute in session settings and then call UpdateSession
.
FOnlineSubsystemAccelByte* AccelByteOSS = static_cast<FOnlineSubsystemAccelByte*>(IOnlineSubsystem::Get(ACCELBYTE_SUBSYSTEM));
if(AccelByteOSS == nullptr)
{
// Abort if AccelByteOSS is not found
return;
}
FOnlineSessionV2AccelBytePtr SessionInterface = StaticCastSharedPtr<FOnlineSessionV2AccelByte>(AccelByteOSS->GetSessionInterface());
// Grab the local session setting data and update it with an attribute
FOnlineSessionSettings* SessionSettings = SessionInterface->GetSessionSettings(NAME_GameSession);
SessionSettings->Set(FName("attributename"), TEXT("attributeValue"));
// Listen to the delegate for completing a session update
FDelegateHandle UpdateSessionCompleteHandle;
UpdateSessionCompleteHandle = SessionInterface->AddOnUpdateSessionCompleteDelegate_Handle(FOnUpdateSessionCompleteDelegate::CreateLambda(
[&SessionInterface, &UpdateSessionCompleteHandle](FName SessionName, bool bWasSuccessful)
{
// Do something after the update completes here
// Remove the delegate handler so it doesn't trigger another time
SessionInterface->ClearOnUpdateSessionCompleteDelegate_Handle(UpdateSessionCompleteHandle);
}));
SessionInterface->UpdateSession(NAME_GameSession, *SessionSettings);
var session = AccelByteSDK.GetClientRegistry().GetApi().GetSession();
var sessionId = "abc123"; // Insert session ID here
var updateGameSessionRequest = new SessionV2GameSessionUpdateRequest()
{
version = 1 // Change according to latest version from the backend
};
updateGameSessionRequest.attributes.Add("testAttribute", "attributeValue");
session.PatchGameSession(sessionId, updateGameSessionRequest, result =>
{
{
if (result.IsError)
{
// Do something if PatchGameSession has an error
Debug.Log($"Error PatchGameSession, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
return;
}
// Do something if PatchGameSession succeeds
}
});
Attributes will also be filled if a session that is using attributes in the match ticket is created from matchmaking.
Handle update conflicts
Requests to update session data will only be accepted if the update request's version is equal to the version in the backend.
- OSS
- Unity
In Unreal OSS, if your update request failed because of a conflicting update, the OSS will refresh the session data and query for the latest backend data. After that, it will trigger a delegate set in AddOnSessionUpdateConflictErrorDelegate_Handle
while passing in the session setting that failed to update. Then, you can retry the update session call.
SessionInterface->AddOnSessionUpdateConflictErrorDelegate_Handle(FOnSessionUpdateConflictErrorDelegate::CreateLambda(
[](FName SessionName, FOnlineSessionSettings FailedSessionSettings)
{
// Do something if the update session fails because of an update conflict
}));
In Unity, if an update request fails because of old data, it will respond with the error code ErrorCode.SessionVersionMismatch
. If you receive this error code, you must query the backend first to get the latest session data, then retry the update with the latest session version.
Read session attribute
Session attributes will be returned when you request game session details.
- OSS
- Unity
FOnlineSubsystemAccelByte* AccelByteOSS = static_cast<FOnlineSubsystemAccelByte*>(IOnlineSubsystem::Get(ACCELBYTE_SUBSYSTEM));
if(AccelByteOSS == nullptr)
{
// Abort if AccelByteOSS is not found
return;
}
FOnlineSessionV2AccelBytePtr SessionInterface = StaticCastSharedPtr<FOnlineSessionV2AccelByte>(AccelByteOSS->GetSessionInterface());
// Get the attribute value
FString Attribute{};
SessionInterface->GetSessionSettings(NAME_GameSession)->Get(FName("attributename"), Attribute);
var session = AccelByteSDK.GetClientRegistry().GetApi().GetSession();
var sessionId = "abc123"; // Insert session ID here
session.GetGameSessionDetailsBySessionId(sessionId, result =>
{
{
if (result.IsError)
{
// Do something if GetGameSessionDetailsBySessionId has an error
Debug.Log($"Error GetGameSessionDetailsBySessionId, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
return;
}
// Do something if GetGameSessionDetailsBySessionId succeeds
Dictionary<string, object> sessionAttributes = result.Value.attributes;
}
});
Listen to notifications on session data updates
When there is an update to the session, notifications will be sent to each user in the session. You can add a listener for this notification to know if there is an update.
- OSS
- Unity
FOnlineSubsystemAccelByte* AccelByteOSS = static_cast<FOnlineSubsystemAccelByte*>(IOnlineSubsystem::Get(ACCELBYTE_SUBSYSTEM));
if(AccelByteOSS == nullptr)
{
// Abort if AccelByteOSS is not found
return;
}
FOnlineSessionV2AccelBytePtr SessionInterface = StaticCastSharedPtr<FOnlineSessionV2AccelByte>(AccelByteOSS->GetSessionInterface());
UpdateNotificationHandle = SessionInterface->AddOnSessionUpdateReceivedDelegate_Handle(FOnSessionUpdateReceivedDelegate::CreateLambda(
[&UpdateNotificationHandle, &SessionInterface_User2](FName SessionName) {
// Do something once a session update delegate is received
}));
var lobby = AccelByteSDK.GetClientRegistry().GetApi().GetLobby();
lobby.SessionV2GameSessionUpdated += result =>
{
if (result.IsError)
{
// Do something if SessionV2GameSessionUpdated has an error
Debug.Log($"Error SessionV2GameSessionUpdated, Error Code: {result.Error.Code} Error Message: {result.Error.Message}");
return;
}
// Do something if SessionV2GameSessionUpdated is successfully received
Dictionary<string, object> sessionAttributes = result.Value.attributes;
};