Wie kann man Erfolge beim Spielen erkennen?

10

Ich habe dies fälschlicherweise in stackoverflow gepostet und jetzt hier basierend auf einem Vorschlag auf dieser Seite gepostet ...

Dies ist eine sehr hochrangige konzeptionelle Frage. Angenommen, in einer Softwareanwendung habe ich 4 verschiedene Aktionen, zum Beispiel: Hochladen, Teilen, Kommentieren und dergleichen

Und ich möchte Benutzern Leistungsabzeichen geben wie:

  • Rookie - Laden Sie Ihre ersten 5 Dateien hoch
  • Junkie hochladen - Laden Sie 20 Dateien an einem Tag hoch
  • Night Crawler - Laden Sie eine Datei nach Mitternacht hoch
  • Share-a-holic - Teilen Sie 10 verschiedene Dateien
  • Likes-Everything - Wie 20 verschiedene Dateien

Du hast die Idee. Wie kann er am besten überprüfen, ob ein Benutzer eine bestimmte Leistung erzielt hat, ohne die Logik für die Leistung in meinem Code kompilieren zu müssen? Und .. - Behalten Sie die Möglichkeit bei, nach dem Kompilieren neue Erfolge hinzuzufügen (xml oder db). - Erfolge müssen bestimmte Aktionen, die Anzahl der Male und zusätzliche Kriterien (wie die Tageszeit) verfolgen. - Die Erkennung sollte nahezu in Echtzeit erfolgen, damit der Benutzer benachrichtigt wird fast sofort, wenn ein Erfolg abgeschlossen ist

Meine größte Frage ist, wie ich feststelle, dass diese Erfolge erzielt werden. Muss ich:

1) Überprüfen Sie nach jeder Aktion, ob ... (meistens in Echtzeit) 2) Lassen Sie die Datenbank jederzeit von einem anderen Programm anhand einer Reihe von Regeln überprüfen? (Am einfachsten)

Gibt es ein anderes Paradigma, das mir fehlt? Ich habe das Gefühl, dass dies definitiv der Fall ist, weil ich in vielen Spielen (wie zum Beispiel Jetpack für iOS) über den Erfolg informiert werde, den ich in dem Moment freigeschaltet habe, in dem ich ihn freigeschaltet habe, was ich ziemlich beeindruckend fand.

Vielen Dank

Tan Rezaei
quelle
Haben Sie das Erfolgssystem bereits entworfen oder hergestellt und möchten nur wissen, wie Sie es im Spiel verwenden können?
Harrison Brock

Antworten:

6

Was Sie im Allgemeinen tun, ist ein "Leistungs" -System. Jede Aktion, die passiert, ruft das Erfolgssystem auf und sagt "Hey, das Ding ist gerade passiert".

Das Leistungssystem besteht dann normalerweise aus einer Reihe von Regeln, die normalerweise aus einer einfachen kombinatorischen Logik und Zählern für verschiedene "Ereignisse" bestehen. Es liegt dann in der Verantwortung des Leistungssystems, mithilfe der Regeln und Zähler zu erarbeiten, was passiert ist und welche Erfolge zu vergeben sind.

Der Grund, warum Sie dies tun, ist zweierlei.

  • Sie möchten Ihre Statuslogik nicht über Ihre gesamte Codebasis verteilen.

  • Manchmal erfordern Erfolge Kombinationen von "Dingen", die in völlig unterschiedlichen Systemen / Zeiten / usw. vorkommen können, und die Verbreitung der Logik dafür auf Ihrer Codebasis würde zu einer großen Menge unnötiger Komplexität führen.

In der Vergangenheit habe ich ein skriptfähiges Regelsystem verwendet (wobei scriptable ein sehr loser Begriff ist, normalerweise nur eine Art datengesteuerter Komparator). Sie können also etwas Ähnliches sagen:

  • Wenn "der Benutzer etwas gedrückt hat" passiert, wird die Variable "gedrückt" inkrementiert.

Dann könnten Sie eine andere Regel haben, die ist

  • Wenn die "gedrückte" Variable "größer" als "irgendein Wert" ist, verteilen Sie die Leistung "bla"

Oder vielleicht

  • Wenn "der Benutzer den Boss tötet" passiert, verteilen Sie "Leistung" bla ".

Das Leistungssystem hat auch die Aufgabe, den Status beizubehalten, in dem bereits Erfolge vergeben wurden, damit Sie keine Duplikate erhalten.

Matt D.
quelle
0

Ein guter Weg, um damit umzugehen, könnte ein Spezifikationsmuster sein. Sie hätten einen Leistungsmanager, der Ihre Benutzer regelmäßig nach denjenigen abfragt, die einer Reihe von Spezifikationen entsprechen. Ihre Leistungsklasse würde daher wie gewohnt einen Namen, ein Logo, eine Punktzahl usw. sowie eine Spezifikation enthalten, die einen Benutzer beschreibt, der diese Leistung erzielt hat. In C # könnte die Errungenschaft "Share-a-holic" beispielsweise folgendermaßen aussehen:

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

AchievementManager.AddAchievementType(ShareAHolic);

und dann kann Ihr Leistungsmanager an der entsprechenden Stelle Folgendes tun:

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

Die .Award()Methode Ihres Leistungsmanagers kann auch direkt an der entsprechenden Stelle aufgerufen werden, wenn eine Leistung sofort erkannt werden kann. Möglicherweise möchten Sie auch eine Methode hinzufügen, um diese Überprüfungen für einen bestimmten Benutzer auszuführen, damit Sie nach wichtigen Ereignissen eine Überprüfung auslösen können, damit Benutzer sofort Erfolge erzielen können.

Anaximander
quelle
Das Partitionieren von Erfolgen wird schnell wichtig. AchType benötigt eine 'sope'-Eigenschaft, die DB.Users.Where () unterstützen kann, um nach Möglichkeit nicht verwandte Erfolge zu vermeiden. Wenn die Dateifreigabe nur im PvP vergeben werden kann, suchen Sie nur nach PvP. Während etwas Generisches wie Plünderungen global machbar sein könnte und keinen solchen Umfang hätte.
HPVC