ゲームセッションの属性を統合する
Overview
Game sessions 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 DS have read and write access to this data.
This article shows how to store, read, and listen to notifications on session data updates through the AccelByte Gaming Services (AGS) Game SDK.
Integrate a game session attribute using the AGS Game SDK
This section provides code snippets showing how to:
- Store session attribute
- Handle update conflicts
- Read session attribute
- Listen 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 a game session creation.
- OSS
- Unity
Session attributes in Unreal OSS is stored inside session settings, so you need to set the session attribute in session settings, then call UpdateSession
.
FOnlineSubsystemAccelByte* AccelByteOSS = static_cast<FOnlineSubsystemAccelByte*>(IOnlineSubsystem::Get(ACCELBYTE_SUBSYSTEM));
if(AccelByteOSS == nullptr)
{
// Bail out 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 session update session complete delegate
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 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 has been successful
}
});
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 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 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 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 for game session details.
- OSS
- Unity
FOnlineSubsystemAccelByte* AccelByteOSS = static_cast<FOnlineSubsystemAccelByte*>(IOnlineSubsystem::Get(ACCELBYTE_SUBSYSTEM));
if(AccelByteOSS == nullptr)
{
// Bail out 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 has been successful
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)
{
// Bail out 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 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;
};