Présentation
L'API Steamworks permet à votre jeu de tirer pleinement parti de Steam en accédant à tous les systèmes sous-jacents proposés via l'API. Ceci inclut des éléments tels que mettre en pause votre jeu lorsque quelqu'un ouvre
l'overlay Steam, inviter des contacts à jouer, autoriser les joueurs et joueuses à débloquer des
succès Steam, permettre à la communauté de s'affronter pour une place dans les
classements Steam et plus encore.
L'article
Références de l'API Steamworks catalogue et documente chaque interface, fonction, rappel et type pris en charge par l'API.
L'intégration à l'API Steamworks n'est jamais obligatoire pour la publication de votre produit sur Steam, mais elle est fortement recommandée, car elle vous permet de mettre en œuvre de nombreuses interactions auxquelles s'attendent les utilisateurs et utilisatrices de Steam.
C'est parti
REMARQUE : L'API Steamworks prend officiellement en charge le C++, à l'aide de Microsoft Visual Studio 2008+ sur Microsoft Windows, de GCC 4.6+ et de Clang 3.0+ sur macOS et SteamOS/Linux. Si vous utilisez un moteur tiers ou un langage de programmation différent du C++, vous devriez alors jeter un œil à l'article
Moteur du commerce et prise en charge des langages non C++ afin de voir si d'autres instructions spécifiques sont disponibles pour vous aider à démarrer avec le moteur ou le langage de votre choix. Dans certains cas, il est possible que vous puissiez passer un bon nombre de ces étapes.
- Si vous ne l'avez pas déjà fait, téléchargez le SDK Steamworks et décompressez-le.
- Copiez le dossier d'entêtes de l'API Steamworks
public/steam
dans un endroit approprié de l'arborescence source de votre application.
- Copiez les fichiers redistribuables concernés de
redistributable_bin
dans un endroit approprié dans le dossier de votre projet.
- Windows
Vous devez avoir steam_api[64].lib
associé à votre projet Visual Studio. Il peut être associé soit à l'exécutable principal, soit à un module utilisant Steam. Cela vous permet d'accéder à la fonctionnalité contenue dans steam_api[64].dll
exposée via les entêtes de l'API Steamworks. Lecture complémentaire : associer un exécutable à une DLL (MSDN)
Vous devez également publier steam_api[64].dll
dans votre répertoire d'exécution (à côté de votre exécutable de programmes ou dans le chemin d'accès à vos dll).
- macOS
libsteam_api.dylib
fournit à la fois la version x86 et x64 de l'API Steam. Vous devez relier ceci à votre projet XCode et le livrer en même temps que votre exécutable.
Lecture complémentaire :
Utiliser les bibliothèques dynamiques.
- Linux
libsteam_api.so
: vous devez l'associer et l'envoyer en même temps que votre exécutable.
Initialisation et arrêt
SteamAPI_Init
Une fois l'API Steamworks configurée au sein de votre projet, vous pouvez l'utiliser en appelant la fonction
SteamAPI_Init afin d'initialiser l'API. Ceci définira le statut global et remplira les pointeurs d'interface accessibles via les fonctions globales correspondant au nom de l'interface. Cette fonction
DOIT être appelée et renvoyée avec succès avant l'accès à une des
Interfaces Steamworks !
L'API Steamworks ne s'initialisera pas si elle ne connait pas l'AppID de votre jeu. Lorsque vous lancez votre application depuis la plateforme Steam elle-même, elle disposera automatiquement de l'AppID disponible. Pendant le développement, vous devrez le suggérer à Steam à l'aide d'un fichier texte. Créez le fichier texte nommé
steam_appid.txt
à côté de votre exécutable ne contenant que l'AppID et rien d'autre. Celui-ci se substituera à la valeur fournie par Steam. Vous ne devez pas le livrer avec vos versions. Exemple :
480
Un renvoi
false indique l'une des conditions suivantes.
- Le client Steam n'est pas en cours d'exécution. Un client Steam en cours d'exécution est requis pour fournir l'implémentation des différentes interfaces Steamworks.
- Le client Steam n'a pas pu déterminer l'AppID du jeu. Si vous exécutez votre application directement depuis l'exécutable ou le débogueur, alors vous devez avoir un fichier
steam_appid.txt
dans le répertoire de votre jeu, dans le même dossier que l'exécutable. Ce fichier texte ne doit contenir que l'AppID du jeu et rien d'autre. Steam va chercher ce fichier dans le répertoire de travail actuel. Si vous lancez votre exécutable depuis un répertoire différent, vous devrez peut-être déplacer le fichier steam_appid.txt
.
- Votre application ne s'exécute pas sous le même contexte d'utilisation de système d'exploitation que le client Steam. Il peut s'agir d'un niveau d'accès d'utilisation ou d'administration différent.
- Le compte Steam actuellement actif ne possède pas de licence pour l'AppID. Assurez-vous que votre jeu s'affiche dans votre bibliothèque Steam.
- Votre AppID n'est pas complètement paramétré (
Statut de publication : indisponible
), ou il lui manque des packages par défaut.
Si vous rencontrez des problèmes d'initialisation, consultez l'article
Débogage de l'API Steamworks de la documentation pour en apprendre plus sur les diverses méthodes de débogage de l'API Steamworks.
SteamAPI_RestartAppIfNecessary
SteamAPI_RestartAppIfNecessary vérifie si votre exécutable a été lancé via Steam et le relance via Steam si ce n'était pas le cas.
Cette opération est optionnelle, mais fortement recommandée, car le contexte de Steam associé à votre application (dont votre AppID) ne sera pas défini si la personne lance l'exécutable directement. Si cela se produit,
SteamAPI_Init
échouera et vous serez incapable d'utiliser l'API Steamworks.
Si vous choisissez de l'utiliser, alors ce doit être le premier appel de fonction Steamworks que vous effectuez, avant
SteamAPI_Init.
Si cette fonction renvoie
true, alors elle lance le client Steam si nécessaire et lance votre jeu à nouveau via le client. Vous devrez alors demander l'arrêt du processus actuel dès que possible. La fonction exécute
steam://run/<AppID>
. Ainsi, l'exécutable lancé par la fonction peut ne pas être le même qui l'a appelée (par exemple, si vous l'exécutiez depuis votre débogueur). L'exécutable se relancera toujours depuis la version installée dans le dossier de votre bibliothèque Steam.
Si cette fonction renvoie
false, alors votre jeu sera lancé par le client Steam et aucune action ne sera nécessaire. Une exception existe si un fichier
steam_appid.txt
est présent ; la fonction renverra alors
false dans tous les cas. Cela vous permet de développer et de tester votre jeu sans le lancer via le client Steam. Pensez à supprimer le fichier
steam_appid.txt
lorsque vous mettez en ligne le jeu dans votre dépôt Steam !
REMARQUE : cette vérification n'est pas nécessaire si vous utilisez l'outil de protection DRM Steam sur votre fichier exécutable principal, car l'outil de protection DRM s'en chargera en interne.
SteamAPI_Shutdown
Lorsque vous avez terminé d'utiliser l'API Steamworks, vous devez appeler
SteamAPI_Shutdown pour libérer les ressources utilisées par votre application en interne au sein de Steam. Vous devez effectuer cet appel pendant le processus de fermeture, si possible.
Cela ne supprimera pas le hook de l'
overlay Steam associé à votre jeu, car il n'est pas garanti que votre API de rendu ait terminé de l'utiliser.
Interfaces Steamworks
L'API Steamworks se compose de plusieurs interfaces proposant toute une gamme limitée et spécifique de fonctionnalités.
Une fois que Steamworks s'est initialisé avec succès, vous pouvez accéder aux interfaces via leurs fonctions globales. Les fonctions correspondent toujours au nom de leur interface. De fait, vous pouvez accéder à
ISteamApps via l'accesseur
SteamApps()
et
ISteamFriends via
SteamFriends()
.
Vous pouvez utiliser ces interfaces pour effectuer des appels comme suit :
// Récupère le nom du compte utilisant Steam.
const char *name = SteamFriends()->GetPersonaName();
Vous pouvez afficher la liste complète des interfaces sur la
Références de l'API Steamworks ou en consultant les fichiers d'entête de l'API Steamworks.
Rappels
Les rappels sont l'un des aspects les plus importants de Steamworks : ils vous permettent de récupérer des données de manière asynchrone depuis Steam sans bloquer votre jeu. L'objectif des rappels est de proposer une méthode simple, légère, de type sécurisé et thread-safe de déclencher des évènements asynchrones pour tout objet enregistré comme écouteur.
Les rappels sont généralement déclenchés par un évènement survenant depuis Steam, comme la connexion ou la déconnexion d'un contact, ou par le résultat asynchrone de certaines fonctions d'API. Chaque rappel se compose d'un struct contenant un identifiant unique et d'un petit ensemble de données. Les rappels sont déclarés dans les fichiers d'entête
ISteam*.h
, groupés avec l'interface apparentée la plus proche.
Pour écouter le déclenchement d'un rappel, une structure ou une classe doit utiliser la macro
STEAM_CALLBACK( :classname, :functionname, :callbackname )
dans sa déclaration.
-
:classname
doit être le nom de la classe ou de la structure dans laquelle vous le définissez. (par exemple, CGameManager
)
-
:functionname
sera le nom de la fonction recevant ce rappel. (par exemple, OnGameOverlayActivated
)
-
:callbackname
est le nom du rappel. (par exemple, GameOverlayActivated_t
)
Ceci définit une fonction membre locale pour cette classe, automatiquement prototypée sous la forme
void :functionname( :callbackname *pCallback )
. La création d'une nouvelle instance de l'objet entrainera l'autoenregistrement de cette fonction membre comme écouteur auprès de l'API Steamworks ; la destruction de l'objet entrainera l'annulation de cet enregistrement.
REMARQUE : assurez-vous que Steam se soit bien initialisé avant de créer des objets à l'écoute des rappels.
Pour les rappels devant être dirigés vers des écouteurs enregistrés, vous devez appeler
SteamAPI_RunCallbacks. Il est recommandé d'effectuer cet appel fréquemment, car plus l'intervalle entre les appels est important, plus la latence sera importante entre les évènements ou les résultats reçus depuis l'API Steamworks. La plupart des jeux effectuent cet appel une fois par image rendue. Nous vous recommandons fortement d'effectuer cet appel au moins une fois par seconde. Toutes les fonctions d'écouteurs enregistrées seront invoquées pendant cet appel, dans le contexte du thread depuis lequel
SteamAPI_RunCallbacks
a été rappelé.
Exemple :
Un rappel que vous souhaiterez probablement utiliser sera
ISteamFriends::GameOverlayActivated_t. Comme son nom l'indique, cette fonction vous adresse un rappel chaque fois que la personne active ou désactive l'
Overlay Steam.
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" );
}
Un cas d'utilisation populaire et recommandé du rappel
ISteamFriends::GameOverlayActivated_t est la mise en pause du jeu à l'ouverture de l'overlay.
Résultats d'appel
De nombreuses méthodes Steamworks utilisent les résultats d'appel au lieu d'un rappel afin de renvoyer de manière asynchrone les résultats depuis un appel de fonction. La différence entre un rappel et les résultats d'appel est que les rappels sont émis à l'attention de tous les écouteurs, tandis que les résultats d'appel ne ciblent qu'un écouteur spécifique. Comme pour les rappels, votre jeu devra appeler
SteamAPI_RunCallbacks pour diriger les résultats d'appel vers leur écouteur.
Vous pouvez identifier une fonction fournissant un résultat d'appel en inspectant sa valeur de retour ; si elle renvoie
SteamAPICall_t et dispose d'un attribut
CALL_RESULT()
, vous devez alors vous enregistrer pour recevoir le résultat d'appel.
REMARQUE : les rappels et les résultats d'appel ne sont pas interchangeables. Un évènement ne passera que par l'un ou par l'autre canal, pas par les deux. Vous devez vous assurer de bien vous enregistrer pour le bon type d'évènement !
Les résultats d'appel doivent être créés en tant que membre d'un struct/d'une classe à l'aide du type CCallResult ; vous devrez également créer la fonction membre qui recevra le rappel.
void func( :callresultname *pCallback, bool bIOFailure );
CCallResult< :classname, :callresultname > m_callresultname;
-
:classname
doit être le nom de la classe ou de la structure dans laquelle vous le définissez. (par exemple, CGameManager
)
-
:callresultname
est le nom du rappel. (par exemple, NumberOfCurrentPlayers_t
)
N'hésitez pas à donner le nom de votre choix à la fonction, aux paramètres de fonction et au type CCallResult.
Exemple :
Voici un exemple d'utilisation de l'API
ISteamUserStats::GetNumberOfCurrentPlayers qui produit un résultat d'appel
ISteamUserStats::NumberOfCurrentPlayers_t.
// Dans la définition de votre classe.
class CGameManager
{
public:
void GetNumberOfCurrentPlayers();
private:
void OnGetNumberOfCurrentPlayers( NumberOfCurrentPlayers_t *pCallback, bool bIOFailure );
CCallResult< CGameManager, NumberOfCurrentPlayers_t > m_NumberOfCurrentPlayersCallResult;
};
// Effectue la requête asynchrone pour recevoir le nombre actuel de personnes.
void CGameManager::GetNumberOfCurrentPlayers()
{
printf( "Getting Number of Current Players\n" );
SteamAPICall_t hSteamAPICall = SteamUserStats()->GetNumberOfCurrentPlayers();
m_NumberOfCurrentPlayersCallResult.Set( hSteamAPICall, this, &CGameManager::OnGetNumberOfCurrentPlayers );
}
// Appelée quand SteamUserStats()->GetNumberOfCurrentPlayers() renvoie de manière asynchrone, après un appel de 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 );
}
REMARQUE : si vous ne pouvez pas utiliser le système CCallResult, vous pouvez alors utiliser
ISteamUtils::IsAPICallCompleted,
ISteamUtils::GetAPICallResult et
ISteamUtils::GetAPICallFailureReason pour suivre l'état d'un résultat d'appel.
Expédition des rappels manuels
Les classes et les macros utilisées pour enregistrer les rappels sont pratiques en code C++, mais il y a aussi un mécanisme de bas niveau pour gérer les rappels. Ce mécanisme opère plutôt comme une boucle évènements Windows. Au lieu d'une seule fonction qui enverrait tous les rappels et résultats d'appels aux écouteurs actifs, vous allez chercher le rappel disponible suivant en boucle et vous l'envoyez via les mécanismes que vous préférez utiliser. Le mode d'expédition manuel est particulièrement utile pour relier les couches qui exposent le SDK Steamworks à d'autres langages que C++. Référez-vous à
SteamAPI_ManualDispatch_Init()
dans
steam_api.h
pour en savoir plus.
Serveurs de jeu Steam
L'API Steamworks inclut la prise en charge nécessaire pour l'exécution de serveurs de jeu, ainsi que pour celle de clients habituels. Un serveur de jeu, en termes d'API Steamworks, est une entité du système à laquelle les personnes se connectent pour jouer à des jeux multijoueurs. Ce peut être par le biais d'une connexion via Internet à un serveur de jeu distant, ou via une connexion locale à un serveur de jeu situé dans le même processus que le client. Les serveurs de jeu disposent de leur propre ensemble de fonctions d'API et de leur propre SteamID par lequel les utilisateurs et utilisatrices peuvent les désigner.
Pour utiliser l'API Steam des serveurs de jeu, vous devez inclure
steam_gameserver.h
au lieu de
steam_api.h
.
L'initialisation et l'utilisation de l'API des serveurs de jeu sont très similaires à celles de l'API normale.
Après l'initialisation d'un serveur de jeu, vous avez accès aux deux interfaces exclusives des serveurs de jeu,
ISteamGameServer et
ISteamGameServerStats.
Vous pouvez également accéder aux interfaces habituelles suivantes depuis le serveur de jeu.
- ISteamClient, à laquelle vous pouvez accéder via l'interface globale
SteamGameServerClient()
.
- ISteamUtils à laquelle vous pouvez accéder via l'interface globale
SteamGameServerUtils()
.
- ISteamNetworking à laquelle vous pouvez accéder via l'interface globale
SteamGameServerNetworking()
.
- ISteamHTTP à laquelle vous pouvez accéder via l'interface globale
SteamGameServerHTTP()
.
- ISteamUGC à laquelle vous pouvez accéder via l'interface globale
SteamGameServerUGC()
.
- ISteamApps à laquelle vous pouvez accéder via l'interface globale
SteamGameServerApps()
.
Si vous exécutez un serveur de jeu dédié (un serveur sans aucun composant client), vous devez seulement initialiser l'API des serveurs de jeu, vous n'avez pas à initialiser l'API utilisateur normale.
Consultez la section
Exemple d'application utilisant l'API Steamworks (Spacewar) pour un exemple en pleine charge de l'utilisation de l'API des serveurs de jeu.
Contrairement aux jeux, un serveur dédié fonctionne généralement dans un environnement où aucun client Steam n'est installé pour fournir les derniers binaires Steamworks. Pour que le serveur dédié en dispose, vous devrez inclure les redistribuables du serveur dédié avec votre application. Connectez-vous à
partner.steamgames.com et allez dans les paramètres techniques de l'application. Dirigez-vous ensuite sur l'onglet « Installation/Redistribuables » et cochez l'option « Redistribuables du serveur dédié ».
Moteur du commerce et prise en charge des langages non C++
Si vous utilisez un moteur de jeu trouvé dans le commerce ou un langage autre que le C ou le C++, vous devrez vous assurer du niveau de prise en charge proposé par l'API Steamworks.
Une prise en charge intégrée est proposée dans certains moteurs, tandis que pour d'autres, vous pourriez avoir besoin d'une solution tierce.
Si votre moteur ne dispose pas d'une prise en charge native, vous pouvez utiliser l'
API Web Steam pour accéder aux nombreuses fonctionnalités que Steam prend en charge.
Indépendamment de la manière dont le SDK Steamworks est implémenté dans votre moteur, vous devrez disposer de la dernière version du SDK Steamworks pour
télécharger votre application vers Steam.
REMARQUE : si certains des logiciels que vous livrez sur Steam sont disponibles sous une licence open source restrictive, veuillez consulter la section
Distribution d'applications open source sur Steam.
Vous trouverez ci-dessous quelques moteurs communément utilisés par les équipes de développement pour livrer des jeux sur Steam, accompagnés de la documentation pertinente expliquant comment commencer à utiliser le SDK Steamworks en conjonction avec ces moteurs.
REMARQUE : Valve ne soutient en aucune façon un quelconque des moteurs ou de ces solutions proposées par de tierces parties. La liste est classée exclusivement par ordre alphabétique, et n'est en aucun cas exhaustive : elle n'a pour objectif que de servir de guide de référence. Les moteurs ne figurent dans la liste que s'ils comprennent la prise en charge native ou s'ils disposent d'une solution tierce correspondant aux recommandations. Les solutions de parties tierces ne figurent dans la liste que si elles sont raisonnablement tenues à jour vis-à-vis du SDK Steamworks, qu'elles sont disponibles gratuitement sous licence permissive (voir
Distribution d'applications open source sur Steam) et qu'elles disposent d'un fil dans le
forum de discussion Steamworks. Nous vous recommandons de consulter la communauté pour voir quelle option fonctionnerait le mieux dans votre configuration spécifique.
Moteurs :
Langages :
- ActionScript (Adobe Flash, AIR)
- C#
- D
- Java
- JavaScript
- Python
- Rust
Interface plate pour l'association avec d'autres langages
Le SDK dispose de certaines fonctionnalités pour faciliter la création de couches d'associations avec d'autres langages.
-
steam_api_flat.h
déclare une série de fonctions dites « plates » reflétant les fonctions de l'interface dans le SDK. Il ne contient pas de code C pur, mais utilise ses conventions d'association et d'appel, ce qui facilite l'interopérabilité avec d'autres langages. Ces fonctions sont exportées par steam_api[64][.dll/.so/dylib]
.
-
steam_api.json
décrit presque toutes les interfaces, types et fonctions dans le SDK. Il peut être utilisé via un processus automatisé de génération de couche d'association. Nous espérons que 95 % du travail pourra ainsi être automatisé, mais il reste encore quelques cas particuliers qui doivent être traités manuellement. CSteamID et CGameID nécessiteront probablement un traitement spécial par votre couche d'association pour être efficaces.
Détails techniques
Steam emploie toute une gamme de techniques pour exposer les fonctionnalités à votre application. Il n'est absolument pas vital de comprendre avec exactitude la manière dont fonctionne l'API Steamworks, mais elle est plutôt simple et peut être utile pour planifier la façon de coder votre jeu en gardant à l'esprit l'intégration à Steam.
Lorsque vous établissez un lien vers
steam_api[64][.dll/.so/dylib]
, l'API procure un accès à un
nombre de fonctions C précédées de la macro
S_API
. Ces fonctions sont toutes exposées dans
steam_api.h
et
steam_gameserver.h
. Le module
steam_api
en lui-même est très petit et n'expose que les fonctionnalités de base nécessaires pour initialiser et arrêter l'API Steamworks.
Lorsque l'API Steamworks s'initialise, elle trouve le processus du client Steam en cours d'exécution et charge
steamclient.dll
depuis ce chemin.
steamclient.dll
est par essence le moteur cœur du client Steam. Il renferme et tient à jour les informations nécessaires à l'exécution de Steam. L'interface du client Steam utilise un ensemble similaire aux fonctions exposées ici pour accéder aux données fournies par
steamclient.dll
. Comme ces données sont situées dans le processus Steam, tous les appels d'API Steam sont rassemblés de manière transparente et effectués via un mécanisme RPC/IPC (un canal transprocessus,
ISteamClient::HSteamPipe).
Le processus Steam, via
steamclient.dll
maintient une connexion constante avec les serveurs de l'interface Steam. C'est via cette connexion que s'effectuent toutes les tâches d'authentification, de matchmaking, de liste de contacts et de communication VAC. La connexion peut tomber si l'utilisateur ou l'utilisatrice souffre d'un problème réseau ou si le serveur Steam auquel il ou elle est connecté(e) reçoit une mise à jour. Les rappels seront affectés à toute application en cours d'exécution si la connexion tombe ou se rétablit. Le client Steam tentera de se reconnecter automatiquement et les clients en train d'exécuter une application seront prioritaires. Le temps de reconnexion moyen ne dépasse généralement pas la barre des 10 secondes, bien que, dans de rares cas, l'attente puisse se prolonger jusqu'à 5 minutes.
L'API Steamworks est versionnée via une procédure similaire à COM, dans laquelle un nom de chaine de caractères et la version d'une interface sont transmis à
steamclient.dll
qui renvoie alors la version correcte de l'interface à l'appelant.
steamclient.dll
: contient un ensemble d'adaptateurs pour toutes les versions publiées d'une interface, qui redirigent ou réinterprètent les anciens appels dans le contexte de la dernière interface. Les adaptateurs résident dans le client Steam, ils sont donc faciles à mettre à jour si un problème survient.