Uden tilknytning

Hjem Dokumentation og hjælp
Steamworks-dokumentation
Oversigt over Steamworks-API

Oversigt

Steamworks-API'en gør det muligt for dit spil at udnytte mulighederne ved Steam bedst muligt ved at få adgang til alle de underliggende systemer, som leveres gennem API'en. Dette inkluderer ting såsom at sætte dit spil på pause, når brugeren åbner Steam-overlayet, invitere venner til at spille, lade spillere låse op for Steam-præstationer, lade spillere konkurrere på Steam-førertavlerne og meget mere.

Steamworks API Reference dokumenterer alle grænseflader, funktioner, tilbagekald og typer, som er understøttet i API'en.

Integrering med Steamworks-APIen er aldrig et krav for at udgive dit produkt på Steam, men det anbefales kraftigt, fordi det gør det muligt for dig at udføre mange interaktioner, som Steam-brugere forventer.

Sådan kommer du i gang

BEMÆRK: Steamworks-API'en understøtter officielt C++ ved hjælp af Microsoft Visual Studio 2008+ på Microsoft Windows, GCC 4.6+ og Clang 3.0+ på macOS og SteamOS/Linux. Hvis du bruger en tredjepartsmotor eller et andet programmeringssprog end C++, bør du først kigge på Understøttelse af kommercielle motorer og sprog, som ikke er C++ for at se, om der er nogle mere specifikke instruktioner til at komme i gang med din valgte motor eller sprog. I nogle tilfælde kan du muligvis springe over mange af disse trin.

  • Hvis du ikke allerede har gjort det, skal du downloade Steamworks-SDK'en og pakke den ud.
  • Kopier Steamworks-API-headermappen public/steam til et passende sted i dit applikationskildetræ.
  • Inkluder en af de følgende headerfiler i dit C++-projekt:
    • steam_api.h – Dette inkluderer alle andre Steamworks-headers og giver adgang til at initialisere Steamworks-API'en.
    • steam_gameserver.h – Dette bør kun inkluderes, hvis du bruger Steam-GameServer-API'en. Dette inkluderer steam_api.h internt, så det er ikke nødvendigt at inkludere begge.
  • Kopier de relevante redistributuable-filer fra redistributable_bin til et passende sted i din projektmappe.
    • Windows
      Du skal have steam_api[64].lib-tilknytning i dit Visual Studio-projekt. Dette kan tilknyttes til enten den primære eksekverbare fil eller et modul, som bruger Steam. Dette giver dig adgang til funktionalitet i steam_api[64].dll, som vises via Steamworks-API-headerne. Yderligere oplysninger: Tilknytning af en eksekverbar fil til en DLL (MSDN)

      Du skal også udgive steam_api[64].dll i din kørselsmappe (ved siden af dit programs eksekverbare fil eller i din DLL-søgningssti).
    • macOS
      libsteam_api.dylib giver både x86- og x64-versionen af Steam-API'en. Du skal tilknytte dette i dit XCode-ptojekt, og det kræves, at du udgiver dette sammen med din eksekverbare fil.
      Yderligere oplysninger: Sådan bruges dynamiske biblioteker
    • Linux
      libsteam_api.so Du skal både tilknytte og udgive dette sammen med din eksekverbare fil.

Initialisering og lukning

SteamAPI_Init

Når du har sat Steamworks-API'en op i dit projekt, kan du begynde at bruge den ved at kalde SteamAPI_Init-funktionen for at initialisere API'en. Dette vil indstille den globale tilstand og udfylde grænseflademarkørerne, som er tilgængelige via globale funktioner, som passer til navnet på grænsefladen. Dette SKAL kaldes og returneres, før Steamworks-grænseflader tilgås!

Steamworks-API'en bliver ikke initaliseret, hvis den ikke kender app-ID'et til dit spil. Når du starter din app fra selve Steam, vil den automatisk have app-ID'et. Under udviklingsarbejdet skal du give Steam besked om dette med en tekstfil. Opret en tekstfil kaldet steam_appid.txt ved siden af din eksekverbare fil, som kun indeholder app-ID'et og intet andet. Dette overskriver værdien, som Steam giver. Du bør ikke udgive dette med dine builds. Eksempel:
480

