> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tablas de clasificación

> Recree las tablas de clasificación de Steam en el GDK de XBOX mediante estadísticas basadas en eventos y reglas de estadísticas del Centro de partners, con ejemplos de código que comparan las dos API de tablas de clasificación.

Las tablas de clasificación de los servicios de XBOX se derivan de las estadísticas de usuario y se generan mediante consultas. Esto es diferente de las tablas de clasificación de Steam, que se basan en "puntuaciones" que se cargan en la API. De forma similar a los logros, el XBOX Game Development Kit (GDK) tiene dos API para las estadísticas: basadas en eventos y administradas por el título. A diferencia de los logros, recomendamos usar las estadísticas y tablas de clasificación basadas en eventos en lugar de las administradas por el título. En este tema nos centramos en esa API. Para obtener más información sobre las diferencias entre estas dos API, consulte [Estadísticas basadas en eventos frente a estadísticas administradas por el título](/services/xbox-services/player-data/stats-leaderboards/index).

Ambas plataformas definen las tablas de clasificación en sus portales. La diferencia es que los servicios de XBOX le piden que defina primero una regla de estadística en el Centro de partners y que, a continuación, cree una tabla de clasificación basada en la estadística que esa regla genera. Steam, en cambio, no distingue entre las dos cosas: crea una tabla de clasificación en su portal o mediante programación y, a continuación, carga las puntuaciones de los usuarios directamente en esa tabla de clasificación.

Para ilustrar cómo puede usarse cada una de estas API en comparación con la API de tablas de clasificación de Steam, se proporcionan ejemplos de código sobre cómo crear una tabla de clasificación para la mayor distancia recorrida (el ejemplo procede de la documentación de la API de Steamworks) en el SDK de Steam y en la plataforma de estadísticas basadas en eventos del XBOX Game Development Kit (GDK). Las secciones siguientes explican la lógica paso a paso.

## Creación de una estadística o tabla de clasificación en el portal

### Steamworks

En el portal de administración de Steamworks, vaya a **Stats & Achievements** > **Leaderboards**. Complete el formulario como se muestra en la siguiente captura de pantalla (de la documentación de Steamworks).

<img src="https://mintcdn.com/microsoft-4404708b/5IpvKlT-jmAaVkeY/images/nda/steam-porting-guide/steam-portal-add-leaderboard.png?fit=max&auto=format&n=5IpvKlT-jmAaVkeY&q=85&s=e8a3f4a76f8a9bdc60689571bf5a9dbb" alt="Captura de pantalla del formulario usado para crear una tabla de clasificación en el portal de administración de Steamworks" width="806" height="190" data-path="images/nda/steam-porting-guide/steam-portal-add-leaderboard.png" />

### XBOX Game Development Kit (GDK) (basado en eventos)

En el Centro de partners, vaya a su juego y seleccione **XBOX services** > **Gameplay settings**. En la barra de navegación del panel derecho, seleccione **Player Stats** > **Stat Rules** y agregue una regla de estadística como **Show**, configurándola para satisfacer las necesidades de su estadística. Como nuestras actualizaciones de la estadística incluirán un valor calculado de la distancia que ha recorrido el jugador (usuario) desde la última actualización, especificaremos un campo de medición del que el servicio obtendrá este valor.

