¿Cómo debo verificar si un jugador ha completado un logro?

13

Estoy haciendo un juego MMO y acabo de llegar a un punto en el que necesito implementar logros ... ¿Cómo hago eso? Lo más sencillo sería ejecutar esto una vez cada 100 ms:

for a in achievements
    for p in players
        if a.meetsRequirements(p) then p.completeAchievement(a)

Pero eso solo plantea aún más complicaciones. Por ejemplo, ¿cómo verifico si el logro realmente se ha completado? ¿Los jugadores tienen propiedades personalizadas solo para un logro específico? Hice este tipo de cosas con misiones, porque son principalmente "recoger 100 madera", por lo que las misiones activas en un jugador comprueban eso. Además, debe haber un mejor momento para comprobarlo, creo que esto ralentizaría periódicamente mi servidor.

jcora
fuente
77
¿Por qué no simplemente realizar verificaciones pertinentes a medida que se realizan las acciones? Es decir, si el usuario recolecta madera, vea si coinciden con la especificación "recolectar 100 madera".
Mike Cluck
1
Eso parece un poco desordenado ... Habría toneladas de cheques en todas partes. Creo que me atendré al algoritmo anterior debido a su simplicidad ...
jcora
10
Hay maneras de hacerlo menos desordenado: como tener un controlador de eventos "OnChange" y luego adjuntar "objetos" de logros a esos y manejar la lógica allí. También comprenda que con su configuración actual tiene un nivel de complejidad O (n ^ 2), lo que significa que su juego se vuelve más lento y más rápido con más personajes. Un tipo de problema para un MMO
Mike Cluck

Respuestas:

23

Lo que haces depende de la naturaleza del logro. A menos que todos sus logros se ajusten a un patrón simple (recoja X número de Ys), tendrá que hacer un caso especial hasta cierto punto.

Mediante un sistema de comunicación basado en mensajes, puede proporcionar enlaces que hacen que la codificación de casos especiales esté localizada. Puede hacer que ciertas acciones envíen mensajes a los oyentes que se registran. Luego, su código / secuencia de comandos de logro solo puede registrarse con los oyentes apropiados y hacer cualquier prueba que sea necesaria para disparar el logro.

Tendrías mensajes para los eventos típicos que podrías querer escuchar para los logros. Cosas como "el jugador ha adquirido el elemento X" o "la entidad Y mató a la entidad Z". De esta manera, puedes rastrear cosas como cuántas Z's ha matado el jugador.

Eso es probablemente lo mejor que puede hacer para un sistema de logros. Centraliza el código tanto como sea posible y pone la responsabilidad de los oyentes para la detección del logro real.

Además, debe tenerse en cuenta que, para los sistemas de logros centralizados (X-Box Live, logros de Steam), el progreso hacia los logros generalmente se almacena en el servidor. Entonces, para los logros de acumulación ("realizar la tarea XY varias veces"), el script de logros solo detecta cuándo se ha realizado X y aumenta el recuento del servidor. Para otros tipos de logros ("realizar la tarea X"), el logro del servidor es binario: o lo has hecho o no lo has hecho.

Nicol Bolas
fuente
+1 Esta es una gran información. Incluso útil sin que necesite implementar logros en este momento.
Joshua Hedges
¡Gracias! No puedo esperar para implementar esto, desearía tener esta idea antes ...
jcora
3

Dependiendo de la naturaleza de sus logros, también podría introducir algún tipo de "logros de marcador".

Si tienes, por ejemplo, 3 logros consecutivos:
Madera 1 - Recoge 100 madera
Madera 2 - Recoge 500 madera
Madera 3 - Recoge 1k madera

Entonces tendría sentido registrar un evento OnChange para el primer logro hasta que el jugador lo complete. Al finalizar, puede registrar el siguiente objeto de logro.

Por supuesto, esto requiere el diseño (o cálculo) de un árbol de dependencia de logros.

Principe Carlos
fuente