ロビーに対するクエリ

プレイヤーは、クエリ API を使用して、参加したい Public ロビーを検出できます。ロビーを参照し、パブリック情報を表示できます。各ロビーに固有のメタデータがあります。これには、ロビー名、プロジェクト ID、最大プレイヤー数、プレイヤーのリストが含まれます。ゲーム開発者は、カスタムメタデータを追加して、マップ ID など、ゲームに固有の特定のタイプのデータを追加することもできます。ロビーに参加していないプレイヤーが表示できるのは、パブリックの可視性に設定されているカスタムデータだけです。

ロビーのソート

プレイヤーは、クエリ API によって返されるロビーのソート順を指定できます。例えば、プレイヤーが最後に作成したロビーのみを表示したい場合は、ロビーを作成時刻でソートできます。

ロビーのフィルタリング

プレイヤーは、クエリ API を使用してパラメーターに適合するロビーのみを表示するときに、1 つ以上のフィルターを指定できます。例えば、プレイヤーはロビー名、最大ロビーサイズ、使用可能なプレイヤースロット、作成時刻でフィルタリングしたり、ゲームタイプ、マップ、レベル要件などのカスタムデータを使用してフィルタリングしたりできます。独自のプロジェクトと環境内でのみフィルタリングできます。

以下のコードサンプルは、ロビーのフィルタリング方法を示しています。

C#

try
{
    QueryLobbiesOptions options = new QueryLobbiesOptions();
    options.Count = 25;

    // Filter for open lobbies only
    options.Filters = new List<QueryFilter>()
    {
        new QueryFilter(
            field: QueryFilter.FieldOptions.AvailableSlots,
            op: QueryFilter.OpOptions.GT,
            value: "0")
    };

    // Order by newest lobbies first
    options.Order = new List<QueryOrder>()
    {
        new QueryOrder(
            asc: false,
            field: QueryOrder.FieldOptions.Created)
    };

    QueryResponse lobbies = await Lobbies.Instance.QueryLobbiesAsync(options);

    //...
}
catch (LobbyServiceException e)
{
    Debug.Log(e);
}

カスタムデータでのフィルタリング

ロビーには、クエリに使用できる 5 つのカスタム 文字列 フィールド (S1 - S5) と 5 つのカスタム 数値 フィールド (N1 - N5) があります。これは、プレイヤーのロビー参照体験をカスタマイズするのに役立ちます。例えば、ゲームでプレイヤーがモード、マップ、地域、スキルでフィルタリングできるようにすることができます。

以下のコードサンプルは、カスタムデータのフィルタリング方法を示しています。

C#

// Creating a custom indexed string property to be used as lobby data
var lobbyData = new Dictionary<string, DataObject>
{
    {
        "GameMode", new DataObject(
            visibility: DataObject.VisibilityOptions.Public,
            value: "Conquest",
            index: DataObject.IndexOptions.S1)
    }
};

// ... set the lobby data ...

// Create query filter for the custom data that was set above
var queryFilter = new List<QueryFilter>()
{
    new QueryFilter(
        field: QueryFilter.FieldOptions.S1,
        op: QueryFilter.OpOptions.EQ,
        value: "Conquest")
};

ランダム化されたクエリ結果

同じクエリフィルターを持つ複数のプレイヤーが同時にロビーをクエリし、リクエストされた数よりも多くの結果が使用可能な場合、Lobby サービスはランダム化されたサンプリングを使用して異なるクエリ結果を返します。これは、競合を最小化し、ロビー間にプレイヤーを均等に分散して、できるだけ早くゲームを開始できるようにするのに役立ちます。これにより、複数のプレイヤーが類似するゲームに接続しようとしている場合に、ロード時間が短縮され、ゲームへの接続が促進されます。

ランダム化されたサンプリングにより、プレイヤーがクエリの実行後に満員になったロビーに参加しようとすることにつながる、同じ検索条件を持つプレイヤーに同じクエリ結果が表示されることがなくなります。ただし、プレイヤーがすでに満員のロビーに参加しようとする潜在的な競合状態は常に存在します。クライアントロジックでは、この状況の発生を予想し、ロビー参加の失敗を適切に処理するよう計画する必要があります。

ページ処理

クライアントは、クエリ結果をランダム化しないことを選択することもできます。この場合、結果をページ処理できます。ランダム化されていない結果に対してクエリを実行すると、レスポンスに継続トークンが返されます。このトークンを後続のクエリに提供して、結果の次のページをフェッチできます。次のページのロビー数が 0 の場合でも、継続トークンは提供されることに注意してください。

以下のコードサンプルは、継続トークンを使用するための基本パターンを示しています。

C#

// Common query options to use for paging
        var queryOptions = new QueryLobbiesOptions
        {
            SampleResults = false, // Paging cannot use randomized results
            Filters = new List<QueryFilter>
                    {
                        // Only include open lobbies in the pages
                        new QueryFilter(
                            field: QueryFilter.FieldOptions.AvailableSlots,
                            op: QueryFilter.OpOptions.GT,
                            value: "0")
                    },
            Order = new List<QueryOrder>
                    {
                        // Show the oldest lobbies first
                        new QueryOrder(true, QueryOrder.FieldOptions.Created),
                    }
        };

        var response = await LobbyService.Instance.QueryLobbiesAsync(queryOptions);
        var lobbies = response.Results;

        // A continuation token will still be returned when the next page is empty,
        // so continue paging until there are no new lobbies in the response
        while (lobbies.Count > 0)
        {
            // Do something here with the lobbies in the current page

            // Get the next page. Be careful not to modify the filter or order in the
            // query options, as this will return an error
            queryOptions.ContinuationToken = response.ContinuationToken;
            response = await LobbyService.Instance.QueryLobbiesAsync(queryOptions);
            lobbies = response.Results;
        }