前々から疑問だったのでちょっと書いてみました。
かなり昔に友人と一緒にHSPで単純なゲーム開発をしてたのですが、
セーブとロードの実装をどうやるかで色々と話し合いました。(結局作業量の問題で実装はしませんでしたが。)
その時に友人が出した提案が、
・各ラベルを用意して、セーブ機能でそのラベル名を記録し、ロード機能でラベル名を判定し、そのラベル名へGotoする。
という物でした。
しかし、これでは、制作者が予めセーブポイントを用意しなくてはならないため、
RPGの様な「どんな場所でもセーブが可能」という事をするのは非常に困難だと思います。
更に、ロード機能でラベルまでジャンプさせるだけでは、完璧な復元にはなりません。
RPGで例えると、現在のステータスや座標、アイテムなど、様々なデータが必要になるはずです。
もし、現状のロード機能でこれらの実装をするととてつもなく大変な作業になりそうです。
ですが、結果的に現在の情報を保存して、復元すると言うことは、
はやり全ての情報を解析してその情報に基づいた形でロードしなければなりません。
とすると、それなりの作業は必要になるはずだと思います。
問題はラベルへのジャンプです。
このままでは、全ての場所でセーブ可能にする場合、全ての箇所でセーブポイント(ラベル)が必要になってきます。
シューティングの様な物であれば、各ステージ事に用意すればいいので、そこまで苦にはなりませんが、
ノベルゲームやRPGではかなり大変な作業になってくるはずです。
ノベルゲームのスクリプトをちょっと弄ってみた所、吉里吉里という言語では自前で全てのセーブポイントを用意しなければなりませんでした。
一方、RPGではラベルを気にする必要はなく、この場所はセーブが可能場場所か?不可能な場所か?という、
フラグ管理だけで、そのままできてしまいます。
自分なりに考えてみたところ、RPGではフラグ情報とステータス情報、座標情報、と言った情報を元に、
ラベルへジャンプしているのではなく、そのままの状態を再現しているだけなのでは?と思いました。
ですが、ノベルの方ではRPGの様に実現しにくい気がします。
とりあえず、自分なりに考えてみた方法だと、
1つは無限ループで外部シナリオを読み込むタイプの場合、現在のフラグ情報と、背景、音楽、立ち絵などの情報と、現在の台詞(シナリオデータ)の一部を保存しておき、
読み込むときに、今までのフラグ情報を読み込み、シナリオデータから保存されたシナリオの一部と合致する所から読み込む。
という方法ですが、保存した一部のシナリオデータが複数存在する可能性が高いため、読み間違えの危険性がありそうです。
もう1つは、無限ループとは違い、最初から最後まで絶対に重複しないラベルを予め全ての箇所に用意しておき、フラグ情報を読み込み、その箇所へ
飛ぶ。という物です。(これでは友人の提案のまんまですが。)
最後にもう一つ。
読み込んだ行数を記録して、そこから読み込む。という方法。
しかしこれだと、シナリオデータを1つに統合しなければなりません・・・。
何かいい方法はないのか、ずっと疑問なのですが、何か楽な方法はありませんかね?
4件のコメント
yamaguchi · 2007-06-25 13:58
C#やJavaならシリアライズを使うとべんりですよ。
クラスのインスタンスをファイルに書き込んだり、ファイルから読み込んだりできます。
mori · 2007-06-25 22:37
ん? RPGとかと同じ方法じゃ駄目なの?
シナリオ上の位置 = 座標 なわけだから、後はシナリオファイルが複数に分かれても、一意にその位置を決めることができる規則さえ作れば、フラグ情報+座標情報を、構造体orクラス(のインスタンス)に格納して、バイナリデータとして落としてしまえば完了な気がするけども?
というか、『最初から最後まで絶対に重複しないラベル』って座標のことだよね。
つまり、シナリオファイルに対して、自動で一意なラベルを作る機構を作れば解決すると、そういう話な気がする。
まぁ、この方法の大問題は、座標の規則によっては、シナリオファイルの修正で、セーブデータ互換性がなくなることだけれども。
どっちにしても、フラグ管理まで修正かかると、互換性なくなるから、そんなに気にする必要は無いかもしれない。
Qwx · 2007-06-26 00:34
>クラスのインスタンスをファイルに書き込んだり、ファイルから読み込んだり
>バイナリデータとして落としてしまえば
そんなことができたんですねorz
でもHSPで可能かどうかはわからないですが・・・。
>自動で一意なラベルを作る機構を作れば
しかしこれだと、シナリオに[Label: hoge000001]のような物が大量に作られそうな・・・。
一瞬、ソース上のラベルに対して変数が扱えるのかと思ってしまいました。
var += 1;
Label: var
ShowMessage(‘hoge’);
いや、こんな事ができるわけないですよねorz
というか、できても意味なさげですね・・・。
ありがとうございます。参考になりました。ちょこっとシリアライズとやらを覗いてみます。
mori · 2007-06-26 03:34
いやいや、つまり、そのノベルゲームの元になるスクリプトエンジンがそもそもそういう機能を持っていればいいってお話。
外部にシナリオがあるってことは、そのシナリオを読み込むエンジンが必ずあるわけで、そのエンジン自体がそういう機構を持つべきだと思う。
いわゆるRPGツクールはそういうことをしてるわけで、ノベルゲーム作成用エンジンも、そうであるべき。
まぁ、無いならコンバータを自分で書くしかないけどね。
現在コメントは受け付けていません。