Como devo verificar se um jogador completou uma conquista?

13

Estou fazendo um jogo MMO e cheguei a um ponto em que preciso implementar conquistas ... Como faço isso? A coisa mais simples a fazer seria executar isso uma vez a cada 100ms:

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

Mas isso apenas levanta ainda mais complicações. Por exemplo, como verifico se a conquista foi realmente concluída? Os jogadores têm propriedades personalizadas em si mesmos apenas para uma conquista específica? Eu fiz esse tipo de coisa com missões, porque elas são principalmente "colecionam 100 lenha", e missões ativas em um jogador verificam isso. Além disso, deve haver um momento melhor para verificá-lo, isso diminuiria periodicamente meu servidor, eu acho.

jcora
fonte
7
Por que não executar verificações pertinentes à medida que as ações são executadas? Ou seja, se o usuário coletar madeira, verifique se ele corresponde à especificação "coletar 100 madeira".
Mike Cluck #
1
Isso meio que parece muito confuso ... Haveria toneladas de cheques em todos os lugares. Acho que vou ficar com o algoritmo acima por causa de sua simplicidade ...
jcora
10
Existem maneiras de torná-lo menos confuso: como ter um manipulador de eventos "OnChange", anexar "objetos" de conquista a eles e manipular a lógica lá. Entenda também que, com sua configuração atual, você tem um nível de complexidade O (n ^ 2), o que significa que seu jogo se torna mais lento e mais rápido com mais personagens. Tipo de problema para um MMO #
Mike Cluck 24/12

Respostas:

23

O que você faz depende da natureza da conquista. A menos que todas as suas realizações se encaixem em um padrão simples (colete o número X de Ys), você precisará especificá-las até certo ponto.

Usando um sistema de comunicação baseado em mensagens, você pode fornecer ganchos que tornam a codificação de caso especial localizada. Você pode executar determinadas ações para enviar mensagens aos ouvintes que se registram. Então, seu código / script de conquista pode se registrar com os ouvintes apropriados e fazer os testes necessários para iniciar a conquista.

Você teria mensagens para os eventos típicos que deseja obter realizações. Coisas como "o jogador adquiriu o item X" ou "a entidade Y matou a entidade Z". Dessa forma, você pode rastrear coisas como quantos Zs o jogador matou.

Provavelmente é o melhor que você pode fazer por um sistema de realizações. Ele centraliza o código o máximo possível e coloca os ônus nos ouvintes para a detecção real de realizações.

Além disso, deve-se notar que, para sistemas de conquista centralizados (X-Box Live, conquistas do Steam), o progresso em direção às conquistas é normalmente armazenado no servidor. Portanto, para conquistas de acumulação ("executar a tarefa XY várias vezes"), o script de conquista apenas detecta quando X foi executado e aumenta a contagem do servidor. Para outros tipos de conquistas ("executar a tarefa X"), a conquista do servidor é binária: você fez ou não.

Nicol Bolas
fonte
+1 Esta é uma ótima informação. Mesmo útil sem que eu precise implementar conquistas no momento.
Joshua Hedges
Obrigado! Mal posso esperar para implementar isso, eu gostaria de ter essa idéia antes ...
jcora
3

Dependendo da natureza de suas conquistas, você também pode introduzir algum tipo de "conquista de marcadores".

Se você tiver, por exemplo, 3 conquistas consecutivas:
Madeira 1 - Colete 100 madeira
Madeira 2 - Colete 500 madeira
Madeira 3 - Colete 1k madeira

Então faria sentido apenas registrar um evento OnChange para a primeira conquista até que o jogador o concluísse. Após a conclusão, você pode registrar o próximo objeto de conquista.

Obviamente, isso requer o design (ou cálculo) de uma árvore de dependência de conquista.

Príncipe Charles
fonte