Documentación de Steamworks
Steamworks API Overview

Introducción

La API de Steamworks permite a tu juego aprovechar Steam al máximo accediendo a todos los sistemas subyacentes proporcionados a través de la API. Esto incluye cosas como pausar tu juego cuando el usuario abre Steam Overlay, invitando a los amigos a jugar, permitiendo a los jugadores desbloquear Logros de Steam, dejar que los jugadores compitan en Steam Leaderboards y mucho más.

Referencia de la API de Steamworks cataloga y documenta todas las interfaces, funciones, devoluciones de llamada y tipos admitidos en la API.

La integración con la API de Steamworks nunca es un requisito para publicar tu producto en Steam, aunque se recomienda encarecidamente que se procure, ya que permite muchas interacciones que los usuarios de Steam esperan.

Primeros pasos

NOTA: La API de Steamworks admite oficialmente C++, el uso de Microsoft Visual Studio 2008+ en Microsoft Windows, GCC 4.6+ y Clang 3.0+ en macOS, y SteamOS/Linux. Si utilizas un motor de terceros o un lenguaje de programación distinto de C++, consulta Commercial engine and non-C++ language support para ver si hay más instrucciones específicas antes de ponerte en marcha con tu motor o lenguaje preferido. En muchos casos es posible saltarse muchos de estos pasos.

  • Si aún no lo has hecho, descarga el Steamworks SDK y descomprime.
  • Copia la carpeta de encabezados de la API de Steamworks public/steam en un lugar apropiado en el árbol de fuentes de tu aplicación.
  • Copy the relevant redistributable files from redistributable_bin into an appropriate place in your project folder.
    • Windows
      You must have steam_api[64].lib linking in your visual studio project. This can be linked to either the primary executable or a module that uses Steam. This allows you to access the functionality contained in steam_api[64].dll which is exposed via the Steamworks API headers. Additional Reading: Linking an Executable to a DLL (MSDN)

      You must also ship the steam_api[64].dll in your run-time directory (next to your programs executable, or in your dll search path).
    • macOS
      libsteam_api.dylib provides both the x86 and x64 version of the Steam API. You must link to this in your XCode project and you must ship this along side your executable.
      Additional Reading: Using Dynamic Libraries
    • Linux
      libsteam_api.so You must both link to and ship this along side your executable.

Inicialización y cierre

SteamAPI_Init

Una vez que tienes la API de Steamworks configurada dentro de tu proyecto, puedes empezar a usarla realizando llamadas a la función SteamAPI_Init para inicializar la API. Esto establecerá el estado global y rellenará los punteros de la interfaz que sean accesibles mediante las funciones globales y concuerden con el nombre la interfaz. ¡Este DEBE ser llamado y regresará exitosamente antes de acceder a cualquiera de las Interfaces de Steamworks!

La API de Steamworks no se inicializará si no conoce el id. de aplicación de tu juego. Cuando inicias tu aplicación desde el propio Steam, el id. de aplicación está disponible automáticamente. Durante el desarrollo hay que indicar esto a Steam mediante un archivo de texto. Crea un archivo de texto llamado steam_appid.txt junto a tu ejecutable que contiene solo el id. de la aplicación y nada más. Este valor tiene preferencia sobre el que Steam proporciona. Este archivo no debe incluirse en las compilaciones. Para más información sobre cómo garantizar la seguridad de tu cuenta de Steam, por favor, consulta la guía
480

Un retorno de false indica una de las siguientes condiciones:
  • El cliente de Steam no se está ejecutando. Se requiere un cliente de Steam en ejecución para aportar implementaciones de las diversas interfaces de Steamworks.
  • El cliente de Steam no pudo determinar el id. de aplicación del juego. Si estás ejecutando tu aplicación desde el ejecutable o el depurador directamente, debes tener un steam_appid.txt en tu directorio de juegos al lado del ejecutable, con tu id. de aplicación y nada más. Steam buscará este archivo en el directorio actual de trabajo. Si estás ejecutando tu ejecutable desde un directorio diferente, es posible que debsa reubicar el archivo steam_appid.txt.
  • La aplicación no se está ejecutando bajo el mismo contexto de usuario del SO que el cliente de Steam, por ejemplo, bajo un usuario distinto o un nivel de acceso administrativo diferente.
  • Es necesario asegurarse de que se posee una licencia para el id. de aplicación en la cuenta de Steam activa actualmente. El juego que se quiere ejecutar debe aparecer en la biblioteca de Steam.
  • Tu id. de aplicación no está completamente configurada, es decir, en Estado de la versión: no disponible, o faltan paquetes predeterminados.
