> ## 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를 사용하여 게임에 매치메이킹을 추가하기 위한 전체 과정을 안내합니다.

이 자습서는 게임을 찾기 위해 특정 큐에 티켓을 제출하는 방법을 설명합니다. 큐는 일반적으로 하나 이상의 게임 모드(예: 같은 큐 안의 깃발 뺏기 모드와 킹 오브 더 힐 모드)에 매핑됩니다.

매치메이킹 서비스는 큐 내 티켓들 사이에서 매치를 찾는 일을 처리합니다. 매치가 발견되면 타이틀은 게임 플레이를 위해 플레이어들을 서로 연결하는 것을 처리해야 합니다.

<Note>
  PlayFab Multiplayer SDK는 PlayFab Lobbies용 API도 제공합니다. \* C++ API에 대한 자세한 내용은 [Lobby SDK quickstart](/services/playfab/multiplayer/lobby/lobby-getting-started)를 참조하세요. \* Unity API에 대한 자세한 내용은 [Quickstart for Unity](/services/playfab/multiplayer/lobby/lobby-matchmaking-sdks/multiplayer-unity-sdk-getting-started)를 참조하세요. \* Unreal API에 대한 자세한 내용은 [Quickstart for Unreal](/services/playfab/multiplayer/networking/party-unreal-engine-oss-quickstart)을 참조하세요.
</Note>

## 사전 요구 사항

PlayFab Matchmaking을 사용하려면 [PlayFab 계정](https://developer.playfab.com)이 필요합니다. 계정 생성 방법은 [Quickstart: Game Manager](/services/playfab/live-service-management/gamemanager/quickstart)를 참조하세요.

## Game Manager에서 매치메이킹 큐 구성

이 라이브러리는 Game Manager에서 구성된 큐에 대한 티켓을 만드는 사용자들을 서로 매칭합니다. 큐 설정 방법에 대한 자세한 내용은 [Configuring matchmaking queues](/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 인터페이스에 대해서는 다음 문서를 참조하세요. \* [Quickstart for Unity](/services/playfab/multiplayer/lobby/lobby-matchmaking-sdks/multiplayer-unity-sdk-getting-started) \* [Quickstart for 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 기능을 빠르게 시작할 수 있는 방법이지만 제품 출시 시 사용할 로그인 메커니즘으로 설계된 것은 아닙니다. 로그인 가이드는 [Login basics and best practices](/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)을 받아 티켓이 대상으로 하는 큐, 티켓의 타임아웃, 이 티켓과 매치되기를 원하는 원격 사용자를 지정합니다.

### 단일 로컬 사용자를 사용한 매치메이킹

**PFMultiplayerCreateMatchmakingTicket** 호출을 통해 단일 로컬 사용자에 대해 매치메이킹을 시작할 수 있습니다.

```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);
```

### 원격 사용자 그룹을 사용한 매치메이킹

원격 사용자와 함께 그룹 매치메이킹을 시작할 때는 한 클라이언트를 리더로 생각하는 것이 유용합니다. 리더가 **PFMultiplayerCreateMatchmakingTicket**을 사용하여 티켓을 만들고 **configuration** 매개 변수를 통해 그룹의 다른 사용자를 지정하도록 합니다. 티켓이 생성된 후에는 **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** 함수에 하나의 **PFEntityKey**를 전달하는 대신 키 목록을 전달해야 합니다. 마찬가지로 각 사용자의 특성 목록도 전달해야 합니다. 각 목록 항목 위치는 서로 대응해야 합니다. 즉, attributes 목록의 첫 번째 항목은 **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** 상태 변경을 반환합니다.

### Matchmaking 클라이언트 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, 함께 매치된 사용자, 매치의 선호 지역, 매치와 연결된 lobby에 대한 arrangement 문자열이 포함됩니다.

**PFMatchmakingMatchDetails** 구조체에서 필요한 정보를 검색한 후에는 [PFMultiplayerDestroyMatchmakingTicket](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pfmatchmaking/functions/pfmultiplayerdestroymatchmakingticket)으로 티켓을 삭제해야 합니다.

### Matchmaking 클라이언트 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)을 호출할 수 있습니다.

### Matchmaking 클라이언트 SDK 사용 예시

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

PFMultiplayerDestroyMatchmakingTicket(g_pfmHandle, ticket);
```

## (선택 사항) 플레이어를 Lobby에 함께 연결

플레이어들이 매치된 후에는 lobby에서 함께 참가할 수 있습니다. 매치된 티켓의 **PFMatchmakingMatchDetails**에는 사용자를 동일한 Lobby에 참가시키는 데 사용할 수 있는 **lobbyArrangementString** 필드가 포함되어 있습니다.

Lobby와 Matchmaking이 함께 상호 작용하는 방식에 대한 자세한 내용은 [Use lobby and matchmaking together](/services/playfab/multiplayer/lobby/lobby-and-matchmaking)를 참조하세요.

PlayFab Lobbies에 대한 자세한 내용은 [PlayFab Lobby Overview](/services/playfab/multiplayer/lobby)를 참조하세요.

### Matchmaking 클라이언트 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](/ko/services/playfab/multiplayer/matchmaking/quickstart.md)
- [PlayFab Lobby 및 Matchmaking SDK](/ko/services/playfab/multiplayer/lobby/lobby-matchmaking-sdks/lobby-matchmaking-sdks.md)
- [Lobby 및 Matchmaking C++ SDK 오류 처리](/ko/services/playfab/multiplayer/lobby/lobby-and-matchmaking-client-sdk-errors.md)
- [PlayFab Lobby 및 Matchmaking SDK의 진단 추적](/ko/services/playfab/multiplayer/lobby/lobby-matchmaking-sdks/lobby-matchmaking-logging.md)
- [비동기 Lobby 및 Matchmaking C++ SDK 작업 가이드](/ko/services/playfab/multiplayer/lobby/lobby-and-matchmaking-client-sdk-async.md)
