Documentação do Steamworks
Matchmaking e lobbies do Steam

Vista geral

O matchmaking peer-to-peer (P2P) do Steam baseia-se no conceito de salas conhecidas como lobbies. Um lobby é uma entidade situada nos servidores do backend do Steam que é bastante parecida com uma sala de chat. Os utilizadores podem criar um lobby novo, associar dados a um lobby, procurar por lobbies com base nesses dados, entrar em lobbies e partilhar informações com outros utilizadores no lobby. Um único lobby pode conter até 250 utilizadores, mas a maioria dos jogos costuma ter lobbies de 2 a 16 jogadores no máximo. Matchmaking de acordo com o nível de habilidade dos jogadores usa este sistema.

A API de matchmaking P2P do Steam é um conjunto de funções que permite aos utilizadores encontrar outros com quem jogar. As funções de matchmaking fazem todas parte da API ISteamMatchmaking, que contém mais detalhes sobre os parâmetros de cada função. Lobbies são identificados por um SteamID, como utilizadores ou servidores de jogos. O exemplo do Steamworks tem uma implementação completa e funcional de lobbies.

Fluxo do processo de matchmaking

O modelo habitual para agrupar jogadores funciona da seguinte forma:
  1. O utilizador seleciona no jogo que deseja jogar no modo multijogador, assim como todas as especificações (regras, cenário, etc.).
  2. O jogo usa a API de procura de lobbies para procurar por lobbies que tenham um conjunto semelhante de regras.
  3. Se um lobby for encontrado, então o jogo entra nesse lobby. Caso contrário, é criado um lobby novo.
  4. Os utilizadores ficam num lobby até que haja um número suficiente de jogadores prontos para iniciar a partida. Dados são comunicados entre os membros do lobby (tais como as personagens selecionadas por cada jogador ou outras definições individuais). Se houver regras que devam ser seguidas no lobby (por exemplo, só um jogador poder usar uma personagem específica), haverá apenas um único líder do lobby que as poderá aplicar.
  5. Pode ou não haver uma interface de utilizador associada ao lobby. Se houver, as funções de comunicação de dados do lobby podem ser usadas para enviar mensagens de chat entre os membros do lobby. Dados de voz também podem ser enviados, mas só através da API Comunicação em rede no Steam.
  6. Quando a partida estiver pronta para ser iniciada, os utilizadores entram em conjunto no servidor da partida (ou estabelecem ligação com o jogador nomeado para hospedar a partida) e depois saem do lobby. Assim que todos os utilizadores saírem de um lobby, este será destruído automaticamente.

Procurar lobbies

Para que o seu jogo procure por um lobby, terá de chamar a função: ISteamMatchmaking::RequestLobbyList
Esta função é assíncrona e retorna um handle SteamAPICall_t handle que pode usar para acompanhar o estado do pedido. Dependendo da ligação do utilizador ao backend do Steam, esta chamada pode demorar de 300 milissegundos a 5 segundos para ser concluída e tem um tempo-limite de 20 segundos.
O número retornado de resultados está no resultado de chamada LobbyMatchList_t, que pode depois ser usado com a função ISteamMatchmaking::GetLobbyByIndex para iterar pelos lobbies e obter os respetivos IDs.
Até 50 resultados podem ser retornados, mas normalmente são só alguns. Os resultados são retornados por ordem de distância geográfica e baseados em quaisquer filtros de proximidade definidos. Por predefinição, não iremos retornar lobbies que já estejam cheios e o filtro de proximidade está definido como k_ELobbyDistanceFilterDefault (próximos). Para adicionar filtros, terá de chamar uma ou mais das seguintes funções de filtragem antes de chamar RequestLobbyList:

Criar um lobby

Quando não é possível encontrar um lobby existente para um utilizador, o ideal é criar um lobby. Basta chamar a função
ISteamMatchmaking::CreateLobby e aguardar pela conclusão. O resultado da chamada indica se foi bem-sucedida ou não e, se for, será retornado o SteamID do lobby numa struct LobbyCreated_t, que pode ser usada para definir os metadados do lobby. A primeira coisa a fazer antes da criação de um lobby é definir os dados do mesmo, que poderão ser usados por outros clientes para o encontrar (mais informações abaixo).

Entrar num lobby

Se encontrou um lobby do seu agrado, seja através do resultado de uma procura ou da recomendação de um amigo, use a função ISteamMatchmaking::JoinLobby e aguarde pelo resultado de chamada LobbyEnter_t. Uma vez no lobby, use a API de dados do lobby para obter detalhes sobre o lobby e saber o que apresentar (se houver algo que apresentar).

Quando um utilizador entra ou sai de um lobby, um callback LobbyChatUpdate_t é enviado para todos os membros do lobby, incluindo o líder.

