Документація 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.