マッチメイキング SDK のクイック スタート

このクイック スタート ガイドでは、PlayFab マルチプレイヤー SDK を使用してマッチメイキングをゲームに追加するプロセス全体について説明します。

このチュートリアルでは、ゲームを見つけるために、チケットを特定のキューに送信する方法を説明します。 キューは、ゲーム モードまたは複数のゲーム モードにマッピングされる可能性があります (例: 同じキュー内のフラグ モードのキャプチャとヒル モードのキング)。

マッチメイキング サービスは、キュー内のチケットの中から一致するものを見つける処理を行います。 マッチが見つかった場合、タイトルはゲームプレイのためにプレイヤー同士を結びつけます。

注意

PlayFab マルチプレイヤー SDK には、PlayFab ロビー用の API も用意されています。

前提条件

PlayFab マッチメイキングを使用するには、PlayFab アカウントが必要です。 アカウントを作成する手順については、「クイック スタート: ゲーム マネージャー」を参照してください。

Game Manager でマッチメイキング キューを構成する

ライブラリは、ゲーム マネージャーで構成されたキューのチケットを作成するユーザーを一緒に一致させます。 設定方法の詳細については、「マッチメイキング キューの構成」を参照してください。

PlayFab マルチプレイヤー SDK をダウンロードして設定する

プラットフォーム用の C/C++ SDK をダウンロードし、プロバイダー ヘッダーとライブラリ ファイルをビルドに統合します。

注意

このクイック スタートでは、C/C++ SDK の使用に焦点を当てます。 Unity と Unreal のインターフェイスについては、次の記事を参照してください。

PlayFab エンティティにログインする

PlayFab ロビー SDK を使用するには、PlayFab エンティティ キーとエンティティ トークンを使用してクライアントを認証する必要があります。 LoginWithCustomId REST API を使用してログインすることで、PlayFab エンティティ キーとエンティティ トークンのペアを取得します。 この API は、PlayFab REST SDK を介して C/C++ プロジェクションとしても使用できます。

注意

LoginWithCustomId は、PlayFab 機能を簡単に使い始める方法ですが、付属のログイン メカニズムを意図したものではありません。 ログイン ガイダンスについては、「ログインの基本とベスト プラクティス」を参照してください。

PlayFab マルチプレイヤー SDK を初期化する

次の基本的な手順に従って、PlayFab マルチプレイヤー SDK を初期化します。

  1. PFMultiplayerInitialize を呼び出して SDK を初期化する
  2. PFMultiplayerSetEntityToken を呼び出して、プレイヤーの代わりにライブラリで使用されるエンティティ キーとエンティティ トークンを設定します。
static PFMultiplayerHandle g_pfmHandle = nullptr;
...
...
HRESULT hr = S_OK;

// Initialize the PFMultiplayer library.
hr = PFMultiplayerInitialize(titleId, &g_pfmHandle);
if (FAILED(hr))
{
    // handle initialize failure
}

// Set an entity token for a local user. The token is used to authenticate PlayFab operations on behalf of this user. 
// Tokens can expire, and this API token should be called again when this token is refreshed.
hr = PFMultiplayerSetEntityToken(g_pfmHandle, localUserEntity, entityToken);
if (FAILED(hr))
{
    // handle set entity token failure
}

マッチメイキング チケットを作成する

PFMultiplayerCreateMatchmakingTicket を使用してマッチメイキング チケットを作成します。このチケットでは、一致の一部である必要があるすべてのローカル ユーザーと、これらのユーザーに関連付ける属性を指定します。

また、この関数では PFMatchmakingTicketConfiguration も使用します。ここでは、チケットの対象となるキュー、チケットのタイムアウト、およびこのチケットに一致させるリモート ユーザーを指定します。

1 人のローカル ユーザーとのマッチメイキング

PFMultiplayerCreateMatchmakingTicket を呼び出して、1 人のローカル ユーザーのマッチメイキングを開始できます。

const char* yourQueueName = ...; // This is the name of the queue you configured in Game Manager.

PFMatchmakingTicketConfiguration configuration{};
configuration.timeoutInSeconds = 120;
configuration.queueName = yourQueueName;

const char* attributes = "\"{\"color\":\"blue\", \"role\":\"tank\"}\"";

const PFMatchmakingTicket* ticket;
HRESULT hr = PFMultiplayerCreateMatchmakingTicket(
    g_pfmHandle,
    1, // number of local users
    localUserEntity,
    &attributes,
    &configuration,
    nullptr, // optional asyncContext
    &ticket);
RETURN_IF_FAILED(hr);

リモート ユーザーのグループとのマッチメイキング