Hvis false returneres, indikerer det en af de følgende tilstande:
  • Steam-klienten kører ikke. Der kræves en kørende Steam-klient for at give implementeringer af forskellige Steamworks-grænseflader.
  • Steam-klienten kunne ikke bestemme spillets app-ID. Hvis du kører din applikation fra den eksekverbare fil eller direkte fra fejlfinderen, skal du have en steam_appid.txt i din spilmappe ved siden af den eksekverbare fil sammen med dit app-ID og intet andet. Steam kigger efter denne fil i den nuværende arbejdsmappe. Hvis du kører din eksekverbare fil fra en anden mappe, kan du blive nødt til at flytte steam_appid.txt-filen.
  • Din applikation kører ikke under den samme OS-brugerkontekst som Steam-klienten, såsom en anden bruger eller administrationsadgangsniveau.
  • Du skal sikre dig, at du ejer en licens for app-ID'et på den nuværende aktive Steam-konto. Dit spil skal dukke op i dit Steam-bibliotek.
  • Dit app-ID er ikke helt sat op, for eksempel i Release State: Unavailable, eller det mangler standardpakker.
Hvis du støder på problemer med initialisering, skal du tjekke dokumentationen Debugging the Steamworks API for at lære mere om de forskellige metoder.

SteamAPI_RestartAppIfNecessary

SteamAPI_RestartAppIfNecessary tjekker, om din eksekverbare fil blev startet gennem Steam, og genstarter den gennem Steam, hvis den ikke blev startet gennem Steam første gang.

Dette er valgfrit, men anbefales kraftigt, da Steam-konteksten, som er tilknyttet din applikation (inklusive dit app-ID), ikke vil blive sat op, hvis brugeren starter den eksekverbare fil direkte. Hvis dette sker, vil SteamAPI_Init fejle, og du vil ikke være i stand til at bruge Steamworks-API'en.
Hvis du vælger at bruge denne, bør det være det første Steamworks-funktionskald, du laver lige før SteamAPI_Init.

Hvis true returneres, vil det starte Steam-klienten, hvis det er påkrævet, og starte dit spil gennem Steam. Du bør afslutte processen så snart, det er muligt. Dette kører reelt set steam://run/<AppID>, så det kan være, at det ikke genoptager den samme eksekverbare fil, som kaldte denne funktion (for eksempel hvis du kørte fra din fejlfinder). Det vil altid starte op igen fra versionen, som du har installeret i din Steam-biblioteksmappe.

Ellers hvis dette returnerer false, blev dit spil startet af Steam-klienten, og ingen handling er nødvendig. En undtagelse er, hvis en steam_appid.txt-fil findes, så vil dette returnere false uanset. Dette giver dig mulighed for at udvikle og teste uden at starte dit spil gennem Steam-klienten. Sørg for at fjerne steam_appid.txt-filen, når du uploader spillet til dit Steam-depot!

BEMÆRK: Hvis du bruger Steam DRM-wrapperen på din primære eksekverbare fil, er denne kontrol unødvendig, da DRM-wrapperen vil udføre dette internt.

SteamAPI_Shutdown

Når du er færdig med at bruge Steamworks-API'en, bør du kalde SteamAPI_Shutdown for at frigive resurserne, som bruges af din applikation internt i Steam. Du bør kalde dette under lukningsprocessen, hvis det er muligt.

Dette vil ikke fjerne tilknytningen af Steam-overlay fra dit spil, da der ikke er nogen garanti for, at din gengivelses-API er færdig med at bruge den.

Steamworks-grænseflader

Steamworks-API'en er sammensat af flere grænseflader, som alle viser en begrænset, specifik mængde af funktionalitet.

Når Steamworks er korrekt initialiseret, kan du tilgå grænsefladerne via deres globale funktioner. Funktionerne matcher altid navnet på deres grænseflade. Derfor kan du tilgå ISteamApps gennem SteamApps()-accessoren og ISteamFriends gennem SteamFriends().

Du kan bruge disse grænseflader til at foretage kald således:
// Henter den nuværende brugers Steam-navn. const char *name = SteamFriends()->GetPersonaName();

Du kan se den komplette liste over grænseflader på Steamworks API Reference eller ved at se på Steamworks-API-headerfilerne.

Tilbagekald

Tilbagekald er et af de vigtigste aspekter af Steamworks, da de gør det muligt for dig at hente data asynkront fra Steam uden at låse for dit spil. Formålet med tilbagekald er at give en simpel, let, type- og trådsikker metode til at hæve asynkrone hændelser på ethvert objekt, som er registreret som lytter.

