メインコンテンツまでスキップ

ゲームセッションを統合する

Last updated on November 22, 2024

Overview

You can manage game sessions with AccelByte Gaming Services (AGS) Session through the AGS Game SDK or Extend SDK. This article walks you through integrating game sessions and provides code snippets for:

  • Creating a game session
  • Querying a game session list
  • Retrieving the current user's game sessions
  • Retrieving game session details
  • Updating a game session
  • Deleting a game session
  • Inviting a player to a game session
  • Joining a game session
  • Cancelling a game session invite
  • Rejecting a game session invite
  • Leaving a game session
  • Promoting a game session leader
  • Kicking a player from a game session
  • Listening to game session notifications

Create a game session

Create a new game session based on the creation request.

FApiClientPtr ApiClient = FMultiRegistry::GetApiClient();

FAccelByteModelsV2GameSessionCreateRequest Request;
Request.ConfigurationName = ConfigurationName; // MANDATORY
Request.Joinability = EAccelByteV2SessionJoinability::INVITE_ONLY; // Optional
Request.Type = EAccelByteV2SessionConfigurationServerType::DS; // Optional
Request.ClientVersion = GameServerVersion; // Optional
Request.ServerName = LocalServerName; // Optional
Request.Deployment = Deployment; // Optional
Request.RequestedRegions = {"us-west-1", "us-west2"}; // Optional

// Optional
TArray<FString> TeamA = {TeamAUserId1, TeamAUserId2};
TArray<FString> TeamB = {TeamBUserId1, TeamBUserId2};
TArray<FAccelByteModelsV2GameSessionTeam> Teams;
Teams.Add({TeamA});
Request.Teams = Teams;

// Optional
Request.Attributes.JsonObject = MakeShared<FJsonObject>();
Request.Attributes.JsonObject->SetStringField("PartyAttribute", "Attribute1");

Request.MaxPlayers = 10; // Optional
Request.MinPlayers = 1; // Optional
Request.InactiveTimeout = 30; // Optional
Request.InviteTimeout = 86400; // Optional


ApiClient->Session.CreateGameSession(Request,
THandler<FAccelByteModelsV2GameSession>::CreateLambda(
[&](const FAccelByteModelsV2GameSession& Result)
{
// Do something when operation is successful
}),
FErrorHandler::CreateLambda(
[&](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something when operation fails or has an error
}));

Query a game session list

Query all the game sessions that have the same attribute as the request. Supported operations:

  1. EAccelByteV2SessionQueryComparisonOp::EQUAL (query comparator with specific value similar to equals)
  2. EAccelByteV2SessionQueryComparisonOp::NOT_EQUAL (query with specific value notEquals)
  3. EAccelByteV2SessionQueryComparisonOp::CONTAINS (query similar to in)
  4. EAccelByteV2SessionQueryComparisonOp::NOT_CONTAINS (query similar to notIn)
  5. EAccelByteV2SessionQueryComparisonOp::GREATER_THAN (query similar to greaterThan)
  6. EAccelByteV2SessionQueryComparisonOp::GREATER_THAN_EQUAL (query similar to greaterThanEquals)
  7. EAccelByteV2SessionQueryComparisonOp::LESS_THAN (query similar to lessThan)
  8. EAccelByteV2SessionQueryComparisonOp::LESS_THAN_EQUAL (query similar to lessThanEquals)
FApiClientPtr ApiClient = FMultiRegistry::GetApiClient();

// query with specific value `equals`
FAccelByteModelsV2GameSessionQuery Query;
Query.AddParam("map", EAccelByteV2SessionQueryComparisonOp::EQUAL, "SampleMap");

// query with `in`
TArray<FString> PossibleValues;
PossibleValues.Add(TEXT("solo"));
PossibleValues.Add(TEXT("adventure"));
Query.AddParam("custom_game_mode", EAccelByteV2SessionQueryComparisonOp::CONTAINS, PossibleValues);

// query with range value `greaterThanEquals`
constexpr int32 QueriedGreater = 2;
FAccelByteModelsV2GameSessionQuery Query;
Query.AddParam("level", EAccelByteV2SessionQueryComparisonOp::LESS_THAN_EQUAL, QueriedGreater);

