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

Matchmaking to a DS on Armada

Last updated on November 6, 2023
note

Armada はまだ AGS Starter ティアではご利用いただけません。まもなく提供を開始します。

概要

このガイドは、専用サーバー (DS) における AccelByte マッチメイキング機能の基礎について説明しています。AccelByte オンラインサブシステム (OSS) は、V2 セッションやマッチメイキングバックフィルとやり取りするために使用されます。

目標

  • 専用サーバーからセッション情報を取得する。
  • 専用サーバーからのバックフィル提案を承諾または拒否する。
  • 専用サーバーからのバックフィルを有効または無効にする。

前提条件

  • ロビー、セッション、マッチメイキングサービスについてよく知っている。

  • オンラインサブシステム (OSS) の使用など、Unreal Engine の知識がある。

  • ゲームの管理者ポータルと名前空間にアクセスできる。

  • タイプが DS に設定されたセッションテンプレートと、適切なデプロイメントを設定している。

  • マッチプールとマッチルールセットを設定し、それらをセッションテンプレートに関連付けている。

  • ゲームクライアントが AGS マッチメイキングと統合されている。

  • DefaultEngine.ini で V2 セッションが有効になっている。

    [OnlineSubsystemAccelByte]
    bEnableV2Sessions=true

バックフィル提案フロー

このセクションでは、マッチメイキングサービスと専用サーバーの間で実行される、バックフィル提案フローについて説明します。

Matchmaking Backfill Proposal Flow

ゲームセッションが作成され、マッチしたプレイヤーに招待が送信されると、セッションサービスは DS ハブを介して専用サーバーをプロビジョニングするようにリクエストします。

専用サーバーの準備が整うと、接続情報がゲームセッションに返され、接続が試行されます。

  1. ゲームセッションが専用サーバーに正常に接続されると、サーバーはセッションデータをクエリできます。

  2. ゲームセッションが満員でない場合、自動バックフィルが有効になっていれば、またはバックフィルチケットをマッチメイキングサービスに直接送信すれば、追加のプレイヤーとマッチングできます。

  3. 自動または手動でバックフィルリクエストが送信された場合、マッチメイキングサービスは提案を専用サーバーに返します。

  4. その後、専用サーバーが提案を処理し、実行可能かどうかを評価します。競合状態のために別のプレイヤーがオープンスポットに既に収まっている可能性があるため、提案を受け入れる前に、ゲームセッションにまだ枠があるかを確認することが重要です。

  5. その後、専用サーバーは提案を承諾するか拒否し、マッチメイキングサービスに通知します。承諾すると、新しいプレイヤーはゲームセッションに参加するための招待を受け取ります。

セッション情報の取得方法

ゲームセッションが専用サーバーに接続されると、プレイヤーはセッションに保存されている接続の詳細を使用できるようになります。これにより、プレイヤーは専用サーバーとの接続が可能になります。同時に、サーバーはセッションと接続されたプレイヤーに関する情報をクエリできます。

  1. まず、V2 セッションインターフェイスを取得して、ゲームサーバーを Armada に登録する必要があります。

    FOnlineSessionV2AccelBytePtr SessionInterface;
    if (!ensure(FOnlineSessionV2AccelByte::GetFromWorld(GetWorld(), SessionInterface)))
    {
    return;
    }
  2. サーバーへのセッション割り当てをマークするイベント OnServerReceivedSession をリッスンします。

    const FOnServerReceivedSessionDelegate OnServerReceivedSessionDelegate =
    FOnServerReceivedSessionDelegate::CreateUObject(
    this, &MyClass::OnServerReceivedSession);
    FDelegateHandle OnServerReceivedSessionDelegateHandle =
    SessionInterface->AddOnServerReceivedSessionDelegate_Handle(
    OnServerReceivedSessionDelegate);
  3. RegisterServer メソッドを呼び出します。

    const FOnRegisterServerComplete OnRegisterServerCompleteDelegate =
    FOnRegisterServerComplete::CreateUObject(
    this, &MyClass::OnRegisterServerComplete);
    SessionInterface->RegisterServer(SessionName, OnRegisterServerCompleteDelegate);
  4. OnServerReceivedSession のデリゲートハンドラ内では、ゲームクライアントと同じ方法でセッションを取得できます。まず、セッションインターフェイスをもう一度取得し、それからセッションを取得します。

    // Here `SessionName` is a param to the session received delegate
    FNamedOnlineSession* Session = SessionInterface->GetNamedSession(SessionName);
    if (!ensure(Session != nullptr))
    {
    return;
    }
  5. サーバーがセッション設定およびデータとやり取りできるようになります。

  6. 一般的に、先ほど使用した FDelegateHandle を使用して、OnServerReceivedSession デリゲートをクリアすることをお勧めします。

バックフィルの有効化と無効化の方法

2 つの方法のいずれかを使用して、マッチのバックフィルを有効にできます。1 つ目の方法は、マッチルールセット内から設定する方法です (ゲームモードに適用可能な場合)。または、専用サーバーから直接バックフィルチケットを作成して送信することもできます。

バックフィルを有効にするには、セッションインターフェイスを取得してから、バックフィルチケットを作成します。

const FOnCreateBackfillTicketComplete OnCreateBackfillTicketCompleteDelegate =
FOnCreateBackfillTicketComplete::CreateUObject(
this, &MyClass::OnCreateBackfillTicketComplete);
SessionInterface->CreateBackfillTicket(
NAME_GameSession, OnCreateBackfillTicketComplete);
注記