Si tienes problemas de inicialización, consulta la documentación Depuración de la API de Steamworks para conocer los distintos métodos de depuración de la API de Steamworks.

SteamAPI_RestartAppIfNecessary

SteamAPI_RestartAppIfNecessary verifica si tu ejecutable se lanzó a través de Steam y lo reinicias a través de Steam si no se hizo así.

Esto es opcional pero se recomienda encarecidamente, ya que el contexto de Steam asociado con tu aplicación (lo que incluye el id. de aplicación) no se establecerá si el usuario lanza el ejecutable directamente. Si esto ocurre, SteamAPI_Init fallará y no podrá utilizar la API de Steamworks.
Si eliges usar esto, entonces debería ser la primera llamada a la función de Steamworks que realice, justo antes de SteamAPI_Init.

Si devuelve true, inicia el cliente de Steam si se requiere e inicia el juego a través del mismo, y se deberá abandonar el proceso lo antes posible. Esto ejecuta efectivamente steam://run/<AppID> por lo que no puede reiniciar el ejecutable exacto que llamó a esta función (por ejemplo, si estaba ejecutando desde tu depurador). Siempre volverá a iniciarse desde la versión instalada en tu carpeta de la biblioteca de Steam.

En caso contrario, si devuelve false, el juego se inició desde el cliente de Steam y no es necesario realizar otras acciones. Una excepción es si un archivo steam_appid.txt está presente, esto devolverá false independientemente. Esto permite desarrollar y testear sin iniciar el juego a través del cliente de Steam. ¡Asegúrate de eliminar el archivo steam_appid.txt cuando subas el juego a tu depósito de Steam!

NOTA: Si utilizas en encapsulador Steam DRM en tu archivo ejecutable principal, esta comprobación no es necesaria porque el contenedor DRM la realizará internamente.

SteamAPI_Shutdown

Cuando termines de usar la API de Steamworks deberías llamar a SteamAPI_Shutdown para liberar los recursos empleados por la aplicación internamente dentro de Steam. Debe llamarse a esta función durante el proceso de cierre, si fuese posible.

No desenlazará la Interfaz de Steam del juego, ya que no hay garantía de que la API de representación haya terminado de usarla.

Interfaces de Steamworks

La API de Steamworks está compuesta por varias interfaces, cada una de las cuales expone características específicas y limitadas.

Una vez inicializado Steamworks correctamente, puedes acceder a estas interfaces mediante las funciones globales. Las funciones siempre tienen el nombre de su interfaz. Como tal, puedes acceder a ISteamApps a través del acceso a SteamApps() y ISteamFriends a través de SteamFriends().

Estas interfaces se pueden utilizar para realizar llamadas como:
// Obtenga el nombre actual de Steam de los usuarios.. const char *name = SteamFriends()->GetPersonaName();

Se puede ver una lista completa de las interfaces en la Referencia de la API de Steamworks o dentro de los archivos de encabezado de la API de Steamworks.

Devoluciones de llamada

Las devoluciones de llamada son uno de los aspectos más importantes de Steamworks, pues permiten recuperar datos de forma asíncrona de Steam sin bloquear el juego. El objetivo de las devoluciones de llamada es proporcionar un método liviano que proporciona seguridad de tipos y seguridad para uso en subprocesos y que es capaz de generar eventos asíncronos en cualquier objeto registrado como escucha.

Las devoluciones de llamada se suelen activar mediante un evento que se produce en Steam, por ejemplo, cuando un amigo inicia o cierra sesión, o como resultado asíncrono de alguna función de la API. Cada devolución de llamada consiste en una estructura que contiene un identificador exclusivo y un pequeño conjunto de datos. Las devoluciones de llamada se declaran en los archivos de encabezado ISteam*.h, agrupados con la interfaz a la que más pertenece.

