No afiliado

Inicio Documentación y ayuda
Documentación de Steamworks
Logros y estadísticas

Introducción

Los logros y estadísticas de Steam brindan un modo sencillo de proporcionar a los usuarios un seguimiento persistente y móvil de este tipo de elemento. Los datos de los usuarios se vinculan a su cuenta de Steam, y a los logros y estadísticas se les puede dar un formato y mostrar en los perfiles de la Comunidad Steam.

Utilidad

Además de ofrecer recompensas muy apreciadas por los jugadores, los logros son útiles para estimular y recompensar el trabajo de equipo y la interacción entre los jugadores, ya que añaden más dimensiones a los objetivos del juego y premian a los usuarios por dedicar más tiempo a jugar.

Las estadísticas son un seguimiento de datos detallados, como el tiempo de juego, la cantidad de potenciadores empleados, etc. Se pueden usar, simplemente, para llevar un seguimiento de los datos internos del juego; de esta forma, por ejemplo, podría concederse un logro a partir de las estadísticas de juego multisesión del usuario, recogidas de varios ordenadores.

Resumen de implementación

Definir las estadísticas y logros del juego

Los logros son específicos para cada aplicación y se configuran en la página del administrador de apps del sitio asociado de Steamworks.

El juego puede almacenar tres tipos de estadísticas:
  • INT: un entero de 32 bits (con signo) (por ejemplo, la cantidad de juegos jugados)
  • FLOAT: un valor de punto flotante de 32 bits (por ejemplo, número de millas recorridas)
  • AVGRATE: una media móvil. Mira: Tipo de estadística AVGRATE

El sitio web de asociados de Steamworks proporciona una interfaz para definir y actualizar las estadísticas y logros del juego. Se puede utilizar para lo siguiente:
  • Definir las estadísticas y logros iniciales.
  • Añadir más estadísticas y logros.
  • Actualizar los nombres, descripciones e iconos de los logros.
  • Actualizar los parámetros y restricciones de las estadísticas (valores máximos y mínimos, tamaños de media móvil de ventanas, etc.).
Las estadísticas tienen las siguientes propiedades:
  • ID: una identificación numérica generada automáticamente para cada estadística.
  • Type: el tipo de esta estadística: INT, FLOAT o AVGRATE.
  • API Name: la cadena utilizada para acceder a esta estadística mediante la API.
  • Set By: establece quién puede modificar la estadística. El valor predeterminado es "Client". Para más información, mira Estadísticas del servidor de juego.
  • Increment Only: si se establece, esta estadística solo puede aumentar su valor con el tiempo.
  • Max Change: si se establece, establece un límite en la cantidad que el valor de la estadística puede cambiar de una llamada a SetStat a la siguiente.
  • Min Value: si se establece, el valor numérico mínimo que puede tomar esta estadística. De forma predeterminada, el mínimo es el mínimo del tipo numérico subyacente (INT_MIN o -FLT_MAX).
  • Max Value: si se establece, el valor numérico máximo que puede tomar esta estadística. De forma predeterminada, el máximo es el máximo del tipo numérico subyacente (INT_MAX o FLT_MAX).
  • Default Value: si se establece, el valor predeterminado con el que se establecerá inicialmente esta estadística para un nuevo usuario. Si no se establece, el valor predeterminado es 0.
  • Aggregated: si se establece, Steam mantendrá un total global para esta estadística. Consulta las Estadísticas globales siguientes para obtener más información.
  • Display Name: el nombre de esta estadística, cuando se muestra en la comunidad de Steam. Se puede traducir a otros idiomas.
AVGRATE Las estadísticas tienen las siguientes propiedades adicionales:
  • Ventana: tamaño de la "ventana deslizante" que se usará para hallar la media de los datos.
Una estadística de AVGRATE es una que promedia automáticamente Steam. Consulta la sección AVGRATE a continuación para obtener más información.

