Pracuję nad podstawowym roguelike przy użyciu HTML5 i jQuery, i natknąłem się na problem.
W obecnym stanie gry system zapisuje stan gry tylko za każdym razem, gdy użytkownik porusza się między piętrami - aby zminimalizować koszty ogólne. Niebezpieczeństwo polega na tym, że jeśli użytkownik wpakuje się w kłopoty, może po prostu zamknąć okno i powrócić do gry na początku bieżącego piętra. To drastycznie zmniejsza trudność gry (i prawie pokonuje cel roguelike) - ale nie ma sensu zapisywanie stanu gry przy każdym ruchu lub ataku każdego gracza.
Badałem sposoby zapisywania stanu gry w oknie przeglądarki, ale nie jestem z nich zadowolony. Moje pytanie brzmi: zakładając, że „zapisywanie stanu gry” oznacza średnio ciężkie żądanie ajax / post, jak udaremnić to oszustwo? Czy znana jest metodologia kwantyfikacji przyrostowych / proceduralnych zmian mapy 2d zamiast zapisywania całego stanu mapy? Uwaga: nie pytam o „najbardziej efektywny sposób” - szukam istniejących metod, aby naprawić mój brak doświadczenia.
źródło
Odpowiedzi:
Oczywistym rozwiązaniem jest wysłanie każdego polecenia odtwarzacza na serwer w stanie, w jakim jest wykonane, i serwer musi je zarejestrować; w ten sposób, jeśli gra zostanie przerwana z jakiegokolwiek powodu, zarejestrowane polecenia mogą zostać odtworzone, aby przywrócić grę do punktu, w którym została przerwana.
Oczywiście po prawidłowym zapisaniu stary dziennik poleceń można wyrzucić (chociaż można go również zapisać, aby umożliwić powtórkę starych gier; jeśli to zrobisz, możesz dołączyć do dziennika znaczniki czasu w celu odtwarzania w czasie rzeczywistym) ). Możesz także chcieć automatycznie wykonać pełne zapisywanie po wydaniu n poleceń od ostatniego zapisu (gdzie, powiedzmy, n = 1000), aby uniknąć zbyt długich powtórzeń, jeśli gracz pozostaje zbyt długo na tym samym poziomie przed zamknięciem lub zawieszeniem gry .
Jeśli gra zawiera losowe liczby (a ponieważ jest to roguelike, prawdopodobnie tak jest), musisz także upewnić się, że można je poprawnie odtworzyć podczas powtórki. Jednym z rozwiązań jest włączenie każdej losowej liczby do dziennika powtórek; innym jest użycie deterministycznego generatora liczb pseudolosowych i zapisanie ziarna po zapisaniu gry.
Pamiętaj, że wszystkie te metody można wykorzystać, manipulując przy kliencie, ale jest to naprawdę nieuniknione, gdy masz logikę gry na kliencie. Jako odporną na oszustwa alternatywę, możesz uruchomić rzeczywistą grę na serwerze i po prostu poprosić klienta o przesłanie wszystkich poleceń gracza na serwer i otrzymanie z powrotem aktualizacji ekranu. W przypadku roguelike może to być wykonalne. Oczywiście rozwiązałoby to również problem z zapisywaniem stanu (chociaż nadal możesz zaimplementować jakąś formę rejestrowania poleceń na serwerze, zarówno dla funkcji odtwarzania, jak i dla umożliwienia odzyskiwania po awarii serwera). Minusem jest to, że zrobienie tego uniemożliwiłoby grę w trybie off-line (chyba że oczywiście udostępnisz kod po stronie serwera, aby gracze mogli uruchamiać się lokalnie, jeśli chcą).
źródło
Zobacz /programming/3888902/javascript-detect-browser-close-tab-close-browser, aby uzyskać bardziej ogólne pytanie o to samo pytanie.
Zastanów się także nad zapisaniem pełnej gry przy zmianach podłogi i przyrostowych deltach przy każdym ruchu. Następnie możesz odtworzyć grę do momentu ostatniego ruchu.
Zakładając, że istnieje pewne zastosowanie generatorów liczb losowych, możesz wygenerować i ponownie wygenerować generator liczb losowych na początku każdego nowego piętra, a następnie zapisać go wraz z podłogą. Następnie możesz ponownie załadować po załadowaniu i powinieneś być w stanie odtworzyć ruchy w tej samej sekwencji, aż do ostatniej wykonanej.
źródło
Podejście do, nie przyrostowe oszczędności, ale znalezienie czasu na pełne zapisanie:
onunload
, jak już wspomniano. Przekonałem się, że jest to niezawodne (ale używalocalStorage
, a nie sieci, co może coś zmienić).źródło