Tilbagekald udløses normalt via en hændelse, der sker fra Steam, såsom når en ven logger på eller af eller asynkrone resultater fra API-funktioner. Hvert tilbagekald består af en struktur, som indeholder en unik identifikator og et mindre datasæt. Tilbagekald erklæres i ISteam*.h-headerfilerne, grupperet med grænsefladen, som kaldet hører tættest til.

For at lytte efter et tilbagekald skal en struktur bruge makroen STEAM_CALLBACK( :classname, :functionname, :callbackname ) i dens erklæring.
  • :classname skal være navnet på strukturen eller klassen, hvor du definerer dette. (for eksempel CGameManager)
  • :functionname vil være navnet på funktionen, som modtager dette tilbagekald. (for eksempel OnGameOverlayActivated)
  • :callbackname er navnet på tilbagekaldet. (for eksempel GameOverlayActivated_t)
Dette definerer en lokal medlemsfunktion for klassen, som automatisk er lavet som prototype som void :functionname( :callbackname *pCallback ). Oprettelse af en ny forekomst af objektet vil forårsage, at denne medlemsfunktion vil registrerer sig selv som lytter med Steamworks-API'en. Destruktion af objektet vil forårsage, at det vil afregistrere.

BEMÆRK: Du bør sikre, at Steam er opstartet, før du opretter objekter, som lytter efter tilbagekald.

For at forberede tilbagekald til at sende til registrerede lyttere skal du kalde SteamAPI_RunCallbacks. Det er best at kalde dette ofte, da desto tid imellem kald, desto mere forsinkelse mellem modtagende begivenheder eller resultater fra Steamworks-API'en. De fleste spil kalder denne én gang gengivelsesbillede. Det anbefales stærkt, at du laver dette kald mindst én gang i sekundet. Alle registrerede lyttefunktioner vil blive aktiveret under dette kald i trådkonteksten, hvor SteamAPI_RunCallbacks blev kaldt fra.

Eksempel

Et tilbagekald, som du med stor sandsynlighed ønsker at bruge, er ISteamFriends::GameOverlayActivated_t. Som navnet hentyder, sender det et tilbagekald til dig, hver gang brugeren aktiverer eller deaktiverer Steam-overlay.

class CGameManager { private: STEAM_CALLBACK( CGameManager, OnGameOverlayActivated, GameOverlayActivated_t ); }; void CGamemanager::OnGameOverlayActivated( GameOverlayActivated_t* pCallback ) { if ( pCallback->m_bActive ) printf( "Steam overlay now active\n" ); else printf( "Steam overlay now inactive\n" ); }

En populær og anbefalet anvendelse af ISteamFriends::GameOverlayActivated_t-tilbagekaldet er at sætte spillet på pause, når overlayet åbner.

CallResults

Mange Steamworks-metoder bruger resultater fra kald i stedet for et tilbagekald for asynkront at returnere resultater fra et funktionskald. Forskellen mellem et tilbagekald og kaldsresultater er, at tilbagekald sendes til alle, som lytter, hvorimod kaldsresultater kun sendes til en specifik lytter. Ligesom med tilbagekald skal dit spil kalde SteamAPI_RunCallbacks for at sende kaldsresultater til lyttere.

Du kan identificere en funktion, som giver kaldsresultater ved at kigge på returværdien. Hvis SteamAPICall_t returneres og har en CALL_RESULT()-attribut, skal du registrere for at modtage kaldsresultatet.

BEMÆRK: Tilbagekalds- og kaldsresultater er ikke udskiftelige. En hændelse vil kun gå igennem det ene eller det andet, ikke begge. Du skal sørge for, at du registrerer den rigtige type hændelse!

Resultater fra kald skal oprettes som et medlem i en struktur/klasse ved at bruge CCallResult-typen, og du skal også oprette medlemsfunktionen, som vil modtage tilbagekaldet.
void func( :callresultname *pCallback, bool bIOFailure ); CCallResult< :classname, :callresultname > m_callresultname;
  • :classname skal være navnet på strukturen eller klassen, hvor du definerer dette. (for eksempel CGameManager)
  • :callresultname er navnet på tilbagekaldet. (for eksempel NumberOfCurrentPlayers_t)

Du er velkommen til at navngive funktionen, funktionsparametre og CCallResult efter eget valg.

Eksempel

