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.
quelle
Antworten:
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).
quelle
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.
quelle
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 (aberlocalStorage
nicht das Netzwerk, das Dinge ändern kann).quelle