リモート ユーザーとのグループ マッチメイキングを開始するには、1 つのクライアントをリーダーと考えると便利です。 PFMultiplayerCreateMatchmakingTicket を使用して、グループ内の他のユーザーを構成パラメーターで指定して、リーダーにチケットを作成してもらいます。 チケットが作成されたら、 GetTicketId を呼び出してチケット ID を取得します。 ネットワーク メッシュや共有 PlayFab ロビーなどの外部メカニズムを介してこの ID を互いのユーザーに送信し、各クライアントに、チケット ID を使用して PFMultiplayerJoinMatchmakingTicketFromId を呼び出してマッチメイキング チケットに参加させます。 チケットの状態は、指定したプレイヤーが参加するのを待っている間は PFMatchmakingTicketStatus::WaitingForPlayers になり、すべてのプレイヤーがチケットに参加すると PFMatchmakingTicketStatus::WaitingForMatch に変更されます。

// Creating the ticket on the leader's client

const char* remoteMemberEntityId1 = ...;
const char* remoteMemberEntityId2 = ...;

std::vector<PFEntityKey> remoteMatchMemberEntityKeys;
remoteMatchMemberEntityKeys.push_back({ remoteMemberEntityId1, "title_player_account" });
remoteMatchMemberEntityKeys.push_back({ remoteMemberEntityId2, "title_player_account" });

const char* yourQueueName = ...; // This is the name of the queue you configured in Game Manager.

PFMatchmakingTicketConfiguration configuration{};
configuration.timeoutInSeconds = 120;
configuration.queueName = yourQueueName;
configuration.membersToMatchWithCount = 2; // number of remote members to match with
configuration.membersToMatchWith = remoteMatchMemberEntityKeys.data();

const char* attributes = "\"{\"color\":\"blue\", \"role\":\"tank\"}\"";

const PFMatchmakingTicket* ticket;
HRESULT hr = PFMultiplayerCreateMatchmakingTicket(
    g_pfmHandle,
    1, // number of local users
    localUserEntity,
    &attributes,
    &configuration,
    nullptr, // optional asyncContext
    &ticket);
RETURN_IF_FAILED(hr);

// Getting the ticket ID

PCSTR ticketId;
hr = PFMatchmakingTicketGetTicketId(ticket, &ticketId);
RETURN_IF_FAILED(hr);
// Joining the ticket on the other players' clients

const char* attributes = "\"{\"color\":\"blue\", \"role\":\"healer\"}\"";
const char* yourQueueName = ...; // This is the name of the queue you configured in Game Manager.

const PFMatchmakingTicket* ticket;
HRESULT hr = PFMultiplayerJoinMatchmakingTicketFromId(
    g_pfmHandle,
    1, // number of local users
    localUserEntity,
    &attributes,
    ticketId,
    yourQueueName,
    nullptr, // optional asyncContext
    &ticket);

複数のローカル ユーザーとのマッチメイキング

複数のローカル ユーザーとマッチメイキングする場合、1 つの PFEntityKeyPFMultiplayerCreateMatchmakingTicket 関数または PFMultiplayerJoinMatchmakingTicketFromId 関数に渡す代わりに、キーのリストを渡す必要があります。 同様に、各ユーザーの属性のリストを渡す必要があります。 各リストエントリの位置は、相互に対応している必要があります。 つまり、属性リストの最初のエントリは、PFEntityKey リスト内の最初のプレイヤーの属性である必要があります。

const char* yourQueueName = ...; // This is the name of the queue you configured in Game Manager.

PFMatchmakingTicketConfiguration configuration{};
configuration.timeoutInSeconds = 120;
configuration.queueName = queueName;

std::vector<PFEntityKey> localMatchMemberEntityKeys{ ... };
std::vector<PCSTR> localMatchMemberAttributes{ ... };

const PFMatchmakingTicket* ticket;
HRESULT hr = PFMultiplayerCreateMatchmakingTicket(
    g_pfmHandle,
    static_cast<uint32_t>(localMatchMemberEntityKeys.size())
    localMatchMemberEntityKeys.data(),
    localMatchMemberAttributes.data(),
    &configuration,
    nullptr, // optional asyncContext
    &ticket);
RETURN_IF_FAILED(hr);

マッチメイキング チケットのステータスを確認する

PFMultiplayerStartProcessingMatchmakingStateChanges を呼び出して状態の変更を受け取り、これらの状態変更の処理が完了したら PFMultiplayerFinishProcessingMatchmakingStateChanges を呼び出して、チケットの更新をチェックする必要があります。

SDK は、チケットの状態が変更されるたびに TicketStatusChanged 状態変更を返し、マッチメイキングが完了したときに TicketCompleted 状態変更を返します。

マッチメイキング クライアント SDK の使用例

HRESULT hrTicketError = S_OK;

uint32_t stateChangeCount;
const PFMatchmakingStateChange * const * stateChanges;
hr = PFMultiplayerStartProcessingMatchmakingStateChanges(g_pfmHandle, &stateChangeCount, &stateChanges);
RETURN_IF_FAILED(hr);

