Como detectar conquistas nos jogos?

10

Eu postei isso por engano no stackoverflow e agora estou postando aqui com base em uma sugestão nesse site ...

Essa é uma questão conceitual de nível muito alto. Digamos que em um aplicativo de software eu tenho 4 ações diferentes, por exemplo: Carregar, Compartilhar, Comentar e Curtir

E quero dar distintivos de conquista a usuários como:

  • Novato - Envie seus 5 primeiros arquivos
  • Upload Junkie - Upload 20 arquivos em 1 dia
  • Rastreador noturno - Carregar um arquivo depois da meia-noite
  • Share-a-holic - Compartilhe 10 arquivos diferentes
  • Likes-everything - Como 20 arquivos diferentes

Você entendeu a ideia. Qual é a melhor maneira de verificar e verificar se um usuário alcançou uma conquista específica sem precisar compilar a lógica da conquista no meu código? E .. - Manter a capacidade de adicionar novas conquistas após a compilação (xml ou db) - As conquistas devem rastrear ações específicas, número de vezes e critérios adicionais (como a hora do dia) - A detecção deve ser quase em tempo real, para que o usuário seja notificado quase instantaneamente quando uma conquista é concluída

Minha maior dúvida é: como eu detecto essas conquistas sendo alcançadas? Eu:

1) Verifique depois de cada ação para ver se ... (Em tempo real) 2) Outro programa verifica o banco de dados o tempo todo em relação a um conjunto de regras? (Mais fácil)

Existe outro paradigma que estou perdendo? Eu sinto que definitivamente existe, porque em muitos jogos (como o jetpack para iOS, por exemplo), sou notificado da conquista que desbloquei no instante em que desbloquei, o que achei bastante impressionante.

Obrigado

Tan Rezaei
fonte
Você já projetou ou criou o sistema de conquistas e quer saber como usá-lo no jogo?
precisa

Respostas:

6

O que você geralmente faz é ter um sistema de "conquistas". Qualquer ação que acontece chama o sistema de conquista e diz "ei, isso acabou de acontecer".

O sistema de conquista é geralmente um conjunto de regras, geralmente composto de lógica combinatória e simples contadores para vários "eventos". É então a responsabilidade do sistema de conquistas em elaborar, com a ajuda das regras e contadores, aguçadas ocorridas e quais conquistas devem ser entregues.

A razão pela qual você faz isso é dupla.

  • Você não deseja espalhar sua lógica de estado por toda a sua base de código.

  • às vezes, as conquistas exigirão combinações de "coisas" que podem acontecer em sistemas / tempos / etc completamente diferentes, e espalhar a lógica disso em sua base de código resultaria em grandes quantidades de complexidade desnecessária.

A maneira como eu fiz isso no passado é usar um sistema de regras com script (onde script é um termo muito flexível, geralmente apenas algum tipo de comparador orientado a dados). Então você pode dizer algo parecido com:

  • Quando "o usuário pressionou algo" acontece "incrementa" a variável "pressionado".

Então você poderia ter outra regra que é

  • Quando a variável "pressionada" é "maior" do que "algum valor", entregue a conquista "blá"

Ou talvez

  • Quando "o usuário mata o chefe" acontece "distribui" conquista "blá".

O sistema de conquista também terá a tarefa de manter o estado de quais conquistas já foram entregues, para que você não obtenha duplicatas.

Matt D
fonte
0

Uma maneira elegante de lidar com isso pode ser um padrão de especificação. Você teria um gerente de realizações, que periodicamente consultaria seus usuários em busca daqueles que correspondam a qualquer conjunto de especificações. Portanto, sua classe de conquistas incluiria um nome, logotipo, pontuação de pontos, etc. normalmente, e também uma especificação descrevendo um usuário que conquistou essa conquista. Por exemplo, em C #, a conquista "Compartilhar um holic" pode ter a seguinte aparência:

AchievementType ShareAHolic = new AchievementType
{
    Name = "Share-a-holic",
    Description = "Shared 10 files",
    Score = 25,
    Specification = (user => user.SharedFiles.Distinct().Count() > 10)
};

AchievementManager.AddAchievementType(ShareAHolic);

e, no momento apropriado, seu gerente de conquistas pode fazer algo assim:

foreach (AchievementType achievement in AchievementTypes)
{
    var users = DB.Users.Where(achievement.Specification && !(user.Achievements.Contains(achievement)));
    foreach (User u in shareaholics)
    {
        AchievementManager.Award(u, achievement);
    }
}

O .Award()método do seu gerente de conquistas também pode ser chamado diretamente no ponto apropriado se uma conquista puder ser detectada imediatamente. Você também pode adicionar um método para executar essas verificações em um usuário específico, para poder disparar uma verificação após eventos importantes para permitir que os usuários obtenham conquistas imediatamente.

anaximander
fonte
Como realizar conquistas de particionamento se torna rapidamente importante, o AchType precisa de uma propriedade 'sope' que possa ajudar DB.Users.Where () a evitar conquistas não relacionadas, quando possível. Portanto, se a conquista de compartilhamento de arquivos puder ser concedida apenas no PvP, pesquise apenas pelo PvP. Embora algo genérico como saques possa ser viável globalmente e não tenha esse escopo.
Hpavc # 21/16