オリジナル以外の特定のマッチプールが必要な場合は、このメソッドにマッチプール名を指定することもできます。

バックフィルを無効にするには、バックフィルチケットを削除します。

const FOnDeleteBackfillTicketComplete OnDeleteBackfillTicketCompleteDelegate =
FOnDeleteBackfillTicketComplete::CreateUObject(
this, &MyClass::OnDeleteBackfillTicketComplete);
SessionInterface->DeleteBackfillTicket(
NAME_GameSession, OnDeleteBackfillTicketCompleteDelegate);

バックフィル提案の処理方法

マッチルールセットで自動バックフィルが設定されているために、またはサーバーから直接リクエストされたためにセッションのバックフィルがリクエストされた場合、ゲームセッションに追加のプレイヤー用のオープンスポットがあれば、サーバーは提案の受信を開始します。

マッチメイキングのバックフィル提案は DS に送信され、そこで承諾または拒否されます。サーバーを登録する前に、バックフィル提案を受信するためのデリゲートハンドラを追加します。

FOnBackfillProposalReceivedDelegate OnBackfillProposalReceivedDelegate =
FOnBackfillProposalReceivedDelegate::CreateUObject(
this, &MyClass::OnBackfillProposalReceived);
FDelegateHandle OnBackfillProposalReceivedDelegateHandle =
SessionInterface->AddOnBackfillProposalReceivedDelegate_Handle(
OnBackfillProposalReceivedDelegate);

そのハンドラ内で、提案を承諾するか拒否するかを決定できます。まず、セッションインターフェイスを取得します。それから、決定ロジックを経て、提案を承諾するか拒否します。以下は、承諾する場合の例です。

FOnAcceptBackfillProposalComplete OnAcceptBackfillProposalCompleteDelegate =
FOnAcceptBackfillProposalComplete::CreateUObject(
this, &MyClass::OnAcceptBackfillProposalComplete);
SessionInterface->AcceptBackfillProposal(
NAME_GameSession, Proposal, false, OnAcceptBackfillProposalCompleteDelegate)

以下は、拒否する場合の例です。

FOnRejectBackfillProposalComplete OnRejectBackfillProposalCompleteDelegate = 
FOnRejectBackfillProposalComplete::CreateUObject(
this, &MyClass::OnRejectBackfillProposalComplete);
SessionInterface->RejectBackfillProposal(
NAME_GameSession, Proposal, false, OnRejectBackfillProposalCompleteDelegate);
注記

これらの承諾メソッドと拒否メソッド両方の 3 番目の引数は、セッションインターフェイスにバックフィルを停止するかどうかを伝えるブール値です。例では、それぞれのメソッドに false 引数が渡されるため、拒否または承諾後もバックフィル提案を受け取ることになります。

例:バックフィルチケット ID の取得

auto_backfill マッチルールセット設定が有効になっていて、マッチメイキングプロセスでゲームが満員でない場合、セッションが作成される前にバックフィルチケットが生成されます。結果として、セッションを受信すると、DS は必要に応じて、送られてくるマッチで自動バックフィルが行われるかどうかを示すバックフィルチケット ID の存在を確認できます。

const FNamedOnlineSession* Session =
SessionInterface->GetNamedSession(NAME_GameSession);
if (!ensure(Session != nullptr))
{
return;
}

const TSharedPtr<FOnlineSessionInfoAccelByteV2> SessionInfo =
StaticCastSharedPtr<FOnlineSessionInfoAccelByteV2>(Session->SessionInfo);
if (!ensure(SessionInfo.IsValid()))
{
return;
}

const TSharedPtr<FAccelByteModelsV2GameSession> SessionData =
SessionInfo->GetBackendSessionDataAsGameSession();
if (!ensure(SessionData.IsValid()))
{
return;
}

const bool bIsBackfillEnabled = !SessionData->BackfillTicketID.IsEmpty();

トラブルシューティング

このセクションには、サービス使用時に発生しうる一般的なエラーや問題、およびそれらを解決する方法についての推奨事項を記載しています。

バージョンの競合によりセッションの更新に失敗する

現在、DS はセッションの更新を自動的に受信しないようになっているので、サーバーがセッションを更新しようとして問題が発生する可能性があります。DS 側のセッションデータが古くなった場合、セッションを更新するとバージョン競合エラーが発生する可能性があります。UpdateSession 呼び出し時に記録されたエラーメッセージからこの種類のエラーを検出することは可能ですが、この特定のケースではエラーデリゲートを使用することもできます。

FOnSessionUpdateConflictErrorDelegate OnSessionUpdateConflictErrorDelegate =
FOnSessionUpdateConflictErrorDelegate::CreateUObject(
this, &MyClass::OnSessionUpdateConflictError);
SessionInterface->AddOnSessionUpdateConflictErrorDelegate_Handle(
OnSessionUpdateConflictErrorDelegate);

セッションサービスまたは AccelByte OSS には、競合が発生した場合にどのセッション設定を更新するか判断するための実際の汎用的な解決策がないため、上記のデリゲートを使用して更新を再試行したり、競合を解決するためのロジックを格納したりしてください。

注記

更新に失敗すると、セッションデータはバックエンドから自動的に更新され、競合エラーデリゲートは失敗した更新に渡されるセッション設定のコピーを受け取ります。