Menyimpan keadaan game roguelike?

11

Saya sedang mengerjakan roguelike dasar menggunakan HTML5 dan jQuery, dan saya menemukan masalah.

Cara permainan saat ini berdiri, sistem hanya menyimpan status permainan setiap kali pengguna bergerak di antara lantai - untuk meminimalkan overhead. Bahaya dari hal ini adalah bahwa, jika pengguna mendapat masalah, mereka cukup menutup jendela dan kembali ke permainan mereka di awal lantai saat ini. Ini secara drastis mengurangi kesulitan permainan (dan hampir mengalahkan tujuan roguelike) - tetapi tidak masuk akal untuk menyelamatkan kondisi permainan dengan setiap gerakan atau serangan pemain tunggal.

Saya telah meneliti cara-cara untuk menyimpan status gim di dekat jendela peramban, tetapi saya tidak senang dengannya. Pertanyaan saya adalah ini: dengan asumsi "save a game state" berarti permintaan ajax / post yang cukup berat, bagaimana cara saya menggagalkan perilaku curang ini? Apakah ada metodologi yang dikenal untuk mengukur perubahan inkremental / prosedural ke peta 2d, yang bertentangan dengan menyelamatkan seluruh keadaan peta? Harap dicatat, saya tidak meminta "cara paling efisien" - Saya sedang mencari metodologi yang ada untuk memperbaiki pengalaman saya.

CodeMoose
sumber
Pertanyaan pemrograman JavaScript yang sangat umum dan umum. Saya menolak tetapi kemudian saya berpikir ulang karena ini agak menarik jika Anda mempertimbangkan bagaimana Anda akan melakukannya jika Anda tidak dapat memicu acara bongkar-muat.
Tim Holt
Mungkin saya akan ulangi untuk mengatasi masalah itu secara langsung =)
CodeMoose
@TimHolt - diedit sesuai saran Anda
CodeMoose

Jawaban:

8

Solusi yang jelas adalah mengirim setiap perintah pemain ke server sebagaimana dibuat dan minta server mencatatnya; dengan cara itu, jika game dibatalkan dengan alasan apa pun, perintah yang dicatat dapat diputar ulang untuk mengembalikan game ke titik di mana game itu ditinggalkan.

Tentu saja, ketika save yang tepat dibuat, log perintah lama dapat dibuang (meskipun Anda juga bisa menyimpannya untuk memungkinkan replay game lama; jika Anda melakukannya, Anda mungkin ingin memasukkan cap waktu di log untuk replay real time ). Anda mungkin juga ingin secara otomatis melakukan save penuh setelah n perintah dibuat sejak save terakhir (di mana, katakanlah, n = 1000) untuk menghindari replay yang terlalu lama jika pemain tetap di level yang sama terlalu lama sebelum menutup atau menabrak game .

Jika gim Anda melibatkan angka acak (dan, seperti roguelike, mungkin memang demikian), Anda juga harus memastikan bahwa angka itu dapat dibuat kembali dengan benar selama replay. Salah satu solusinya adalah memasukkan setiap nomor acak ke dalam log replay; yang lain adalah menggunakan generator nomor pseudorandom deterministik dan menyimpan seed ketika game disimpan.

Perhatikan bahwa semua metode ini dapat dieksploitasi dengan mengutak-atik klien, tetapi itu benar-benar tak terhindarkan setiap kali Anda memiliki logika permainan pada klien. Sebagai alternatif cheat-proof, Anda bisa menjalankan gim sebenarnya di server dan hanya meminta klien mengirim semua perintah pemain ke server dan menerima pembaruan tampilan kembali. Untuk roguelike, ini mungkin layak. Jelas, ini juga akan memecahkan masalah penghematan negara Anda (meskipun Anda mungkin masih ingin menerapkan beberapa bentuk perintah logging di server, baik untuk fungsi replay dan untuk memungkinkan pemulihan dari server crash). Kelemahannya adalah melakukan hal ini akan membuat permainan offline menjadi tidak mungkin (kecuali, tentu saja, Anda juga membuat kode sisi server tersedia bagi pemain untuk dijalankan secara lokal jika mereka mau).

Ilmari Karonen
sumber
1
AFAIK semua RGN adalah pseudorandom .. Anda memerlukan perangkat keras khusus untuk mendapatkan nilai acak yang benar-benar (tidak dibutuhkan ).
bobobobo
1
@obobobo ada pseudorandom (diunggah) dan ada nomor acak yang aman secara kriptografis (tidak diunggulkan) di Platform .Net. Ini mungkin / mungkin bukan perangkat keras acak, tetapi cukup dekat untuk tidak bisa hanya menyimpan sebuah seed.
Rangoric
2

Lihat /programming/3888902/javascript-detect-browser-close-tab-close-browser untuk pertanyaan yang lebih umum tentang pertanyaan yang sama.

Juga pertimbangkan untuk menyimpan game penuh pada perubahan lantai, dan delta tambahan pada setiap gerakan. Kemudian Anda dapat memutar ulang game hingga titik langkah terakhir.

Dengan asumsi ada beberapa penggunaan generator angka acak, Anda dapat menghasilkan dan menabur benih kembali generator nomor acak di awal setiap lantai baru, dan kemudian menyimpannya bersama dengan lantai. Kemudian, Anda dapat memulai kembali pada beban, dan harus dapat memutar ulang gerakan dengan urutan yang sama hingga yang terakhir dilakukan.

Tim Holt
sumber
Terima kasih Tim - begitu saya masuk ke pola pikir dev game, sangat mudah untuk memasukkan apa pun yang menyentuhnya ke dalam dev game. Alat peraga untuk memberikan jawaban.
CodeMoose
Jangan khawatir - lihat komentar saya yang direvisi pada pertanyaan juga :)
Tim Holt
Saya akan mengatakan delta tambahan pada setiap gerakan juga.
bobobobo
2

Pendekatan untuk, bukan penghematan tambahan, tetapi menemukan waktu untuk menghemat penuh:

  • onunload, seperti yang telah disebutkan sebelumnya. Saya telah menemukan ini dapat diandalkan (tetapi menggunakanlocalStorage , bukan jaringan, yang dapat mengubah banyak hal).
  • Simpan ketika jendela Anda kehilangan fokus.
  • Simpan secara berkala: ketika penyimpanan terakhir belum dalam n menit dan pengguna belum membuat input dalam m detik.
Kevin Reid
sumber