로비 관련 쿼리

플레이어는 쿼리 API를 사용하여 자신이 참여하고 싶은 공개 로비를 찾을 수 있습니다. 플레이어가 로비를 둘러보고 공개 로비 정보를 볼 수 있습니다. 로비마다 있는 자체 메타데이터에는 로비 이름, 프로젝트 ID, 최대 플레이어 수, 플레이어 목록이 포함되어 있습니다. 또한 게임 개발자는 커스텀 메타데이터를 추가하여 게임에 고유한 특정 데이터 유형(예: 맵 ID)을 더할 수 있습니다. 로비에 참여하지 않은 플레이어는 공개로 설정된 커스텀 데이터만 볼 수 있습니다.

로비 정렬

쿼리 API에 따라 반환되는 로비의 정렬 순서는 플레이어가 지정할 수 있습니다. 예를 들어 가장 최근에 만들어진 로비만 보고 싶은 플레이어의 경우 로비 생성 시간별로 정렬할 수 있습니다.

로비 필터링

플레이어는 쿼리 API를 사용할 때 하나 이상의 필터를 지정하여 입력한 파라미터에 해당하는 로비만 볼 수 있습니다. 예를 들어 플레이어는 로비 이름, 최대 로비 크기, 사용 가능한 플레이어 슬롯, 생성일별로 필터링하거나 게임 유형, 지도, 레벨 요구 사항 등 커스텀 데이터를 사용해 필터링할 수 있습니다. 필터링은 내 프로젝트와 환경에서만 할 수 있습니다.

다음 코드 샘플은 로비를 필터링하는 방법을 보여 줍니다.

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

커스텀 데이터로 필터링

로비에는 커스텀 문자열 필드(S1-S5) 5개와 커스텀 숫자 필드(N1-N5) 5개가 포함되어 있으며 이를 쿼리에 사용할 수 있습니다. 이렇게 하면 로비를 둘러보는 플레이어의 경험을 커스터마이즈할 수 있습니다. 예컨대 게임에서 플레이어가 모드, 맵, 영역, 기술별로 필터링할 수 있습니다.

다음 코드 샘플은 커스텀 데이터로 필터링하는 방법을 보여 줍니다.

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;
        }