pretextgosubとgettag

NScripterには、タグ機能がある。
表示文の頭に、[と]で囲まれたタグを挿入することができる。
この機能は、それぞれのセリフに対する色々な付随情報をシステムに知らせる用途を想定している。オフィシャルが例示しているのは、発言者の名前やボイスファイル名の指定だが、他にも想像力次第でできることは多い。
私はかつてこの機能を使って立ち絵操作(表情の変更や立ち位置の移動等)背景・音楽操作ができるようなライブラリを作ったことがあった。NScripterなでしこ化の試みでもあった。

タグ機能の使用

このタグ機能を使用したい場合は、define節中で、pretextgosubでラベルを一つ指定し、かつラベル先をサブルーチンとして実装しなければならない。

*define
pretextgosub *pretext ; *pretextラベルをサブルーチンとして指定する。
zenkakko ; 【】も有効にする。zenkakkoについては後述している。
game

; 表示文の前、実際に表示文が表示される直前に実行されるルーチンここから。
*pretext
gettag $0 ; 与えられたタグを取得する。
return

*start
[圭一/voice0001.ogg]「タグつきだとこうなる」@
	【魅音/voice0002.ogg】	「これでもオーケー。タグと表示文の間にある空白も無視されます」@
end

表示文があった場合、表示する前にpretextgosubで指定したラベルにgosubで飛ぶ。
このラベルからreturnが実行された後で、実際に表示文が画面に反映される。
また、このgosubからreturnまでの間に、必ずgettag命令を実行しなければならない。(さもなければフリーズしてしまう。)

タグ無しの処理

一度pretextgosubを実行してしまうと、表示文の先頭にタグがなくても割り込みは発生する。(gettagでは空文字列や0が取得される)

; pretextgosubしていると、
こういう文章は
[]こういう文章と等価。
@ ; クリック待ちだけだったとしても
[]@ ; やっぱりこのように解釈される。

この仕様により、タグで発言者名を渡したりしている場合は、

  1. 発言者が空文字列だった場合の処理を考慮する
  2. ナレーター等の発言者名を設定する

などの処理が必要になる。ボイスファイル名を渡す場合でも同様、ファイル名が指定されていなければ放っておくように組む必要があるだろう。

タグの取得

gosub先のサブルーチンでは、gettag命令によってどんなタグが与えられたかを取得できる。

[圭一/voice0001.ogg]実例その1。

*pretext
; 上記の表示文の場合
gettag $0,$1 ; スラッシュで区切ったそれぞれが代入される。
; $0 = "圭一"
; $1 = "voice0001.ogg"
return

この例の場合、文字列スプライトを使って発言者名を表示できるし、また、ボイスファイルの指定もできる。
タグの内部はスラッシュを使って事実上いくつでも分割できるが、gettagでは決まった数の変数分だけしか取得できないので、数を合わせる必要がある。

[圭一/voice0001.ogg/その他]タグが三つあるのに。
; 二つしかタグを取得しないと
*pretext
gettag $0,$1
return
; returnで帰った後に、「表示文中の、/の次は改行文字でなければなりません。」と言うエラーが出て止まってしまう。

この例の場合、途中までしかタグを取得しなかったため、表示文が「/その他]タグが三つあるのに。」と解釈され、「/は末尾にしかつけられない」ルールによりエラーになってしまう。
逆に、タグのスラッシュ区切りの数よりもgettagの指定変数の方が多い場合はエラーは起きない。対応するスラッシュ区切りがない変数は、""になるか0になるかどちらかである。
タグの与え方と、取得したタグの使い方は完全にプログラマーに任されているので、ルールの設定はしっかり慎重に行うこと。(全部のタグを変更するのに多大な労力が必要なのは言うまでもないことだろう)

[]タグは0個です。

*pretext
gettag $0,%0,$1
return
; $0,$1="", %0=0

タグに使えないこと。

mov $100,"タグ1/タグ2"
[$100]「これは無理。タグに"$100"と言う文字列が渡されるだけ」
puttext "[タグ1/タグ2]これも駄目。全部が表示文として認識される。"

zenkakko命令

同じdefine節の命令でzenkakko命令がある。この命令(引数無)を実行しておくと、タグに[]だけでなく【】も使えるようになる。タグに日本語を多く使う場合は、【】の方がIMEの切り替えが少なくて(多少)シナリオの執筆速度に寄与することになる。

【タグ1】「全部日本語でいけた!」

後の応用その1と組み合わせると、更にシナリオの執筆速度が上がる、かも。

gettagの応用その1

gettagは"/"半角スラッシュで区切り文字が固定されている。そこを逆手にとって/を使わず別の文字を区切りとして記述する。

[圭一,voice0001.ogg]「こういう文章」
; こういう文章だとすると、
gettag $0
; $0 = "圭一,voice0001.ogg"
; このように取得できる。

多少別のプログラムの助力を得て、splitを実装すれば、可変長のタグ取得が可能になる。もうちょっと頑張って区切り文字を全角文字でも可能にすると、さらに執筆速度に寄与できるだろう。

【圭一・voice0001.ogg】「これ、かなり入力早くね?」

gettagの応用その2

実は、pretextgosubのサブルーチン中でなくてもgettagは実行できるし、実行してもエラーは出ない。しかし分割すべきタグがないので、与えられた変数全てに""か0が代入される。
この性質を利用して、gettagを一行で複数の変数を初期化できる便利な命令として扱うこともできる。はず。
※pretextgosubのサブルーチン中に、複数回gettagを実行しても構わない。有効なのは1回目だけで、2回目以降は""か0になるだけだが。

english命令実行時

define節でenglish命令を実行していると、半角英数字がきれいに表示できるようになる。ただし、その場合のタグの指定方法はこうなる。

[english/tag]>Oh, No!@

ただし、【】はzenkakkoを実行したしないに関わらず失敗し、NScripterがフリーズする。

gettaglog

類似品でgettaglogがある。過去ログと、それに付随するタグを取得する命令であるが、分割機能がついていない。
split命令で"/"で分割するか、応用その1と同じように処理するか、多少のプログラミングが必要になるだろう。