Matchmaking e Salas
Última atualização: 15 de setembro de 2026
Uma sala é uma instância ao vivo do seu jogo, hospedada por um game server e identificada por um nome. A partir de um cliente Unity você leva um jogador para uma sala de duas maneiras: navegar pela lista de salas abertas e deixar o jogador escolher, ou entrar em uma sala pelo nome diretamente. De todo modo você recebe uma reserva — um ticket de curta duração mais os dados de conexão do servidor — que você usa para abrir o seu transporte de jogo.
Este é o lado do cliente Unity: descobrir e reservar uma sala. Rodar o game server que hospeda salas é uma questão separada, do lado do servidor. Salas não exigem matchmaking automático — navegar e entrar-pelo-nome funcionam sozinhos. A alocação automática é uma camada à parte, coberta no fim, e ainda não está em serviço.
Navegar pelas salas abertas
BrowseRoomsAsync lê a lista pública de salas de uma função de game server, usando a sessão do jogador logado. Você recebe uma página de salas; o jogador escolhe uma.
using PlayServ.Sdk.Matchmaking;
var page = await PlayServMatchmaking.BrowseRoomsAsync("arena");
foreach (PlayServRoomListing room in page.Rooms)
{
// room.RoomName, room.Players / room.Capacity, room.State,
// room.Region, room.Connect (host/port/transport)
}
// A paginação é explícita — peça a próxima página só se quiser:
if (page.HasMore)
page = await PlayServMatchmaking.BrowseRoomsAsync("arena",
new PlayServRoomBrowseQuery { Cursor = page.CursorNext });
Um PlayServRoomBrowseQuery pode filtrar por PlacementState (por exemplo, apenas salas em que dá para entrar) e Region, definir um Limit (padrão 50) e carregar um Cursor para a próxima página. Navegar nunca aloca nem lança nada — é uma leitura.
Entrar em uma sala pelo nome
Assim que o jogador escolheu uma sala — ou se o seu jogo já sabe o nome da sala (uma partida privada, a sala de um amigo, uma sala do seu próprio server browser) — JoinRoomAsync pede uma reserva para exatamente aquela sala.
PlayServMatchResult result = await PlayServMatchmaking.JoinRoomAsync("arena", roomName);
if (result.IsMatched)
{
PlayServMatchReservation r = result.Reservation;
// r.RoomName, r.ReservationToken, r.ExpiresAt
// r.Connect.Host, r.Connect.Port, r.Connect.Transport, r.Connect.ConnectString, r.Connect.Region
}
JoinRoomAsync faz uma coisa: pede uma reserva. Não aloca, não lança, não faz polling, não tenta de novo e não abre transporte — o que a mantém previsível. Se você pedir duas vezes a mesma sala enquanto uma reserva ainda está ativa, recebe a mesma de volta em vez de uma duplicada.
Quando um join não pode ser atendido, o resultado carrega o motivo — a sala não existe (room_not_found), está cheia (room_full) ou está fechada/drenando (room_closed). Trate esses casos mandando o jogador de volta ao navegador.
A reserva
Ambos os caminhos terminam em um PlayServMatchReservation, que é tudo o que você precisa para alcançar a sala:
| Campo | O que é |
|---|---|
RoomName | A sala que a reserva admite. |
ReservationToken | Um token opaco, de uso único, atrelado à sua sessão. Apresente-o ao game server ao conectar. |
ExpiresAt | Quando a reserva expira — conecte-se logo. |
Connect | Onde o servidor está: Host, Port, Transport, mais um ConnectString e Region opcionais. |
A reserva é a sua permissão para entrar em uma sala específica. Ela expira e é de uso único, então resgate-a logo depois de recebê-la.
Entrar e conectar em uma só chamada
JoinRoomAsync deliberadamente não toca na sua rede, porque o PlayServ não é dono do seu transporte de jogo (Netcode for GameObjects, Unity Transport, Mirror, um socket cru — sua escolha). Quando você preferir não juntar os dois passos à mão, JoinRoomAndConnectAsync reserva a sala e então entrega a reserva a um conector que você fornece, onde você abre o transporte para Connect e apresenta o ReservationToken.
await PlayServMatchmaking.JoinRoomAndConnectAsync(
new PlayServJoinRoomRequest { FunctionSlug = "arena", RoomName = roomName },
connector: async (reservation, ct) =>
{
// abra SEU transporte para reservation.Connect e entregue o token
});
O conector precisa rodar no contexto principal (de sincronização) da Unity, pois normalmente toca objetos de rede da Unity. Tudo o que o conector precisa — endereço e token — está na reserva.
Para todo o caminho, do login até dentro da sala, incluindo como a reserva e os dados de conexão se encaixam, veja Conectando-se a um Jogo.
Conversar com outros jogadores na sala
Entrar em uma sala é separado de trocar mensagens dentro dela. Para chat de lobby, ready-check e sinal de "quem está aqui", use Grupos: assine um grupo com a chave da sala e publique eventos para todos nela. O matchmaking leva o jogador à sala; os grupos deixam a sala conversar.
Matchmaking automático
O SDK também expõe alocação automática — FindMatchAsync e JoinGameAsync, que escolhem uma sala pelo jogador em vez de ele navegar ou nomear uma. Hoje a plataforma não tem matchmaking em serviço, então esses métodos não têm nada por trás. Construa sobre navegar + entrar-pelo-nome (acima), que é totalmente suportado. Esta seção documenta apenas o formato pretendido.
Quando entrar em serviço, o matchmaking automático deixará um jogador pedir uma partida e ser alocado em uma sala adequada (iniciando uma se preciso), devolvendo o mesmo tipo de reserva que você já trata:
// AINDA NÃO ESTÁ EM SERVIÇO
var result = await PlayServMatchmaking.JoinGameAsync(
new PlayServJoinGameRequest { FunctionSlug = "arena" });
// result.Status: Matched · Bot · NotFound → result.Reservation como acima
Como o resultado é o mesmo tipo de reserva, o código que já navega e entra pelo nome vai se aproveitar com pouca mudança quando a alocação entrar no ar.
Próximos passos
- Conectando-se a um Jogo — o caminho Unity completo: login → reservar → conectar → jogar
- Grupos — chat, sinal de presença e broadcast na sala
- Hospedagem de Game Server — o servidor que hospeda as salas que você navega e conecta