NScripterのシステムカスタマイズにおける問題点の洗い出しと対策の模索

define節にてtextgosubを実行する。すると、start節で表示文中に@ないし\があった場合、通常の処理をせずにtextgosubで指定したラベルにgosubする。
システムカスタマイズとは、要約するとこれだけのことである。
よって、textgosubで指定されたラベルで始まるルーチンには、最低限以下の機能が要求される。

  • returnで終了すること。
  • クリック待ちをすること。
  • 終了時直前、@の場合は改行を、\の場合は改ページ(表示内容の消去)をすること。

ただし、現在のノベルゲームのシステムに対するユーザーの要求を勘案すると、上記条件は低機能すぎると言わざるを得ない。

  • セーブ・ロード画面へ遷移できること。
  • クイックセーブ・クイックロードができること。
  • テキスト履歴画面へ遷移できること。
  • コンフィグ画面へ遷移できること。
  • テキストウィンドウを非表示にする(イベント画像鑑賞)画面へ遷移できること。
  • スクリーンショットを外部出力できること。
  • オートモード(読み上げモード)があること。
  • 既読スキップモードがあること。
  • 上記の操作・遷移を、システムボタンとキー入力の両方で操作できること。
  • ありとあらゆるキーになんらかの操作が設定されていることが望ましい。

これくらいはなければ、今のユーザーからは「システムが○○」よばわりは避けられないのではないだろうか。
これらの仕様を現状のNScripterで実装するとなると、大部分はbexec命令によって解決できる。bexecは、ボタン化したスプライトのクリックも、キー入力も取得できるからだ。
何が入力されたのかがわかれば、そこから分岐する実装は特に難しいものではない。
bexec命令で若干問題になるのは、スプライトのクリックは、ボタンダウン&ボタンアップがセットで検出されるのに対し、キーの入力はボタンダウンだけで反応してしまうことだ。これは、CTRLキーによる強制スキップを見越しての実装だろうが、bexecを上書きしてCTRLキー以外ではボタンアップまで含めて判定するのが望ましい。
また、オートモードも、btime命令による時間制限を設けることで実装が可能になる。
唯一、bexec命令にできないことは、既読スキップモードの検出だけである。ただし、この問題が大きいためにtextbtnwaitを捨てられないと言う向きもあるのではないか。
そこで対案として考えたのは、「両方を採用する」と言う遣り方である。
define節でkidokuskip命令を実行すると、既読スキップが有効になる。systemcall skipを実行することで、textbtnwait命令が既読かどうかの判定を行い、既読であればすぐに処理を返すようになる。
これを使って、iskidoku命令が実装できる。

; %iskidokuは、既読スキップかどうかのフラグを格納する固定変数とする。
; 他で使われる予定はないとする。
; %bwaitは、同様に入力を検出しその結果を保存する専用の変数とする。
*iskidoku
	btndef clear
	btntime 1 ; 数値は要調整
	btnwait %bwait ; 既読行なら%bwaitに0が入り、そうでないならタイムアウトの-2/-5のどちらかが入る。
	mov %iskidoku,1/(1-%bwait) ; %bwaitが0の時1が、それ以外の時0が代入される。
return
; この命令は、CTRLの押しっぱなしを考慮していないので、押しっぱなしを検出した後で行われるのが望ましい。
; systemcall skipを実行しておかなければ、この命令は常に0を返す。

これで、bexecによるリッチな入力を実現しながら、既読スキップを実装できる。