int64 Offset = 0;
int64 Limit = 20;
ApiClient->Session.QueryGameSessions(
Query,
THandler<FAccelByteModelsV2PaginatedGameSessionQueryResult>::CreateLambda(
[&](const FAccelByteModelsV2PaginatedGameSessionQueryResult& Result)
{
// Do something when the operation succeeds
}),
FErrorHandler::CreateLambda(
[&](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something when the operation fails or has an error
}),
Offset,
Limit);

Retrieve the current user's game sessions

Retrieve the list of the user's game sessions and its information.

FApiClientPtr ApiClient = FMultiRegistry::GetApiClient();

ApiClient->Session.GetMyGameSessions(
THandler<FAccelByteModelsV2PaginatedGameSessionQueryResult>::CreateLambda(
[&](const FAccelByteModelsV2PaginatedGameSessionQueryResult& Result)
{
// Do something when the operation succeeds
}),
FErrorHandler::CreateLambda(
[&](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something when the operation fails or has an error
}));

Retrieve game session details

Retrieve the specific game session details by specifying the game session identity.

FApiClientPtr ApiClient = FMultiRegistry::GetApiClient();

ApiClient->Session.GetGameSessionDetails( SessionId,
THandler<FAccelByteModelsV2GameSession>::CreateLambda(
[&](const FAccelByteModelsV2GameSession& Result)
{
// Do something when the operation succeeds
}),
FErrorHandler::CreateLambda(
[&](int32 ErrorCode, const FString& ErrorMessage)
{
// Do something when the operation fails or has an error
}));

Update a game session

Update the game session's data from the specific game session.

FApiClientPtr ApiClient = FMultiRegistry::GetApiClient();

FAccelByteModelsV2GameSessionUpdateRequest Request;
Request.Version = PartyDataVersion; // Mandatory, must be the same version as current data in the backend
Request.Joinability = EAccelByteV2SessionJoinability::INVITE_ONLY; // Optional
Request.Attributes.JsonObject = MakeShared<FJsonObject>(); // Optional
Request.Attributes.JsonObject->SetStringField("AttributeName", "Attribute1"); // Optional
Request.MaxPlayers = 10; // Optional
Request.MinPlayers = 1; // Optional
Request.InactiveTimeout = 30; // Optional
Request.InviteTimeout = 86400; // Optional

ApiClient->Session.UpdateGameSession(GameSessionID, Request, THandler<FAccelByteModelsV2GameSession>::CreateLambda(
[&](const FAccelByteModelsV2GameSession& Result)
{
// Do something when the operation succeeds
}),
FErrorHandler::CreateLambda([&](int32 ErrorCode, const FString& Message)
{
// Do something when operation fails or has an error
}));

Delete a game session

Remove the existing game session.

FApiClientPtr ApiClient = FMultiRegistry::GetApiClient();
ApiClient->Session.DeleteGameSession(SessionId, FVoidHandler::CreateLambda([]
{
// Successfully deleted game session
}),
FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& Message)
{
// Error deleting game session
}));

Invite a player to a game session

Invite other players to join the game session by specifying their user identity.

FApiClientPtr ApiClient = FMultiRegistry::GetApiClient();

ApiClient->Session.SendGameSessionInvite(SessionId, UserIdToInvite, FVoidHandler::CreateLambda(
[&]
{
// Do something when the operation succeeds
}),
FErrorHandler::CreateLambda([&](int32 ErrorCode, const FString& Message)
{
// Do something when the operation fails or has an error
}));

Cancel outgoing game session invitation

Players can cancel outgoing invitations. Invitees and inviters will receive a notification that the invitation has been canceled. Invitees can't accept the previous invitation after it is canceled.

// Invitee and inviter listen for session invite canceled notification.
auto OnSessionInviteCanceledDelegate = SessionInterface->AddOnSessionInviteCanceledDelegate_Handle(
FOnSessionInviteCanceledDelegate::CreateLambda([](const FString& SessionID) // ID of canceled game session.
{
// Received invitation canceled.
}));

