ERB開発Q&A¶
元となったページ
eratohoまとめ V3 ERB開発Q&A
eramakerおよびEmueraにおいて開発に使うERA-BASICに関する雑多なネタをQ&A方式にて解説するページの予定だったが、変数と関数の基礎的な部分を解説するページになっている。
変数について¶
Q:配列変数とはなんですか?¶
A:家族だと思えばいいかと
eramakerにおいて、ほぼすべての変数は配列変数となっています。 たとえば、一文字変数A
の中にはA:0
とかA:1
とかA:2
とか複数の変数があります。これらはA
という家族の中の一員だと思えば分かりやすいかと。
しかし、同じ名前とはいえ、家族ごとに違った個性がありますので、それを一括して指定することはできません。例えば…、
A = 2
上では、A:0
(変数が単独で書かれている場合はたいてい後ろに:0
が省略されていると思えばいいでしょう)に2
が代入されますが、A:1
とかA:2
とかは中身が変化することはありません。
ここで、わざわざそうやって同じ名前にまとめる意味があるのか分からない人もいるでしょう。そこで、アイテムを実際に管理しているITEM
という変数について考えてみましょう。
ITEM:1
が1
であるということはアイテム番号1
を既に購入済みだということをあらわしています。これを配列にしないとするとたとえば、変数I
をアイテム1の購入フラグだとすれば、じゃあ、アイテム2は?アイテム3は?となると、どんどん新たな変数を使う必要があります。そして、実はERBにおいて一文字変数はアルファベット26文字分しかないので、アイテムは26個しか管理できなくなります。
それだけではありません。アイテムを購入した場合、アイテムフラグを1(以上)にする必要がありますが、そのときの処理としてITEM:BOUGHT = 1
ということをしています。これがもしITEM管理を別個の変数でしていた場合、1というアイテムを購入したときは変数I
、2を購入すれば変数J
、3を購入すれば変数K
…などと、購入するアイテムごとに違う変数を操作しなければなりませんし、そのための分岐処理などを余計につくる必要があります。
そういう煩わしさをなくして分かりやすいコードにするためにも配列変数は必要不可欠であるといえます。
Q:配列変数の要素って?¶
A:その配列の具体的な入れ物を示すものです
前項のとおり、配列変数には同じ名前の付いた入れ物が複数ありますが、それを区別するのが「要素」です。たとえば、「A:2
」というのは、名前がA
で要素が2
の数値配列変数であるとします。
また、変数の中には要素を複数持つものがあります。たとえば、「CFLAG:4:2
」というものがありますが、これは、CFLAG
という名前の要素が4
の2
の変数です。このように要素がふたつあるのを2次元配列といいます。A:2
のようにひとつしかないのを1次元配列といいます。なおeramakerでは3次元配列などはありません(Emueraでは3次元配列変数が導入されています)
前項で配列変数を「家族」のようなものだと言いましたが、2次元配列に関してはむしろ、「団地」のようなものだと解釈したほうがいいかもしれません。同じ団地の住人ではあっても、実際に居住している階が違いますし、違う階なら同じ番号の部屋でも同じ部屋ではありませんから。
Q:RESULT
とかPLAYER
とかも配列変数なの?¶
A:彼らも世帯持ちです
eraの世界において、世帯を持たない変数はほとんどありません。まったくもって羨ましいわけですが、たとえば、COUNT、RESULT、DAY、TIME、MONEY、MASTER、TARGET、ASSI、PLAYER、ASSIPLAY、SELECTCOM、PREVCOM、LOSEBASE、UP、DOWN、PALAMLV、EXPLV、EJAC、FLAG、TFLAG、ITEM、ITEMSALES、BOUGHT、NOITEM、PBAND、RESULTS、STR、SAVESTR、NO、ISASSI、NAME、CALLNAME、BASE、MAXBASE、ABL、TALENT、EXP、MARK、RELATION、JUEL、CFLAG、EQUIP、TEQUIP、PALAM、STAIN、EX、SOURCE、NOWEX、GOTJUELはいずれも配列変数です。
なお、上の変数の中には特定のタイミングで初期化されたりするものがありますが、そのときにその配列変数の要素がすべて初期化されるのか、それとも特定の要素のみが初期化されるのかが違うものがあるので注意してください。たとえば、調教開始時にPREVCOM:0
は-1
に初期化されますが、PREVCOM:1
やPREVCOM:2
以降は初期化されません。
参考:Emueraの変数表
Q:一文字変数ってなに?¶
A:アルファベット一文字の名前の数値型配列変数です。
つまり、A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z
の26種類の数値型の配列変数です。数値型ですので文字列代入などには使えませんが、数字を扱うのに基本となる変数のことです。
なお、口上呼び出しなどで口上側が処理をする場合、バリアント本体側で使用している変数を口上側で操作するのは危険なことがありますので注意すべきです。
たとえば、本体側でA:0
に本来の調教対象のキャラ番号を入れたまま口上を呼び出した場合、口上側でA = RAND:2
などのようにA
を書き換えてしまいますと、本体側に処理が戻ったときに不具合が起こってしまいます。
通常ならば、イベント呼び出しタイミングにおいて、破壊してはならない変数(フラグ)が明確であるべきですが、バリアント側でその情報が十分に用意されていないこともあります。そのときは口上作者側がGrepやソースチェックなどで、破壊してはならない変数をしっかり把握すべきであるでしょう。 また、Emueraバリアントにおいては、ローカル変数であるLOCAL
やLOCALS
を活用すべきでしょう。
Q:eramakerは変数少なすぎだ!¶
A:待ってください、ちゃんと配列を活用できてますか?
変数の数に限りがあることは既にご承知のことでしょうが、それも工夫次第でどうにかなる場合もあります。特に一番陥りやすい間違いが、
ABCDEFGIJKMNPQRSTUVXYZっておいおい22も使ってやがる!
あと使えるのはHLOWの4つしかないだろ!
という間違いです。これはこれらの一文字変数が「配列変数」であることを失念しているからこうなるのです。
同じようなことをしているフラグは同名のものにまとめることを考慮するべきでしょう。たとえば、別のソースにそれぞれ代入しているA
とB
とC
という変数があればそれを、A
とA:1
とA:2
という風に変えればBとCの部分は別の変数として利用できますね。こうして、フラグを整理してしまえば、フラグ不足なんてそうそう起きませんよ。
Q:数値型変数と文字型変数の違いは?¶
A:中身に入るのがただの数字がそれとも文字列か?の違いです。
数値型変数とは中身に数値が入る変数のことです。そしてそれは、四則演算などで数学的に処理ができます。たとえば、
C = A:2 + B:1
という場合、C:0
という数値変数にA:2
という数値変数の中の数値とB:1
という数値変数の中の数値を単純に加算したものが代入されます。
文字型変数とは中身に文字列が入る変数のことです。たとえばキャラクターの名前だとか、素質などの名前とかを入れたい場合に使われます。そしてそれは、数値型変数のような数学的処理はできません。ただし、文字列操作という形で加工することはできます。
Q:変数の名前に特別な意味はあるのですか?¶
A:ある場合もあります
変数の中には特別な意味を持つ名前が付けられているものもあります。たとえば、TARGETという変数は調教対象をあらわしていますし、PALAMという変数はパラメータをあらわしています。
元々のerakanonにおいてそう使うべく用意された変数ですので、それに見合った使い方をするのが一番分かりやすいと思われますが、開発の上ではそれに縛られることはありません。製作者のやりたいように変数を使えばいいのです。ただし、それぞれの変数には初期値が設定されていたり、特定のタイミングで初期化されたりしますので、その変数名を使った場合、どういう挙動をするかをよく分かった上で使いましょう。
以下に使用に注意すべき主な変数を記します。
COUNT
:REPEAT
ループにおけるカウントに使われている数値型変数です。変更しないほうがいいと思われます。また、前述のとおり、COUNT
も配列変数ですが、実際にループカウント用として使われているのはCOUNT:0
のみですので、REPEAT
ループを入れ子にすることはeramakerではできません。Emuera拡張でFOR
やDO
やWHILE
などを併用すれば可能ですが、そのときもカウントの数値変数を共用することはできません。RESULT
:何らかの結果が代入されている数値型変数です。CALL
からRETURN
で戻ったときのRETURN
での戻り値だとか、INPUT
で代入された数値とかがRESULT:0
に入ったりします。RESULT:1
以降はeramakerでは特に役割はありません。RESULTS
:何らかの結果が代入されている文字型変数です。INPUTS
で入力された文字列だとかがRESULTS:0
に入ったりします。RESULTS:1
以降はeramakerでは特に役割はありません。SELECTCOM
:この調教ターンに選択された調教コマンドの番号を示す数値型変数です。SELECTCOM:1
以降はEmueraの拡張命令のCALLTRAIN
で使用しています。なお、SELECTCOM
はeramakerの調教(BEGIN TRAIN
で始まる一連の処理)を使用しない場合には使われていないこともありえます(例:eratohoSB)ITEMSALES
:そのアイテムが販売されているかどうかを示す数値型変数です。STAIN
:汚れをあらわす数値型変数です。ビット管理されているので注意してください。ビット管理については別のページの説明や本家の説明を読むなどをして勉強する必要があります。CHARANUM
:現在の登録キャラ数を表す数値型変数です。どの要素にも同じ数値が入っています。代入しても数値が変わらないので意味はありません。なお、Emueraでは代入しようとするとエラーになります。RAND
:ランダムな数値を返す擬似配列の数値型変数です。代入しても意味はありません。なお、Emueraでは代入しようとするとエラーになります。
以上の変数は自動的に説明通りの使い方がされます。一方、次からの変数はERBで設定しないとただの容れ物です。
MASTER
:主人の登録番号を示す数値型変数です。なお、主人の登録番号が必ず「0」であるとは限らないこともあります。PLAYER
:調教者の登録番号を示す数値型変数です。なお、実際に調教者を入れ替えるための仕組みを作らないとこの変数を使う意味はほとんどないでしょう。TARGET
:調教対象の登録番号を示す数値型変数です。「0」ならたいていは主人が調教対象であることをあらわし、「-1」ならたいていは調教対象が存在しないことをあらわします。ASSI
:助手の登録番号を示す数値型変数です。「-1」ならたいていは助手が存在しないことをあらわします。ASSIPLAY
:助手調教中であるかどうかを示す数値型変数です。たいていは「0」なら助手調教中ではなくて、「1」なら助手調教中であることを示します。どのキャラが助手であるか?とか助手がいるかどうかは示していませんので注意してください。PREVCOM
:ひとつ前の調教ターンに選択されていた調教コマンドの番号を示す数値型変数です。ちなみに調教に入ったそのときには「-1」が代入されています。なお、PREVCOM:1
以降は何も仕組みを作らなければ代入されることはありません。またPREVCOM
に前ターンのSELECTCOM
を代入するということは実際にその処理がなければ起こらないことに注意してください。自動的にそうなるわけではありません。NEXTCOM
:次回の調教ターンに実行すべき調教コマンドの番号が入っている数値型変数です。調教ターン中にSHOW_STATUS
を呼ばれる直前にチェックがあり、そこで0以上の数が入っているばあい、調教コマンド入力を省略して、NEXTCOM:0
にはいっている数値に該当するTrain.csv
の調教コマンドを実行しようとします。なお、NEXTCOM:1
以降にはそういう働きはありません。なおこの変数については色々と挙動に問題があるので完全に理解できるまでは使わないほうがいいでしょう。LOSEBASE
:調教ターンにおけるBASE
値の減少値を示す数値型変数です。なおキャラクター変数ではない(=2次元配列変数ではない)ため、アクセスはTARGET
を利用する必要があります。キャラクタ変数として使用したい場合はDOWNBASE
を使用してください。EJAC
:射精ゲージに関係する数値型変数です。ただし、射精があったときに自動的に変化したりはしません。そういう仕組みは別途拵える必要があります。ITEM
:そのアイテムを所有しているかどうかおよび所有数を示す数値型変数です。NOITEM
:アイテムなし設定が有効か無効かを示す数値型変数です。「1」ならアイテムなし設定で「0」ならアイテムなし設定ではないということを示しますが、たいていのバリアントでは「0」であると思われます。また、0と1以外の数値を取る可能性もあります。STR
:文字型変数です。一文字変数は数値型であるから、文字型変数をeraで扱いたいならこちらを多用することになるかもしれません。初期値はstr.csvで定義されます。なお、セーブデータに保存はされません。保存されたい文字型変数が使いたいなら次のSAVESTR
を使うべきでしょう。SAVESTR
:文字型変数です。こちらはセーブデータに保存されるため、より貴重な存在だといえるでしょう。ただし、makerでは数値変数で出来る仕事しか出来なかったりします。(INPUTS
で入力した文字を保存したりはできない)ISASSI
:そのキャラが助手になったことがあるかどうかを示す数値型変数ですが、自動で設定はされないので助手化の処理で値を真に変える必要があります。また、キャラクター変数ではないことにも注意しましょう。NAME
、CALLNAME
:いずれもそのキャラの名前が入っている文字型変数ですが、NAME
の方が本名でCALLNAME
の方が呼ばれ方もしくはあだ名などのように使うことになるでしょう。もちろん、まったく同じにそろえるとか、フルネームと略称という風に使い分けてもいいでしょう。CFLAG
:キャラクターごとに保持できる数値型変数ですが、実はChara**.csv
にて「フラグ,***,###
」という形式で初期設定することができます。EQUIP
:本家では説明されていませんが、キャラクター変数としてeramakerで利用することが可能な数値型変数です。Emuera拡張変数ではありません。PBAND
:もともとは、特殊な処理の多かったペニスバンドを扱いやすくするための、数値型変数で、たとえば、ITEM:PBAND
とすれば、ペニスバンドのアイテム番号が何番になっても中身の修正の必要がないなどの利点がありました。しかし、実際のところは単なる数値変数ですので、そのように使っても構わないでしょう。ただしキャラクター変数ではありません。LOCAL
:Emueraでのみ使用可能なローカル数値型配列変数です。ローカル変数というのはeraの関数ごとにそれぞれ使うことができる変数のことで、同じLOCAL
という名前であっても、呼び出した関数によって違う値が入っています。LOCALS
:Emueraでのみ使用可能なローカル文字型配列変数です。上記LOCAL
の文字型版で、同様に使えます。ARG
:Emueraでのみ使用可能なローカル数値型配列変数です。これはLOCAL
と似てますが、関数の間での数値(フラグ)の受け渡し用に使われることを想定しています。ARGS
:Emueraでのみ使用可能なローカル文字型配列変数です。上記ARG
の文字型版で、同様に使えます。CSTR
:Emueraでのみ使用可能なキャラクターごとに保持できる文字型変数です。セーブもされますので、とても使い勝手はよいと思われます。
Q:キャラクター変数とはなんですか?¶
A:登録キャラごとに配列が用意されている二重配列変数のことです
ほとんどすべての変数が配列変数なのですが、中には登録キャラごとに配列が用意されている一連の変数があります。それをキャラクター変数といいます。キャラクター変数でない変数は1次元配列変数であるので、登録キャラごとに別途フラグは用意できません。
キャラクター変数SOURCEの場合
SOURCE:A:B A…登録番号A番のキャラ
B…SOURCE:Bを示す
非キャラクター変数UPの場合
UP:B B…PALAM:Bを示す
対象は必ずTARGET:0(調教対象)
つまり、非キャラクター変数で各キャラクターを管理するには、TARGET:0
を操作してやっていくしかありませんが、現状そうやって操作した場合、別のキャラを退避するフラグが足りなくなると思われるので、eramakerでは調教対象を複数同時に調教するようなバリアントを作る場合にはフラグ不足に対応した仕組みを作る必要があるでしょう。 Emueraではこの辺の事情は少し好転してはいますが、やはり一工夫必要となります。
なお、どの変数がキャラクター変数であって、どの変数が非キャラクター変数であるか?というのは変数一覧を参照してください。
Q:キャラ番号(NO
)と登録キャラ番号(ID)とはなんですか?¶
A:それぞれ意味合いが違う番号です
キャラ番号(NO
)とは、Chara***.csv
で設定される番号で、ゲーム中でADDCHARA (番号)
で追加されるのに使われる番号です。eratohoのほとんどのバリアントでChara001.csv
に博麗霊夢さんのキャラ設定がありますが、そのcsvファイルの中に
番号,1,
という行がありますが、それが霊夢さんのキャラ番号です。
一方、登録キャラ番号もしくはキャラ登録番号もしくは登録番号(ID
)というのは、ゲーム中に主人もしくは奴隷として存在しているキャラクターたちに割り振られている番号です。こちらはキャラ番号とはまったく関係なく、通常はADDCHARAされていくたびに順番に、0,1,2,3…と追加されていくはずです。つまり、まだ登場していないキャラに関しては登録番号なんてありません。あくまで、ゲームに登場しているキャラにのみ割り振られます。
数値変数のMASTER
,ASSI
,TARGET
はそれぞれ中に入っている数値の登録番号のキャラがその役割であることを示します。キャラ番号のキャラがその役割であるというわけではないことに注意してください。
登録番号からそのキャラクターのキャラ番号を求めることはできます。それはNO:(登録番号、ID)
です。主人のキャラ番号が欲しいならNO:MASTER
、調教対象のキャラ番号が欲しいならNO:TARGET
でもNO
でもOKです。
通常、キャラクター変数における第一要素は登録番号でアクセスします。キャラ番号ではありません。なお、RELATION
という関係を表すキャラクター変数の第二要素はキャラ番号でアクセスします。登録番号ではありません。つまり…
RELATION:A:B
A…登録番号(ID) (MASTER,ASSI,TARGET)
B…キャラ番号(NO) (NO:MASTER,NO:ASSI,NO:TARGET)
ということで、キャラ番号と登録番号を混同しないようにしてください。また、EmueraなどでSWAPCHARA
やSORTCHARA
などを使う場合、登録番号が変わることに注意しましょう。
ちなみに、DELCHARA (番号)
は、登録番号で指定します。キャラ番号ではありませんが、それは当然だと分りますね?
関数について¶
Q:関数とはなんですか?¶
`A:特定の処理を行うための一連のコードです** ERBを記していく上で、実行順番は上から下へ~~~です。ですが、ゲームスタートからずっと、上から下へ流していかなければならないというわけではありません。 たとえば、SHOPコマンドで奴隷の購入をする場合と奴隷を調教する場合とゲームデータをセーブする場合とでは、それぞれそこからの処理が違うはずです。それをいちいち
IF RESULT == ~ ELSE ~ ENDIF`で順番に処理していくようにしたら、きっと大変見づらいコードになってしまうでしょう。
そういうときは、奴隷の購入を担当する処理部分を別に作り必要に応じてそれを呼び出すようにすればいいでしょう。そのときの別に作った処理部分のことをeraでは「関数」としています。
関数を呼び出す命令は、JUMP
かCALL
があります。JUMP
というのはその関数に処理が移動します。元々のところにはそのままでは戻りません。それに対してCALLはその関数の処理が終了したら元々のところのCALL
の次の行からまた処理を再開します。 なお、Emueraでは、CALL
した関数からJUMP
という動作が可能ですが、makerでは動作しないので注意が必要です。(っていうか、makerだとJUMP
はどこで使えるんだろう)。
ERBにおいて関数は関数宣言行、すなわち@関数名
の行から開始されます。そして、そのERBファイルの末尾に到達するか、それとも次の関数の始まりの直前までがその関数です。 つまり、次の関数宣言行があれば、そこから先は実行されず、処理は終了します。そのため、CALL
で呼ばれているのならば元々の場所のCALL
の次の行に戻りますし、JUMP
で呼ばれているのならばそこでプログラムそのものが終了します。また、任意の場所で関数を終了させるためには命令RETURN
を使用します。(実は関数の終わりに何もなくてもRETURN 0
が実行されていたりする)
Q:おい待てよ?JUMP
もCALL
もないのに呼ばれてる関数あるぞ?¶
A:関数によっては、自動的に呼ばれる関数も存在します
ただ…、詳しくはもう少し下の設問をお読みください。
Q:RETURN 0
とRETURN 1
の違いは?¶
A:CALLから戻ってきたときに関係あります
関数によくRETURN 0
とかRETURN 1
とかあります。RETURN
は前問の答えのとおり、CALL
で呼ばれたその関数を終わらせて元々の処理に戻すためのものですが、そのときにRETURN
の後ろに数値を付加することが可能です。 そして、それは実はRESULT:0
という変数に代入されるのです。
つまりCALL
文の次の行以降に、IF RESULT == 0 ~ ELSEIF RESULT == 1
などと処理をすれば、CALL
で呼ばれた関数内の処理に応じて戻った後に分岐を掛けることが可能になるというものです。
RETURN B
のように数値変数が指定されている場合はその変数の中身がRESULT
に入ります。ただし、RETURN RESULT
とした場合は、Emueraでは正常に動作しますが、makerではRETURN 0
と同等になります。 また、EmueraではRETURN A+B
のように数値変数だけでなく式を使うことが出来ます。
複数の数値を返したい場合は、RETURN A, B, C
とカンマで区切ります。この場合はA
がRESULT:0
、B
がRESULT:1
、C
がRESULT:2
に代入されます。
なお、RETURN
文でなく、関数が終了した場合もCALL
で呼ばれている場合には元々の処理に戻りますがそのときはRETURN 0
と同様にRESULT
には0
が入っています。(RETURN 0
が自動で実行されていると見ることも出来ます)
なおRETURN
のある関数が以下のケースに当てはまる場合には特殊な処理がおこなわれます。
-
その関数がシステム関数でありなおかつ
#SINGLE
という属性がついている場合
RETURN 1
で戻ったら、それ以降に実行すべき同名のシステム関数があってもそれを実行しません。RETURN 1
以外(当然RETURN 0
も含みます)の場合にはそういう処理はしません。 -
その関数が
COMABLE(数字)
という名前の場合。
数字の値がeramakerの場合は0~2147483647
まで、Emueraの場合は0
~VariableSize.csv
で指定したTRAINNAME
の範囲にないか、もしくはその範囲であってもTrain.csv
に定義されていないならば特に特別な処理はありません。
そうでないのならば、それはそのTRAIN
(コマンド)が実行できるかどうかを表すことを想定されています。RETURN 0
ならば実行できないのでTRAINNAME
(コマンド名)を表示せずにそのTRAIN
の入力を無効にします。RETURN 0
以外(当然RETURN 1
も含みます)の場合には、実行できるのでTRAINNAME
を表示しそのTRAIN
の入力を有効にします。ただし、そもそもTRAINNAME
を表示させない設定にしておればまたその処理は異なります。 -
その関数が
COM(数字)
という名前の場合。
数字の値の範囲や条件はCOMABLE(数字)
と同様で、それに当てはまらないならば特に特別な処理はありません。
そうでなくて、COMABLE(数字)
において、RETURN 0
以外(当然RETURN 1
も含む)を返していたのならば、それはそのTRAIN
が実際に実行されたのかどうかを現すことを想定されています。RETURN 0
ならば実行されなかったのでSHOW_STATUS
関数に処理を戻します。RETURN 0
以外(当然RETURN 1
も含みます)の場合には、実行されたので@SOURCE_CHECK
関数や@EVENTCOMEND
関数を呼び出す処理に移行していきます。
Q:イベント関数とはなんですか?¶
A:特別な働きをするために設定された関数です
eraにおいては、通常、同じ名前の関数は複数存在できません。仮に同じ名前の関数を作ると特定の法則に基づきどの関数が呼ばれるかが決定され、その関数のみが実行され、呼ばれなかったほかの同名関数は無視されます。
ところがイベント関数に関しては例外で、同じ名前の関数が複数存在してもその全てが処理されます。実行順番はやはり特定の法則がありますがそれは一応制御することもできます。
以下に各イベント関数を説明と一緒に列挙します。なお、イベント関数の存在は必須であるわけではないので、バリアントによってはそのイベント関数が存在しないこともありえます。
EVENTFIRST
ゲームをはじめからはじめるときに呼ばれるイベント関数です。EVENTSHOP
SHOPに入るときに呼ばれるイベント関数です。EVENTBUY
SHOPで何かを購入したときに呼ばれるイベント関数です。EVENTTRAIN
TRAIN(調教)に入ったときに呼ばれるイベント関数です。EVENTCOM
調教においてプレイヤーがコマンドを選択したあとに呼ばれるイベント関数です。EVENTCOMEND
調教において、調教ターンの終了時に呼ばれるイベント関数です。EVENTEND
調教終了処理の開始時に呼ばれるイベント関数です。EVENTTURNEND
ターン終了時に呼ばれるイベント関数です。EVENTLOAD
データをロードした直後に呼ばれるイベント関数です。Emuera専用です。
Q:イベント関数に付与する性質とは?¶
A:イベント関数の処理について決定できる仕組みです
前項のとおり、イベント関数は同名関数が複数あることがありますが、そのときにどんな順番で実行したらいいかを制御するために、その関数宣言行の次に性質をあらわすものを付与できます。
- #PRI
これが付与された関数は他の同名関数よりも先に実行されます。ただ、これが付与された関数が複数ある場合にその中での優先度を決めることはそのままではできません。
- #LATER
これが付与された関数は他の同名関数よりも後に実行されます。ただ、これが付与された関数が複数ある場合にその中での優先度を決めることはそのままではできません。
- #SINGLE
これが付与された関数はこれを実行後にRETURN 1
で終了した場合には他の同名関数があっても実行しません。RETURN 0
で終了した場合には、他の同名関数を実行します。若干使い所が難しいので覚えなくても良いでしょう。
- #ONLY
これが付与された関数のみが実行され、他の同名関数は実行されません。ただし、これが複数の関数に付与されている場合には、通常の法則で最初に実行された関数のみが実行されます。ただし、これはEmuera専用でeramakerでは無効です。
Q:特別な働きをする関数はありますか?¶
A:決まったタイミングで呼ばれる関数はあります
前々項でイベント関数のことに触れましたが、eramakerではそれ以外の関数の中にも呼ばれるタイミングが決まっている関数が存在します。それらは想定された処理をするとうまく動作するようになっています。もちろん、それを無視するコードの書き方も可能ではありますが。ともかく、以下にそういう関数を列記して説明します。なお当然のことながらバリアントによっては、これらの関数がないこともありえます。
以下の説明において、~であることを想定していますとなっている場合、そうでない使われ方をされている場合はありますがそれは実際のコードで確認してください。
SHOW_SHOP
EVENTSHOP
の後(もしくはそれがない場合にはBEGIN SHOP
直後)に呼ばれる関数です。販売可能な商品の陳列とSHOPコマンド入力をさせることを想定しています。USER_SHOP
SHOPで0~99
以外の数字が選ばれた場合に呼ばれる関数です。SHOPでアイテムの購入以外のコマンド(調教開始や休憩やステータスチェックやセーブやロードなど)を実行するための処理に移行させる処理を想定しています。終了後はBEGIN
などがなければ@SHOW_SHOP
に戻ります。SHOW_STATUS
EVENTTRAIN
の後(もしくはそれがない場合にはBEGIN TRAIN
直後)に呼ばれる関数です。調教に必要なステータスなどを表示することを想定しています。COM_ABLExx
SHOW_STATUS
の後に、すべての調教コマンドについて呼び出される関数です。調教コマンドxxの実行可能か不可能かの決定を想定しており、返り値が0でなければ実行可能であり調教コマンドとして表示されます。0のときは実行不可能でありそのコマンドは表示されません。SHOW_USERCOM
COM_ABLExx
の後に呼び出される関数です。COM_ABLExx
の結果を踏まえて調教コマンドを表示したあとに、プレイヤーにコマンド入力をさせることを想定しています。COMxx
EVENTCOM
の後(もしくはそれがない場合にはプレイヤーが調教コマンドを選んだ直後)に呼ばれる関数で、選んだ調教コマンドに対応したCOMxx
のみが呼び出されます。対応するCOMxx
がない場合にはこの下のUSERCOM
が呼ばれるのでこちらは呼ばれません。選ばれた調教コマンドの実行処理を想定しています。USERCOM
上の項目の通り、対応するCOMxx
がない調教コマンドが入力された後に呼ばれる関数です。調教ターン中の実際の調教以外のステータス表示やヘルプや調教そのものの終了やプレイヤー交代などのコマンド処理を想定しています。SOURCE_CHECK
COMxx
からの戻り値(RESULT:0
)が0でないとき(すなわち調教コマンドが実行されたとき)にその直後に呼び出される関数です。調教コマンド実行後のSOURCE
変化やパラメータへの反映などを想定しています。終了後はEVENTCOMEND
があればそれを呼び出します。そして、それが終わるかEVENTCOMEND
がなければ…他にBEGIN
命令などない場合NEXTCOM:0
をチェックします。NEXTCOM
が0以上ならばNEXTCOM
の内容の調教コマンドを実行します。そうでなければ@SHOW_STATUS
に戻ります。SHOW_JUEL
BEGIN ABLUP
直後に呼び出される関数です。能力UPのために必要な対象の所有珠を表示させるというのを想定しています。SHOW_ABLUP_SELECT
SHOW_JUEL
の後に呼び出される関数です。プレイヤーに対象のどの能力をUPさせるかを選ばせるというのを想定しています。ABLUPxx
SHOW_ABLUP_SELECT
において、プレイヤーにより入力された数が0~99
でなおかつ対応するABLUPxx
がある場合に呼び出される関数です。対応するABLUPxx
がなければ再入力を要求されるでしょう。また、入力した数が0~99
の範囲外ならばこの下のUSERABLUP
が呼ばれます。xx
に対応した能力をUPさせる処理を想定しています。終了後はBEGIN
などがなければ@SHOW_JUEL
に戻ります。USERABLUP
SHOW_ABLUP_SELECT
において、プレイヤーにより入力された数が0~99
の範囲外である場合に呼び出される関数です。通常のABLUP
による能力UPではうまくいかない能力変化をさせる処理を想定しています。終了後はBEGIN
などがなければSHOW_JUEL
に戻ります。SAVE_INFO
セーブデータに概要をつけるための関数です。この働きがあるのはこの関数のみです。呼び出されるタイミングはゲームデータがセーブされる直前です。
Q:BEGIN命令って何ですか?¶
A:さまざまなシステム命令を呼び出す命令です
以上の設問より、特別なタイミングで関数が存在することは分ったと思います。そして、その特別なタイミングをERBで制御するための命令がBEGIN
命令です。 これを使うことにより、SHOPを呼び出したり調教を開始したり調教を終了したりターンを終了したりすることができます。もちろん、この仕掛けを無視して当該処理関数を直接CALLすることによりゲームを進行させる仕組みにすることもできますが、その場合は、必要となる各種フラグの初期化などをすべてコードとして記述する必要があります。 それが分らないうちは既存の構造を利用しましょう。冒険するのは理解してからでも遅くはありません。
BEGIN
命令が実行された場合、すぐに当該処理が行われるわけではなく、イベント関数やCALL
で呼ばれた関数など実行すべきコードを全て実行し終えてから処理が行われます。また、BEGIN命令ができないタイミングも存在し、そのタイミングでBEGIN
命令がされた場合にエラーにより挙動がおかしくなることがあるので注意してください。
BEGIN SHOP
SHOPを呼び出すBEGIN
命令です。EVENTSHOP
があれば呼び出し、なければSHOW_SHOP
に直行します。BEGIN TRAIN
調教を開始するためのBEGIN
命令です。調教関連の一部のフラグを初期化した後、EVENTTRAIN
があれば呼び出し、なければSHOW_STATUS
に直行します。BEGIN AFTERTRAIN
調教を終了するためのBEGIN
命令です。EVENTEND
に直行します。BEGIN ABLUP
能力アップ画面を呼び出すためのBEGIN
命令です。SHOW_JUEL
に直行します。BEGIN TURNEND
ターン(調教ターンのことではない)を終了するためのBEGIN
命令です。@EVENTTURNEND
に直行します。BEGIN FIRST
ゲームを最初からはじめるところを呼び出すためのBEGIN
命令で、Emueraで拡張されたものですのでeramakerでは使えません。なお変数の初期化は行われないのでRESETDATA
命令を使うべきでしょう。BEGIN TITLE
タイトル画面を呼び出すBEGIN
命令で、Emueraで拡張されたものですのでeramakerでは使えません。なお変数の初期化は行われないのでRESETDATA
命令を使うべきでしょう。
Q:ユーザー定義式中関数って何ですか?¶
A:Emueraで拡張された新しいタイプの関数です
eraにおいて通常の関数はCALLやJUMPで呼び出したり飛んで行ったりしますが、Emueraにおいては、あらたに「ユーザー定義式中関数」と呼ばれるものが導入されています。これは、数式の中でまるで予約語のように使える関数です。すなわち、
LOCAL = HOGE()
(中略)
@HOGE
#FUNCTION
LOCAL = RAND:6
RETURNF LOCAL
こういった場合、関数HOGE
がユーザー定義式中関数となっています。このHOGE
はCALL
やJUMP
で直接呼び出すことはできませんが、その上の数式のように式の中で呼び出し、その値を利用することができます。なお、上の例ではLOCAL:0
という数値変数に、0~5
までのランダムの数値を代入する処理をしています。
ここで@HOGE
という関数宣言文の下の#FUNCTION
はその関数が数値を返すユーザー定義式中関数であるという属性を示しています。もちろん、文字列を返すユーザー定義式中関数も作ることができ、それの属性は#FUNCTIONS
で宣言します。
上のHOGE
呼び出しのところの後ろに括弧がありますが、あれは、もし引数は存在すれば、引数を入れて呼び出します。引数が必要ない関数であっても括弧は省略してはいけません。式中関数呼び出しであることをEmueraに教える必要がありますので。以下に引数がある場合のユーザー定義式中関数の例を例示しておきます。
LOCALS = HOGES(STR:0)
(中略)
@HOGES(ARGS)
#FUNCTIONS
LOCALS = %ARGS%%ARGS%
RETURNF LOCALS
上の例では結局LOCALS:0
という文字列変数にSTR:0
の中身の文字列を二つ連ねた文字列を代入する処理をしています。
式中関数化された関数内においては、INPUT
やWAIT
などの入力を求める命令や、CALL
やJUMP
といった別の関数に飛ぶような命令を使うことができないのに注意してください。ただし、式中関数内で別の式中関数を呼び出すことはできます。
ユーザー定義式中関数から戻るときは通常のRETURN
やRETURNFORM
ではなくて、RETURNF
を使うことに注意してください。 RETURNF
がなくて関数終端に至った場合、#FUNCTION
のユーザー定義式中関数なら0
が返りますし、#FUNCTIONS
のユーザー定義式中関数ならば空白の文字列が返ります。なおRESULT:0
やRESULTS:0
に返るわけでもありません。大抵の場合呼び出し元の代入先変数(上の例ならばHOGE()
ならばLOCAL:0
、HOGES(ARGS)
ならばLOCALS:0
)に代入されるか、そのまま分岐文の条件として使われたりするでしょう。 ともかく、#FUNCTION
のユーザー定義式中関数内のRETURNF
で文字列を返したり、#FUNCTIONS
のユーザー定義式中関数内のRETURNF
で数値を返すことはできません。
なお、ユーザー定義式中関数を無理に使う必要はありません。使えばすっきりとした分りやすいコードになる場合もありますが、よく分からなければ式中関数は使わず、自分にとって分りやすい命令だけで組むべきでしょう。
なお、ユーザー定義ではなくあらかじめ用意されている式中関数も当然存在します。それらについては、命令・式中関数の一覧を参照してください。それらに関しても分かる範囲で利用すればいいと思われます。
FORM構文における特殊な省略形¶
Q:PRINTFORM +++
で「+++
」が表示されません。¶
A:eramakerの仕様として一部の記号文字を3つ続けた場合に特定の文字変数の中身を表示する仕様になっています。
そうではなくそのままその記号文字そのものを表示したいときはPRINTという風にFORMをつけない命令を利用してください。以下に記号文字と対応する文字変数の一覧を記述します。なお、これはEmueraでも同様です。
*** = NAME:TARGET
/// = NAME:ASSI
$$$ = CALLNAME:TARGET
+++ = CALLNAME:MASTER
=== = CALLNAME:PLAYER
Q:なんか///
を表示させたらエラー出たけど?¶
A:前項の説明にもあるとおり、FORM構文内において///
はキャラクター文字列変数 NAME:ASSI
のことを意味します。
ところが、通常のバリアントにおいてASSI
の初期値は-1
であり、明示的に助手が加わるような処理がなければ、基本的にはNAME:ASSI
を表示しようとしただけで以下のエラーを出す(Emueraの場合)ことになるでしょう。
PRINTFORML ///
キャラクタ配列変数NAMEの第1引数(-1)はキャラ登録番号の範囲外です
eramakerにおいても同様のエラーをだします。回避するにはいくつか方法がありますが PRINTL ///
ならば簡単に回避できるでしょう。