Para escuchar una devolución de llamada, una estructura o clase debe usar la macro STEAM_CALLBACK( :classname, :functionname, :callbackname ) en su declaración.
  • :classname debe ser el nombre de la estructura o clase en la que está definiendo esto. (por ejemplo, CGameManager)
  • :functionname será el nombre de la función que recibe esta devolución de llamada. (por ejemplo, OnGameOverlayActivated)
  • :callbackname es el nombre de la devolución de llamada. (por ejemplo, GameOverlayActivated_t)
Esto define una función miembro local para esa clase que se crea automáticamente como prototipo como void :functionname( :callbackname *pCallback ). Crear una nueva instancia del objeto hace que esta función miembro se registre a sí misma como escucha en la API de Steamworks; este registro se anula con la destrucción del objeto.

NOTA: Se debe asegurar que Steam se ha inicializado antes de crear objetos que escuchan devoluciones de llamada.

Para que las devoluciones de llamadas se envíen a oyentes registrados, debes llamar a SteamAPI_RunCallbacks. Lo mejor es llamar a esta función con frecuencia, puesto que, a mayor tiempo entre llamadas, más latencia se produce entre los eventos de recepción o los resultados de la API de Steamworks. La mayoría de los juegos llaman a esta función una vez por cada cuadro de representación; se recomienda encarecidamente realizar al menos una llamada por segundo. Todas las funciones de escucha registradas se invocarán durante esta llamada, en el contexto del subproceso desde donde se llamó a SteamAPI_RunCallbacks.

Por ejemplo

Una devolución de llamada que probablemente desearás usar es ISteamFriends::GameOverlayActivated_t. Como su nombre implica, envía una devolución de llamada cada vez que el usuario activa o desactiva la Interfaz de 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 caso de uso popular y recomendado para la devolución de llamada ISteamFriends::GameOverlayActivated_t es pausar el juego cuando se abre la superposición.

Resultado de llamada

Muchos métodos de Steamworks utilizan resultados de llamada en vez de devoluciones de llamada para devolver resultados de forma asíncrona ante la llamada a una función. La diferencia entre las devoluciones y los resultados de llamada es que las primeras se retransmiten a todas las escuchas, mientras que los segundos se dirigen a una escucha específica. Al igual que las devoluciones de llamada, tu juego deberá llamar a SteamAPI_RunCallbacks para enviar los resultados de las llamadas a su oyente.

Puedes identificar una función que proporciona un resultado de llamada al inspeccionar su valor de retorno; si devuelve un SteamAPICall_t y tiene un atributo CALL_RESULT(), entonces debes registrarte para recibir el resultado de la llamada.

NOTA: Las devoluciones de llamada y los resultados de llamada no son intercambiables. Los eventos llegarán a través de uno o de otro, pero no de ambos. ¡Asegúrate de registrarte para el tipo de evento correcto!

Los resultados de llamada deben crearse como miembro de una estructura o clase que use el tipo CCallResult. Además, tendrás que crear la función miembro que reciba la devolución de llamada.
void func( :callresultname *pCallback, bool bIOFailure ); CCallResult< :classname, :callresultname > m_callresultname;
  • :classname debe ser el nombre de la estructura o clase en la que está definiendo esto. (por ejemplo, CGameManager)
  • :callresultname es el nombre de la devolución de llamada. (por ejemplo, NumberOfCurrentPlayers_t)

Puedes ponerles los nombres que quieras a la función, sus parámetros y el tipo CCallResult.

Por ejemplo

