> ## 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.

# ロビーの検索

> 検索可能なプロパティ、メンバー数、距離ベースの並べ替えに基づいてフィルターおよびソート文字列を使い、公開の PlayFab Lobby を検索してロビーを発見します。

タイトルは、マップや難易度など、その他のゲーム内の要素を含む特定の条件を満たすロビーをプレイヤーが見つけられるようにすると便利なことがよくあります。この検索機能により、プレイヤーは望むメンバーとともに望むゲーム セッションを見つけられます。

この記事では、**FindLobbies** を使用してプレイヤーがロビーを見つけられるようにする方法について説明します。**FindLobbies** がゲーム タイトルでどのように利用されるかについては、[一般的なシナリオ](#common-scenarios) を参照してください。

<Note>
  **FindLobbies** をバックグラウンド マッチメイキングの実装に使用することは推奨されません。そのシナリオでは [マッチメイキング機能](/services/playfab/multiplayer/matchmaking) の使用を強く推奨します。それ以外の場合、フィルタリング、ソート、および検索データ フィールドでランダム化値を使うなどの技術を通じて、同じロビーに参加しようとするプレイヤー間の衝突を処理する必要があります。
</Note>

## ロビー検索プロパティとロビー検索の関係を理解する

プレイヤーは検索プロパティを定義することで、自分のロビーを発見可能にします。プレイヤーは、現在アクティブなロビー全体で定義されている検索プロパティに基づいて検索結果をフィルターおよびソートするクエリ文字列を指定して **FindLobbies** を呼び出し、これらの発見可能なロビーを見つけます。これらのクエリに一致するロビーが呼び出し元のプレイヤーに返されます。

検索プロパティの定義の詳細については、[検索可能なロビーの作成](/services/playfab/multiplayer/lobby/define-search-keywords) を参照してください。

## FindLobbies の使用方法

**FindLobbies** を呼び出す際、filter パラメーターを使用して、ロビーのカスタム検索プロパティに基づく特定の基準に一致する検索結果のみを返すようクエリを制限できます。

さらに、sorting パラメーターを使用して、サービスから返される結果を検索プロパティに基づいて並べ替えられます。サービスは限られた数の検索結果のみを返すため、これは便利です。並べ替えることで、最も関連性の高い検索結果が確実に得られます。

### 一般的なシナリオ

タイトルで **FindLobbies** 機能が使用される一般的な方法をいくつか示します。

* タイトルの特定のゲーム モード向けのゲーム セッションのロビーを検索する
* フレンドがホストしているゲーム セッションのロビーを検索する
* ローカル プレイヤー全員が参加できる十分な人数のゲーム セッションのロビーを検索する
* 予期しないゲーム クライアントやゲーム サーバーのクラッシュ後に接続を回復するために、すでに参加しているロビーを検索する

### サポートされる検索キー

カスタム検索プロパティを定義する際に使用できるキーは制限されたセットのみです。

* 文字列プロパティの場合、次のキーがサポートされます: string\_key1、string\_key2、\[...] string\_key30
* 数値プロパティの場合、次のキーがサポートされます: number\_key1、number\_key2、\[...] number\_key30

### FindLobbies 用のクエリ文字列の構築

**FindLobbies** API のクエリ文字列は OData ライクな構文で構成されます。フィルター文字列の最大サイズは 600 文字です。

クエリ文字列の構成には、これらの OData 演算子を使用できます。演算子は大文字と小文字を区別します。

| 演算子 | 意味    | 例                                                       |
| --- | ----- | ------------------------------------------------------- |
| eq  | 等しい   | string\_key1 eq 'CaptureTheFlag'                        |
| lt  | より小さい | number\_key2 lt 10                                      |
| le  | 以下    | number\_key2 le 10                                      |
| gt  | より大きい | number\_key3 gt 100                                     |
| ge  | 以上    | number\_key3 ge 100                                     |
| ne  | 等しくない | string\_key1 ne 'CaptureTheFlag'                        |
| and | かつ    | string\_key1 eq 'CaptureTheFlag' and number\_key2 lt 10 |

<Note>
  文字列プロパティを比較する場合、比較する値を必ずシングル クォートで囲んでください。例: 「string\_key1 eq **'SOME STRING VALUE'**」。数値プロパティは囲む必要はありません。
</Note>

事前定義された演算子も使用できます。指定する際は「lobby/」というプレフィックスを付ける必要があります。

| 演算子                  | 意味                                                | 例                                  |
| -------------------- | ------------------------------------------------- | ---------------------------------- |
| memberCount          | ロビー内のプレイヤー数                                       | lobby/memberCount eq 5             |
| maxMemberCount       | ロビーで許可される最大プレイヤー数                                 | lobby/maxMemberCount gt 10         |
| memberCountRemaining | ロビーに参加できる残りのプレイヤー数                                | lobby/memberCountRemaining gt 0    |
| membershipLock       | ロビーのロック ステータス。'Unlocked' または 'Locked' に等しい必要があります | lobby/membershipLock eq 'Unlocked' |
| amOwner              | 自分がオーナーのロビー。'true' に等しい必要があります                    | lobby/amOwner eq 'true'            |
| amMember             | 自分がメンバーのロビー。'true' に等しい必要があります                    | lobby/amMember eq 'true'           |
| amServer             | サーバーがクライアント所有ロビーに参加しているロビー。'true' に等しい必要があります     | lobby/amServer eq 'true'           |

これらの定数の SDK 定義は [こちら](/services/playfab/multiplayer/lobby/playfabmultiplayerreference-cpp/pflobby/constants/pflobbysearchkeys) に記載されています。

### 並べ替え

このクエリに対する並べ替えを昇順 (「asc」) または降順 (「desc」) で含む OData スタイルの文字列。OrderBy 句は、任意の検索用数値キーまたは数値である事前定義された検索キーに対して使用できます。指定した数値に最も近いものでソートするには、distance モニカーを使用して、指定した数値検索キーからの距離でソートできます。distance ソートに ascending や descending は使用できません。このフィールドは 1 つの sort 句または 1 つの distance 句のいずれか一方のみをサポートします。sort が指定されない場合や、指定された sort でタイブレークが必要な場合、既定のソートは作成時刻の降順になります。

| 例                           | 意味               |
| --------------------------- | ---------------- |
| number\_key1 asc            | 数値検索キーで昇順に並べ替え   |
| lobby/memberCount desc      | 数値検索キーで降順に並べ替え   |
| distance\{number\_key1 = 5} | 指定した数値からの距離で並べ替え |
| *既定*                        | 作成時刻の降順で並べ替え     |

## Lobby and Matchmaking SDK を使用してロビーを検索する例

この例では、プレイヤーは次の要件を満たすすべてのロビーを探したいとします。

* ゲーム モードが "DeathMatch"
* 競技スタイルが "Ranked"
* プレイヤーのスキル レベルがロビーの最小および最大スキル制限内にある

さらに、プレイヤーは以下のガイドラインに従って結果をソートしたいと考えています:

* プレイヤーのスキル レベルに最も近い最適スキル レベルのロビーが上位に来るようにソートする

```cpp theme={null}
static PFMultiplayerHandle g_pfmHandle = nullptr;

#define SUPPORT_XBL_CROSSPLAY

#define PFLOBBY_SEARCH_KEY_GAME_MODE "string_key1"
#define PFLOBBY_SEARCH_KEY_COMPETITION_STYLE "string_key2"
#define PFLOBBY_SEARCH_KEY_SKILL "number_key1"

#define GAME_MODE_DEATH_MATCH "DeathMatch"
#define COMPETITION_STYLE_RANKED "Ranked"

// Find lobbies based on player's search criteria.
void FindGamesWithRuntimeQuery(
    uint32_t minimumSkill,
    uint32_t maximumSkill,
    uint32_t optimalSkill)
{
    PFLobbySearchFriendsFilter friendsFilter;
    friendsFilter.includeSteamFriends = true;
#ifdef SUPPORT_XBL_CROSSPLAY
    friendsFilter.includeXboxFriendsToken = MyGame::GetLocalUserXboxToken();
#endif // SUPPORT_XBL_CROSSPLAY

    // Limit results based on friend's filter.
    PFLobbySearchConfiguration searchConfiguration = { 0 };
    searchConfiguration.friendsFilter = &friendsFilter;

    // Create filter string based on player's search parameters.
    std::string filterString;
    filterString += PFLOBBY_SEARCH_KEY_GAME_MODE + std::string(" eq ") + "'" + GAME_MODE_DEATH_MATCH + "'";
    filterString += " and ";
    filterString += PFLOBBY_SEARCH_KEY_COMPETITION_STYLE + std::string(" eq ") + "'" + COMPETITION_STYLE_RANKED + "'";
    filterString += " and ";
    filterString += PFLOBBY_SEARCH_KEY_SKILL + std::string(" ge ") + std::to_string(minimumSkill);
    filterString += " and ";
    filterString += PFLOBBY_SEARCH_KEY_SKILL + std::string(" le ") + std::to_string(maximumSkill);

    // Create sort string based on player's sort preference.
    std::string sortString;
    sortString += std::string("distance{") + PFLOBBY_SEARCH_KEY_SKILL + "=" + std::to_string(optimalSkill) + "}";

    searchConfiguration.filterString = filterString.c_str();
    searchConfiguration.sortString = sortString.c_str();

    HRESULT hr = PFMultiplayerFindLobbies(g_pfmHandle, &m_localUser, &searchConfiguration, nullptr);
}

void ProcessStateChanges()
{
    while (true)
    {
        uint32_t stateChangeCount;
        const PFLobbyStateChange* const* stateChanges;
        RETURN_VOID_IF_FAILED(PFMultiplayerStartProcessingLobbyStateChanges(
            g_pfmHandle,
            &stateChangeCount,
            &stateChanges));

        for (uint32_t i = 0; i < stateChangeCount; ++i)
        {
            const PFLobbyStateChange* stateChange = stateChanges[i];
            switch (stateChange->stateChangeType)
            {
                case PFLobbyStateChangeType::FindLobbiesCompleted:
                {
                    GuiPostCurrentLobbySearchResults(
                        static_cast<const PFLobbyFindLobbiesCompletedStateChange&>(*stateChange));
                    break;
                }
                default:
                {
                    break;
                }
            }
        }

        RETURN_VOID_IF_FAILED(PFMultiplayerFinishProcessingLobbyStateChanges(
            g_pfmHandle,
            stateChangeCount,
            stateChanges));
    }
}

// Update game UI to display search results when a list of matching lobbies is returned.
void GuiPostCurrentLobbySearchResults(
    const PFLobbyFindLobbiesCompletedStateChange& stateChange)
{
    if (FAILED(stateChange.result))
    {
        GuiToastErrorAndExitScreen();
        return;
    }

    for (uint32_t i = 0; i < stateChange.searchResultCount; ++i)
    {
        const PFLobbySearchResult& searchResult = stateChange.searchResults[i];
        GuiPostLobbySearchResultRow(searchResult); // defined elsewhere
    }
}
```

## 関連項目

* [検索可能なロビーの作成](/services/playfab/multiplayer/lobby/define-search-keywords)
* [ロビーへの参加](/services/playfab/multiplayer/lobby/join-lobbies)
* [ロビーとマッチメイキング](/services/playfab/multiplayer/lobby/lobby-and-matchmaking)
* [ロビーのプロパティ](/services/playfab/multiplayer/lobby/lobby-properties)
* [ロビーの作成](/services/playfab/multiplayer/lobby/create-a-lobby)


## Related topics

- [MPSD から PlayFab Multiplayer と MPA への移行](/ja-jp/services/xbox-services/multiplayer/mpsd/concepts/live-mpsd-to-mlp.md)
- [検索可能なロビーの作成](/ja-jp/services/playfab/multiplayer/lobby/define-search-keywords.md)
- [ロビーの招待](/ja-jp/services/playfab/multiplayer/lobby/lobby-invites.md)
- [ロビーへの参加](/ja-jp/services/playfab/multiplayer/lobby/join-lobbies.md)
- [ロビーの有効期間と有効期限](/ja-jp/services/playfab/multiplayer/lobby/lobby-ttl.md)