for (uint32_t i = 0; i < stateChangeCount; ++i)
{
    const PFMatchmakingStateChange& stateChange = *stateChanges[i];

    switch (stateChange.stateChangeType)
    {
        case PFMatchmakingStateChangeType::TicketStatusChanged:
        {
            const auto& ticketStatusChanged = static_cast<const PFMatchmakingTicketStatusChangedStateChange&>(stateChange);

            PFMatchmakingTicketStatus status;
            if (SUCCEEDED(PFMatchmakingTicketGetStatus(ticketStatusChanged.ticket, &status)))
            {
                printf("Ticket status is now: %i.\n", status);
            }

            break;
        }
        case PFMatchmakingStateChangeType::TicketCompleted:
        {
            const auto& ticketCompleted = static_cast<const PFMatchmakingTicketCompletedStateChange&>(stateChange);

            printf("PFMatchmaking completed with Result 0x%08x.\n", ticketCompleted.result);

            if (FAILED(ticketCompleted.result))
            {
                // On failure, we must record the HRESULT so we can return the state change(s) and then bail
                // out of this function.
                hrTicketError = ticketCompleted.result;
            }

            break;
        }
    }
}

hr = PFMultiplayerFinishProcessingMatchmakingStateChanges(g_pfmHandle, stateChangeCount, stateChanges);
RETURN_IF_FAILED(hr);

// Now that we've returned the state change(s), bail out if we detected ticket failure.
RETURN_IF_FAILED(hrTicketError);

マッチを取得する

PFMatchmakingStateChangeType::TicketCompleted 状態変更を受け取った後、PFMatchmakingTicketGetMatch を呼び出して一致の詳細を取得します。 これらの詳細には、一致 ID、一緒に一致したユーザー、一致の優先リージョン、一致に関連付けられたロビーの並べ替え文字列が含まれます。

PFMatchmakingMatchDetails 構造体から必要な情報を取得したら、PFMultiplayerDestroyMatchmakingTicket でチケットを破棄する必要があります。

マッチメイキング クライアント SDK の使用例

const PFMatchmakingMatchDetails* match;
HREULT hr = PFMatchmakingTicketGetMatch(ticket, &match);
RETURN_IF_FAILED(hr);

std::string matchId = match->matchId;
std::string lobbyArrangementString = match->lobbyArrangementString;

PFMultiplayerDestroyMatchmakingTicket(g_pfmHandle, ticket);

マッチメイキング チケットのキャンセル

何らかの理由で、PFMatchmakingTicketConfiguration で設定されたタイムアウトの前にクライアントがマッチメイキング プロセスを取り消したい場合は、チケット ハンドルで PFMatchmakingTicketCancel を呼び出します。

この API を呼び出しても、チケットが取り消されることが保証されるわけではありません。 取り消しを処理する前に引き続きチケットが完了する可能性があります。または、ネットワークまたはサービス エラーが原因でキャンセル要求が失敗する可能性があります。 チケットの結果を取得するには、マッチメイキング状態の変更を引き続き処理する必要があります。

マッチメイキング クライアント SDK の使用例

HRESULT hr = PFMatchmakingTicketCancel(ticket);

(省略可能) プレイヤーを一緒にロビーに接続する

プレイヤーが一致したら、ロビーで一緒に参加できます。 一致したチケットの PFMatchmakingMatchDetails には、lobbyArrangementString フィールドが含まれています。これは、ユーザーを同じロビーに参加させるために使用できます。

ロビーとマッチメイキングの相互作用の詳細については、「ロビーとマッチメイキングを一緒に使用する」を参照してください。

PlayFab ロビーの詳細については、「PlayFab ロビーの概要」を参照してください。

マッチメイキング クライアント SDK の使用例

const PFMatchmakingMatchDetails* match;
HREULT hr = PFMatchmakingTicketGetMatch(ticket, &match);
RETURN_IF_FAILED(hr);

std::string matchId = match->matchId;
std::string lobbyArrangementString = match->lobbyArrangementString;

PFMultiplayerDestroyMatchmakingTicket(g_pfmHandle, ticket);

PFLobbyHandle lobby;
RETURN_IF_FAILED_HR(PFMultiplayerJoinArrangedLobby(
    m_pfmHandle,
    &joiningUser,
    lobbyArrangementString,
    &joinConfig,
    nullptr, // optional asyncContext
    &lobby));

まとめ

このクイック スタートを使用して、ゲームで成功したマッチメイキング フローを持つ必要があります。 以下の点について考えます。

  • タイトルがグループ編成を行う方法。
  • ユーザーがマッチを待っている間にタイトルが表示する内容。
  • エラーの処理と再試行を行う方法。

関連項目