// Game session leader (inviter) cancel invitation.
FName GameSessionName = NAME_GameSession;
auto OnCancelSessionInviteCompleteDelegate = SessionInterface->AddOnCancelSessionInviteCompleteDelegate_Handle(FOnCancelSessionInviteCompleteDelegate::CreateLambda(
[&](const FUniqueNetId& LocalUserId, FName SessionName, const FUniqueNetId& Invitee, const FOnlineError& ErrorInfo)
{
bool bInvitationCanceled = ErrorInfo.bSucceeded;
// Cancel session invitation complete.
}));

SessionInterface->CancelSessionInvite(PlayerIndex, GameSessionName, *InviteeUniqueNetId);

Join a game session

Join the existing game session by specifying the session identity.

FApiClientPtr ApiClient = FMultiRegistry::GetApiClient();

ApiClient->Session.JoinGameSession(SessionId, THandler<FAccelByteModelsV2GameSession>::CreateLambda(
[&](const FAccelByteModelsV2GameSession& Result)
{
// Do something when the operation succeeds
}),
FErrorHandler::CreateLambda([&](int32 ErrorCode, const FString& Message)
{
// Do something when operation fails or has an error
}));

Join session by code

Players can join a session with a session code if the code is enabled in the session. This is applicable for both party and game sessions. When the user joins the session by code, AGS will bypass the invitation check and session joinability for session type:

  • OPEN
  • INVITE ONLY
  • Friends Only (Friends of members, Friends of leader, and Friends of friends)

Users who join via code can enter the session with the joinability as listed above regardless of whether the user has already been invited or not.

FString SessionCode = TEXT("yourGameSessionCode");

const FApiClientPtr ApiClient = FMultiRegistry::GetApiClient();
ApiClient->Session.JoinGameSessionByCode(
SessionCode,
THandler<FAccelByteModelsV2GameSession>::CreateLambda([&](const FAccelByteModelsV2GameSession& Response)
{
// Do something if JoinGameSessionByCode succeeded
})
, FErrorHandler::CreateLambda([&bIsDone](const int32 ErrorCode, const FString& ErrorMessage)
{
// Do something if JoinGameSessionByCode failed

}));

Avoid hanging sessions

A hanging session occurs when the player is still an active member of a game session when the game client expects the player to have left the session. This situation can happen when the game does not gracefully leave the session when it crashes or is forced to close.

This can impact the data correctness from both the back-end and game client sides. Some unexpected behavior might happen when there are too many hanging session data on the backend side, for example:

  • The game admin configures the max active session for a player to be only one session at a time.
  • When there is a hanging session data in the backend, the game will get an error when joining a new session since the player is still registered in the old session.

AccelByte recommends that the game retrieves the player's active sessions upon joining a new session and leaves them first. This will come in handy in the session browser flow.

Check out the Implementing the subsystem - Introduction to Session article in Byte Wars for an implementation example.

To limit the player's activity to one game session at a time, enable the Auto-leave Game Session option in the session. When enabled, the session automatically kicks out the player from the active game session upon joining a new one. This makes the game session behave like a party session and ensures the player can only be in one active game session at a time. For more information, refer to the configure session templates article.

Reject a game session invitation

Reject another player's invitation to the join the game session.

FApiClientPtr ApiClient = FMultiRegistry::GetApiClient();

ApiClient->Session.RejectGameSessionInvite(GameSessionID, FVoidHandler::CreateLambda(
[&]
{
// Do something when the operation succeeds
}),
FErrorHandler::CreateLambda([&](int32 ErrorCode, const FString& Message)
{
// Do something when operation fails or has an error
}));

Leave a game session

Leave the current joined game session by specifying its game session identity.

FApiClientPtr ApiClient = FMultiRegistry::GetApiClient();

ApiClient->Session.LeaveGameSession(SessionId, FVoidHandler::CreateLambda(
[&]
{
// Do something when the operation succeeds
}),
FErrorHandler::CreateLambda([&](int32 ErrorCode, const FString& Message)
{
// Do something when operation fails or has an error
}));

