Документація Steamworks
Пошук матчів Steam і лобі

Огляд

Пошук матчів «один до одного» (P2P) розроблено навколо концепції лобі. Лобі — це сутність, що знаходиться на внутрішніх серверах Steam і схожа на чат. Користувачі можуть створювати нові лобі, пов’язувати дані з лобі, шукати лобі на основі цих даних, приєднуватися до лобі та ділитися інформацією з іншими користувачами в лобі. Одне лобі може включати до 250 користувачів, хоча більшість ігор потребують від 2 до 16 гравців. Поверх цієї системи розроблено пошук матчів на основі рівня навичок.

API пошуку матчів «один до одного» в Steam — це набір функцій, які дозволяють користувачам знаходити інших користувачів для спільної гри. Усі функції пошуку матчу знаходяться в ISteamMatchmaking, що містить більше подробиць про параметри кожної функції. Лобі мають унікальний ідентифікатор SteamID, як і користувачі чи ігрові сервери. Приклад Steamworks має впроваджену систему лобі.

Процес пошуку матчів

Звичайна модель поєднання груп для спільної гри така:
  1. Користувач у грі вказує, що бажає грати в багатокористувацький режим, а також обирає тип (правила, сценарій тощо).
  2. Гра шукає лобі з таким самим набором правил за допомогою API пошуку лобі.
  3. Якщо лобі знайдено, то гра приєднується до цього лобі. Якщо лобі не знайдено, то створюється нове лобі.
  4. Користувачі залишаються в лобі, допоки не знайдеться необхідна для початку матчу кількість гравців. Між учасниками лобі відбувається обмін даними про те, яких персонажів вони обирають, чи про інші унікальні для гравців налаштування. Якщо в лобі треба забезпечити виконання правила (наприклад, якщо певного персонажа може обрати лише один гравець), то рішення приймає власник лобі.
  5. Для лобі необов’язково мати користувацький інтерфейс. Якщо він є, то функції обміну даними можна використовувати для надсилання повідомлень у чаті лобі. Також можна надсилати й голосові дані, але для них використовується API мережевих функцій.
  6. Коли матч готовий до запуску, то всі користувачі приєднуються до ігрового сервера чи до користувача-хоста, а потім покидають лобі. Коли всі користувачі залишають лобі, воно автоматично знищується.

Пошук лобі

Для пошуку лобі грою вам потрібно викликати ISteamMatchmaking::RequestLobbyList
Це асинхронна функція, що повертає SteamAPICall_t, який можна використовувати для відстеження стану запиту. Залежно від швидкості підключення користувачів до серверів Steam завершення цього виклику може зайняти від 300 мс до 5 с. Максимальний час очікування: 20 с.
Результати виклику повертаються в списку LobbyMatchList_t. Ви можете використати ISteamMatchmaking::GetLobbyByIndex для ітерації між ними й отримання ID лобі.
Може повертатися до 50 значень, але зазвичай їх лише кілька. Результати відсортовуються за географічною дистанцією й іншими встановленими фільтрами. Стандартно ми не повертаємо заповнені лобі, а фільтр відстані встановлений стандартно як k_ELobbyDistanceFilterDefault (найближчий регіон). Для додавання фільтрів перед викликом RequestLobbyList потрібно викликати одну чи більше функцій фільтрування:

Створення лобі

Якщо не вдається знайти лобі для користувача, то зазвичай створюється нове лобі. Для цього просто викличте
ISteamMatchmaking::CreateLobby й зачекайте на завершення виклику. Результат виклику показує, чи був він успішним. Якщо так, то повертається SteamID лобі в структурі LobbyCreated_t, який можна використовувати для створення метаданих для лобі. Одразу після створення лобі слід встановити дані лобі, які інші ігрові клієнти зможуть використовувати для пошуку цього лобі (див. нижче).

Приєднання до лобі

Якщо знайдено належне лобі, від друга чи внаслідок пошуку, використайте ISteamMatchmaking::JoinLobby й зачекайте на результат виклику LobbyEnter_t. Після приєднання до лобі скористайтеся API даних лобі, щоб отримати подробиці про лобі для показу (якщо щось показується).

Коли користувач приєднується до лобі чи залишає його, то зворотний виклик 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, що містить SteamID лобі, до якого користувач хоче приєднатися. Ваша гра вирішує, чи виконувати запит.

Якщо ви хочете, щоби користувач міг вибирати, кого з друзів запросити в лобі, можна викликати ISteamFriends::ActivateGameOverlayInviteDialog.
Це активує внутрішньоігровий оверлей Steam, де буде показано вікно для запрошення друзів до поточного лобі.

Автентифікація

Будь-який користувач у лобі Steam уже повністю автентифікований на серверах Steam. Немає потреби в додатковій автентифікації за винятком тих випадків, коли треба перевірити, чи не має користувач блокування VAC (див. античіт Valve). Якщо користувач пробує увійти з іншого місця з цього самого акаунта, то його попередній вхід буде автоматично вилучено з усіх наявних лобі.

Очищення

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

Підказки щодо лобі

  • Загалом, створюйте лобі лише тоді, коли це потрібно. Наприклад, коли користувач запрошує до гри друга, або коли дія користувача потребує створення лобі.
  • Не оновлюйте метадані лобі надто часто. У метадані додавайте лише значення, які використовуються для пошуку (наприклад, тип чи стан гри). Вам не потрібно вказувати кількість гравців, бо пошук лобі й так шукає лобі з вільними місцями.
  • Не приєднуйтеся до лобі лише для отримання їхніх метаданих. Метадані лобі можна завантажити окремо для всіх лобі, а потім ваша гра може або показати користувачу список лобі для вибору одного з них, або автоматично вирішити, до якого лобі його приєднати.

Маєте ще питання?

Запитуйте на форумі обговорень пошуку матчів і лобі Steam.