Documentación de Steamworks
Paso a paso: Tablas de clasificación

Introducción

Aquí te presentamos una guía rápida, paso a paso, para integrar, en menos de 10 minutos, tablas de clasificación de Steam en una aplicación. El SDK de Steamworks contiene una magnífica aplicación de ejemplo, Spacewar], que no solo exhibe el espectro completo de funciones de Steam, sino que también debería ser la primera parada para todo desarrollador que desee verlas en acción. Este tutorial resume la información que se encuentra en Spacewar y en la API de tablas de clasificación de Steam encontrada en ISteamUserStats, de manera que presenta lo imprescindible para evitar complicaciones.

Paso 1: Definir las tablas de clasificación del juego

Las tablas de clasificación son específicas de la aplicación y se configuran en la página configuración de las tablas de clasificación en el sitio asociado de Steamworks.

Los siguientes campos deben completarse para definir una tabla de clasificación:
  • Name: configúralo para que sea un nombre que tenga sentido como parte del desarrollo interno.
  • Community Name: si la tabla de clasificación debe mostrarse en el Centro de la comunidad, establece aquí el nombre del público. Si no se introduce ningún nombre, la tabla de clasificación no aparecerá.
  • Sort Method: establece el orden de clasificación de la tabla de clasificación. Para tablas de clasificación basadas en la posición, usa Ascendente. Para tablas de clasificación basadas en las puntuaciones más altas, usa Descendente.
  • Display Type: determina los tipos de datos que se mostrarán con la tabla de clasificación. Se puede elegir entre Numérico, Segundos o Milisegundos.
  • Writes : si se configura como Confiable, los puntajes de la tabla de clasificación no pueden ser establecidos por los clientes, y solo se pueden establecer a través de SetLeaderboardScore WebAPI. El valor predeterminado es false.
  • Reads: si se establece como Amigos, el juego solo puede leer las puntuaciones de las tablas de clasificación de los amigos del usuario. WebAPI puede leer siempre todas las puntuaciones.0> El valor predeterminado es false.

spacewar_leaderboards

Paso 2: Encapsular las tablas de clasificación

El código que sigue no depende de ningún juego y los desarrolladores pueden agregarlo al suyo a su propia discreción. La clase es perfectamente funcional tal cual, pero se puede ampliar fácilmente para dar respuesta a cualquier necesidad a mayores. Todo este código se ha tomado directamente de los archivos de ejemplo de Spacewar Leaderboards.cpp/h.

Archivo de encabezado

