Документация Steamworks
Подбор игр и лобби

Введение

Система пирингового (p2p) подбора игр построена на понятии лобби. Лобби — это сущность, которая образуется на внутренних серверах Steam, и подобна чатам. Пользователи могут создавать новые лобби, отмечать лобби с помощью разного рода данных, искать лобби на основании этих данных, заходить в лобби и делиться информацией с другими пользователями в лобби. В одном лобби могут находиться до 250 игроков, однако для большинства игр это значение варьируется в диапазоне от 2 до 16. Подбор игр, который исходит из опыта игроков, построен поверх этой системы.

API подбора игр представляет собой набор функций, которые позволяют пользователям находить друг друга для игры. Все функции подбора игр находятся в ISteamMatchmaking, где описаны подробности для каждой из них. У каждого лобби есть свой номер SteamID, как у пользователей и у серверов. Образец приложения Steamworks полностью поддерживает лобби.

Процесс подбора игр

Обычно процесс образования групп для игры таков:
  1. В игре пользователь указывает, что хочет играть в многопользовательском режиме, а также тип многопользовательского режима (правила, сценарий и т. д.)
  2. Игра находит лобби, для которых установлены схожие правила, используя API поиска лобби.
  3. Если лобби найдено, игра присоединяется к нему, если нет — создает новое.
  4. Пользователи остаются в лобби, пока не найдется необходимое для начала игры число игроков. Между участниками лобби идет обмен данными о том, каких персонажей они выбирают, или о других настройках, уникальных для каждого игрока. Если в лобби необходимо обеспечить исполнение какого-либо правила (к примеру, определенного персонажа может выбрать только один игрок), для вынесения решения используется владелец лобби.
  5. Для лобби необязателен пользовательский интерфейс. Если он есть, функции обмена данными можно использовать для отправки сообщений в чате. Можно отправлять и голосовые данные, но для этого придется использовать API, описанный здесь: Сетевые функции Steam.
  6. Как только игра готова к запуску, пользователи присоединяются к игровому серверу или пользователю, который назначен хостом игры, и затем покидают лобби. Как только все пользователи покинули лобби, оно уничтожается.

Поиск лобби

Чтобы игра начала поиск лобби, она должна вызвать ISteamMatchmaking::RequestLobbyList
Эта функция асинхронна и возвращает дескриптор SteamAPICall_t, который можно использовать для отслеживания состояния запроса. В зависимости от скорости соединения пользователя с серверами Steam завершение вызова может занять от 300 мс до 5 сек. Максимальное время ожидания — 20 сек.
Результаты вызова возвращаются в списке LobbyMatchList_t. С помощью итератора ISteamMatchmaking::GetLobbyByIndex можно получить номера (SteamID) лобби.
Может быть возвращено до 50 результатов, но обычно не более 2. Они отсортированы по расстоянию и другим установленным фильтрам. По умолчанию, уже заполненные лобби не будут включены в результаты, а фильтр расстояния также установлен в значение по умолчанию k_ELobbyDistanceFilterDefault (регион пользователя и близлежащие к нему). Чтобы добавить фильтры, прежде чем вызвать RequestLobbyList, вызовите нужные функции:

Создание лобби

Если найти лобби не удается, в этот момент обычно создается новое. Просто вызовите
ISteamMatchmaking::CreateLobby и подождите завершения вызова. Результат вызова показывает, был ли он успешен, и если да, записывает Steam ID лобби в структуру LobbyCreated_t, который можно использовать для создания метаданных о лобби. Сразу после создания лобби следует задать метаданные, которые другие игровые клиенты могут использовать для поиска (см. ниже).

Присоединение к лобби

Если найдено подходящее лобби, от друга или в результате поиска, используйте ISteamMatchmaking::JoinLobby и подождите результата LobbyEnter_t. После присоединения к лобби вызовите данные о лобби и используйте их, чтобы определить, что показать на экране пользователя (если вообще что-то показывается).

Когда пользователь присоединяется к лобби или покидает его, обратный вызов LobbyChatUpdate_t отправляется всем участникам лобби, включая владельца.

Чтобы узнать, какие пользователи сейчас находятся в лобби, используйте:

Чтобы получить больше информации о другом пользователе в лобби, используйте API друзей (см. Друзья, приглашения и лобби).

Метаданные лобби

Метаданные лобби позволяют задать произвольное состояние лобби, включая название лобби, текущую карту, игровой режим, текущее состояние игры и т. д.