Promote a game session leader

A game session leader can promote another member to become a game session leader. Since there is only one game session leader, the previous leader will become a normal member.

注記

The code snippet for Unreal will be added soon.

Kick a player from a game session

A game session leader or a dedicated server can kick a member from a game session.

const FString GameSessionID = TEXT("game-session-id");
const FString PlayerID = TEXT("player-id");

// Game session leader kick a player from a game session
FApiClientPtr ApiClient = FMultiRegistry::GetApiClient();

ApiClient->Session.KickUserFromGameSession(GameSessionID, PlayerID
, FVoidHandler::CreateLambda([]()
{
// Do something when the operation succeeds
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& Message)
{
// Do something when operation fails or has an error
}));

// Dedicated server kicks a player from a game session
FServerApiClientPtr ServerApiClient = FMultiRegistry::GetServerApiClient();
ServerApiClient->ServerSession.KickUserFromGameSession(GameSessionID, PlayerID
, FVoidHandler::CreateLambda([]()
{
// Do something when the operation succeeds
}), FErrorHandler::CreateLambda([](int32 ErrorCode, const FString& Message)
{
// Do something when operation fails or has an error
}));

Listen to game session notifications

There are some game session notifications that can be listened to in order to receive various updates from the game session. This uses a WebSocket connection to ensure that the notification can be received in real time.

FApiClientPtr ApiClient = FMultiRegistry::GetApiClient();

ApiClient->Lobby.SetV2GameSessionInvitedNotifDelegate(Api::Lobby::FV2GameSessionInvitedNotif::CreateLambda(
[&](const FAccelByteModelsV2GameSessionUserInvitedEvent& Notif)
{
// Do something when a notification is received
}));

ApiClient->Lobby.SetV2GameSessionMembersChangedNotifDelegate(Api::Lobby::FV2GameSessionMembersChangedNotif::CreateLambda(
[&](const FAccelByteModelsV2GameSessionMembersChangedEvent& Notif)
{
// Do something when a notification is received
}));

ApiClient->Lobby.SetV2GameSessionJoinedNotifDelegate(Api::Lobby::FV2GameSessionJoinedNotif::CreateLambda(
[&](const FAccelByteModelsV2GameSessionUserJoinedEvent& Notif)
{
// Do something when a notification is received
}));

ApiClient->Lobby.SetV2GameSessionRejectedNotifDelegate(Api::Lobby::FV2GameSessionRejectedNotif::CreateLambda(
[&](const FAccelByteModelsV2GameSessionUserRejectedEvent& Notif)
{
// Do something when a notification is received
}));

ApiClient->Lobby.SetV2GameSessionKickedNotifDelegate(Api::Lobby::FV2GameSessionKickedNotif::CreateLambda(
[&](const FAccelByteModelsV2GameSessionUserKickedEvent& Notif)
{
// Do something when a notification is received
}));

ApiClient->Lobby.SetV2GameSessionUpdatedNotifDelegate(Api::Lobby::FV2GameSessionUpdatedNotif::CreateLambda(
[&](const FAccelByteModelsV2GameSession& Notif)
{
// Do something when a notification is received
}));

ApiClient->Lobby.SetV2DSStatusChangedNotifDelegate(Api::Lobby::FV2DSStatusChangedNotif::CreateLambda(
[&](const FAccelByteModelsV2DSStatusChangedNotif& Notif)
{
// Do something when a notification is received
}));

Refresh Game Session

The game session can be refreshed to synchronize with the backend utilizing the Refresh Session method. The provided SessionName parameter may correspond to NAME_GameSession.

SessionInterface->RefreshSession(SessionName, FOnRefreshSessionComplete::CreateLambda([]()
{
// On refresh session complete
}));

Refresh active sessions

To prevent issues and ensure proper synchronization with the backend, use the following function to refresh all active sessions that are cached locally on the client:

SessionInterface->RefreshActiveSessions(FOnRefreshActiveSessionsComplete::CreateLambda(
[&](bool bWasSuccessful)
{
// On refresh active sessions complete
}));
-