Steamworks-dokumentasjon
Matchmaking og lobbyer på Steam

Oversikt

Steams matchmaking er bygget rundt lobbykonseptet. Lobbyer er objekter som eksisterer i tjenerdelen til Steam, og disse ligner på et samtalerom. Brukere kan opprette en ny lobby, tilknytte data til en lobby, søke etter lobbyer basert på dataene, bli med i lobbyer og dele informasjon med andre brukere i lobbyen. En enkelt lobby kan ha plass til opptil 250 brukere, men de fleste spill har vanligvis 2–16 spillere. Matchmaking basert på ferdighet er bygget oppå dette systemet.

Steams matchmaking-API er et sett med funksjoner som gjør det mulig for brukere å finne andre brukere de kan spille med. Matchmakingfunksjoner finnes i ISteamMatchmaking som inneholder detaljer om parametre for hver funksjon. Lobbyer identifiseres unikt etter Steam-ID, som brukere eller spilltjenere. Steamworks-eksempelet har en fullstendig implementasjon av lobbyer som fungerer.

Prosessflyt for matchmaking

Den vanlige modellen for å få grupper til å spille sammen er som følger:
  1. Brukeren velger spillet som de har lyst til å spille flerspiller i, og hva slags flerspiller de vil ha (regler, scenario, osv.).
  2. Spillet søker etter lobbyer med et lignende sett med regler, med API-et for lobbysøk.
  3. Hvis en lobby finnes, så blir spillet med i den lobbyen. Hvis ingen lobby finnes, så opprettes en ny lobby.
  4. Brukere blir i lobbyen inntil den har nok spillere til å starte spillet. Data kommuniseres mellom lobbymedlemmer om hvilken karakter de har lyst til å spille, eller andre innstillinger per bruker. Hvis det finnes regler som må håndheve i lobbyen (for eksempel hvis kun én bruker kan spille som en spesifikk karakter), så finnes det én og kun én eier av lobbyen som kan brukes for å avgjøre dette.
  5. Det kan finnes et brukergrensesnitt tilknyttet lobbyen – i så fall kan funksjonene for datakommunikasjon i lobbyen brukes for å sende samtalemeldinger mellom lobbymedlemmer. Stemmedata kan også sendes, men dette må gjøres gjennom Steam-nettverk-API-et.
  6. Når spillet er klart til å starte, så blir alle brukere med i spilltjeneren eller kobler til brukeren som er valgt til å være vert for spillet, og forlater så lobbyen. Når alle brukere har forlatt en lobby, så ødelegges den automatisk.

Lobbysøk

For å få spillet til å søke etter en lobby, så må du bruke ISteamMatchmaking::RequestLobbyList
Denne funksjonen er asynkron, og returnerer en SteamAPICall_t-referanse som kan brukes til å spore statusen til forespørselen. Avhengig av brukernes tilkobling til Steams tjenere, så kan dette kallet ta fra 300 ms til 5 sekunder før det er ferdig, og det får tidsavbrudd etter 20 sekunder.
Antall resultater som returneres er resultatet av LobbyMatchList_t, som du så kan bruke ISteamMatchmaking::GetLobbyByIndex iterativt på for å hente ID-er.
Opptil 50 resultater kan returneres, men vanligvis er det bare noen få. Resultatene som returneres er sortert etter geografisk avstand og basert på nærhetsfiltre. Som standard returneres ikke lobbyer som allerede er fulle, og avstandsfilterer er satt til k_ELobbyDistanceFilterDefault (i nærheten). For å legge til filtre må du kalle til én eller flere av filterfunksjonene før du kaller RequestLobbyList:

Oppretter en lobby

I tilfeller der en bruker ikke kan bli med i en eksisterende lobby, så er dette typisk når man oppretter en lobby. Bare kall
ISteamMatchmaking::CreateLobby og vent til det er ferdig. Resultatet av kallet indikerer om det var vellykket, og hvis det var vellykket, så returnerer det Steam-ID-en til lobbyen i et LobbyCreated_t-objekt, som kan brukes for å angi metadata for lobbyen. Det første du må gjøre etter at du oppretter lobbyen er å angi data i lobbyen som andre spillklienter kan bruke for å søke etter den (se nedenfor).

Bli med i lobby

Hvis du har funnet en god lobby, enten gjennom søk eller fra en venn, så kan du bruke ISteamMatchmaking::JoinLobby og vente på resultatet fra LobbyEnter_t. Når du er i lobbyen så bør du bruke API-et for lobbydata for å hente informasjon om lobbyen for å finne ut hva som skal vises (om noe).

Når en bruker blir med i eller forlate en lobby, så sendes et tilbakekall med LobbyChatUpdate_t til alle medlemmer i lobbyen, inkludert eieren.

For å finne brukere som for øyeblikket er i lobbyen, bruk:

