Documentación de Steamworks
Emparejamiento y salas

Introducción

En Steam, el emparejamiento P2P se construye en torno al concepto de la sala de espera. Una sala de espera es una entidad que reside en los servidores del backend de Steam y resulta muy similar a una sala de chat. Los usuarios pueden crear una sala de espera nueva, asociar datos con una sala de espera, buscar salas a partir de esos datos, unirse a salas y compartir información con otros usuarios de la sala de espera. Cada sala de espera puede tener hasta 250 usuarios, aunque lo más habitual es que los juegos tengan entre 2 y 16 jugadores. Sobre este sistema, se construye el emparejamiento basado en habilidades.

La API de emparejamiento P2P de Steam es un conjunto de funciones que permiten a los usuarios encontrar a otros usuarios con los que jugar. Todas las funciones de emparejamiento están contenidas en ISteamMatchmaking, donde podrás ver más detalles sobre los parámetros de cada función. Las salas se identifican de forma única por su id. de Steam, al igual que los usuarios o los servidores de juego. El ejemplo de Steamworks incluye una implementación totalmente funcional de las salas.

Flujo del proceso de emparejamiento

El modelo habitual para formar grupos de juego es el siguiente:
  1. El usuario selecciona el juego en el que desea participar en modo multijugador y el tipo de multijugador que desea (reglas, escenario, etc.).
  2. Con la API de búsqueda de salas, el juego busca salas que tengan un conjunto de reglas semejante.
  3. Si se encuentra una sala de espera, entonces el juego se une a ella. Si no se encuentra ninguna, el juego crea una sala de espera nueva
  4. Los usuarios permanecen en la sala de espera hasta que hay suficientes jugadores para iniciar el juego. Entre los miembros de la sala de espera se comunican datos como el personaje con el que van a jugar u otros ajustes del nivel de usuario. Si hay alguna regla que deba aplicarse en la sala de espera (por ejemplo, que un mismo personaje solo pueda ser elegido por un jugador), el propietario de la sala de espera, que es único, será el mediador que se encargue de aplicar las reglas.
  5. La sala de espera puede tener una interfaz de usuario asociada; si la tiene, las funciones de comunicaciones de datos de la sala de espera se pueden usar para que sus miembros se envíen mensajes de chat. También se pueden usar datos de voz, pero necesitan enviarse usando la API Conectividad de red de Steam.
  6. Cuando el juego está listo para empezar, todos los usuarios se unen al servidor de juego, o se conectan al usuario designado para alojar la partida, y después abandonan la sala de espera. Cuando todos los usuarios han abandonado la sala de espera, esta se cierra automáticamente.

Búsqueda de salas

Para hacer que tu juego busque una sala de espera, necesitas llamar a ISteamMatchmaking::RequestLobbyList
Esta función es asíncrona y devuelve el handle o identificador de acción SteamAPICall_t que puedes usar para hacer el seguimiento del estado de la petición. Dependiendo de la conexión del usuario al back-end de Steam, esta llamada puede tardar en completarse entre 300 milisegundos y 5 segundos, y se cancela al cabo de 20 segundos.
El número de resultados que se reciben está disponible en el resultado de la llamada LobbyMatchList_t, que puede usar a continuación ISteamMatchmaking::GetLobbyByIndex para iterar sobre ellos y obtener sus identificadores.
Se pueden devolver hasta 50 resultados, pero normalmente no hay más de un par. Los resultados se devuelven ordenados según su distancia geográfica y aplicando cualquier filtro establecido. De forma predeterminada, no se incluyen en los resultados salas llenas, y el filtro de distancia está establecido como k_ELobbyDistanceFilterDefault (cerca). Para añadir filtros, antes de llamar RequestLobbyList necesitas hacer una llamada a una o más de las funciones de filtro:

Creación de una sala de espera

Cuando no se puede encontrar una sala de espera para que se una a ella un usuario, es cuando normalmente se crea una. Simplemente llama a
ISteamMatchmaking::CreateLobby y espera a que se complete. El resultado de llamada indica si se efectuó correctamente o no y, en caso afirmativo, devolverá el id. de Steam de la sala de espera en un LobbyCreated_t struct, que se puede usar para establecer los metadatos en la sala. Lo primero que querrás hacer después de crear una sala de espera es establecer datos para ella, de manera que otros clientes puedan usarlos para buscarla (véase abajo).

Unirse a una sala de espera

Si has encontrado una buena sala, bien mediante una búsqueda o a través de un amigo, puedes usar ISteamMatchmaking::JoinLobby y esperar el resultado de la llamada LobbyEnter_t. Una vez en la sala de espera, querrás usar la API de datos de sala para obtener detalles de la sala de espera y determinar qué mostrar (si lo hubiese).

Cuando un usuario se une o abandona una sala, se les muestra la devolución de llamada LobbyChatUpdate_t a todos los participantes de la sala, incluido el dueño.

