> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Matchmaking SDK quickstart

> PlayFab Multiplayer SDK のマッチメイキング クライアント フローのクイックスタート チュートリアル: ライブラリを初期化し、チケットを送信して、マッチ結果を受け取ります。

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

このチュートリアルでは、ゲームを見つけるために特定のキューにチケットを送信する方法を示します。キューは通常、1 つのゲーム モードまたは複数のゲーム モードに対応します (例: 同じキュー内での capture the flag モードと king of the hill モード)。

マッチメイキング サービスは、キュー内のチケット間でのマッチの発見を処理します。マッチが見つかったら、タイトルはプレイヤー同士をゲームプレイのために接続する処理を行う必要があります。

<Note>
  PlayFab Multiplayer SDK は PlayFab ロビー用の API も提供します。\* C++ API の詳細については、[Lobby SDK クイックスタート](/services/playfab/multiplayer/lobby/lobby-getting-started) を参照してください。\* Unity API の詳細については、[Unity 向けクイックスタート](/services/playfab/multiplayer/lobby/lobby-matchmaking-sdks/multiplayer-unity-sdk-getting-started) を参照してください。\* Unreal API の詳細については、[Unreal 向けクイックスタート](/services/playfab/multiplayer/networking/party-unreal-engine-oss-quickstart) を参照してください。
</Note>

## 前提条件