Para iterar quais utilizadores estão atualmente no lobby, use:

Para obter mais detalhes sobre outro utilizador no lobby, terá de usar a API de amigos. Consulte a documentação sobre Amigos, convites e lobbies para mais informações.

Metadados do lobby

Os metadados do lobby permitem definir o estado arbitrário do lobby, incluindo o nome do lobby, mapa atual, modo de jogo, estado atual da partida ou qualquer outro detalhe que desejar.

Um utilizador receberá automaticamente os dados mais recentes dos lobbies a que pertence. No caso de lobbies retornados como resultado de uma procura, o utilizador terá os dados do momento da procura. Caso se trate do lobby de um amigo, os dados do lobby não estarão disponíveis até que uma chamada a ISteamMatchmaking::RequestLobbyData seja efetuada e concluída com êxito.

Se os dados de um lobby forem alterados, todos os membros do lobby irão receber um callback LobbyDataUpdate_t (este callback é o mesmo usado quando uma chamada a ISteamMatchmaking::RequestLobbyData é concluída).

Estas são as funções que pode usar para obter e definir dados de um lobby. Só o líder do lobby pode definir ou eliminar os dados do lobby.

Funções que permitem iterar pelos metadados (normalmente usadas apenas para depuração):

Lobbies também permitem que membros definam os seus próprios metadados, cujas atualizações podem ser recebidas por outros membros com as seguintes funções:

Comunicação dentro de um lobby

Para enviar informações dentro de um lobby (mensagens de chat, sinais de início de partida, etc.), precisa de chamar ISteamMatchmaking::SendLobbyChatMsg, que envia uma simples mensagem binária a todos os utilizadores no lobby. Os membros do lobby precisam de escutar o callback ISteamMatchmaking::LobbyChatMsg_t. Depois da receção do callback, use ISteamMatchmaking::GetLobbyChatEntry para recuperar o conteúdo da mensagem.

Amigos, convites e lobbies

É possível encontrar todos os lobbies com amigos ao usar a API de amigos:
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 é um lobby válido. Pode entrar neste lobby ou usar RequestLobbyData() para recuperar os respetivos metadados } }

Pode convidar um amigo para um lobby através da função ISteamMatchmaking::InviteUserToLobby
Esse utilizador irá receber uma notificação no chat com um link para entrar na partida. Se o utilizador clicar no link e não estiver com o jogo aberto, este será iniciado com a seguinte opção de arranque:
+connect_lobby <ID de 64 bits do lobby>. Certifique-se de que a sua aplicação implementou a função ISteamApps::GetLaunchCommandLine para que possa desativar o aviso pop-up quando a inicia através da linha de comandos.

Se o utilizador já estiver numa partida a decorrer, um callback ISteamFriends::GameLobbyJoinRequested_t será enviado, contendo o SteamID do lobby em que o utilizador pretende entrar. Cabe ao seu jogo decidir se obedece ou não.

Caso queira que o utilizador selecione qual amigos convidar para um lobby a partir de uma lista, pode chamar a função ISteamFriends::ActivateGameOverlayInviteDialog.
Isto irá ativar o Painel Steam com uma janela dedicada ao convite de amigos ao lobby atual.

Autenticação

Qualquer utilizador num lobby do Steam já está completamente autenticado com o backend do Steam. Não é necessário que o jogo faça qualquer tipo de autenticação com utilizadores no lobby, a não ser que seja para verificar se foram banidos pelo VAC ou não (consulte a documentação sobre a tecnologia antibatota da Valve para mais informações). Se um utilizador tentar iniciar sessão a partir de outro local com a mesma conta, a sessão anterior será removida automaticamente de quaisquer lobbies existentes.

Limpeza

Após o início da partida, cada utilizador pode sair do lobby através da função:
ISteamMatchmaking::LeaveLobby
Assim que todos os utilizadores saírem, o lobby será destruído automaticamente no backend.

Dicas para lobbies

  • De uma forma geral, crie lobbies apenas quando necessário. Por exemplo, quando o utilizador convida um amigo para jogar ou realiza uma ação manual que requer um lobby.
  • Não atualize os metadados de lobbies com muita frequência. Adicione apenas metadados e valores usados para procurar lobbies (por exemplo, o tipo ou o estado da partida). Não precisa de introduzir a quantidade de jogadores, pois ao procurar por lobbies, já são filtrados aqueles com vagas disponíveis.
  • Não entre em lobbies só para obter os respetivos metadados. Os metadados podem ser transferidos separadamente para todos os lobbies e ser usados pelo seu jogo para apresentar uma lista de lobbies ou para o jogo decidir automaticamente em qual entrar.

Perguntas ou dúvidas?

Faça perguntas no fórum de discussão sobre matchmaking e lobbies do Steam.