Documentação do Steamworks
Criação de partidas e salas no Steam

Visão geral

O sistema de criação de partidas P2P do Steam é baseado no conceito de sala. Uma sala é uma entidade que vive nos servidores de backend do Steam que é bem similar a uma sala de conversa. Usuários podem: criar uma sala nova; associar dados com uma sala; buscar salas com base nesses dados; entrar em salas; e compartilhar dados com outros usuários na sala. Uma única sala pode ter até 250 usuários, mas a maioria dos jogos tem salas de 2 a 16 jogadores no máximo. A criação de partidas baseada em habilidade usa esse sistema.

A API de criação de partidas P2P do Steam é um conjunto de funções que permite que usuários encontrem outros usuários para jogar. As funções de criação de partidas fazem parte da interface ISteamMatchmaking, que contém mais detalhes sobre os parâmetros de cada função. Salas são identificadas pelo ID Steam, como usuários ou servidores de jogos. O exemplo do Steamworks contém uma implementação completa e funcional de salas.

Fluxo do processo de criação de partidas

O modelo mais comum para agrupar jogadores para jogar é:
  1. O usuário seleciona no jogo que deseja jogar no modo multijogador, assim como o tipo de modo que deseja (regras, cenário etc.);
  2. O jogo busca partidas com um conjunto similar de regras, usando a API de busca de salas;
  3. Se uma sala for encontrada, então o jogo entra nela; caso contrário, uma nova sala é criada;
  4. Usuários ficam em uma sala até que haja um número suficiente de jogadores prontos para iniciar a partida. Dados são comunicados entre os membros da sala, tais como o personagem escolhido para o jogo ou outras configurações individuais de cada usuário. Caso haja regras para serem seguidas na sala (por exemplo, apenas um usuário pode jogar com um determinado personagem), haverá apenas um único dono da sala que pode aplicá-las;
  5. Pode ou não haver uma interface de usuário associada à sala; se houver, as funções de comunicação de dados da sala podem ser usadas para enviar mensagens entre membros da sala. Também é possível enviar dados de voz, mas apenas por meio da API de Comunicação de rede no Steam;
  6. Quando a partida estiver pronta para ser iniciada, os usuários entram no servidor ou se conectam ao jogador indicado para hospedar a partida, e então saem da sala. A sala é destruída automaticamente assim que todos os usuários saírem.

Busca por salas

Para que o jogo busque uma sala, é necessário chamar a função: ISteamMatchmaking::RequestLobbyList
Essa função é assíncrona, retornando um handle SteamAPICall_t que pode ser usado para acompanhar o estado da requisição. Dependendo da conexão do usuário ao backend do Steam, essa chamada pode levar de 300 ms a 5 segundos para ser concluída, com um tempo-limite de 20 segundos.
A quantidade de resultados retornada está no resultado de chamada LobbyMatchList_t, que pode então ser usado com a função ISteamMatchmaking::GetLobbyByIndex para iterar pelas salas e recuperar os respectivos IDs.
Até 50 resultados podem ser retornados, mas raramente são muitos. Os resultados são retornados em ordem de distância geográfica e de acordo com filtros de proximidade definidos. Por padrão, não retornamos salas cheias e usamos o filtro de distância com valor k_ELobbyDistanceFilterDefault (próximas). Para adicionar filtros, será necessário chamar uma das funções de filtragem abaixo antes da função RequestLobbyList:

Criação de sala

Quando não é possível encontrar uma sala existente para o usuário entrar, costuma-se criar uma sala. Chame a função
ISteamMatchmaking::CreateLobby e espere a sua conclusão. O resultado da chamada indicará se foi bem-sucedida, e em caso positivo, retorna o ID Steam da sala em uma struct LobbyCreated_t, que pode ser usada para definir os metadados da sala. A primeira coisa a se fazer depois de criar uma sala é definir dados na sala, que poderão ser usados por outros clientes para encontrá-la (veja abaixo).

Entrada em uma sala

Se achou uma sala boa, seja por uma busca ou por recomendação de um amigo, use a função ISteamMatchmaking::JoinLobby e espere o resultado de chamada LobbyEnter_t. Uma vez na sala, use a API de dados de sala para recuperar os detalhes da sala para saber o que exibir (se houver o que exibir).

Quando um usuário entra ou sai de uma sala, um retorno de chamada LobbyChatUpdate_t é disparado a todos os membros da sala, incluindo o dono.