Para iterar qué usuarios están en ese momento en una sala de espera, puedes usar:

Para obtener más información acerca de otro usuario de la sala de espera, será necesario usar la API para amigos. Consulta Amigos, invitaciones y salas para obtener más información.

Metadatos de salas

Los metadatos de salas permiten establecer el estado arbitrario de la sala, incluyendo el nombre de la sala, el mapa actual, el modo de juego, el estado actual del juego o cualquier otra cosa que se pueda considerar.

Un usuario tendrá, de forma automática, los datos más recientes de cualquier sala de espera de la que sea miembro. Para aquellas salas devueltas a través de resultados de búsqueda, el usuario poseerá datos de la sala de espera para el momento en el que se realizó dicha búsqueda. Si se trata de la sala de un amigo, no habrá datos de la sala disponibles para ver hasta que se haga una llamada a ISteamMatchmaking::RequestLobbyData y se complete con éxito.

Si los datos de la sala cambian en esa sala, todos los participantes de la sala recibirán una llamada LobbyDataUpdate_t (esta llamada es la forma de saber que la llamada ISteamMatchmaking::RequestLobbyData se ha completado).

Estos son los conjuntos de funciones que se pueden usar para obtener y establecer datos de sala de espera. Solo el propietario de la sala de espera puede establecer o borrar los datos de la sala.

Funciones que permiten iterar los metadatos, (normalmente, solo se usa con fines de depuración):

Las salas también permiten a los miembros establecer sus propios metadatos, de los que los demás miembros pueden recibir actualizaciones con las siguientes funciones.

Comunicación dentro de las salas

Para enviar información dentro de una sala de espera (mensajes de chat, señales de inicio de juego, etc.), es necesario llamar a ISteamMatchmaking::SendLobbyChatMsg; esta función envía un simple mensaje binario a todos los usuarios de la sala de espera. Los miembros de la sala necesitan escuchar la llamada ISteamMatchmaking::LobbyChatMsg_t. Después de recibir la llamada puedes usar para ISteamMatchmaking::GetLobbyChatEntry recuperar el contenido del mensaje.

Amigos, invitaciones y salas

Pueden averiguarse todas las salas en las que están los amigos de un usuario con la API para 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 es una sala válida, puedes unirte o usar RequestLobbyData() para obtener sus metadatos. } }

Puedes invitar a un amigo a la sala con ISteamMatchmaking::InviteUserToLobby
Ese usuario recibirá un cuadro de diálogo de chat con un enlace para unirse al juego. Si el usuario hace clic en el enlace y no está ejecutando el juego en ese momento, lo iniciará con la línea de comando:
+connect_lobby <64-bit lobby id>

Si el usuario ya está en una partida, se muestra la llamada ISteamFriends::GameLobbyJoinRequested_t, que incluye el id. de Steam de la sala a la que se quiere unir el usuario. Es el juego el que determina si obedecer o no.

Si quieres que el usuario seleccione amigos de una lista para invitarlos a una sala, puedes llamar a ISteamFriends::ActivateGameOverlayInviteDialog.
Esto activará la interfaz de Steam dentro del juego con un cuadro de diálogo diseñado para invitar amigos a la presente sala.

Autenticación

Cualquier usuario de una sala de espera de Steam está ya completamente autenticado en el backend de Steam. No hay necesidad de que el juego ejecute ningún paso de autenticación más con los usuarios de las salas, a menos que se quiera establecer si la VAC (véase la tecnología antitrampas de Valve) los ha bloqueado. Si un usuario intenta conectarse desde una segunda ubicación con la misma cuenta, su sesión previa será eliminada automáticamente de cualquier sala de espera existente.

Limpieza

Una vez que la partida empieza, cada usuario puede simplemente abandonar la sala con:
ISteamMatchmaking::LeaveLobby
.
Después de que todos los usuarios se van, se elimina la sala automáticamente en el backend.

Sugerencias de la sala de espera

  • En general, crea salas solo cuando sea necesario. Por ejemplo, cuando el usuario invite a un amigo a jugar o cuando se inicie una acción manual que requiere tener una sala
  • No actualices los metadatos de las salas con demasiada frecuencia. Únicamente añade datos y valores que se usen para búsquedas (por ejemplo, tipo de juego y estado del juego). No necesitas incluir un contador de jugadores, pues la búsqueda de la sala ya busca salas con espacios disponibles
  • No te unas a salas únicamente para saber cuáles son sus metadatos. Los metadatos de la sala se pueden descargar de forma separada para todas las salas, algo que tu juego puede usar bien para mostrar una lista de salas que el usuario puede elegir o bien para que el juego decida automáticamente a qué resultado de búsqueda se puede unir

¿Más preguntas?

Plantea tus preguntas en el Foro de discusión de emparejamiento y de las salas de Steam.