ローグライクゲームの状態を保存していますか?


11

私はHTML5とjQueryを使用して基本的なローグライクに取り組んでおり、問題に遭遇しました。

現在のゲームの状態では、システムはユーザーがフロア間を移動するたびにゲームの状態のみを保存し、オーバーヘッドを最小限に抑えます。これの危険性は、ユーザーが問題を抱えた場合、ウィンドウを閉じて、現在のフロアの最初でゲームに戻ることができるということです。これにより、ゲームの難易度が大幅に低下します(ローグライクの目的をほとんど破ります)。

ブラウザウィンドウを閉じてゲームの状態を保存する方法を調査しましたが、満足できません。私の質問はこれです。「ゲームの状態を保存する」とは、適度に重いajax / postリクエストを意味すると仮定して、この不正行為を阻止するにはどうすればよいですか?マップ全体の状態を保存するのではなく、2Dマップへの増分/手順の変更を定量化する既知の方法論はありますか?私が「最も効率的な方法」を求めているのではないことに注意してください-私の経験不足を正すための既存の方法論を探しています。


非常に一般的で一般的なJavaScriptプログラミングの質問。私は反対票を投じましたが、on-unloadイベントをトリガーできなかった場合の方法を検討すると、興味深いので再考しました。
Tim Holt

多分私はその問題に直接対処するためにそれを言い換える=)
CodeMoose

@TimHolt-提案に従って編集
CodeMoose

回答:


8

明らかな解決策は、作成されたすべてのプレーヤーコマンドをサーバーに送信し、サーバーに記録させることです。このようにして、何らかの理由でゲームが中止された場合、ログに記録されたコマンドを再生して、中断した時点までゲームを復元できます。

もちろん、適切な保存が行われると、古いコマンドログを破棄できます(ただし、古いゲームの再生を可能にするために保存することもできます。そうする場合は、リアルタイムで再生するためにログにタイムスタンプを含めることができます) )。また、最後の保存(たとえば、n = 1000)からn個のコマンドが実行された後、プレーヤーがゲームを終了またはクラッシュする前に同じレベルにとどまりすぎた場合に過度に長いリプレイを回避するために、自動的に完全保存することもできます。。

ゲームに乱数が含まれている場合(およびローグライクである場合は、おそらくそうです)、リプレイ中に乱数を正しく再作成できることを確認する必要もあります。1つの解決策は、すべての乱数を再生ログに含めることです。もう1つは、確定的な疑似乱数ジェネレータを使用して、ゲームが保存されたときにシードを保存することです。

これらのメソッドはすべて、クライアントを改ざんすることで悪用される可能性がありますが、クライアントにゲームロジックがある場合は、それが本当に避けられないことに注意してください。チートプルーフの代替手段として、サーバーで実際のゲームを実行し、クライアントにすべてのプレーヤーコマンドをサーバーに送信させ、表示の更新を受信させることができます。ローグライクの場合、これは十分に可能です。明らかに、これにより状態保存の問題も解決されます(ただし、再生機能とサーバークラッシュからの回復の両方のために、サーバーに何らかの形式のコマンドログを実装することもできます)。欠点は、これを行うとオフラインでのプレイが不可能になることです(もちろん、プレイヤーがローカルで実行できるようにサーバー側のコードを利用できるようにする場合を除きます)。


1
私の知る限り、すべてのRGNは疑似ランダムです。真に(シードされていない)ランダムな値を取得するには、専用のハードウェアが必要です。
bobobobo 2013

1
@bobobobo .Net Platformには、疑似乱数(シード済み)と暗号で保護された乱数(シードなし)があります。ハードウェアランダムである場合とそうでない場合がありますが、シードを格納するだけでは不十分です。
Rangoric 2013

2

同じ質問に対するより一般的な質問については、https://stackoverflow.com/questions/3888902/javascript-detect-browser-close-tab-close-browserを参照してください

また、フロアの変更時にゲーム全体を保存し、移動ごとに差分を増分することも検討してください。その後、最後の動きの時点までゲームをリプレイできます。

乱数ジェネレータの使用が想定されている場合、新しい各フロアの開始時に乱数ジェネレータを生成して再シードし、それをフロアとともに保存できます。次に、ロード時に再シードすることができ、最後に行われたものまで同じシーケンスで動きを再生できるはずです。


ティムに感謝-ゲーム開発者の考え方に入ると、それに触れるものをゲーム開発者にバケツで入れるのは本当に簡単です。とにかく答えを提供するための小道具。
CodeMoose 2013

心配ありません-質問に対する私の改訂コメントもご覧ください:)
Tim Holt

私も、それぞれの動きで増分デルタを言ったでしょう。
bobobobo 2013

2

増分保存ではなく、完全保存の時間を見つける方法:

  • onunload、前述のとおり。これは信頼できることがわかりました(ただしlocalStorage、ネットワークではなくを使用しているため、状況が変わる可能性があります)。
  • ウィンドウがフォーカスを失ったときに保存します。
  • 定期的に保存:最後の保存がn分以内でなく、ユーザーがm秒以内に入力を行わなかった場合。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.