Para iterar pelos usuários que estão na sala, use:

Para recuperar mais dados sobre outro usuário que está na sala, será necessário usar a API de amigos; consulte a documentação sobre Amigos, convites e salas para mais informações.

Metadados da sala

Os metadados da sala permitem definir o estado da sala, incluindo o nome da sala, mapa atual, modo de jogo, estado atual da partida ou o que vier à cabeça.

Um usuário terá, automaticamente, os dados das salas das quais é membro. Para salas retornadas como resultado de uma busca, o usuário terá os dados do momento da busca. Se for uma sala de um amigo, os dados da sala não estarão disponíveis até uma chamada à função ISteamMatchmaking::RequestLobbyData ser realizada e concluída.

Se os dados de uma sala forem alterados, o retorno de chamada LobbyDataUpdate_t será disparado para todos os membros (esse retorno de chamada é o mesmo usado quando uma chamada à função ISteamMatchmaking::RequestLobbyData é concluída).

Estas são as funções usadas para recuperar e definir dados de uma sala. Apenas o dono da sala pode definir ou excluir os dados da mesma.

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

Salas também permitem que membros definam os próprios metadados cujas atualizações serão recebidas pelos outros membros com as seguintes funções.

Comunicação na sala

Para enviar dados em uma sala (mensagens de texto, sinais de início de partida etc.), chame a função ISteamMatchmaking::SendLobbyChatMsg; ela envia uma simples mensagem em binário a todos os usuários na sala. Membros da sala devem observar o retorno de chamada ISteamMatchmaking::LobbyChatMsg_t. Depois do disparo do retorno de chamada, use a função ISteamMatchmaking::GetLobbyChatEntry para recuperar o conteúdo da mensagem.

Amigos, convites e salas

É possível descobrir todas as salas com amigos usando 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 eh uma sala valida, voce pode entrar nela ou usar RequestLobbyData() para recuperar os metadados } }

É possível convidar um amigo para uma sala por meio da função ISteamMatchmaking::InviteUserToLobby
Esse usuário receberá uma notificação com um link para entrar na sala. Se o usuário clicar no link e não estiver com o jogo aberto, o jogo será iniciado com o seguinte parâmetro de inicialização:
+connect_lobby <ID de 64 bits da sala>. Certifique-se de que o seu aplicativo implementou a função ISteamApps::GetLaunchCommandLine para que você possa desativar o alerta quando inicializada por meio da linha de comando.

Se o usuário já estiver em uma partida em andamento, um retorno de chamada ISteamFriends::GameLobbyJoinRequested_t será disparado, contendo o ID Steam da sala que o usuário deseja entrar. Cabe ao jogo obedecer ou não.

Se deseja que o usuário selecione qual amigo convidar a partir de uma lista, chame a função ISteamFriends::ActivateGameOverlayInviteDialog.
Isso ativará o Painel Steam com uma janela projetada para convidar amigos à sala atual.

Autenticação

Qualquer usuário em uma sala do Steam já está autenticado com o backend do Steam. Não é necessário que o jogo faça qualquer autenticação adicional com usuários na sala, a não ser que seja verificação de banimento VAC (consulte a documentação do VAC). Caso um usuário tente iniciar a sessão a partir de um segundo local com a mesma conta, a sessão anterior será removida de quaisquer salas existentes.

Limpeza

Quando a partida estiver em andamento, usuários podem deixar a sala por meio da função
ISteamMatchmaking::LeaveLobby
Assim que todos os usuários saírem, a sala será automaticamente destruída no backend.

Dicas para salas

  • Em geral, crie salas apenas quando necessário, como quando o usuário convida um amigo para jogar ou realiza uma ação manual que exige uma sala;
  • Não atualize os metadados de salas com muita frequência. Apenas adicione metadados e valores usados em buscas (por exemplo, o tipo e estado da partida). Não é necessário informar a quantidade de jogadores; a busca por salas já filtra aquelas com vagas disponíveis;
  • Não entre em salas exclusivamente para recuperar os seus metadados. Metadados podem ser baixados separadamente para todas as salas, os quais podem então ser usados seja para exibir uma lista de salas para o usuário escolher ou para o jogo decidir em qual entrar.

Alguma dúvida?

Tire as suas dúvidas no fórum de discussões de criação de partidas e salas no Steam.