Επισκόπηση
Steam's peer-to-peer matchmaking is built around the concept of a lobby. A lobby is a entity that lives on the Steam back-end servers that is a lot like a chat room. Users can create a new lobby; associate data with a lobby; search for lobbies based on that data; join lobbies; and share information with other users in the lobby. A single lobby can have up to 250 users in it, although typically most games have at most 2-16 players. Skill-based matchmaking is built on top of this system.
The Steam peer-to-peer matchmaking API is a set of functions that enable users to find other users to play a game with. The matchmaking functions all live in
ISteamMatchmaking, which contains more details on the parameters for each function. Lobbies are uniquely identified by Steam ID, like users or game servers. The Steamworks Example has a full working implementation of lobbies.
Matchmaking process flow
The usual model for getting groups together to play is as follows:
- User selects in the game that they want to play multiplayer, and what kind of multiplayer they want (rules, scenario, etc.)
- The game searches for lobbies that have a similar same set of rules, using the lobby search API.
- If a lobby is found, then the game joins that lobby; if no lobby is found, then it creates a new lobby
- Users stay in a lobby until there are enough players ready to launch the game. Data is communicated between the lobby members about which character they want to play, or other per-user settings. If there are some rules that need to be enforced in the lobby (for example, only one user can play as a certain character), there is one and only one lobby owner who you can use to arbitrate that.
- There may or may not be a user interface associated with the lobby; if there is, the lobby data communications functions can be used to send chat messages between lobby members. Voice data can also be sent, but needs to be sent using the Steam Networking API.
- Once the game is ready to launch, the users all join the game server, or connect to the user nominated to host the game, and then leave the lobby. Once all users have left a lobby, it is automatically destroyed.
Searching for lobbies
To have your game search for a lobby, you need to call:
ISteamMatchmaking::RequestLobbyListThis function is asynchronous, returning a SteamAPICall_t handle which you can use to track the state of the request. Depending on the users connection to the Steam back-end, this call can take from 300ms to 5 seconds to complete, and has a timeout of 20 seconds.
The number of results returned is in the
LobbyMatchList_t call result, which you can then use
ISteamMatchmaking::GetLobbyByIndex to iterate over them all and get their IDs.
Up to 50 results may be returned, but usually it's no more than a couple. The results are returned ordered by geographical distance and based on any near filters set. By default, we will not return lobbies that are already full, and the distance filter is set to
k_ELobbyDistanceFilterDefault (nearby). To add filters, before you call
RequestLobbyList
you need to call one or more of the filtering functions:
Creating a lobby
If you can't find an existing lobby for a user to join, this is when you'd typically create a lobby. Just call
ISteamMatchmaking::CreateLobby and wait for it to complete. The call result indicates whether or not it succeeded, and if it did, it will return the steamID of the lobby in a
LobbyCreated_t struct, which can be used to set metadata on the lobby. The first thing you'll want to do after you create a lobby is set a data on the lobby, that other game clients can use to search for it (see below).
Joining a lobby
If you've found a good lobby, either from a search or from a friend, you can use
ISteamMatchmaking::JoinLobby and wait for the
LobbyEnter_t call result. Once in the lobby, you'll want to use the lobby data API to get details about the lobby to work out what to display (if there is any display).
When a user joins or leaves a lobby, a
LobbyChatUpdate_t callback is posted to all members of that lobby, including the owner.
To iterate which users are currently in a lobby, use:
To get more information about another user in the lobby, you'll need to use the friends API, see
Friends, invites, and lobbies for more information.
Lobby Metadata
Lobby Metadata allows you to set the arbitrary state of the lobby, including the lobbies name, current map, game mode, current state of the game, or anything else you can think of.
A user will automatically have the latest lobby data for any lobby they are a member of. For lobbies returned via search results, the user will have lobby data for at the point in time as to when they did the search. If it's a friends' lobby, there will be no lobby data available to look at until
ISteamMatchmaking::RequestLobbyData is called and has successfully completed.
If lobby data is changed on a lobby, all lobby members will receive a
LobbyDataUpdate_t callback (this callback is the same way you know a
ISteamMatchmaking::RequestLobbyData call has completed).
These are the set of functions you can use to get and set lobby data. Only the lobby owner can set or delete the lobby data.
Functions which allow you to iterate over the metadata, (this is typically only used for debugging purposes):
Lobbies also allow members to set their own metadata that other members can receive updates for with the following functions.
Communication within a lobby
To send information around within a lobby (chat messages, game start signals, etc.) you need to call
ISteamMatchmaking::SendLobbyChatMsg, this sends a simple binary message to all users in the lobby. Lobby members need to listen for the callback
ISteamMatchmaking::LobbyChatMsg_t. After receiving the callback you then can use
ISteamMatchmaking::GetLobbyChatEntry to retrieve the contents of the message.
Friends, invites, and lobbies
You can find out all the lobbies a user's friends are in with the friends API:
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 is a valid lobby, you can join it or use RequestLobbyData() get its metadata
}
}
You can invite a friend to a lobby with
ISteamMatchmaking::InviteUserToLobbyThat user will receive a chat dialog with a link to join the game. If the user clicks the link, and they are not currently running the game, it will launch the game with the command-line:
+connect_lobby <64-bit lobby id>
. Be sure your app implements
ISteamApps::GetLaunchCommandLine so you can disable the popup warning when launched via a command line.
If the user is already in a game, a
ISteamFriends::GameLobbyJoinRequested_t callback will be posted, which contains the Steam ID of the lobby the user wishes to join. It's up to your game to decide to obey it or not.
If you want the user to select from a list of friends to invite to a lobby, you can call
ISteamFriends::ActivateGameOverlayInviteDialog.
This will activate the Steam in-game overlay to a dialog designed for inviting friends to the current lobby.
Authentication
Any user in a Steam lobby is already fully authenticated with the Steam back-end. There is no need for the game to do any more authentication steps with lobby users, unless it's looking to see if they're VAC banned (see Valve Anti-Cheat Technology). If a user tries to log in from a second location with the same account, their prior login will automatically be removed from any existing lobbies.
Cleaning up
Once the game has started, each user can just leave the lobby with:
ISteamMatchmaking::LeaveLobbyOnce all the users have left, the lobby is automatically destroyed on the back-end.
Lobby Tips
- In general, only create lobbies when needed. For example, when the user invites a friend to play, or triggers a manual action that requires a lobby
- Do not update the metadata on lobbies at a high frequency. Only add in metadata and values that are used for search (for example, game type or game state). You will not need to put in player counts, as a lobby search will already look for lobbies with available slots
- Do not join lobbies just to find out their metadata. Lobby metadata can be downloaded separately for all lobbies, which your game can then use to either show a list of lobbies for a user to pick from, or the game can automatically decide which search result to join
More Questions?
Ask questions on the
Steam Matchmaking & Lobbies discussion forum.