システムカスタマイズについてダラダラやるよーその1

NScripterのシステムカスタマイズについて、1から話をしてみようと思う。その第1回目。

基礎の基礎

例えばの話、NScripterスクリプトにこのように書くと、テキストウィンドウに文字を表示する。

文字を書いてみる。

こんな風に書くと、その通りに画面に反映される訳だが、表示された後、すぐに次の処理に入ってしまう。
いや、プレイヤーがちゃんと読み終わって満足してマウスクリックするまで待って欲しいんだけど。
そのためには、こうする。

クリック待ちをさせてみる。@

そう。最後に"@"をつける。これで、文章を表示した後、プレイヤーからの入力を待つモードに変わる。

改ページってのもある。\

"@"のかわりに"\"を使うと、同じクリック待ちだけれども、クリック待ちを抜けた時にテキストウィンドウを空にするようになる。
さて、ここまではデフォルトのシステムの話。

不満顔

で、はっきり言って、デフォルトのクリック待ちは……ダメだ。いやほんともうなんて言うか、現在(2013年)の基準からすると、完全に機能が足りてない。
いやまあ、伝説のTo Heartなんかは、当時これくらいの機能で売りに出してた訳でノベルゲーは内容なんだなと言うことを改めて意識させられるところなんだけど、もう世紀をまたいでしまった以上は、なんらかの進化があってしかるべきでありましょうと。
そこで出てきたのが、システムカスタマイズ。
"@"や"\"の動作を、自由に定義できるようにする仕組みです。
問題は、自由とは荒野に一人投げ出されると言うことでもあって、デフォルトのシステムにやってもらったことも全て自分でやらなければならなくなること。
とりあえず、荒野に最初の一歩を踏み出してみる。

*start

こんな感じで!@

そしてこんな感じで。\

end

*define

deletemenu

textgosub *text_lb

game

*text_lb

return

キモは、*define節にあるtextgosubと、そのtextgosubで指定されている*text_lbラベル以下returnまでの部分。
textgosub命令は、ラベルを一つ引数に取るdefine節専用の命令で、"@"や"\"があると、通常の処理はせずに、引数になったラベルへgosubするようになる命令。
なので、*text_lbからreturnの間に、クリック待ちに必要な全てを詰め込まなければならない。
ちなみに上記のスクリプトは本当に最低限、エラーが出ないと言うだけで全く機能を持っていない。
実行すれば、下記のような画面になった後、そのまま終わってしまう。

クリック待ちはしないわ、改行もテキスト消去も何もしなくなってしまう訳で、「おいおいそこからかよ」とがっくり膝をつきたくなる。
モダンなクリック待ちの実現には、長い道程を歩かなければならないようだ。

クリック待ちをやってみる。

まずは、*text_lb以下に、クリック待ちの命令を追加する。
クリック待ちの命令は、bexecだ。いや、他のシステムカスタマイズの記事やマニュアルには、btnwaitだのbtnwait2だのと書かれているけれども、最も機能が充実し、最も基本性能がよいのは、最後に追加されたこのbexecなのは間違いない。
なので、本記事ではbexecを使う。

*start

こんな感じで!@

そしてこんな感じで。\

end

*define

deletemenu

mov %0,100
numalias bexec,%0:inc %0

textgosub *text_lb

game

*text_lb

bclear

bexec $bexec,%bexec

return

追加されたのは、三点。

define節のnumalias関係。

numaliasは、文字列に数字を結びつけ、文字列をナンバーエイリアスにする命令。NScripterスクリプトの中で、数字を置くべきところには、全てこのナンバーエイリアスをかわりに置くことができる。
このnumaliasが便利なのは、これを使っておけば後で数値が変更になった時でも、*define節の一行を変更するだけで済むなどの点。
ここでは、bexecと言うnumaliasを作り、その番号の変数をbexecからの返り値を受け取る専用であると宣言したこと。
実際には本当に宣言なので、bexec番の変数を他のことに使ってもいいのだけれども、自分で決めたルールに従えないような人間は何もできんよねと道徳的に言ってみる。

bclear

bclearは、後述するbspなどのb関係命令で定義したボタンの情報などを全て削除して初期化する命令。
削除する命令なんだけれども、実際には、「ここから入力待ちルーチンですよ」と宣言する意味も持つ。
bexecと対になって、bclearとbexecの間に他の全てのb関係命令を押しこむ形になる。

bexec

本命の命令。一旦処理を停止し、プレイヤーからの何らかの入力を待つ命令。入力があれば、どんな入力かを変数に保存して、次に処理を回す。
引数には、文字列変数を一つと数値変数を一つ取る。この変数に入力内容が保存される。勿体無いからいつも両方受け取るようにしたい。

スクリプトの解説

上記のスクリプトを実行すると、とりあえず、"@"と"\"のところで処理が止まる模様。ただし、何をやっても進む扱いになって、セーブもロードもできないし、テキストウィンドウの消去もできていない。
次は、"@"か"\"を判別し、それによって処理を分岐させる方法。