Her er et eksempel på, hvordan du bruger ISteamUserStats::GetNumberOfCurrentPlayers-API, som producerer et ISteamUserStats::NumberOfCurrentPlayers_t-kaldsresultat.
// I din klassedefinition class CGameManager { public: void GetNumberOfCurrentPlayers(); private: void OnGetNumberOfCurrentPlayers( NumberOfCurrentPlayers_t *pCallback, bool bIOFailure ); CCallResult< CGameManager, NumberOfCurrentPlayers_t > m_NumberOfCurrentPlayersCallResult; }; // Gør, at asynkrone anmodninger modtager antallet af aktuelle spillere. void CGameManager::GetNumberOfCurrentPlayers() { printf( "Getting Number of Current Players\n" ); SteamAPICall_t hSteamAPICall = SteamUserStats()->GetNumberOfCurrentPlayers(); m_NumberOfCurrentPlayersCallResult.Set( hSteamAPICall, this, &CGameManager::OnGetNumberOfCurrentPlayers ); } // Kaldes, når SteamUserStats()->GetNumberOfCurrentPlayers() returnerer asynkront efter et kald til SteamAPI_RunCallbacks(). void CGameManager::OnGetNumberOfCurrentPlayers( NumberOfCurrentPlayers_t *pCallback, bool bIOFailure ) { if ( bIOFailure || !pCallback->m_bSuccess ) { printf( "NumberOfCurrentPlayers_t failed!\n" ); return; } printf( "Number of players currently playing: %d\n", pCallback->m_cPlayers ); }

BEMÆRK: Hvis du ikke kan bruge CCallResult-systemet, kan du muligvis bruge ISteamUtils::IsAPICallCompleted, ISteamUtils::GetAPICallResult og ISteamUtils::GetAPICallFailureReason til at spore statussen af et kaldsresultat.

Steam-spilservere

Steamworks-API'en inkluderer understøttelse til kørende spilservere såvel som almindelige klienter. I Steamworks-API-terminologi er en spilserver en enhed i systemet, som normale brugere tilknytter for at spille multiplayer-spil. Denne kan forbindes over internettet til en ekstern spilserver eller forbindes lokalt til en spilserver, som er i den samme proces som klienten. Spilservere har deres egne sæt af API-funktioner til brug, og deres eget unikke Steam-ID, som andre brugere kan anvende til at henvise til dem.

For at bruge Steam-spilserver-API'en skal du først inkludere steam_gameserver.h i stedet for steam_api.h.

Initialisering og brug af spilserver-API'en ligner den normale API meget:

Efter initialisering af en spilsever har du adgang til to eksklusive spilservergrænseflader: ISteamGameServer og ISteamGameServerStats.

Du kan også tilgå følgende almindelige grænseflader fra spilserveren:
  • ISteamClient, som du kan tilgå via den globale grænseflade: SteamGameServerClient()
  • ISteamUtils, som du kan tilgå via den globale grænseflade: SteamGameServerUtils()
  • ISteamNetworking, som du kan tilgå via den globale grænseflade: SteamGameServerNetworking()
  • ISteamHTTP, som du kan tilgå via den globale grænseflade: SteamGameServerHTTP()
  • ISteamInventory, som du kan tilgå via den globale grænseflade: SteamGameServerInventory()
  • ISteamUGC, som du kan tilgå via den global grænseflade: SteamGameServerUGC()
  • ISteamApps, som du kan tilgå via den globale grænseflade: SteamGameServerApps()

Hvis du kører en dedikeret spilserver (en, som ikke har nogen klientkomponent), skal du kun initalisere spilserver-API'erne. Du behøver ikke at initalisere den normale bruger-API.

Se Steamworks API Example Application (SpaceWar) for et komplet eksempel på brug af spilserver-API'en.

Understøttelse af kommercielle motorer og sprog, som ikke er C++

Hvis du bruger en kommerciel spilmotor eller et sprog andet end C eller C++, vil du sikkert gerne se, hvilket niveau af understøttelse af Steamworks-API'en der er til det.
I nogle motorer er der indbygget understøttelse, for andre kan det være, at du skal bruge en tredjepartsløsning.

Hvis din motor ikke har indbygget understøttelse, kan du bruge Steams web-API til at tilgå mange funktioner, som Steam understøtter.

Uanset hvordan Steamworks-SDK'en er implementeret i din motor, skal du have den seneste Steamworks-SDK for at uploade din applikation til Steam.

BEMÆRK: Hvis noget af softwaren, som du udgiver på Steam, er tilgængelig under en begrænset open source-licens, skal du se Distribuering af open source-applikationer på Steam.

Her er nogle almindelige motorer, som folk ofte bruger til at udgive spil på Steam, og den relevante dokumentation om, hvordan du kommer i gang med at bruge Steamworks-SDK'en med dem.