Los logros tienen las siguientes propiedades:
  • ID: una identificación numérica generada automáticamente para cada logro.
  • API Name: la cadena utilizada para acceder a este logro mediante la API.
  • Progress Stat: especifica una estadística que se usa como una barra de progreso en la Comunidad para este logro. El logro se desbloqueará automáticamente cuando la estadística alcance el valor de desbloqueo.
  • Display Name: el nombre que este logro tendrá en las ventanas emergentes de notificación al cliente y en la Comunidad. Se puede traducir a otros idiomas.
  • Description: una descripción de este logro, para mostrar en la Comunidad. Se puede traducir a otros idiomas.
  • Set By: establece quién puede desbloquear el logro. El valor predeterminado es "client". Para más información, mira Estadísticas del servidor de juego.
  • Hidden: si es true, un "oculto" el logro no se muestra en la página de la Comunidad de un usuario (en absoluto) hasta que lo hayan logrado.
  • Achieved Icon: el icono que se muestra cuando se alcanza.
  • Unachieved Icon: el icono que se muestra cuando aún no se ha alcanzado.

La siguiente es la lista de logros de Steamworks API Example Application (SpaceWar):
achievements_spacewar.png

Instrucciones de uso

Cómo acceder a los logros y estadísticas desde dentro del juego:

Tipo de estadística AVGRATE

Este tipo de estadística ofrece una funcionalidad especial y muy útil, pero requiere una explicación algo más detallada.

Supongamos que queremos llevar un seguimiento de una estadística de media, como "puntos ganados por hora". Un enfoque sería tener dos estadísticas, un INT "TotalPoints" y un FLOAT "TotalPlayTimeHours", y luego divide los puntos por tiempo para obtener Puntos por hora.

El inconveniente de esta implementación es que, cuando el jugador acumula una amplia cantidad de tiempo de juego, la media calculada cambia con una lentitud extrema. De hecho, cuanto más juegue el usuario, peor responderá esta media. Si el usuario ha pasado 100 horas jugando al juego, la media calculada estará 50 horas por detrás. Si el usuario aumenta su habilidad, no verá el aumento en puntos por hora que espera.

El tipo de estadística AVGRATE permite utilizar un "efecto de ventana deslizante" con la media. Por ejemplo, se pueden utilizar solo las últimas horas de juego para que la estadística refleje con más precisión el nivel de habilidad actual del jugador.

Configuremos una estadística AVGRATE que calcule "puntos por hora" empleando las últimas 20 horas de juego para hallar el valor. Haríamos lo siguiente:
  • Se debe tener en cuenta que, como estamos calculando la media "por horas", la unidad de tiempo de todos los parámetros asociados con esta estadística será la "hora". Esto se aplica a la propiedad del rango en la estadística en sí, y también para la "dSessionLength" parámetro pasado en UpdateAvgRateStat a continuación.
  • Crear una estadística AVGRATE llamada "AvgPointsPerHour" y un abanico temporal de 20 (recordemos que la unidad es la "hora").
  • En los puntos apropiados durante tu juego, llama a ISteamUserStats::UpdateAvgRateStat con los siguientes parámetros:
    • pchName: "AvgPointsPerHour"
    • flCountThisSession: número de puntos que ha ganado el jugador desde la última llamada a UpdateAvgRateStat.
    • dSessionLength: la cantidad de tiempo de juego desde la última llamada a UpdateAvgRateStat. La unidad debería ser la misma que la de la propiedad Ventana de la estadística. En este caso, es de "horas".
  • Por ejemplo, si el jugador obtuvo 77 puntos en la última ronda, que duró 0,225 horas (13,5 minutos), eso sería SteamUserStats()->UpdateAvgRateStat( "AvgPointsPerHour", 77, 0.225 )
En el ejemplo anterior, Steam tomará la media de 342,2 puntos por hora (77 entre 0,225) de la ronda actual para combinarla con el valor anterior. El resultado reflejará la media total de las últimas 20 horas de juego del jugador. Si esta es la primera vez que se actualiza la estadística para el usuario actual, en valor será 342,2.

Este ejemplo usa las "horas" como unidad de tiempo, pero se puede usar cualquier otra unidad de tiempo. Solo hay que tener en cuenta que esa unidad se debe usar homogéneamente como base para "dSessionLength", así como para la propiedad Ventana.

Obtener estadísticas de otros usuarios

Puedes usar ISteamUserStats::RequestUserStats para obtener las estadísticas de otro usuario. Luego puedes usar ISteamUserStats::GetUserStat, ISteamUserStats::GetUserAchievement y ISteamUserStats::GetUserAchievementAndUnlockTime para obtener datos para el usuario. Estos datos no se actualizan automáticamente a medida que el otro usuario carga nuevas estadísticas, por lo tanto, para actualizar los datos simplemente llame a ISteamUserStats::RequestUserStats nuevamente.

