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 é:
- O usuário seleciona no jogo que deseja jogar no modo multijogador, assim como o tipo de modo que deseja (regras, cenário etc.);
- O jogo busca partidas com um conjunto similar de regras, usando a API de busca de salas;
- Se uma sala for encontrada, então o jogo entra nela; caso contrário, uma nova sala é criada;
- 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;
- 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;
- 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::RequestLobbyListEssa 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::InviteUserToLobbyEsse 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::LeaveLobbyAssim 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.