2010-02-26 14 views
33

Muchos juegos que se crean actualmente vienen con su propio sistema de logros que recompensa a los jugadores/usuarios por llevar a cabo ciertas tareas. El sistema de distintivos aquí en stackoverflow es exactamente el mismo.Implementación de sistemas de logros en juegos modernos y complejos

Aunque hay algunos problemas por los que no pude encontrar buenas soluciones.

Los sistemas de logros tienen que estar atentos a ciertos eventos todo el tiempo, piense en un juego que ofrece entre 20 y 30 logros por ej .: combate. El servidor debería verificar estos eventos (por ejemplo, el jugador evitó x ataques del oponente en esta batalla o el jugador caminó x millas) todo el tiempo.

  • ¿Cómo puede un servidor manejar esta gran cantidad de operaciones sin ralentizar y tal vez incluso bloquearse?

sistemas de Logro por lo general necesitan datos que sólo se utiliza en el motor principal del juego y no se necesitarían salir de allí de todos modos si no hubiera esos logros desagradables (piensa por ejemplo: ¿con qué frecuencia saltó el jugador durante cada pelea, no desea almacenar toda esta información en una base de datos). Lo que quiero decir es que, en algunos casos, la única forma de agregar un logro sería agregar el código que verifica su estado actual al núcleo del juego, y esa es generalmente una muy mala idea.

  • ¿Cómo los sistemas de aprovechamiento interactuar con el núcleo del juego que contiene la información necesaria más adelante? (ver ejemplos más arriba)

  • ¿Cómo están separados del núcleo del juego?

Mis ejemplos pueden parecer "inofensiva", pero pensar en los logros de 1000 disponibles en la actualidad en el mundo de Warcraft y los muchos, muchos jugadores en línea al mismo tiempo, por ejemplo.

+0

Esta es una muy buena pregunta y ser un jugador, me he preguntado sobre esto desde que empecé a programar.Sabía que los eventos definitivamente tendrían que ver con eso, pero todavía me pregunto una cosa: hay juegos antiguos que no fueron construidos con los logros en mente, y supongo que no emiten esos eventos. Sin embargo, estos juegos a veces reciben logros cuando se vuelven a publicar en plataformas como Steam. ¿Eso significa que Valve ha hecho algunas modificaciones en el núcleo? – MarioDS

+1