Para no usar demasiada memoria, se mantiene una caché LRU y se descargan ocasionalmente las demás estadísticas del usuario. Cuando esto sucede, se envía automáticamente una devolución de llamada ISteamUserStats::UserStatsUnloaded_t. Cuando se envíe esta devolución de llamada, las estadísticas del usuario especificado no estarán disponibles hasta que se vuelva a llamar a ISteamUserStats::RequestUserStats.

Modo desconectado

Steam mantiene una caché local de los datos de estadísticas y logros, de forma que las API se puedan usar con normalidad en modo desconectado. Las estadísticas que no se puedan enviar se guardan hasta la siguiente vez que el usuario se conecta. En caso de que se hayan modificado en más de una máquina, Steam combinará automáticamente los logros y elegirá el conjunto de estadísticas que tenga mayor progreso. Puesto que Steam guarda los datos de estadísticas en una caché local, no es necesario que el juego mantenga también en el disco una caché local de los datos. De hacerlo, se podría producir un conflicto entre ambas cachés y al usuario le parecería que su progreso ha desaparecido, lo que resultaría frustrante.

Estadísticas del servidor de juego

En paralelo a ISteamUserStats existe ISteamGameServerStats para los servidores de juego. Estos pueden obtener estadísticas para los usuarios de la misma manera que los clientes (descrito anteriormente). También pueden configurar estadísticas y conceder logros, pero solo si "Establecido por" se establece como GS (servidor de juego) o como servidor oficial. La diferencia entre servidores de juego y servidores oficiales de juego es que tú controlas estos últimos y ofertas tu servicio desde ellos. Usar los servidores oficiales de juego para establecer estadísticas aporta mayor seguridad frente a las trampas, ya que los usuarios podrían modificar sus propios servidores de juego o simular ser un servidor de juego. Para definir los servidores oficiales del juego, ingresa los rangos de IP de los servidores aquí.

Las estadísticas y los logros configurables por parte de los servidores de juego no pueden configurarse por los clientes. Los servidores de juego solo pueden configurar estadísticas y logros para usuarios que estén jugando actualmente en el servidor. Si el usuario abandona el servidor, hay un breve periodo de gracia para establecer cualesquiera estadísticas finales, pero después cualquier nueva subida de estadísticas será denegada. Esto es para contribuir a garantizar la consistencia y evitar hacer posible para un servidor de juego malicioso establecer las estadísticas de alguien en cualquier momento. Dada la restricción, es importante no esperar hasta el final de una ronda para establecer las estadísticas. Han de establecerse de forma continuada, para poder almacenarlas cuando un usuario abandona el servidor.

Los clientes obtendrán actualizaciones automáticas cuando un servidor de juego cambie sus estadísticas. Sin embargo, al igual que los clientes, las estadísticas cargadas por el servidor para otros usuarios no se actualizan automáticamente y pueden quedar obsoletas.

Restablecer estadísticas

Durante el desarrollo, a menudo sucede que es deseable una eliminación completa de estadísticas y logros en una cuenta o en todas ellas con fines de testeo. Para borrar las estadísticas de una cuenta, llama a ISteamUserStats::ResetAllStats con bAchievementsToo establecido en true para borrar también los logros. Una vez llamada, ha de recordarse reiterar las estadísticas y logros, y restablecer el estado de juego en memoria. No hay forma de eliminar globalmente las estadísticas y los logros para todos los usuarios. Una de las razones para ello es que, incluso si se hiciese una eliminación global, el progreso dentro del juego podría detectar la eliminación y rescribir los valores en memoria. Afortunadamente, hay una forma sencilla de elaborar un sistema para eliminaciones globales integrado en los juegos. Para ello:
  • Define una estadística con un nombre como "Versión".
  • Pon un número de versión de las estadísticas codificadas en el juego.
  • Una vez que se hayan cargado las estadísticas, compara la "Versión" estadísticas contra tu número de versión codificada.
  • Si no coinciden, llama a ISteamUserStats::ResetAllStats y luego configure la "Versión" de estadística al número codificado.
De esta forma, siempre que se desee realizar una eliminación global, solo es necesario cambiar el número de versión para las estadísticas codificadas de forma rígida. La eliminación global tendrá lugar después, a medida que los usuarios accedan a la nueva compilación.

Consistencia de estadísticas

Figura entre las mejores prácticas considerar cómo las estadísticas relacionadas podrían volverse inconsistentes. Por ejemplo, puedes tener tres estadísticas "GamesWon", "GamesLost" y "GamesPlayed". A pesar de las mejores intenciones, las estadísticas pueden perder su mutua sincronización y, de hecho, así sucede. En este caso, podría producirse que las partidas ganadas y perdidas no diesen como suma el número total de partidas jugadas. Si esto se resolvió eliminando el "GamesLost" de las estadísticas y en lugar de computarlo como "GamesPlayed" - "GamesWon", una inconsistencia podría causar "GamesLost" ser negativo. En este caso, es mejor eliminar las estadísticas "GamesPlayed" y computarlo como "GamesWon" + "GamesLost".

Estadísticas globales

Las estadísticas pueden marcarse como agregadas en la página de administración para ordenar a Steam mantener un total global de todos los valores de los usuarios para la estadística. Puede usarse para obtener datos del total de dinero en la economía, el total de muertes, armas favoritas, mapas favoritos y qué equipo suele obtener mejores resultados. Por otro lado, esto no es deseable para estadísticas como "MostKills", ya que un sumatorio para varios usuarios no tendría sentido. Como las estadísticas están en manos de los usuarios, estos datos están sujetos a manipulación. Por lo tanto, es crucial que cuando se usen estadísticas agregadas se establezcan buenos límites para el valor mínimo, el valor máximo, solo incremental (si fuese apropiado) y la diferencia máxima. La diferencia máxima tiene un significado especial para estadísticas agregadas. Cuando se carga un nuevo valor, el cambio en el valor global no superará el valor de la diferencia máxima. Esto limita lo rápido que un tramposo puede influenciar los totales globales.

Para acceder a los totales globales, llama a ISteamUserStats::RequestGlobalStats y luego ISteamUserStats::GetGlobalStat para cada estadística global. También puedes solicitar ISteamUserStats::RequestGlobalStats para un número específico de días de historial. El historial es la cantidad que cambió la estadística cada día. Puedes acceder a ese historial con ISteamUserStats::GetGlobalStatHistory.

También se pueden solicitar al cliente los porcentajes de compleción de logros globales. Para hacerlo, primero llama a ISteamUserStats::RequestGlobalAchievementPercentages. Luego, itera los logros en el orden de más completo a menos completado llamando a ISteamUserStats::GetMostAchievedAchievementInfo y ISteamUserStats::GetNextMostAchievedAchievementInfo. También puedes obtener el porcentaje de finalización para un logro en particular llamando a ISteamUserStats::GetAchievementAchievedPercent.

La Comunidad de Steam

Después de que el desarrollador haya publicado el juego, la información sobre el progreso individual y global de logros se mostrará en la Comunidad Steam. Cada jugador tendrá un vínculo desde su perfil de la comunidad que dirija a una página donde se exhiban sus logros ya conseguidos, y cuáles debe aún desbloquear.
NOTA: tus logros no se mostrarán hasta que tu aplicación sea visible para la comunidad.

Cada logro se incluye con el icono apropiado, y el nombre y la descripción tal y como se hayan establecido en el panel de control de Steamworks. Si el nombre y la descripción del logro han sido traducidos al idioma que el usuario haya elegido, se mostrarán en ese mismo idioma.

También habrá un vínculo desde esta página y otro desde la página principal de Steam de tu juego para establecer un conjunto de estadísticas de logros globales para el mismo. Muestra el porcentaje de jugadores de Steam que han alcanzado cada logro, ordenados desde el logro más común al más infrecuente. Esto es algo que a los jugadores les gusta ver y también un gran recurso para los desarrolladores: ¿son sus retos más especiales lo suficientemente difíciles? ¿O tal vez demasiado difícil? (Esta información también está disponible en el sitio de Informes de ventas y activaciones).

¿Más preguntas?

Plantea tus preguntas en el Panel de discusiones de estadísticas y logros