- ベストアンサー
ゲームのリプレイモード用データ保存について
- C++初心者~中級者がゲームのリプレイモード用データ保存方法に迷っています。方法としては、領域確保、ファイル開いたまま書き込み、毎フレーム追記の3つが考えられますが、定石や注意点はありますか?
- ゲームのリプレイモードを作るために、C++初心者~中級者がデータ保存方法について悩んでいます。領域確保、ファイル開いたまま書き込み、毎フレーム追記の3つの方法を考えていますが、どの方法が適しているのでしょうか?
- C++のゲームを作る初心者~中級者が、リプレイモード用のデータ保存方法について困っています。領域確保、ファイル開いたまま書き込み、毎フレーム追記の3つを考えていますが、適切な方法はありますか?
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
ゲーム自体の内容によりますが、一般的なのは1だと思います。 コンシューマのゲームを思い浮かべて貰えれば分かると思いますが、メモリ以外の外部記憶装置を利用することができないゲームが殆どですので、リプレイデータは一旦メモリに保存しておき、その後、ユーザがリプレイデータを保存するように選択したらファイルに書き出すという手法を取っています。 Windowsであるならば一時ファイルを生成しても良いかとは思いますが、格闘ゲームやレースゲームなどレスポンスを重視するゲームではあまり現実的ではないでしょう。 メモリに保存しておく場合は、フレーム毎にメモリに書き込むのではなくキー操作に変化があったフレームだけを保存しておくやり方でないと、あっという間にメモリオーバーしてしまうと思います(必要に応じてCPUが行った動き始めなども記録しておきます)。 また、メモリが溢れてしまう際には古いデータから消していくという処理も追加しないといけません。エースコンバットみたいなジャンルのゲームを見てみると分かりますが、長丁場になればなるほどゲーム開始時のリプレイがなくなって途中から始まっているのが分かると思います。
その他の回答 (1)
- axsies
- ベストアンサー率64% (38/59)
この手のどの実装を選ぶかという問題を考えるときに、何となく遅そうとか、何となく気持ち悪い、といった「何となく」で止まっていても結論は絶対に出ません。 ファイルハンドル開きっぱなしだとどういうデメリットがあるのか、毎フレームファイルをオープンして書き出すと全実行時間の何%くらいを占めるのか、ゲーム性にどう影響を与えるのか、といった所まで考えた上で、実験、実測して始めて結論が出せます。 と、まぁ理想は「実証主義」ですが、あらゆる可能性を実験することも難しいですし、理屈よりも経験が物を言うのは否定できません。 現代のコンピュータのアーキテクチャは非常に複雑なので、適切な手法に当たりをつける事すら経験による面が大きいです。 なので、経験の浅いウチは失敗を覚悟の上で適当に作り、問題が起きたら回避策を講じるか作り直すというのが最もベターな方法だと思います。 また、格ゲーだから、STGだから、レスポンスが大事だから、というのも良く見られる意見なんですが、作ってるゲームが本当に数FPSの揺らぎまで気になるようなシビアなゲームバランスなのかどうかもよく考える必要があります。 時代によって、プラットフォームの性能やアーキテクチャが変わればタブーも変わりますし、作ってるゲームにかなり左右されるので、一般論的な話は疑ってかかった方がいいです。 具体的な検討ですが、 1の方式なら、必要に応じて一定サイズごとに拡張すれば、メモリが許す限り記録し続けることは可能です。(1kbを超えるごとに新しく領域を作ってやる等) 2か3かですが、ずっと常駐するアプリって訳ではないですし、他のアプリケーションと共有して使われるファイルというわけでもないですので、記録が終了したらちゃんと閉じていれば、ファイル開きっぱなしが問題になる要素はないと思います。 一般に「ファイルは必要なくなったら閉じろ」と言われますが、その背景をもう少し詰めて考えてみてください。 ただメインループでファイルに描き込んでると、ファイル書き込み時(バッファをフラッシュするとき)に一瞬止まったり、レスポンスが悪くなるといった問題が発生する可能性はあります。 それが問題になったとしても、非同期で描き込むとか、リプレイ記録用スレッドで処理するといった回避策はあります。 1と2の最大の違いはメモリ使用量になるでしょう。 1プレイのリプレイサイズがどれくらいまで膨れあがり、最小スペックはどれくらいを見積もっているかが問題です。 メモリ溢れてスワップが発生しまくってたら、HDDに書き込みが発生するわけで、2以上のパフォーマンスロスも考えられます。 そういう訳で私としては1か2どちらでもいいと思うのですが、既に2で組んでおられるのでそのまま作ってしまい、問題が発生したならスレッド化を検討するか、1に切り替えてみる、という感じでいいと思います。
お礼
回答ありがとうございました。 適当にソースコードを書き換えながら1~3試してみたんですが、現状では書き込み量が少ないためか、いずれの方法でも気になるような処理落ちの発生などはありませんでした。(60FPS固定なので時間の比較は出来ない……とか思ってしまいましたがよく考えたら記録部分前後の時間が出来たかも知れませんでした…)で、結局、リプレイファイルのサイズが最大80kB程度でそこまで大きくないように思われたので今は1で組んでいます。 とは言え、基礎的な部分の知識が足りないのは痛感したところで、メモリ管理やスワッピングになるとほとんど単語でしか知らない状況なので勉強していきたいと思います。
お礼
回答ありがとうございます。 作っているのがSTGでレスポンスを要求するゲームではあるのですが、 書き込み容量が少ないためか2の方法でもさしあたりは影響はありませんでした。ただ、No.2の方の指摘もありましたが考えているスペックに対しメモリ使用量があまり大きくないように思われたので、とりあえず1に組み直して様子を見ることにしました。 キー操作に変化があった場合のみ記録することでデータ量の節約になることを教えていただき、またリプレイが途中から始まる、という懐かしい現象を思い出させていただいたため、ベストアンサーとさせていただきます。