Roguelike Spielstatus speichern?

11

Ich arbeite mit HTML5 und jQuery an einem einfachen Roguelike und bin auf ein Problem gestoßen.

So wie das Spiel derzeit steht, speichert das System den Spielstatus nur jedes Mal, wenn sich der Benutzer zwischen den Etagen bewegt - um den Overhead zu minimieren. Die Gefahr besteht darin, dass der Benutzer, wenn er in Schwierigkeiten gerät, einfach das Fenster schließen und zu Beginn des aktuellen Stockwerks zu seinem Spiel zurückkehren kann. Dies reduziert die Schwierigkeit des Spiels drastisch (und macht den Zweck eines Roguelike fast zunichte) - aber es ist unvernünftig, den Spielstatus bei jeder Bewegung oder jedem Angriff eines einzelnen Spielers zu speichern.

Ich habe nach Möglichkeiten gesucht, den Spielstatus beim Schließen des Browserfensters zu speichern, bin aber mit ihnen nicht zufrieden. Meine Frage lautet: Unter der Annahme, dass "Speichern eines Spielstatus" eine mäßig schwere Ajax- / Post-Anfrage bedeutet, wie kann ich dieses Betrugsverhalten vereiteln? Gibt es eine bekannte Methode zur Quantifizierung inkrementeller / prozeduraler Änderungen an einer 2D-Karte, anstatt den gesamten Kartenstatus zu speichern? Bitte beachten Sie, dass ich nicht nach dem "effizientesten Weg" frage - ich suche nach vorhandenen Methoden, um meine Unerfahrenheit zu korrigieren.

CodeMoose
quelle
Sehr allgemeine und allgemeine JavaScript-Programmierfrage. Ich habe abgewählt, aber dann habe ich überlegt, da es interessant ist, wenn Sie überlegen, wie Sie es tun würden, wenn Sie kein Ereignis beim Entladen auslösen könnten.
Tim Holt
Vielleicht werde ich es umformulieren, um das Problem direkt
anzugehen
@ TimHolt - bearbeitet nach Ihrem Vorschlag
CodeMoose

Antworten:

8

Die naheliegende Lösung besteht darin, jeden Player-Befehl sofort an den Server zu senden und vom Server protokollieren zu lassen. Auf diese Weise können die protokollierten Befehle wiederholt werden, wenn das Spiel aus irgendeinem Grund abgebrochen wird, um das Spiel an dem Punkt wiederherzustellen, an dem es aufgehört hat.

Wenn eine ordnungsgemäße Speicherung durchgeführt wird, kann das alte Befehlsprotokoll natürlich weggeworfen werden (obwohl Sie es auch speichern können, um Wiederholungen alter Spiele zuzulassen. Wenn Sie dies tun, möchten Sie möglicherweise Zeitstempel für die Echtzeitwiedergabe in das Protokoll aufnehmen ). Möglicherweise möchten Sie auch automatisch eine vollständige Speicherung durchführen, nachdem seit dem letzten Speichern n Befehle ausgeführt wurden (z. B. n = 1000), um zu lange Wiederholungen zu vermeiden, wenn der Spieler zu lange auf demselben Level bleibt, bevor er das Spiel schließt oder abstürzt .

Wenn Ihr Spiel Zufallszahlen enthält (und dies ist wahrscheinlich ein Roguelike), müssen Sie auch sicherstellen, dass diese während einer Wiederholung korrekt neu erstellt werden können. Eine Lösung besteht darin, jede Zufallszahl in das Wiedergabeprotokoll aufzunehmen. Eine andere Möglichkeit besteht darin, einen deterministischen Pseudozufallszahlengenerator zu verwenden und den Startwert zu speichern, wenn das Spiel gespeichert wird.

Beachten Sie, dass alle diese Methoden durch Manipulationen am Client ausgenutzt werden können. Dies ist jedoch immer dann unvermeidlich, wenn Sie eine Spielelogik auf dem Client haben. Als cheatsichere Alternative können Sie das eigentliche Spiel auf dem Server ausführen und den Client einfach alle Spielerbefehle an den Server senden lassen und Anzeige-Updates zurückerhalten. Für einen Roguelike kann dies durchaus machbar sein. Dies würde natürlich auch Ihr Problem beim Speichern des Status lösen (obwohl Sie möglicherweise immer noch eine Form der Befehlsprotokollierung auf dem Server implementieren möchten, sowohl für die Wiedergabefunktion als auch um die Wiederherstellung nach Serverabstürzen zu ermöglichen). Der Nachteil ist, dass dies das Offline-Spielen unmöglich machen würde (es sei denn, Sie stellen den serverseitigen Code natürlich auch für Spieler zur Verfügung, die lokal ausgeführt werden können, wenn sie dies möchten).

Ilmari Karonen
quelle
1
AFAIK Alle RGNs sind pseudozufällig. Sie benötigen spezielle Hardware , um echte (nicht gesetzte) Zufallswerte zu erhalten.
Bobobobo
1
@bobobobo Es gibt Pseudozufall (Seed) und kryptografisch sichere Zufallszahlen (Seed) in der .Net-Plattform. Es kann / kann nicht zufällig Hardware sein, aber es ist nah genug, um nicht nur einen Startwert speichern zu können.
Rangoric
2

Unter /programming/3888902/javascript-detect-browser-close-tab-close-browser finden Sie eine allgemeinere Frage zu derselben Frage.

Erwägen Sie auch, das gesamte Spiel bei Bodenänderungen und inkrementellen Deltas bei jeder Bewegung zu speichern. Dann können Sie das Spiel bis zum letzten Zug wiederholen.

Unter der Annahme, dass Zufallszahlengeneratoren verwendet werden, können Sie den Zufallszahlengenerator zu Beginn jeder neuen Etage generieren, neu festlegen und dann zusammen mit der Etage speichern. Dann können Sie beim Laden erneut säen und sollten in der Lage sein, die Züge bis zum letzten Schritt in derselben Reihenfolge wiederzugeben.

Tim Holt
quelle
Vielen Dank, Tim. Sobald ich mich in die Denkweise der Spieleentwickler eingearbeitet habe, ist es wirklich einfach, alles, was sie berührt, in die Spieleentwickler zu integrieren. Requisiten für eine Antwort.
CodeMoose
Keine Sorge - siehe auch meinen überarbeiteten Kommentar zur Frage :)
Tim Holt
Ich hätte auch bei jeder Bewegung inkrementelle Deltas gesagt .
Bobobobo
2

Ansätze für nicht inkrementelle Speicherungen, sondern Zeit für eine vollständige Speicherung:

  • onunload, wie vorab erwähnt. Ich habe festgestellt, dass dies zuverlässig ist (aber localStoragenicht das Netzwerk, das Dinge ändern kann).
  • Speichern Sie, wenn Ihr Fenster den Fokus verliert.
  • Regelmäßig speichern: Wenn die letzte Speicherung nicht in n Minuten erfolgt ist und der Benutzer in m Sekunden keine Eingabe vorgenommen hat .
Kevin Reid
quelle