自前で既読ログを作成管理する方法の考察
迷走か進化か - 永字八法の続き。
シナリオライターには、半角英数の命令を使用させず、実質テキストのみでシナリオを記述させることが前提。
こうすると、luacall textが呼び出された時=シナリオの現在行がカウントアップされるとみなすことができる。
概要
仮に、現在の実行行番号を保存する変数を、%scenalio_cursorとする。
これの値は必ずしも実際の実行行数とは一致しない。単純にNSCALL_text()が呼び出される度に内部でインクリメントされる変数である。
また、これとは現在実行しているシナリオ名を保存する変数も作る。仮に、$scenalio_nameとでもする。実質、ここにはラベルが入ると思う。
そして、既読管理システムを作る。これは以下の命令を持つとする。
- 現在これから実行するシナリオ名を指定し、%scenalio_cursorをリセットする命令。
- シナリオ名と行番号を与えると、それが未読か既読かを返す命令。
- シナリオ名と行番号を与えると、それを実行済み(あるいは未読)にする命令。
- シナリオ名を指定して(あるいは全てのシナリオに対して)全て未読もしくは既読にする命令。(これはほぼ開発専用命令になるかも)
- シナリオを終了させる命令。(行毎の既読未読判定の他に、シナリオ毎の既読未読記録があれば、シーン回想が楽になる。)
細かいシーケンス
function NSCALL_text() endの中でどのようなことが発生するか。
※%scenalio_cursorは初期化されると0になるが、luaでは1オリジンの方が色々都合がよい。
- NSCALL_text()が実行される。
- 現在、シナリオが実行中であれば
- %scenalio_cursorをインクリメント
- その行の既読未読情報を取得
- シナリオを実行
- その行を既読にする。
- 処理を終える。
これが基本だが、さらに細かい処理が入る。具体的には、シナリオライターによる細かい分岐を容易にするための処理である。
たとえば、あるキャラクターのセリフに対し、主人公の返答が主人公の性格パラメータによって変わるとする。変わるのはセリフだけで、ストーリーは分岐後再び一つに集約される。
生のNScripterのシナリオでは、このようになる。
*scenalio001 (中略) ライバル「○○○?」 ; 性格による分岐 tablegoto %propaty,*scenalio001_1_1,*scenalio001_1_2,*scenalio001_1_3 *scenalio001_1_1 主人公「性格1の回答」 goto *scenalio001_1_end *scenalio001_1_2 主人公「性格2の回答」 goto *scenalio001_1_end *scenalio001_1_3 主人公「性格3の回答」 goto *scenalio001_1_end *scenalio001_1_end ライバル「そうなのか」 (中略) *scenalio001end return
面倒臭い。やってられるかボケ。ラベル名書き間違えてミスとかしそうでストレスだ。
それをこのように書き換えられるかやってみる。
*scenalio001 (中略) ライバル「○○○?」 【性格分岐・1】 主人公「性格1の回答」 【性格分岐・2】 主人公「性格2の回答」 【性格分岐・3】 主人公「性格3の回答」 【性格分岐・終了】 ライバル「そうなのか」 (中略) 【シナリオ終了】 return
注意すべきなのは、性格分岐をした場合、選ばれなかった性格のシナリオは、未読のままにしなければならないことだ。既読スキップを行っている場合、これは重要な仕様になる。
そこで、シーケンスを次のように書きかえる。
$scenalio_branchを設定する。これは、分岐の名前を設定する。
1.NSCALL_text()が実行される。
2.現在、シナリオが実行中であれば
2.1.%scenalio_cursorをインクリメント
2.2.その行の既読未読情報を取得
3.シナリオを実行する前に、$scenalio_branchが""でないなら
3.1.$scenalio_branchの内容によって、そのシナリオ行を実行するかしないかを決める。しないのであれば6まで飛ぶ。
4.シナリオを実行
4.1.実行した内容が「性格分岐」だった場合、
4.1.1.次のタグが「終了」なら、$scenalio_branchを""に。
4.1.2.それ以外なら、$scenalio_branchをタグと同じにする。
5.その行を既読にする。
6.NSCALL_text()を終了させる。
選択による分岐
また、これを応用すれば、選択肢も簡単に記述できることがわかる。
*scenalio001 (中略) ライバル「○○○?」 【質問・選択肢1・選択肢2・選択肢3】 【分岐・1】 主人公「選択肢1の回答」 【分岐・2】 主人公「選択肢2の回答」 【分岐・3】 主人公「選択肢3の回答」 【分岐・終了】 ライバル「そうなのか」 (中略) 【シナリオ終了】 return
【質問】タグで選択肢を表示、プレイヤーに一つを選択させ、後は分岐と同じように処理ができる。
注意しなければならない点は、選択肢を表示する時に、既読の選択肢の色は変えたいこと。
これをどうやって実装するかは現在考え中。