Estoy seguro de que lo que está buscando es lo siguiente: [¿Cómo puedo configurar un marco flexible para manejar los logros?] (Http://gamedev.stackexchange.com/questions/908/how-can-i-set- up-a-flexible-framework-for-handling-achievements). Estos muchachos proponen algunas soluciones muy buenas. –

Respuesta

21

Los sistemas de logros son en realidad solo una forma de registro. Para un sistema como este, publish/subscribe es un buen enfoque. En este caso, los jugadores publican información sobre ellos mismos, y los componentes de software interesados ​​(que manejan logros individuales) pueden suscribirse. Esto le permite ver valores públicos con un código de registro especializado, sin afectar la lógica del juego principal.

Tome su ejemplo de "jugador caminado x millas". Implementaría la distancia recorrida como un campo en el objeto jugador, ya que este es un valor simple para incrementar y no requiere aumentar el espacio en el tiempo. Un logro que recompensa a los jugadores que caminan 10 millas es entonces un suscriptor de ese campo. Si hubiera muchos jugadores, tendría sentido agregar este valor con uno o más niveles intermedios de intermediarios. Por ejemplo, si hay 1 millón de jugadores en el juego, puede agregar los valores con 1000 intermediarios, cada uno responsable de rastrear 1000 jugadores individuales. El logro se suscribe a estos corredores, en lugar de a todos los jugadores directamente. Por supuesto, la jerarquía óptima y la cantidad de suscriptores es específica de la implementación.

En el caso de su ejemplo de lucha, los jugadores podrían publicar los detalles de su última pelea exactamente de la misma manera. Un logro que monitorea saltos en peleas se suscribirá a esta información y verifica el número de saltos. Como no se requiere un estado histórico, tampoco crece con el tiempo. Nuevamente, no es necesario modificar ningún código central; solo necesita poder acceder a algunos valores.

Tenga en cuenta también que la mayoría de las recompensas no necesitan ser instantáneas. Esto le permite un margen de maniobra para administrar su tráfico. En el ejemplo anterior, es posible que no actualice la distancia publicada del intermediario recorrida hasta que un jugador haya caminado un total de una milla más, o haya transcurrido un día desde la última actualización (incrementándose internamente hasta ese momento). Esto es realmente solo una forma de almacenamiento en caché; los parámetros exactos dependerán de su problema.

+0

¿Qué pasa con algo que no requiere datos históricos? Como hacer algo 6 veces en un minuto. ¿Te verías obligado a registrar todos los eventos (como esta acción u otra) y luego verificas de vez en cuando? –

+2

@JosephShanak - No. Se registraría un subconjunto de los eventos, se correría una ventana y se envejecería el evento a medida que se volviera irrelevante. En su ejemplo, nunca necesita registrar más de 6 valores. Cuando entra un nuevo valor, compare su valor inicial y final, y vea si caen dentro de un minuto. Si lo hacen, obtuviste el logro. Si no lo hacen, suelte el valor más antiguo, desvíe la lista, espere a que aparezca la siguiente y repita. –

+0

@ire_and_curses ¿Qué sucede si necesita datos históricos complejos como "el usuario ha jugado durante más de 2 semanas, ha respondido correctamente a al menos el 65% de las preguntas y ha dado el 100% de respuestas correctas durante los últimos 3 días"? Y además de eso, agrega que es un juego basado en la web donde las estadísticas se almacenan en una base de datos SQL. Las consultas SQL para datos históricos son costosas, especialmente cuando se agregan datos. ¿Sugeriría un enfoque diferente en ese escenario? –

1

Si la arquitectura de su juego es Event-driven, puede implementar el sistema de logros utilizando finite-state machines.

+2

¿Podría profundizar en esto? –

+0

Esta es una respuesta realmente deficiente, por desgracia. Parece interesante... –

3

Hay dos formas de hacerlo en juegos normales.

  1. Juegos sin conexión: nada tan complejo como pub/sub - eso es un exceso masivo. En su lugar, solo utiliza un mapa/diccionario grande y registra los nombres de "eventos". Luego, cada X fotogramas, o Y segundos (o, por lo general, "cada vez que algo muere, y 1 vez al final del nivel"), se repiten los logros y se comprueba rápidamente. Cuando los diseñadores quieren que se registre un nuevo evento, es trivial que un programador agregue una línea de código para grabarlo.

NB: pub/sub no es adecuado para este IME porque los diseñadores nunca quieren "when player.distance = 50". Lo que realmente quieren es "cuando la distancia del jugador percibida por alguien mirando la pantalla parece haber pasado la primera aldea, o al menos 4 anchos de pantalla a la derecha", es decir, mucho más vago y abstracto que un simple contador.

En la práctica, eso significa que la lógica va al punto donde ocurre el cambio (incluso antes de que el evento se publique), que es una forma pobre de usar pub/sub. Hay algunos motores de juego que hacen que sea más fácil hacer una "lógica va en el punto de recepción" (la parte "sub"), pero no son la mayoría, IME.

  1. juegos en línea: casi idénticas, excepto que almacena "contadores" (int que sube), y por lo general también: "deltas" (buffer circular de marco Cosa pasado a fotograma), y: "eventos" (cosas complejas que sucedieron en el juego que pueden codificarse en una sola ID más una matriz de parámetros de tamaño fijo). Estos se exponen entonces a través de SNMP, por ejemplo para otros servidores para recoger a bajo costo CPU y asíncrona

es decir, casi lo mismo que 1 anterior, excepto que usted tiene cuidado de hacer dos cosas:

  • Uso de la memoria de tamaño fijo; y si los servidores de "lectura" se desconectan por un tiempo, los logros ganados en ese momento necesitarán volver a ganar (aunque normalmente puede hacer que un soporte al cliente revise manualmente los registros principales del sistema y determine que el logro "probablemente "se ganó y se lo adjudicó manualmente)
  • Muy poca sobrecarga; SNMP es un buen estándar para esto, y la mayoría de los equipos que conozco terminan usándolo
3

Incluso puede hacer esto si no tiene acceso a la fuente, por ejemplo en emuladores de videojuegos. Se puede escribir una herramienta simple de escaneo de memoria para encontrar la puntuación mostrada, por ejemplo. Una vez que tenga que su sistema de logros es tan fácil como sondear la ubicación de memoria de cada cuadro y ver si su "puntaje" actual o lo que sea es más alto que su puntaje más alto. Lo bueno de los emuladores de videojuegos es que las ubicaciones de memoria son deterministas (sin sistema operativo).

Cuestiones relacionadas