Zapisujesz stan gry roguelike?


11

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.


Bardzo ogólne i ogólne pytanie dotyczące programowania JavaScript. Głosowałem za odrzuceniem, ale potem przemyślałem, ponieważ jest to interesujące, jeśli zastanowisz się, jak byś to zrobił, gdybyś nie mógł wywołać zdarzenia rozładowania.
Tim Holt

Może przeformułuję to, aby rozwiązać ten problem bezpośrednio =)
CodeMoose

@TimHolt - edytowane zgodnie z twoją sugestią
CodeMoose

Odpowiedzi:


8

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ą).


1
AFAIK wszystkie RGN są pseudolosowe .. potrzebujesz specjalistycznego sprzętu, aby uzyskać prawdziwie (nieprzewidziane) losowe wartości.
bobobobo

1
@bobobobo jest pseudolosowy (zaszczepiony) i kryptograficznie bezpieczne losowe liczby (niewidoczne) na platformie .Net. Może / może nie być losowy sprzętowo, ale jest wystarczająco blisko, aby nie mógł po prostu zapisać ziarna.
Rangoric

2

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.


Dzięki Tim - kiedy wejdę w tryb myślenia twórców gry, naprawdę łatwo jest połączyć wszystko, co go dotknie, z twórcą gry. W każdym razie rekwizyty za udzielenie odpowiedzi.
CodeMoose

Nie martw się - zobacz też mój zmieniony komentarz do pytania :)
Tim Holt

Przy każdym ruchu powiedziałbym również przyrostowe delty .
bobobobo

2

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żywa localStorage, a nie sieci, co może coś zmienić).
  • Zapisz, gdy okno przestanie być aktywne.
  • Zapisuj okresowo: gdy ostatni zapis nie nastąpił za n minut, a użytkownik nie wprowadził żadnych danych wm sekund.
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.