BEMÆRK: Valve støtter på ingen måde nogen af disse motorer eller tredjepartsløsninger. Denne liste er udelukkende sorteret efter navn og er på ingen måde altomfattende. Den er blot tiltænkt som et udgangspunkt. Motorer medtages kun på listen, hvis de inkluderer indbygget understøttelse eller har tredjepartsløsninger, som passer med retningslinjerne. Tredjepartsløsninger medtages kun på listen, hvis de holdes forholdsvis opdaterede med Steamworks-SDK'en, er frit tilgængelige under en eftergivende licens (se: Distribuering af open source-applikationer på Steam), og start en tråd på Steamworks-diskussionsiden. Vi anbefaler, at du konsulterer fællesskabet for at se, hvilke muligheder der vil fungere bedst for netop din opsætning.

Motorer:

MotorIndbygget understøttelse?Oplysninger
CRYENGINE ✔️
GameMaker Studio 2 ✔️ Brug af Steamworks-SDK med GameMaker: Studio
Godot Tredjepart: GodotSteam - Steamworks-udviklerdiskussioner – supporttråd
Haxe Tredjepart: SteamWrap - Steamworks-udviklerdiskussioner – supporttråd
Leadwerks Game Engine ✔️ Leadwerks API Reference › Steamworks
RPG Maker MV Tredjepart: Greenworks - Steamworks-udviklerdiskussioner – supporttråd
Source 2013 ✔️ Distribuering af Source Engine-spil
Unity Tredjepart: Facepunch.Steamworks - Steamworks-udviklerdiskussioner – supporttråd
Tredjepart: http://steamworks.github.io - Steamworks-udviklerdiskussioner – supporttråd
Unreal Engine 4 ✔️ Steam, brug af Steam-SDK'en under udvikling
Visionaire Studio ✔️ Udgiv på Steam

Sprog:

Tekniske detaljer

Steam bruger en bred vifte af teknikker til at eksponere funktioner til din applikation. Det er på ingen måde afgørende at forstå præcist, hvordan Steamworks-API'en fungerer, men det er rimelig simpelt og kan være nyttigt til at planlægge, hvordan du skal kode dit spil med Steam-integrering i tankerne.

Når du linker til steam_api[64][.dll/.so/dylib], giver det adgang til et mindre antal af C-funktioner med S_API-makroen som præfiks. Disse funktioner er alle eksponeret i steam_api.h og steam_gameserver.h. Modulet steam_api er meget lille i sig selv. Det eksponerer kun grundfunktionen til initalisering og lukning af Steamworks-API'en.

Efter initialisering finder Steamworks-API'en den aktive proces fra Steam-klienten og loader steamclient.dll fra stien. steamclient.dll er i bund og grund kernemotoren i Steam-klienten. Den indeholder og vedligeholder de oplysninger, som er nødvendige for at køre Steam. Steam-klientens grænseflade anvender et lignende funktionssæt som det, der er beskrevet her, til at tilgå data fra steamclient.dll. Eftersom disse data er i Steam-processen, arrangeres alle Steam-API-kald åbent og sendes via en RPC/IPC-mekanisme. (Krydsproces-pipe: ISteamClient::HSteamPipe).

Steam-processen, via steamclient.dll, vedligeholder en konstant forbindelse til Steam-backend-serverne. Godkendelse, matchmaking, vennelister og VAC-kommunikation sker gennem denne forbindelse. Forbindelsen kan blive afbrudt, hvis der opstår et netværksproblem hos brugeren, eller hvis deb Steam-server, brugeren er forbundet til, modtager en opdatering. Tilbagekald sendes til aktive apps, hvis forbindelsen afbrydes eller genetableres. Steam-klienten prøver automatisk at genoprette forbindelsen, og klienter, som kører en app, prioriteres, så almindeligvis er genoprettelsestiden under 10 sekunder, selvom det i visse sjældne tilfælde kan tage op til 5 minutter.

Steamworks-API'en er versioneret gennem en COM-lignende mekanisme, hvor et strengnavn og en version af en grænseflade sendes til steamclient.dll, som derefter returnerer den korrekte grænsefladeversion til kalderen. steamclient.dll indeholder et sæt adaptere til alle udgivne versioner af en grænseflade, som videresender eller genfortolker de gamle kald i den seneste grænseflades kontekst. Adapterne eksisterer i Steam-klienten, så de er nemme at opdatere, hvis der opstår problemer.