<Note>
  No hay diferencia funcional si almacena los datos para actualizar un evento en el campo Measurements o Dimensions del evento. Los dos campos existen para su uso con Application Insights. Para obtener más información al respecto, consulte \[Application Insights API for custom events and
</Note>

metrics]\([https://learn.microsoft.com/en-us/azure/azure-monitor/app/api-custom-events-metrics](https://learn.microsoft.com/en-us/azure/azure-monitor/app/api-custom-events-metrics)).

La siguiente captura de pantalla muestra el formulario que se usa para crear una regla de estadística en el Centro de partners.

<img src="https://mintcdn.com/microsoft-4404708b/5IpvKlT-jmAaVkeY/images/nda/steam-porting-guide/partner-center-stat-rule.png?fit=max&auto=format&n=5IpvKlT-jmAaVkeY&q=85&s=08b05f51f44f9f912854674ea3c189ae" alt="Captura de pantalla del formulario usado para crear una regla de estadística en el Centro de partners" width="1196" height="1046" data-path="images/nda/steam-porting-guide/partner-center-stat-rule.png" />

Después de guardar, seleccione **Leaderboard** en la barra superior del panel derecho y cree una nueva tabla de clasificación generada por la estadística que acaba de crear, como se muestra en la siguiente captura de pantalla.

<img src="https://mintcdn.com/microsoft-4404708b/5IpvKlT-jmAaVkeY/images/nda/steam-porting-guide/partner-center-leaderboard.png?fit=max&auto=format&n=5IpvKlT-jmAaVkeY&q=85&s=5ffd10e8fdb53ed640fcb59ef31e323a" alt="Captura de pantalla del formulario usado para crear una tabla de clasificación en el Centro de partners" width="1048" height="654" data-path="images/nda/steam-porting-guide/partner-center-leaderboard.png" />

## Carga de una puntuación

### Steamworks

En Steamworks, debe calcular el nuevo valor total de pies recorridos y enviarlo a la API mediante el método `ISteamUserStats::UploaderLeaderboardScore`.

```cpp theme={null}
int32 newFeetTraveled; // Calculate this however you want.
const int32* scoreDetails = {}; // Extra values pertaining to the score.
SteamLeaderboard_t leaderboard; // Handle for the leaderboard to upload the score to...
SteamAPICall_t result = UploadLeaderboardScore( leaderboard, ISteamUserStats::k_ELeaderboardUploadScoreMethodForceUpdate, 100, scoreDetails, int 0);
STEAM_CALLBACK(MyGameClass, OnLeaderboardScoreUploaded, LeaderboardScoreUploaded_t);
// Handle errors in the OnLeaderboardScoreUploaded callback function.
```

### XBOX Game Development Kit (GDK) (basado en eventos)

Con las estadísticas basadas en eventos del XBOX Game Development Kit (GDK), simplemente necesita pasar la diferencia de pies recorridos a [`XblEventsWriteInGameEvent`](/reference/live/xsapi-c/events_c/events_c_members), porque especificamos que queremos incrementar esta estadística al recibir un evento y hemos indicado dónde encontrar este valor `diff` en la cadena JSON de mediciones, como se muestra a continuación.

```cpp theme={null}
// Assume that this holds the feet that the user has traveled since the last update.
int diffFeetTraveled; 
std::stringstream ss;
ss << "{ \"feet\": " << diffFeetTraveled << " }";
std::string measurements = ss.str();
HRESULT hr = XblEventsWriteInGameEvent(
    m_xboxLiveContext,
    "FeetTraveled",
    "",
    measurements.c_str()
);
```

Para obtener más información, consulte [Escritura de un evento para alimentar una estadística basada en eventos](/services/xbox-services/player-data/stats-leaderboards/index).

## Obtención de una tabla de clasificación global

Las tablas de clasificación globales pueden recuperarse con el SDK de Steamworks llamando a `ISteamUserStats::GetLeaderboardEntries` y, a continuación, llamando a `ISteamUserStats::GetDownloadedLeaderboardEntry` en la función `callback` para obtener cada entrada o "fila" de la tabla de clasificación.

### Steamworks

```cpp theme={null}
class MyGameClass
{
    void OnFindLeaderboardCompleted(LeaderboardFindResult_t *callback);
    SteamAPICall_t m_getLoaderboardCall;
    SteamAPICall_t m_getEntriesCall;
};

m_getLoaderboardCall = SteamUserStats()->FindLeaderboard(leaderboardName);
STEAM_CALLBACK(MyGameClass, OnFindLeaderboardCompleted, LeaderboardFindResult_t);

// ...

void MyGameClass::OnFindLeaderboardCompleted(LeaderboardFindResult_t *callback)
{
    if (callback->bLeaderboardFound)
    {
        auto handle = callback->m_hSteamLeaderboard;
        const char *leaderboardName = SteamUserStats()->GetLeaderboardName(handle);
        m_getEntriesCall = SteamUserStats()->GetLeaderboardEntries(handle, ELeaderboardDataRequest::k_ELeaderboardDataRequestGlobal, 0, 100);
        STEAM_CALLBACK(MyGameClass, OnLeaderboardScoresDownloaded, LeaderboardScoresDownloaded_t);
    }
    else
    {
        // Leaderboard wasn't found.
    }

void MyGameClass::OnLeaderboardScoresDownloaded(LeaderboardScoresDownloaded_t *callback)
{
    int numScores = callback->m_cEntryCount;
    for (int i = 0; i < numScores; i++)
    {
        LeaderboardEntry_t entry;
        bool result = SteamUserStats()->GetDownloadedLeaderboardEntry(callback->m_hSteamLeaderboardEntries, i, &entry, nullptr, 0);
        if (!result)
        {
            // Handle error.
        }
        CSteamID userId = entry.m_steamIDUser;
        int32 rank = entry.m_nglobalRank;
        int32 score = entry.m_nScore;
        // Do something with the data. 
    }
}
```

### XBOX Game Development Kit (GDK) (basado en eventos)

Las API del XBOX Game Development Kit (GDK) siguen un patrón similar. Cree una consulta especificando qué tabla de clasificación quiere, qué ámbito debe cubrir, cómo ordenarla, qué campos adicionales debe contener (si los hay) y más. Después de llamar a [`XblLeaderboardGetLeaderboardAsync`](/reference/live/xsapi-c/leaderboard_c/leaderboard_c_members) con su consulta, puede usar [`XblLeaderboardGetLeaderboardResultSize`](/reference/live/xsapi-c/leaderboard_c/leaderboard_c_members) y [`XblLeaderboardGetLeaderboardResult`](/reference/live/xsapi-c/leaderboard_c/leaderboard_c_members) para colocar los resultados en el búfer que especifique e iterar sobre ellos, como se muestra en el siguiente ejemplo de código.

```cpp theme={null}
auto asyncBlock = std::make_unique<XAsyncBlock>();
asyncBlock->queue = m_taskQueue;
asyncBlock->context = nullptr;
asyncBlock->callback = [](XAsyncBlock* asyncBlock)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ asyncBlock }; // Take over ownership of the XAsyncBlock*
    size_t resultSize;
    std::vector<uint8_t> leaderboardBuffer;
    HRESULT hr = XblLeaderboardGetLeaderboardResultSize(asyncBlock, &resultSize);

    if (SUCCEEDED(hr))
    {
        leaderboardBuffer.resize(resultSize);
        XblLeaderboardResult* leaderboard{};

        hr = XblLeaderboardGetLeaderboardResult(asyncBlock, resultSize, leaderboardBuffer.data(), &leaderboard, nullptr);

        if (SUCCEEDED(hr))
        {
            // Use XblLeaderboardResult in result.
            for (int row = 0; row < leaderboard->rowsCount; row++)
            {
                uint64_t xuid = leaderboard->rows[row].xboxUserId;
                uint32_t rank = leaderboard->rows[row].rank;
                const char** values = leaderboard->rows[row].columnValues;
                // Do something with the data.
            }
        }
    }
};

XblLeaderboardQuery leaderboardQuery = {}; 
strcpy(&leaderboardQuery.scid[0], m_scid.c_str());
leaderboardQuery.leaderboardName = leaderboardName.c_str(); 
leaderboardQuery.xboxUserId = 0;
leaderboardQuery.order = XblLeaderboardSortOrder::Descending;
leaderboardQuery.skipResultToRank = 0;
leaderboardQuery.maxItems = 100;
leaderboardQuery.statName = "MyStatName";
leaderboardQuery.socialGroup = XblLeaderboardQueryType::None;
// See the link as follows for more options in XblLeaderboardQuery.

HRESULT hr = XblLeaderboardGetLeaderboardAsync(
    xboxLiveContext,
    leaderboardQuery,
    asyncBlock.get());
if (SUCCEEDED(hr))
{
    // The call succeeded, so release the std::unique_ptr ownership of XAsyncBlock* since the callback will take over ownership.
    // If the call fails, the std::unique_ptr will keep ownership and delete the XAsyncBlock*
    asyncBlock.release();
}
```

Para obtener más información, consulte lo siguiente:

* [Código de ejemplo para tablas de clasificación basadas en eventos](/services/xbox-services/player-data/stats-leaderboards/index)
* [XblLeaderboardQuery](/reference/live/xsapi-c/leaderboard_c/leaderboard_c_members)

## Obtención de una tabla de clasificación social

En Steamworks, puede usar la enumeración `ELeaderboardDataRequest::k_ELeaderboardDataRequestFriends` para limitar el ámbito de la tabla de clasificación a los amigos del usuario actual.

En el XBOX Game Development Kit (GDK), esto se conoce como una *tabla de clasificación social*. Para obtener una tabla de clasificación social de los servicios de XBOX, establezca `xboxIUserId` igual al identificador de usuario de XBOX (XUID) del usuario actual que ha iniciado sesión en los servicios de XBOX, `leaderboardName` en `nullptr` y `socialGroup` como `XblSocialGroupType::People` o `XblSocialGroupType::Favorites` en su estructura [`XblLeaderboardQuery`](/reference/live/xsapi-c/leaderboard_c/leaderboard_c_members). Llame a `XblLeaderboardGetLeaderboardAsync` como se mostró anteriormente.

Para obtener más información, consulte [XblSocialGroupType](/reference/live/xsapi-c/leaderboard_c/leaderboard_c_members).

## Estadísticas destacadas

Además de las estadísticas de usuario habituales que se usan para generar tablas de clasificación similares a las de Steam, los servicios de XBOX tienen un concepto adicional llamado *estadísticas destacadas* (Featured Stats). Las estadísticas destacadas aparecen en varias superficies distintas del ecosistema de XBOX para su juego y pueden mostrar los valores de las estadísticas de los usuarios o de las tablas de clasificación que ya se han generado. Puede crear hasta 20 estadísticas destacadas para su juego.

Para obtener más información sobre las estadísticas destacadas y cómo agregarlas, consulte [Información general de las estadísticas destacadas](/services/xbox-services/player-data/stats-leaderboards/index) y [Configuración en el portal de estadísticas destacadas basadas en eventos](/services/xbox-services/player-data/stats-leaderboards/index).

## Límites de frecuencia

Al escribir eventos, tenga cuidado de no llamar a la API de servicios de XBOX (XSAPI) con demasiada frecuencia, porque puede hacer que su juego alcance su límite de frecuencia. Esto puede causar un comportamiento inesperado y una mala experiencia para sus usuarios. Tenga en cuenta que esta es una preocupación de los servicios de XBOX que no supone un problema en Steam. Escribir valores de estadísticas en Steam no genera una llamada a la API del servidor hasta que su juego los sincroniza explícitamente.

Para los eventos que ocurren con frecuencia, intente agrupar las llamadas a la API en lotes para que se disparen después de que se produzca un número determinado de eventos, o para que se actualicen en el servidor en un intervalo de tiempo determinado.

Puede depurar sus llamadas a la API mediante el [analizador de seguimiento de XBOX Live (XblTraceAnalyzer.exe)](/tools/tools-services/live-trace-analyzer).

Para obtener más información sobre los límites de frecuencia en los servicios de XBOX, consulte [Limitación de frecuencia específica](/services/xbox-services/develop/best-practices/live-fine-grained-rate-limiting).


## Related topics

- [Torneos y tablas de clasificación](/es/services/playfab/community/leaderboards/tournaments-leaderboards/index.md)
- [Cuota de tablas de clasificación](/es/services/playfab/community/leaderboards/quota-leaderboards.md)
- [Tablas de clasificación de temporada](/es/services/playfab/community/leaderboards/seasonal-leaderboards.md)
- [Tablas de clasificación de grupos](/es/services/playfab/community/leaderboards/group-leaderboards.md)
- [Estadísticas y tablas de clasificación](/es/services/xbox-services/player-data/stats-leaderboards/live-stats-leaderboards-nav.md)