Aquí hay un ejemplo de cómo usar la API ISteamUserStats::GetNumberOfCurrentPlayers que produce el resultado de la llamada ISteamUserStats::NumberOfCurrentPlayers_t.
// En tu definición de clase class CGameManager { public: void GetNumberOfCurrentPlayers(); private: void OnGetNumberOfCurrentPlayers( NumberOfCurrentPlayers_t *pCallback, bool bIOFailure ); CCallResult< CGameManager, NumberOfCurrentPlayers_t > m_NumberOfCurrentPlayersCallResult; }; // Haz la solicitud asíncrona para recibir el número de jugadores actuales. void CGameManager::GetNumberOfCurrentPlayers() { printf( "Getting Number of Current Players\n" ); SteamAPICall_t hSteamAPICall = SteamUserStats()->GetNumberOfCurrentPlayers(); m_NumberOfCurrentPlayersCallResult.Set( hSteamAPICall, this, &CGameManager::OnGetNumberOfCurrentPlayers ); } // Llamando cuando SteamUserStats()->GetNumberOfCurrentPlayers() returns asynchronously, after a call to 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 ); }

NOTA: Si no puedes usar el sistema CCallResult, entonces puedes usar ISteamUtils::IsAPICallCompleted, ISteamUtils::GetAPICallResult y ISteamUtils::GetAPICallFailureReason para rastrear el estado de un resultado de llamada.

Manual Callback Dispatch

The classes and macros used to register callbacks are convenient in for C++ code. But there is also a lower-level mechanism for dealing with callbacks. This mechanism operates more like a windows event loop. Instead of a single function that dispatches all of the callbacks and call results to active listeners, you fetch the next available callback in a loop, and dispatch it using whatever mechanisms you want. The manual dispatch mode is especially useful for binding layers that expose the Steamworks SDK to languages other than C++. See SteamAPI_ManualDispatch_Init() in steam_api.h for more information.

Steam Game Servers

The Steamworks API includes support for running game servers as well as regular clients. A game server, in Steamworks API terms, is an entity in the system that normal users connect to to play multi-player games. This can be connecting over the Internet to a remote game server, or connecting locally to a game server that's in the same process as the client. Game servers have their own set of API functions to use, and their own unique Steam ID for other users to refer to them by.

To use the Steam Game Server API you must first include steam_gameserver.h instead of steam_api.h.

Initializing and using the game server API is very similar to the normal API:

After initializing a game server you have access to the two game server exclusive interfaces ISteamGameServer and ISteamGameServerStats.

You can also access the following regular interfaces from the game server:
  • ISteamClient al que puedes acceder a través de la interfaz global: SteamGameServerClient()
  • ISteamUtils al que puedes acceder a través de la interfaz global: SteamGameServerUtils()
  • ISteamNetworking al que puedes acceder a través de la interfaz global: SteamGameServerNetworking()
  • ISteamHTTP al que puedes acceder a través de la interfaz global: SteamGameServerHTTP()
  • ISteamInventory al que puedes acceder a través de la interfaz global: SteamGameServerInventory()
  • ISteamUGC al que puedes acceder a través de la interfaz global: SteamGameServerUGC()
  • ISteamApps al que puedes acceder a través de la interfaz global: SteamGameServerApps()

If you're running a dedicated game server (one which has no client component), you only have to initialize the game server API's, you don't have to initialize the normal user API.

See Ejemplo de aplicación de la API de Steamworks (Spacewar!) for a fully loaded example of using the game server API.

Commercial engine and non-C++ language support

If you're using a commercial game engine or a language other than C or C++ you will want to see what level of support for the Steamworks API is provided for it.
In some engines they provide native built-in support, for others you may need a third-party solution.

If your engine does not have native support you can use the Steam Web API to access many features that Steam supports.

Regardless of how the Steamworks SDK is implemented in your engine you will need to have the latest Steamworks SDK to upload your application to Steam.

NOTA: If some of the software you are shipping on steam is available under a restrictive open source license then please see Distribuir aplicaciones de código abierto en Steam.

Here are some common engines that people routinely use to ship games on Steam and the relevant documentation on how to get started using the Steamworks SDK with them.

NOTA: Valve does not in any way endorse any of these engines or the third-party solutions. This list is sorted exclusively by name, and is in no way comprehensive, it exists solely as a starting guide. Engines will only be listed if they include native support or have a third-party solution that fits the guidelines. Third-party solutions will only be listed if they are kept reasonably up to date with the Steamworks SDK, are freely available under a permissive license (See: Distribuir aplicaciones de código abierto en Steam), and have a thread on the Steamworks Discussion Board. We recommend that you consult the community to see which option would work best for your specific setup.