Пользователь автоматически получит последние данные о лобби для всех лобби, в которых он состоит. Для лобби, которые были возвращены в результатах поиска, пользователь получит данные о лобби, актуальные на момент поиска. Если это лобби друга, данные о лобби будут недоступны, пока не будет вызван и завершён ISteamMatchmaking::RequestLobbyData.

Если данные лобби изменились, все участники лобби получат обратный вызов LobbyDataUpdate_t (с помощью этого обратного вызова также можно узнать о том, что ISteamMatchmaking::RequestLobbyData завершён).

Следующий набор функций используется для получения и задания данных лобби. Устанавливать и удалять данные лобби может только владелец лобби.

Следующий набор функций используется для поиска по метаданным (обычно используется только для поиска и устранения ошибок):

Лобби позволяют участникам установить собственные метаданные. Другие участники могут получить обновления этих данных с помощью следующего набора функций.

Общение в лобби

Чтобы отправлять информацию в лобби (сообщения чата, сигнала начала игры и т. п.), вызовите ISteamMatchmaking::SendLobbyChatMsg, который отправляет простое двоичное сообщение всем пользователям в лобби. Участникам лобби нужно ожидать обратный вызов ISteamMatchmaking::LobbyChatMsg_t. После его получения необходимо использовать ISteamMatchmaking::GetLobbyChatEntry для получения содержимого сообщения.

Друзья, приглашения и лобби

С помощью API можно получить список всех лобби, в которых находятся друзья пользователя:
int cFriends = SteamFriends()->GetFriendCount( k_EFriendFlagImmediate ); for ( int i = 0; i < cFriends; i++ ) { FriendGameInfo_t friendGameInfo; CSteamID steamIDFriend = SteamFriends()->GetFriendByIndex( i, k_EFriendFlagImmediate ); if ( SteamFriends()->GetFriendGamePlayed( steamIDFriend, &friendGameInfo ) && friendGameInfo.m_steamIDLobby.IsValid() ) { // friendGameInfo.m_steamIDLobby является активным лобби, к нему можно присоединиться или использовать RequestLobbyData() для получения метаданных } }

Друга можно пригласить в лобби, используя ISteamMatchmaking::InviteUserToLobby
Пользователь увидит диалоговое окно чата со ссылкой на присоединение к игре. Если пользователь нажмет ссылку (и пока не играет в эту игру), игра будет запущена при помощи командной строки:
+connect_lobby <64-bit lobby id>. Убедитесь, что ваше приложение использует ISteamApps::GetLaunchCommandLine, чтобы вы могли отключить всплывающее предупреждение при запуске с помощью командной строки.

Если пользователь уже в игре, будет отправлен обратный вызов ISteamFriends::GameLobbyJoinRequested_t, в котором будет содержаться Steam ID лобби, к которому хочет присоединиться пользователь. Вам решать, подчинится ли ему игра.

Для того чтобы пользователь мог выбрать, кого из списка друзей пригласить в лобби, можно вызвать функцию ISteamFriends::ActivateGameOverlayInviteDialog.
Она активирует оверлей Steam, в котором будет показано диалоговое окно с возможностью приглашения друзей в текущее лобби.

Аутентификация

Любой пользователь в лобби Steam уже полностью аутентифицирован на серверах Steam. Необходимости в дополнительной аутентификации нет, кроме случаев, когда игра проверяет, нет ли у пользователя блокировки VAC (см. статью про античит Valve). Если пользователь попробует войти в тот же аккаунт из другого места, его предыдущий вход будет убран из всех существующих лобби.

Очистка

Как только игра началась, каждый пользователь может покинуть лобби с помощью:
ISteamMatchmaking::LeaveLobby
Как только все пользователи вышли, лобби уничтожается на серверах Steam.

Советы о лобби

  • В целом, создавайте лобби только тогда, когда это необходимо. К примеру, тогда, когда пользователь приглашает в игру друга, либо тогда, когда действие пользователя требует создания лобби.
  • Не обновляйте метаданные лобби слишком часто. В метаданные добавляйте только данные, которые используются для поиска (к примеру, тип игры или состояние игры). Вам не требуется указывать число игроков, поскольку поиск лобби и так ищет лобби с доступными местами.
  • Не присоединяйтесь к лобби только для того, чтобы узнать их метаданные. Метаданные лобби могут быть скачаны отдельно для всех лобби, и затем ваша игра может либо показать пользователю список лобби, где он может выбрать одно из них, либо игра может автоматически решить, к какому лобби присоединиться.

Остались вопросы?

Задавайте их в обсуждениях подбора игр и лобби.