Definimos una clase auxiliar que encapsulará todas las llamadas a la API de las tablas de clasificación de Steam, además de crear todos los controladores de resultados de llamada de Steam.
class CSteamLeaderboards { private: SteamLeaderboard_t m_CurrentLeaderboard; // Handle to leaderboard public: int m_nLeaderboardEntries; // How many entries do we have? LeaderboardEntry_t m_leaderboardEntries[10]; // The entries CSteamLeaderboards(); ~CSteamLeaderboards(){}; void FindLeaderboard( const char *pchLeaderboardName ); bool UploadScore( int score ); bool DownloadScores(); void OnFindLeaderboard( LeaderboardFindResult_t *pResult, bool bIOFailure); CCallResult m_callResultFindLeaderboard; void OnUploadScore( LeaderboardScoreUploaded_t *pResult, bool bIOFailure); CCallResult m_callResultUploadScore; void OnDownloadScore( LeaderboardScoresDownloaded_t *pResult, bool bIOFailure); CCallResult m_callResultDownloadScore; };

Archivo de código

Constructor

Parámetros: No
Devuelve: N/D
Lo que hace: este constructor solo inicializa las variables miembro.
CSteamLeaderboards::CSteamLeaderboards() : m_CurrentLeaderboard( NULL ), m_nLeaderboardEntries( 0 ) { }

FindLeaderboard()

Parámetros: el identificador de cadena de la tabla de clasificación que quieres encontrar (es decir, "Feet Traveled")
Devuelve: Nada
Lo que hace: este método ajusta una llamada a la ISteamUserStats::FindLeaderboard, que es una llamada asíncrona a Steam que solicita un identificador a la tabla de clasificación dada. Es necesario que esta llamada se realice antes de poder recuperar o establecer entradas de la tabla de clasificación. Este método también configura el método de función callback que hay que utilizar.
void CSteamLeaderboards::FindLeaderboard( const char *pchLeaderboardName ) { m_CurrentLeaderboard = NULL; SteamAPICall_t hSteamAPICall = SteamUserStats()->FindLeaderboard(pchLeaderboardName); m_callResultFindLeaderboard.Set(hSteamAPICall, this, &CSteamLeaderboards::OnFindLeaderboard); }

OnFindLeaderboard()

Parámetros: N/D
Devuelve: Nada
Lo que hace: este método es una función callback que se realiza siempre que se intenta encontrar una tabla de clasificación en Steam. Si se encuentra la tabla de clasificación solicitada, se establece su identificador "handle" como tabla de clasificación actual.
void CSteamLeaderboards::OnFindLeaderboard( LeaderboardFindResult_t *pCallback, bool bIOFailure ) { // see if we encountered an error during the call if ( !pCallback->m_bLeaderboardFound || bIOFailure ) { OutputDebugString( "Leaderboard could not be found\n" ); return; } m_CurrentLeaderboard = pCallback->m_hSteamLeaderboard; }

UploadScore()

Parámetros: un int32 que representa el valor para almacenar en la tabla de clasificación actual.
Devuelve: falsa, si aún no se ha seleccionado una tabla de clasificación; en caso contrario, true.
Lo que hace: este método ajusta una llamada a la ISteamUserStats::UploadLeaderboardScore, que es una llamada asíncrona a Steam que carga la puntuación del usuario actual a la tabla de clasificación seleccionada actualmente. Este método también configura el método de función callback que hay que utilizar. Esta llamada debe realizarse después de haber seleccionado una tabla de clasificación utilizando FindLeaderboard().
bool CSteamLeaderboards::UploadScore( int score ) { if (!m_CurrentLeaderboard) return false; SteamAPICall_t hSteamAPICall = SteamUserStats()->UploadLeaderboardScore( m_CurrentLeaderboard, k_ELeaderboardUploadScoreMethodKeepBest, score, NULL, 0 ); m_callResultUploadScore.Set(hSteamAPICall, this, &CSteamLeaderboards::OnUploadScore); return true; }

OnUploadScore()

Parámetros: N/D
Devuelve: Nada
Lo que hace: este método es una función callback que se realiza siempre que se intenta cargar una puntuación en una tabla de clasificación en Steam.
void CSteamLeaderboards::OnUploadScore(LeaderboardScoreUploaded_t *pCallback, bool bIOFailure) { if ( !pCallback->m_bSuccess || bIOFailure ) { OutputDebugString( "Score could not be uploaded to Steam\n" ); } }

DownloadScores()

Parámetros: N/D
Devuelve: false, si aún no se ha seleccionado una tabla de clasificación; en caso contrario, true.
Lo que hace: este método ajusta una llamada a la ISteamUserStats::DownloadLeaderboardEntries, que es una llamada asíncrona para descargar un conjunto de entradas de la tabla de clasificación seleccionada actualmente. En este caso, se descargan diez entradas: cuatro antes del usuario actual, la del usuario actual y las cinco posteriores. Esta llamada se puede alterar para que devuelva cualquier número de entradas desde cualquier punto de la tabla de clasificación. Este método también configura el método de función callback que hay que utilizar. Esta llamada debe realizarse después de haber seleccionado una tabla de clasificación utilizando FindLeaderboard().
bool CSteamLeaderboards::DownloadScores() { if (!m_CurrentLeaderboard) return false; // load the specified leaderboard data around the current user SteamAPICall_t hSteamAPICall = SteamUserStats()->DownloadLeaderboardEntries( m_CurrentLeaderboard, k_ELeaderboardDataRequestGlobalAroundUser, -4, 5); m_callResultDownloadScore.Set(hSteamAPICall, this, &CSteamLeaderboards::OnDownloadScore); return true; }

OnDownloadScore()

Parámetros: N/D
Devuelve: Nada
Lo que hace: este método es una función callback que se ejecuta siempre que se intenta descargar entradas desde una tabla de clasificación en Steam. Si los datos se descargan correctamente, se copian en el vector de entradas. El número de entradas descargadas se almacena en m_nLeaderboardEntries.
void CSteamLeaderboards::OnDownloadScore(LeaderboardScoresDownloaded_t *pCallback, bool bIOFailure) { if (!bIOFailure) { m_nLeaderboardEntries = min(pCallback->m_cEntryCount, 10); for (int index = 0; index < m_nLeaderboardEntries; index++) { SteamUserStats()->GetDownloadedLeaderboardEntry( pCallback->m_hSteamLeaderboardEntries,index,&m_leaderboardEntries[index],NULL,0); } } }

Paso 3: Integrar en el juego

La siguiente es una lista completa de segmentos de código que los desarrolladores necesitarán integrar en su juego en las ubicaciones adecuadas.

Definiciones y generalidades

La siguiente es la lista de inclusiones que se deben crear para las tablas de clasificación y un puntero global para nuestro objeto auxiliar.
... #include "steam_api.h" #include "SteamLeaderboards.h" // Global access to Leaderboards Object CSteamLeaderboards* g_SteamLeaderboards = NULL; ...

Comienzo

La llamada a SteamAPI_Init inicializa todo Steam y debe llamarse allí antes que nada. Si esta llamada se lleva a cabo correctamente, se creará el objeto auxiliar.
... // Initialize Steam bool bRet = SteamAPI_Init(); // Create the SteamLeaderboards object if Steam was successfully initialized if (bRet) { g_SteamLeaderboards = new CSteamLeaderboards(); } ...

Procesar funciones callback

Para garantizar que procesamos todas las funciones callback de Steam, debemos obtener nuevos mensajes con regularidad. Esto se logra mediante la adición de esta llamada al bucle del juego.
... SteamAPI_RunCallbacks(); ...

Apagar

La llamada a SteamAPI_Shutdown es probablemente algo que ya tiene en su código. La función cierra Steam y debe llamarse antes de que la aplicación del desarrollador se cierre. Por último, borramos el objeto auxiliar que creamos.
... // Shutdown Steam SteamAPI_Shutdown(); // Delete the SteamStats object if (g_SteamStats) delete g_SteamStats; ...

Paso 4: Probar y solucionar problemas

Este código de muestra envía información a la consola de depuración que puede ayudar al desarrollador a entender qué llamadas están ejecutándose correctamente o están dando error. Los siguientes son mensajes de error típicos y sus soluciones:

Esta aplicación no pudo iniciarse porque no se encontró steam_api.dll. Reinstalar la aplicación podría solucionar este problema.
Asegúrate de que steam_api.dll esté en el mismo directorio que el ejecutable.

[S_API FAIL] SteamAPI_Init() ha fallado; no se puede encontrar una instancia en ejecución de Steam o un steamclient.dll local.
Lo más probable es que no se tenga el cliente de Steam en ejecución. Es necesario iniciar Steam e iniciar una sesión.

[S_API FAIL] SteamAPI_Init() ha fallado; no se ha encontrado una appID.
Lo más probable es que no tenga el archivo steam_appid.txt en su lugar. Es necesario ubicarlo en la carpeta de origen y asegurarse de que esta contiene el id. de aplicación propio.
  翻译: