Comment détecter les réalisations dans le jeu?

10

J'ai par erreur posté ceci sur stackoverflow et je publie maintenant ici sur la base d'une suggestion sur ce site ...

Il s'agit d'une question conceptuelle de très haut niveau. Dites dans une application logicielle que j'ai 4 actions différentes, par exemple: télécharger, partager, commenter et aimer

Et je veux donner des badges de réussite à des utilisateurs comme:

  • Rookie - Téléchargez vos 5 premiers fichiers
  • Upload Junkie - Téléchargez 20 fichiers en 1 jour
  • Night Crawler - Téléchargez un fichier après minuit
  • Share-a-holic - Partagez 10 fichiers différents
  • Aime tout - comme 20 fichiers différents

vous avez eu l'idée. Quelle est la meilleure façon de vérifier et de voir si un utilisateur a réalisé une réalisation particulière sans avoir à compiler la logique de la réalisation dans mon code? Et .. - Gardez la possibilité d'ajouter de nouvelles réalisations après la compilation (xml ou db) - Les réalisations doivent suivre des actions spécifiques, le nombre de fois et des critères supplémentaires (comme l'heure de la journée) - La détection doit être presque en temps réel, donc l'utilisateur a été notifié presque instantanément quand une réalisation est terminée

Ma plus grande question est la suivante: comment détecter ces réalisations? Est ce que je:

1) Vérifiez après chaque action pour voir si ... (La plupart du temps en temps réel) 2) Demandez à un autre programme de vérifier la base de données à tout moment par rapport à un ensemble de règles? (Le plus simple)

Y a-t-il un autre paradigme qui me manque? Je pense qu'il y en a certainement parce que dans de nombreux jeux (comme jetpack pour iOS par exemple), je suis informé de la réussite que j'ai débloquée à l'instant où je la déverrouille, ce que j'ai trouvé assez impressionnant.

Je vous remercie

Tan Rezaei
la source
Avez-vous déjà conçu ou réalisé le système de réalisations et voulez-vous simplement savoir comment l'utiliser dans le jeu?
Harrison Brock

Réponses:

6

Ce que vous faites généralement, c'est un système de «réussite». Toute action qui se produit appelle le système de réussite et dit "hé cette chose vient de se passer".

Le système de réalisation est alors généralement un ensemble de règles, généralement composé d'une logique combinatoire simple et de compteurs pour différents "événements". C'est ensuite la responsabilité du système de réussite de travailler, à l'aide des règles et des compteurs, des whets qui se sont produits et des réalisations à donner.

La raison pour laquelle vous faites cela est double.

  • Vous ne voulez pas étendre votre logique d'état sur toute votre base de code.

  • parfois, les réalisations nécessiteront des combinaisons de "trucs" qui peuvent se produire dans des systèmes / temps / etc complètement différents et la diffusion de la logique pour cela autour de votre base de code entraînerait de grandes quantités de complexité inutile.

La façon dont je l'ai fait dans le passé est d'utiliser un système de règles scriptables (où scriptable est un terme très vague, généralement juste une sorte de comparateur piloté par les données). Vous pouvez donc dire quelque chose qui ressemble à:

  • Lorsque "l'utilisateur a appuyé sur quelque chose" se produit "incrémente" la variable "pressé".

Ensuite, vous pourriez avoir une autre règle qui est

  • Lorsque la variable "enfoncée" est "supérieure" à "une certaine valeur", distribuez la réussite "bla"

Ou peut-être

  • Lorsque "l'utilisateur tue le boss" se produit "distribuez" la réalisation "bla".

Le système de réussite sera également chargé de maintenir l'état des réalisations qui ont déjà été distribuées, afin de ne pas obtenir de doublons.

Matt D
la source
0

Une bonne façon de gérer cela pourrait être un modèle de spécification. Vous auriez un gestionnaire de réussite, qui interrogerait périodiquement vos utilisateurs pour ceux qui correspondent à un ensemble de spécifications. Votre classe de réussite comprendrait donc un nom, un logo, un score en points, etc., ainsi qu'une spécification décrivant un utilisateur qui a obtenu cette réussite. Par exemple, en C #, la réussite "Partager un holic" pourrait ressembler à ceci:

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

AchievementManager.AddAchievementType(ShareAHolic);

puis au moment approprié, votre gestionnaire de réussite peut faire quelque chose comme ceci:

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);
    }
}

La .Award()méthode de votre gestionnaire de réussite peut également être appelée directement au point approprié si une réalisation peut être détectée immédiatement. Vous pouvez également souhaiter ajouter une méthode pour exécuter ces vérifications sur un utilisateur spécifique, afin de pouvoir déclencher une vérification après des événements importants pour permettre aux utilisateurs d'obtenir immédiatement des résultats.

anaximandre
la source
Le partitionnement des réalisations devient rapidement important, AchType a besoin d'une propriété 'sope' qui peut aider DB.Users.Where () pour éviter les réalisations indépendantes, lorsque cela est possible. Donc, si la réussite du partage de fichiers ne peut être attribuée qu'en PvP, recherchez uniquement PvP. Alors que quelque chose de générique comme le pillage pourrait être réalisable à l'échelle mondiale et n'aurait pas une telle portée.
hpavc