Motores:

[/table]

Languages:

  • ActionScript (Adobe Flash, AIR)
    • [url]Hilos de discusión
    [/url]
Motor¿Soporte nativo?Información
CRYENGINE ✔️
{ENLACE ELIMINADO}]GameMaker Studio 2[/url] ✔️ Usando el SDK de Steamworks con GameMaker: Studio
Godot De un tercero:
GodotSteam - Hilo de discusión de soporte para desarrolladores de Steamworks
Haxe De un tercero:
SteamWrap - Hilo de discusión de soporte para desarrolladores de Steamworks
Motor de juego de Leadwerks ✔️ Referencia de la API de Leadwerks › Steamworks
RPG Maker MV De un tercero:
Greenworks - [/td] [/tr]
[url]Source 2013[/url] ✔️ Distribuir juegos de Source Engine
[url]Unity[/url] Por un tercero: [url]Facepunch.Steamworks[/url] - [url]Steamworks Developer Discussions support thread[/url]
Por un tercero: [url]Steamworks .NET[/url] - [url]Hilo de discusión de soporte para desarrolladores de Steamworks[/url]
[url]Unreal Engine 4[/url] ✔️ [url]Steam, usando el SDK de Steam durante el desarrollo[/url]
[url]Visionaire Studio[/url] ✔️ [url]Publicar en Steam[/url]
  • C#
  • D
  • Java
  • JavaScript
  • Python
  • Rust
  • [/list]

    Flat interface for binding to other languages

    The SDK has a few features to facilitate the creation of binding layers for other languages.

    • steam_api_flat.h declares a set of "flat" functions that mirror the interface functions in the SDK. This is not pure C code, but it does use plain C linkage and calling conventions, so it is easy to interop with other languages. These functions are exported by steam_api[64][.dll/.so/dylib].
    • steam_api.json describes (almost all of) the interfaces, types, and functions in the SDK. It is intended that this file be used by an automated process to generate binding layer. We hope that this can be used to automate 95% of the work, but there are still a few special cases that need to be handled manually. In particular, CSteamID and CGameID will probably require special handling by your binding layer to make it efficient.

    Technical Details

    Steam uses a variety of techniques to expose functionality to your application. It's by no means critical to understand exactly how the Steamworks API works but it's fairly simple and can be useful in planning out how to code your game with Steam integration in mind.

    When you link to steam_api[64][.dll/.so/dylib] it provides access to a small number of C functions which are prefixed with the S_API macro, these functions are all exposed in steam_api.h and steam_gameserver.h. The steam_api module itself is very small, it only exposes the base functionality to initialize and shutdown the Steamworks API.

    When the Steamworks API initializes it finds the actively running steam client process and loads steamclient.dll from that path. steamclient.dll is essentially the core engine of the Steam client. It contains and maintains the information necessary to run Steam. The Steam client UI uses a similar set of functions as exposed here to access the data provided by steamclient.dll. Since this data is in the Steam process, all Steam API calls are transparently marshaled and sent via an RPC/IPC mechanism. (A cross-process pipe, ISteamClient::HSteamPipe).

    The Steam process, via steamclient.dll maintains a constant connection to the Steam back-end servers. Through this connection all authentication, matchmaking, friends list and VAC communication occurs. This connection may drop if the user has a network issue, or if the Steam server they are connected to receives an update. Callbacks will be posted to any running app if the connection drops or re-establishes. The Steam client will automatically try to reconnect, and clients running an app receive priority, so the typical reconnect time is under 10 seconds, although in some rare cases may be up to 5 minutes.

    The Steamworks API is versioned through a COM-like mechanism, where a string name and version of an interface are passed into steamclient.dll which then returns the correct version of the interface to the caller. steamclient.dll contains a set of adapters for all released versions of an interface which redirect or re-interpret the old calls in the context of the latest interface. The adapters live inside the steam client so that they are easy to update if any issues arise.