PlayFab マッチメイキングを使用するには、[PlayFab アカウント](https://developer.playfab.com) が必要です。アカウントの作成方法については、[クイックスタート: Game Manager](/services/playfab/live-service-management/gamemanager/quickstart) を参照してください。

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

ライブラリは、Game Manager で構成されたキューに対してチケットを作成するユーザー同士をマッチします。設定方法の詳細については、[マッチメイキング キューの構成](/services/playfab/multiplayer/matchmaking/config-queues) を参照してください。

## PlayFab Multiplayer SDK をダウンロードしてセットアップする

プラットフォーム向けの [C/C++ SDK](/services/playfab/multiplayer/lobby/lobby-matchmaking-sdks/lobby-matchmaking-sdks) をダウンロードし、プロバイダーのヘッダーとライブラリ ファイルをビルドに統合します。

<Note>
  このクイックスタートは C/C++ SDK の使用に焦点を当てています。Unity および Unreal のインターフェースについては、以下の記事を参照してください: \* [Unity 向けクイックスタート](/services/playfab/multiplayer/lobby/lobby-matchmaking-sdks/multiplayer-unity-sdk-getting-started) \* [Unreal 向けクイックスタート](/services/playfab/multiplayer/networking/party-unreal-engine-oss-quickstart)
</Note>

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

PlayFab Lobby SDK を使用するには、PlayFab のエンティティ キーとエンティティ トークンを使ってクライアントを認証する必要があります。[LoginWithCustomId](https://learn.microsoft.com/en-us/rest/api/playfab/client/authentication/login-with-custom-id) REST API を使用してログインし、PlayFab のエンティティ キーとトークンのペアを取得します。この API は、[PlayFab REST SDK](/services/playfab/sdks/playfab-sdk-intro) を介して C/C++ プロジェクションとしても利用可能です。

<Note>
  LoginWithCustomId は PlayFab の機能を素早く試すための方法ですが、出荷時のログイン メカニズムとして意図されたものではありません。ログインのガイダンスについては、[ログインの基本とベスト プラクティス](/services/playfab/identity/player-identity/login/login-basics-best-practices) を参照してください。
</Note>

## PlayFab Multiplayer SDK を初期化する

以下の基本ステップに従って、PlayFab Multiplayer SDK を初期化します。

1. [PFMultiplayerInitialize](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmultiplayer/functions/pfmultiplayerinitialize) を呼び出して SDK を初期化します。
2. [PFMultiplayerSetEntityToken](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmultiplayer/functions/pfmultiplayersetentitytoken) を呼び出して、ライブラリがプレイヤーに代わって使用するエンティティ キーとトークンを設定します。

```cpp theme={null}
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](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayercreatematchmakingticket) を使用してマッチメイキング チケットを作成し、マッチの一部となるすべてのローカル ユーザーと、それらのユーザーに関連付けたい属性を指定します。

この関数は [PFMatchmakingTicketConfiguration](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/structs/pfmatchmakingticketconfiguration) も受け取ります。ここで、チケットがどのキューを対象としているか、チケットのタイムアウト、およびこのチケットにマッチさせたいリモート ユーザーを指定します。

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

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

```cpp theme={null}
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 つのクライアントをリーダーと考えると便利です。リーダーは、**configuration** パラメーターを通じてグループ内の他のユーザーを指定して、**PFMultiplayerCreateMatchmakingTicket** を使用してチケットを作成します。チケットが作成されたら、**GetTicketId** を呼び出してチケット ID を取得します。この ID をネットワーキング メッシュや共有 PlayFab Lobby などの外部メカニズムを介して他の各ユーザーに送り、各クライアントはチケット ID を指定して **PFMultiplayerJoinMatchmakingTicketFromId** を呼び出してマッチメイキング チケットに参加します。指定されたプレイヤーが参加するのを待っている間、チケット ステータスは **PFMatchmakingTicketStatus::WaitingForPlayers** となり、すべてのプレイヤーがチケットに参加したら **PFMatchmakingTicketStatus::WaitingForMatch** に変わります。

```cpp theme={null}
// 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);
```

```cpp theme={null}
// 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);
```

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

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

```cpp theme={null}
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](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayerstartprocessingmatchmakingstatechanges) を呼び出して状態変更を受信し、それらの状態変更の処理が終わったら [PFMultiplayerFinishProcessingMatchmakingStateChanges](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayerfinishprocessingmatchmakingstatechanges) を呼び出す必要があります。

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

### マッチメイキング クライアント SDK を使用した例

```cpp theme={null}
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](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmatchmakingticketgetmatch) を呼び出してマッチの詳細を取得します。これらの詳細には、マッチ ID、マッチした状態のユーザー、そのマッチに推奨されるリージョン、およびマッチに関連付けられたロビーの arrangement string が含まれます。

**PFMatchmakingMatchDetails** 構造体から必要な情報を取得したら、[PFMultiplayerDestroyMatchmakingTicket](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayerdestroymatchmakingticket) でチケットを破棄する必要があります。

### マッチメイキング クライアント SDK を使用した例

```cpp theme={null}
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](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmatchmakingticketcancel) を呼び出します。

この API を呼び出しても、チケットがキャンセルされることは保証されません。キャンセルが処理される前にチケットが完了する場合や、ネットワークやサービスのエラーによりキャンセル要求が失敗する場合があります。次に進む前にチケットのキャンセルが完了したことを確認したい場合は、引き続きマッチメイキングの状態変更を処理してチケットの結果を取得できます。それ以外の場合は、即座に [PFMultiplayerDestroyMatchmakingTicket](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayerdestroymatchmakingticket) を呼び出すことができます。

### マッチメイキング クライアント SDK を使用した例

```cpp theme={null}
HRESULT hr = PFMatchmakingTicketCancel(ticket);

PFMultiplayerDestroyMatchmakingTicket(g_pfmHandle, ticket);
```

## (任意) プレイヤー同士を Lobby に接続する

プレイヤーがマッチした後、それらをロビーに集めることができます。マッチしたチケットの **PFMatchmakingMatchDetails** には **lobbyArrangementString** フィールドが含まれており、これを使用してユーザーを同じ Lobby に参加させることができます。

Lobby と Matchmaking を組み合わせて使用する方法の詳細については、[Lobby と Matchmaking を組み合わせて使用する](/services/playfab/multiplayer/lobby/lobby-and-matchmaking) を参照してください。

PlayFab ロビーの詳細については、[PlayFab Lobby の概要](/services/playfab/multiplayer/lobby) を参照してください。

### マッチメイキング クライアント SDK を使用した例

```cpp theme={null}
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));
```

## まとめ

このクイックスタートを使用することで、ゲームでマッチメイキング フローを成功させられるようになりました。加えて、以下の点を検討してください。

* タイトルがグループ形成をどのように処理するか。
* ユーザーがマッチを待つ間、タイトルに何を表示するか。
* 失敗と再試行の処理方法。

## 関連項目

* [Lobby SDK](/services/playfab/multiplayer/lobby/lobby-getting-started)


## Related topics

- [Matchmaking quickstart](/ja-jp/services/playfab/multiplayer/matchmaking/quickstart.md)
- [PlayFab Lobby and Matchmaking SDK](/ja-jp/services/playfab/multiplayer/lobby/lobby-matchmaking-sdks/lobby-matchmaking-sdks.md)
- [Lobby and Matchmaking C++ SDK エラーの処理](/ja-jp/services/playfab/multiplayer/lobby/lobby-and-matchmaking-client-sdk-errors.md)
- [非同期 Lobby and Matchmaking C++ SDK 操作ガイド](/ja-jp/services/playfab/multiplayer/lobby/lobby-and-matchmaking-client-sdk-async.md)
- [PlayFab Lobby and Matchmaking SDK の診断トレース](/ja-jp/services/playfab/multiplayer/lobby/lobby-matchmaking-sdks/lobby-matchmaking-logging.md)