For å få mer informasjon om en annen bruker i lobbyen, så må du bruke venne-API-et. Se Venner, invitasjoner og lobbyer for mer informasjon.

Metadata om lobby

Metadata for lobbyen lar deg angi vilkårlige statuser i lobbyen, inkludert navn på lobbyen, aktuelt kart, spillmodus, spillstatus eller hva som helst annet du kan forestille deg.

En bruker får automatisk de nyeste lobbydataene for alle lobbyer de er medlem av. For lobbyer som returneres gjennom søkeresultater, så har brukeren lobbydata fra øyeblikket da de utførte søket. Hvis det er en venns lobby, så kommer ingen lobbydata til å være tilgjengelig før ISteamMatchmaking::RequestLobbyData kalles og er fullført.

Hvis lobbydata endres i en lobby, så mottar alle lobbymedlemmer et tilbakekall fra LobbyDataUpdate_t (dette tilbakekallet er også hvordan man vet at et kall med ISteamMatchmaking::RequestLobbyData er fullført).

Dette er et sett med funksjoner som kan brukes for å hente og angi lobbydata. Kun den som eier lobbyen kan angi eller slette lobbydata.

Funksjoner som lar deg iterere over metadata, (brukes vanligvis kun til feilsøking):

Lobbyer lar også medlemmer angi egne metadata som andre medlemmer kan motta oppdateringer om med følgende funksjoner.

Kommunikasjon innenfor en lobby

For å sende informasjon rundt innenfor en lobby (samtalemeldinger, startsignaler for spill osv.) så må du kalle ISteamMatchmaking::SendLobbyChatMsg. Dette sender en enkel binærmelding til alle brukerne i lobbyen. Lobbymedlemmer må høre etter tilbakekallet, ISteamMatchmaking::LobbyChatMsg_t. Etter å ha mottatt tilbakekallet, så kan du bruke ISteamMatchmaking::GetLobbyChatEntry for å hente innholdet i meldingen.

Venner, invitasjoner og lobbyer

Du kan finne ut alle lobbyene en brukers venner er i med venne-API-et:
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 er en gyldig lobby. Du kan bli med i den eller bruke RequestLobbyData() for å hente metadata om den }

Du kan invitere en venn til en lobby med ISteamMatchmaking::InviteUserToLobby
Brukeren får da opp en samtalemelding med en lenke til å bli med. Hvis brukeren trykker på lenken og de for øyeblikket ikke kjører spillet, så startes spillet fra kommandolinjen:
+connect_lobby <64-bit lobby id>. Sørg for at applikasjonen implementerer ISteamApps::GetLaunchCommandLine slik at du kan slå av advarselen ved oppstart gjennom kommandolinjen.

Hvis brukeren allerede er i et spill, så sendes et tilbakekall med ISteamFriends::GameLobbyJoinRequested_t som inneholder Steam-ID-en til lobbyen brukeren har lyst til å bli med i. Det er opp til spillet ditt å avgjøre om det skal adlyde eller ikke.

Hvis du vil at du brukeren skal velge fra en liste over venner å invitere til en lobby, så kan du kalle ISteamFriends::ActivateGameOverlayInviteDialog.
Dette aktiverer overlegget i spil på Steam til en dialog som er utformet for å invitere venner til den aktuelle lobbyen.

Autentisering

Enhver bruker i en lobby på Steam er allerede fullstendig autentisert hos tjenerne til Steam. Det er ikke nødvendig for spillet å utføre flere autentiseringssteg med brukere i lobbyen, med mindre man prøver å se om det er utestengt av VAC (Valves teknologi for antijuks). Hvis en bruker prøver å logge inn fra et annet sted med nøyaktig samme konto, så fjernes den tidligere innloggingen automatisk fra eventuelle eksisterende lobbyer.

Opprydding

Når spillet har startet, så kan hver bruker forlate lobbyen med:
ISteamMatchmaking::LeaveLobby
Når alle brukere har forlatt, så ødelegges lobbyen automatisk i tjenerne.

Lobbytips

  • Som hovedregel bør man kun opprette lobbyer når nødvendig. For eksempel når en bruker inviterer en venn til å spille eller utløser en manuell handling som krever en lobby.
  • Ikke oppdater metadataene til lobbyer for ofte. Legg kun til metadata og verdier som brukes til søk (for eksempel spilltype eller spillstatus). Du trenger ikke å angi antall spillere, ettersom lobbysøket allerede leter etter lobbyer med tilgjengelige plasser.
  • Ikke bli med i lobbyer bare for å hente metadata om dem. Metadata for lobby kan lastes ned separat for alle lobbyer, og spillet kan da bruke disse til å enten vise en liste over lobbyer en bruker kan velge fra, eller så kan spillet automatisk velge hvilket søkeresultat å bli med i.

Flere spørsmål?

Still spørsmål på diskusjonsforumet for matchmaking og lobbyer på Steam.