バリアント製作/タイトル実践編¶
元となったページ
eraシリーズを語るスレ まとめWiki V3 タイトル実践編
SYSTEM_FLOW.ERB
¶
さて、タイトルを作ろうという見出しにもかかわらず、
散々書いてきたのはタイトルを作らない方法だった。
うんざりしている人もいるだろう。
etc1821を開いてみよう。
SYSTEM_FLOW.ERB
というファイルがある。開いてみよう。
;[ライセンス]パブリックドメイン
;本ファイルに係る著作権を放棄する。
;本ファイルに係る著作人格権は行使しない。
;2015/11/01 MinorShift(Emuera作者)
と書かれている。
ツールの提供や優しいライセンス、wikiの案内だけではなく導入のフォローまでしてくれている。
ありがたい。MinorShift様の懐の深さを崇め倒しながら書く。
下のほうにスクロールしていくと、
;@SYSTEM_TITLEが定義されていると、標準のタイトル画面の代わりにSYSTEM_TITLEが呼ばれる。
@SYSTEM_TITLE
と書かれている。
『;
』というのは、『ここから行末まで』はコメントだから処理として読み込まないでね、
と伝えるための印だ。
つまり『;@SYSTEM_TITLEが定義されていると~』の行は、
改変しようとしている人に対して、処理内容を説明してくれるための文章だ。
もちろん、コメントは自分が忘れないために書くものでもあるが
etc 1821フォルダの中身は全体的に教えるために書いてくれていることが伝わってくる。
ERBを解読する、という作業の半分は、
こうして日本語で残されているコメントをありがたく追っていく作業だ。
この説明は、
ERBフォルダ内にある、ERBファイルのどれでもいい、どこかに
@SYSTEM_TITLE
という行があったら、
これまでずっと見てきたタイトル画面は表示されなくなって、
代わりにこの下に書いた処理が表示されるよ、という意味だ。
新ファイル作成!¶
では、erakanonフォルダに戻ろう。
ERBフォルダ内に
『TITLE.ERB』を作ってみよう。
エンコードってなに?¶
バリアントによって、エンコードというものが違う可能性がある。
人間にとって文字は文字だが、パソコンは1文字1文字に数字を割り当て、
『この数値ってことは、この文字を表示すればいいんだろ?』と判断している。
エンコードはその判断基準で、なんの文字にどの数字を割り当てるかだ。
動画等のエンコードと区別するためか、文字コードと呼ばれていたりもする。
昔は特に統一されていなかったのでエンコードにはいくつか種類がある。 違う割り当てで読み込んでもらおうとすると、パソコンが混乱して文字化けする。
エディタ | デフォルトのエンコード | 変更方法 |
---|---|---|
Windowsのメモ帳 | Win10 201903以降なら BOMなしUTF-8 それ以外ならShift-JIS | 変更不可能 |
秀丸エディタ | Shift-JIS | その他(O)→上級者向け設定をチェック→ファイル~~→エンコード1→新規作成やASCⅡのとき→変更(D) |
サクラエディタ | BOMなしUTF-8 | 設定→タイプ別設定一覧→基本→設定変更→ウィンドウタブ~~→デフォルトの文字コード |
Visual Studio Code | BOMなしUTF-8 | Setting(Ctrl+, ) のfiles.autoGuessEncoding 項目にチェックを入れる(true)で、オートエンコードが機能 |
Setting(Ctrl+,) の files.encoding 項目で デフォルトのエンコードを変更 | ||
ウィンドウ下部の右側に表示されているUTF-8を選び 表示されたアクション一覧からエンコード付きで再度開く 推測で出る一番上のJapanease(Shift JIS)を選ぶと一時的に変更 |
昔メジャーだったのは『Shift_JIS』で、
今のeraなら『BOM付きUTF-8』がメジャーになってきている。
この理由はいくつかあり、まとめwikiで解説してくれているかたがいる。
erakanonは製作年を見た通り昔の作品なので『Shift_JIS』だ。
エンコードを表示してくれるエディタなら、そう表示されていると思う。
だいたいエンコードや改行については一番右下に表示される。
エンコードが混在していると上手く読み込まれず文字化けしたりする。
長く改変するなら、全部のファイルをBOM付きUTF-8にしてしまうのがいいと思う。
ひとつひとつ保存しなおすのは大変だ。エンコードの変更ツールなどを使って一気にやりたい。
今のところ特に変更していない人は、とりあえずShift_JISで作ってみよう。
今のところ読み飛ばしていい補足
他にUTF-8が関わること。EmueraのERHで『#DIM SAVEDATA』を使ってセーブ可能なキャラ型変数や多次元文字列変数を定義するには、config『セーブデータをバイナリ形式で保存する』の設定をYESにすることが必須。
YESにするとセーブデータは自動的にUTF-8で保存される。
@SYSTEM_TITLE
¶
作成した『TITLE.ERB』がShift-JISになっていることを確かめて、
PRINTL タイトル画面
WAIT
と入力してみよう
起動すると、さっきタイトル画面が表示されたタイミングで、
『タイトル画面』
という文字が表示され、停止しる。
emuera.log¶
クリックするとエラーが出る。
関数の終端でエラーが発生しました。
予期しないスクリプト終端です。
※※※ログファイルを~emuera.logに出力しました
この「emuera.log」というのが、eraをいじると長くお付き合いするパートナーだ。
一旦ゲームを閉じよう。
Emuera1824.exeのあるところに、emuera.logというファイルが生成されている。
ここにはどこでどんなエラーが起きたかが保存される。
どの程度警告を貰うかはconfigで設定できる。
Emuera製作者のひとり、妊)|д゚)の人
様が
おすすめの開発者向け設定を公開してくださっている。ありがたい。
今はこれらの設定を自動的に行ってくれるワンクリック開発者モードというものもある。
関数の区切り、境目ってどこ?¶
SYSTEM_FLOW.ERBの続きを見ていこう。
『@なんとか』=関数は、
1ファイル内に1つしかないこともあるが、
2つ以上ある場合、次の『@なんとか』が始まる前までがひとまとまりだ。
なので、@SYSTEM_TITLEの中身は以下になる。
まるごとTITLE.ERBに貼り付けしてみよう。
@SYSTEM_TITLE
#DIMS VERSIONNAME
;このタイミングでグローバル変数を読んでおけば取りこぼしが無くなる。
;GLOBALはRESETDATAやLOADDATAによって初期化・上書きされない。
;必要に応じてコメントアウトを解除すること。
;LOADGLOBAL
;バージョン表記をVERSIONNAMEに作成。
;1001なら1.001、1100なら1.10と表示される
VERSIONNAME = {GAMEBASE_VERSION / 1000}.%TOSTR(GAMEBASE_VERSION % 1000 / 10,"00")%
SIF GAMEBASE_VERSION % 10 != 0
VERSIONNAME += TOSTR(GAMEBASE_VERSION % 10)
;タイトル表示。
DRAWLINE
ALIGNMENT CENTER
PRINTFORML %GAMEBASE_TITLE%
PRINTFORML %VERSIONNAME%
PRINTFORML %GAMEBASE_AUTHOR%
PRINTFORML (%GAMEBASE_YEAR%)
PRINTL
PRINTFORML %GAMEBASE_INFO%
ALIGNMENT LEFT
DRAWLINE
;選択肢表示
$TITLE_SELECT
PRINTSL "[0] " + GETCONFIGS("システムメニュー0");
PRINTSL "[1] " + GETCONFIGS("システムメニュー1");
$TITLE_INPUT
INPUT
IF RESULT == 0
RESETDATA
;ADDDEFCHARAはeramakerの初期化処理を再現するために存在する専用の関数です
;他の場面ではADDCHARAを使用してください
ADDDEFCHARA
BEGINWORD '= "FIRST"
CALL MAIN_LOOP
ELSEIF RESULT == 1
CALL LOADGAME_EX
GOTO TITLE_SELECT
;LOADGAME_EXでLOADを行わずに戻ってきた場合、もう一度選択しなおす。
ELSE
REUSELASTLINE 無効な値です
GOTO TITLE_INPUT
ENDIF
DIMってなに?¶
一行目の
#DIMS VERSIONNAME
を見てみよう。
DIM
と一般に呼ばれるこれは『ユーザー定義の変数』と呼ばれている。
ユーザーとは、Emueraのユーザーのことなので、Emueraでゲームを作る人達のことだ。
(プレイヤーはエンドユーザー)
つまり、我々が定義していい変数、自分で好きな名前をつけていい変数という意味だ。
日本語も使える。ただし変数名に日本語を使うことについて、意見は分かれるようだ。
日本語名を積極的に使って可読性をあげよう派。
日本語名は日本語文字列と組み合わせるとき混じってわかりにくい派。
GREPで検出するとき地の文を検索でひっかけてしまうから英語のキーワードと組み合わせる派等。
個人の考えによる。
DIMは『@なんとか』の次の行に書くという決まりがある。
(式中関数の場合は#FUNCTION
や#FUNCTIONS
が先に挟まるとか、
広域で使えるようにするERHという専用ファイルもあるが)
#DIM 好きな名前
なら数字を入れられる箱
#DIMS 好きな名前
なら文字列を入れられる箱
のようだ。
(だいたい末尾にS
がつくと文字列版という意味になる。
#FUNCTION
,#FUNCTIONS
とかも同じだ。
文字列を英訳するとcharacter
,string
。
.NETや他言語で文字列関連の処理を、StringクラスとかStringオブジェクトとか呼ぶ。
S
はその略)
このように書いて変数を作ることを『変数を宣言する』と表現する。
他にもさまざまなパターンがある。
中身が何であるかわかりやすく、検索しやすいように名前をつけて可読性を上げよう。
複数人が同じ変数を別の用途で使い、意図せず上書きしてしまうことを防止しよう。
などの目的で、初めから用意されている「LOCAL
」「LOCALS
」「ARG
」「ARGS
」
「A
」「B
」「C
」などの一文字、二文字の変数の代わりとして使われることが多い。
古い処理はわかりにくいから面倒くさい。誰か全部DIM
に直して欲しい。
よくわかる。
が、まとめてくれる人に『なんで最新化しないの?』と問うのはやめよう。
みんなで遊び散らかして帰った後の部屋を見て『なんで掃除しないの?』と部屋主に問えば、
悪鬼羅刹と化すだろう。そういうこともある。
ここでは
#DIMS VERSIONNAME
となっているので、
VERSIONNAME
と名付けられた、文字列の入る箱を作っている。
グローバル変数ってなに?¶
次の行を見てみよう。
;このタイミングでグローバル変数を読んでおけば取りこぼしが無くなる。
;GLOBALはRESETDATAやLOADDATAによって初期化・上書きされない。
;必要に応じてコメントアウトを解除すること。
;LOADGLOBAL
と書かれている。
この行は、グローバル変数を使っていなければ無視していい。
グローバル変数とはゲーム全体で使う変数だ。
ひとくちに全体、といってもイメージが湧きにくいと思う。
例えば、ゲームで遊んで、セーブデータAを保存する。
また新しくはじめて、セーブデータBを保存する。
データAとBの中身は干渉しない。
これが普通のセーブできる変数だ。
しかし、AB両方の情報が同じ場所に保存されることもある。
タイトル画面から閲覧できる回想モードや、コンフィグ設定の保存などだ。
タイトル画面から閲覧できる回想モードはたいてい、
セーブデータに関わらずイベントを見さえすれば回想を閲覧できるようになる。
Aで見たイベント、Bで見たイベント、どちらもフラグが立っている。
コンフィグ設定も、Aで保存した設定をBで読み込んだりできる。
こういう、セーブデータに縛られない
ゲーム全体で使う変数のことをグローバル変数という。
セーブできる場合はグローバルセーブデータと読んだりもする。
グローバルセーブデータはセーブデータとは別に、
global.savというファイルで保存される。
変数名 | 性質 |
---|---|
GLOBAL | SAVEGLOBAL命令によりセーブでき、LOADGLOBAL命令によりロードできる。 |
GLOBALS | GLOBALの文字列型版。 |
#DIM GLOBAL SAVEDATA 好きな名前 | DIM版 |
などがこれに該当する。
もしグローバル変数を使っているなら、ここの
;LOADGLOBAL
のコメントアウト『;』を外して
LOADGLOBAL
にして、ここでグローバル変数を読み込んでおくとゲームに反映されるので
必要に応じて使ってね、ということだ。
バージョンを計算して文字列化¶
次の行を見てみよう。
;バージョン表記をVERSIONNAMEに作成。
;1001なら1.001、1100なら1.10と表示される
VERSIONNAME = {GAMEBASE_VERSION / 1000}.%TOSTR(GAMEBASE_VERSION % 1000 / 10,"00")%
SIF GAMEBASE_VERSION % 10 != 0
VERSIONNAME += TOSTR(GAMEBASE_VERSION % 10)
パッと見て絶望、なんじゃこりゃ。いきなりハードルたっけえわ。と半笑いになる。
実は、1000で割っているだけだ。era basicの都合で、計算結果に小数点を扱えない。
そこでバージョンを表示する際、小数っぽく見えるように
数字を文字列として整えて表示する準備をしている。
なので、ここはこの計算にお任せして見なかったことにしてもいい。
理解したい場合、ひとつひとつ見ていこう。
VERSIONNAME¶
これは上のほうで宣言されているユーザー定義の変数だ。
『DIMS』で宣言されていたので、文字列を格納できる。
右側であれこれ計算しているように見えるが、
結果は文字として扱っていることがわかる。
GAMEBASE_VERSION¶
前半にでまくったGamebase.csvに関わる情報がついに現れた。
『GAMEBASE_VERSION』には、Gamebase.csvで設定した
バージョンが格納されている。
ここで思い出して欲しいのは、バージョンというのは
通常『1.01』とか『0.001』とか小数点で表示されているのに、
Gamebase.csvには『1001』のように四桁の数値で書いたことだ。
バージョン情報らしく見せるには1000で割れば済む。
しかし小数点以下の結果はとれない。
なので、
文字列『.
』の前に、4桁のバージョンを1000で割った数字を置く。
文字列『.
』の後に、4桁のバージョンを1000で割った数字の余りを、更に10で割って、数字を2桁でゼロ埋めして文字列として置く。
更に端数があれば、その後ろに文字列として置く。
すべてをくっつけると、小数っぽく見える文字列になる。
ということをしている。
(1桁目がメジャーバージョン
小数点以下1~2桁目がマイナーバージョン
小数点以下3桁目が不具合修正
と分割するイメージだと思う)
こんな大変なことをするくらいならいっそ初めから文字列でいいのでは?
という気がしてくるだろうが、そうもいかない。
バージョンは数字であって欲しい理由がある。
慣れないとちょっとわかりにくいが、
同じ数字の『1』でも、パソコンに文字列として扱うように頼めば
計算はできない。
文字は文字という情報でしかなく、数字だろうと平文だろうと
パソコン側に判別する基準がないからだ(判別する関数を作れば別)
数字と文字列の違いのひとつは、
計算したり、数値の大小を比較したりできるかどうかだ。
バージョン0.8以下は互換性がない、と指定したい場合に、
0.7はだめ、0.6もだめ…と文字列でひとつひとつ指定したくはない。
Gamebase.csvで『バージョン違い認める?』一か所を指定するだけで、
その数字未満を一括不可にできたほうが楽だ。
そのためには数字でなくてはならない。
そんなわけで、一見複雑なことをやっているように見えるのは、
表示を整えるため苦肉の策のようだ。
{~~}
ってなに?¶
と、聞けばなんとなくやっていることはわかっても、
それを自力で読み解けなければ意味がないと思うかもしれない。
知らない記号がいくつか出てきている。
『{~~}
』はFORM文字列とかFORM構文とか書式付文字列とか呼ばれている。
PRINTFORM
やCALLFORM
などの命令で使うと変数や変数の計算を展開できる。
と表現しても今はわかりにくいかもしれないが、
ERBを開いたことがあれば、口上や地の文によく使われる下のような文でおなじみだろう。
PRINTFORM 好感度が{CFLAG:TARGET:好感度}になった。
『{~~}
』の用途は二つある。
ここでは用途その1『変数の中身、あるいは計算式の結果をくれ』という意味で使われている。
VERSIONNAME = {GAMEBASE_VERSION / 1000}~
を見てみよう。
GAMEBASE_VERSION
を1000で割っている。1000の位を取り出している。
それが{}
という記号で挟まれていることによって、結果を表示できる状態になる。
Gamebase.csvで指定されたバージョンが『1』なら、それが格納されたGAMEBASE_VERSION
も『1』だ。
『/
』は『÷』という意味なので『1 / 1000 = 0.001
』だが、
eraは結果から小数点以下の数字を切り捨てる。結果は『0
』になる。
GAMEBASE_VERSION / 1000
を{}
で挟み、結果『0
』は数字だが、その後に続く式が文字列なので、
加算することで数字も文字列として扱われ、文字列としてVERSIONAME
に代入される。
『{~~}
』の用途その2『行の連結』は、ここではまだ関係ないので、
Wikiの説明されているページを貼っておく。
%~~%
ってなに?¶
『%~~%
』は『文字列変数の中身、あるいは文字列を使った計算式の結果をくれ』という意味だ。
数字ではなく文字列に対して使う。
要するに『{~~}
』用途その1『変数の中身、あるいは計算式の結果をくれ』の文字列版だ。
VERSIONNAME = {GAMEBASE_VERSION / 1000}.%TOSTR(GAMEBASE_VERSION % 1000 / 10,"00")%
と書かれている。{GAMEBASE_VERSION / 1000}
の次にある『.
』はただの文字列だ。
%TOSTR(GAMEBASE_VERSION % 1000 / 10,"00")%
を見てみよう。『%%
』に挟まれている。
GAMEBASE_VERSION
は数字なのに、なぜ文字列? と思うかもしれない。
GAMEBASE_VERSION % 1000 / 10
は、1000で割って余りを計算したり、それを更に10で割ったりしている。
数字でなくてはできないことだ。
そこに『TOSTR()
』が関わってくる。
TOSTR()
ってなに?¶
『文字列に変えてくれ』という意味だ。
TOSTR()
はEmueraに最初から用意されている、式中で使える関数、というものだ。
式中で使える関数には色々便利な機能のものがあるが、大量すぎて覚えるのは難しい。
デフォルトの変数名やDIM
宣言された変数名ではなく、
謎の英単語風のところはだいたい命令だが、命令には()
がつかない。
ついていたら関数だが、@
やCALL
のないところに唐突にある場合は式中で使える関数だ。
この式中で使える関数の一覧がのっているページで検索してみよう。
(この判断が正しいかはともあれ、だいたいこれで探せると思う)
命令・式中関数一覧
CTRLキーとFキーを同時押しすると、
ブラウザのページ内検索ウィンドウが表示される。
検索するとき、()
の中身まで検索しようとすると見つからない。
()
より前の単語だけ抜き出して検索しよう。
もしない場合、そのバリアントの内部でgrep検索してみよう。
処理が書かれているところを探したいので『@検索したい単語』で検索する。
見つけられたら、誰かが自作した式中で使える関数だったということだ。
(エディタにVisualStudio Code等を使っていると、関数名や式中関数名をクリックしたら
自動的にそれが記述されているファイルを開く機能を公開してくれてる人がいる)
ともあれ、TOSTR
は数字を文字列に変換する機能だとわかる。
数字にカンマをつけたり、ゼロで埋めて桁数をそろえたいときに便利な機能だ。
ここでは、
01、02、03…
という風に、数字が1桁でもゼロで埋めて2桁で表示して欲しい
という意味で、"00
"と指定している。
(こうやってゼロで埋めることをゼロパディングと読んだりする)
SIF
ってなに?¶
SIF GAMEBASE_VERSION % 10 != 0
VERSIONNAME += TOSTR(GAMEBASE_VERSION % 10)
を見てみよう。
SIF
は条件分岐というやつだ。
IF~ELSE~ENDIF
のような条件分岐の簡略化で、一行で行うIF
文だ。
SIF
は条件式が0でなければ(成立した場合)次の行を実行します。0の場合(成立しない場合)、次の行をスキップします。
と書かれている。
SIF XXXXX
の、XXXXX
のところが条件を書くところだ。
その次行が、条件が通ったときに実行する処理だ。
SIF GAMEBASE_VERSION % 10 != 0
の場合
GAMEBASE_VERSION
を10で割った余り(%で余りを計算)が、
0でなければ(!
は否定という意味。!=
だとイコールの否定、要するに同じではないという意味になる)
という意味になる。
10で割ってゼロにならないということは、1の位があるということだ。
余りは1の位の数そのものになる。
なので、
SIF GAMEBASE_VERSION % 10 != 0 ;1の位があれば
VERSIONNAME += TOSTR(GAMEBASE_VERSION % 10) ;1の位を文字列として追加してくれ
という意味になる。
※SIF
は処理が増えて行数が増えるとIF
文に書きなおさなくてはならなかったり、
コメントをつけると行がわかりにくくなったり
処理をコメントアウトすると次の行に影響したりすることから、あまり好まない人もいる。
一方で、慣れると作っているときは便利なので多用してしまいがちでもある。個々の考えによる。
補足 =
と'=
¶
VARSIONNAME =
は、今なら
VARSIONNAME '= ""
と書くこともできる。
これは元は使えなかった書き方で、Emueraが進化して使えるようになった。
文字列の代入である、ということがわかりやすい。
ただしこれをすると『文字列変数名 '= "あああ"
』のように"~~"
で囲う必要がある。
ちょっと面倒にもなるが、日本語の変数と文字列の日本語が入り乱れているときでも混乱しにくい。
また、末尾に空白が入った文字列や空白のみの文字列を代入する場合にパッと見てわかりやすい。
メイン部分の表示¶
ようやく次の処理を見てみよう。
;タイトル表示。
DRAWLINE
ALIGNMENT CENTER
PRINTFORML %GAMEBASE_TITLE%
PRINTFORML %VERSIONNAME%
PRINTFORML %GAMEBASE_AUTHOR%
PRINTFORML (%GAMEBASE_YEAR%)
PRINTL
PRINTFORML %GAMEBASE_INFO%
ALIGNMENT LEFT
DRAWLINE
とある。
DRAWLINE
って?¶
区切り線を引いて欲しいという意味だ。
シーン変更、見出し作りなどでよく使う。
DRAWLINEを使うと画面の左端から右端まで----と線を引きます。
と書かれている。
_Replace.csv
¶
DRAWLINE
は、Emueraのデフォルト設定では『-
』を繋げたような線になっている。
これを隙間のない線『─
』にしたり、
あるいは『=
』にして二重線にしたい人もいると思う。
DRAWLINE
を使ったとき表示される線を変えるにはどうしたらいいのか。
etc1821フォルダ内に_Replace.csvというファイルがある。
これをコピーしてerakanonフォルダ内CSVフォルダ内にペーストしてみよう。
;DRAWLINEの表示文字
;DRAWLINEで表示する文字
;DRAWLINE文字 , (半角文字)
;DRAWLINE文字 , +
と書かれている行がある。
;DRAWLINE文字 , +
から
『;
』を消して
DRAWLINE文字 , +
にして保存してみよう。
Emueraを起動すると、それまで
------
という線だったところが
++++++
という線になったはずだ。
これだけでも若干タイトル画面にオリジナリティが出た気がしてくる。
線の種類を使い分けたい人もいるだろう。
大見出しと小見出しで線の種類を分けたい、日付変更時だけ太い線を引きたいなど。
CUSTOMDRAWLINE <文字列>
という命令、
DRAWLINEFORM <FORM文字列>
という命令方法がある。
CUSTOMDRAWLINE ─
のように、その都度線に使いたい記号を指定して書く。
ALIGNMENT CENTER
って?¶
ALIGNMENT
アラインメントとは、並べるとか整列とかいう意味だ。
文字を左揃えにしたり、中央揃えにしたり、右揃えにしたりする指定になっている。
ALIGNMENT RIGHT ;右揃え
ALIGNMENT CENTER ;中央揃え
ALIGNMENT LEFT ;左揃え
通常は左揃えだが、ここではタイトル画面らしく中央に揃えている。
PRINTFORML
って?¶
文字列を表示する命令の一種だ。
いきなり、PRINT(|V|S|FORM|FORMS)(|K|D)(|L|W)
という謎の記述を見て、頭を抱えた人もいるかもしれない。
PRINT
自体は、文字を表示する命令だ。
PRINT
の後、半角スペースをひとつ空け、文字を書き込もう。
PRINT ああああ
のように。
そしてPRINT
の後に続く複雑ななにか。気になると思う。
PRINT
のあと、カッコが3つに別れている。
いくつかのアルファベットや単語が『|
』で区切られている。
これは、欲しい機能をPRINT
にくっつけて使えるよ。という意味だ。
この『|
』で区切られたアルファベットや単語には、それぞれ別の機能が割り当てられている。
1カッコ内の機能はひとつしか選べないが、別のカッコの機能とは組み合わせて使える。
『(|
』になっているところは、『(なし|』という意味なので、省略できる。
このように、みっつのカッコから一つだけ選んで使うこともできるし
PRINTV / PRINTS / PRINTFORM / PRINTFORMS / PRINTK / PRINTD / PRINTL / PRINTW
このように、ひとつめ、ふたつめのカッコからひとつ、選んでくっつけることもでき
PRINTVK / PRINTSK / PRINTFORMK / PRINTFORMSK / PRINTVD / PRINTSD
このように、ひとつめ、ふたつめ、みっつめのカッコからひとつずつ選んでくっつけることもできる
PRINTVKL / PRINTSKL / PRINTFORMKL / PRINTFORMSKL / PRINTVDL / PRINTSDL
ひとつめのカッコからひとつ、みっつめのカッコからひとつなどもだ。
eraは口上や地の文に、文字列変数化されたあなたやキャラの名前を多用することが多い。
そのため{~~}
や%~~%
を使えるPRINTFORM
系はよく使われる。
また、配置を整えるPRINTC
系。
PRINTBUTTON
系で選択肢を表示してINPUT
で受け取る。
ランダムテキスト表示にPRINTDATA
系を使う。
などなど、PRINT
関連は便利で基礎的な情報だ。
ここでは『PRINTFORML
』なので、
『PRINT
』文字を表示するよ。という命令に加えて、
『FORM
』書式付文字を使うよ。
『L
』改行してねクリックはいらないよ。
という機能を組み合わせていることになる。
各表示¶
前半、Gamebase.csvについて話したが、その情報が格納されている変数が羅列されている。
中身はここに書かれている通りだ。
こうしてタイトル画面でGamebase.csvの情報を利用することにより、
Gamebase.csvだけ修正すれば、タイトル画面を弄らなくても更新できることになる。
DRAWLINE
ALIGNMENT CENTER
PRINTFORML %GAMEBASE_TITLE%
PRINTFORML %VERSIONNAME%
PRINTFORML %GAMEBASE_AUTHOR%
PRINTFORML (%GAMEBASE_YEAR%)
PRINTL
PRINTFORML %GAMEBASE_INFO%
ALIGNMENT LEFT
DRAWLINE
Gamebase.csvで整えた情報と、
バージョンの数字を文字列化して整えたVERSIONNAME
、
空行が欲しいところにPRINTL
を使い、
中央寄せを左寄せに直し、
もう一度区切り線を引いて、
タイトルの表示は終了だ。
独自のデザインに¶
文字を左寄せの表示形式に変えたり、欲しい情報を足したり別のところで表示したい情報を消したり、
GAMEBASE_TITLEを省いてアスキーアートに変えたり、画像を表示したり、お好みで改変するといいだろう。
フォントの表示、色変え、特殊な表示など
画像の表示
また、WINDOW_TITLE
は代入可能。
左上のウィンドウタイトルに何か表示を加えたりしても良いかもしれない。
少女祈祷中...
のローディング表示を_Replace.csvで変更したりもできる。
選択肢¶
見た目は弄れるようになってきたと思うが、
ボタンを表示して選んでもらう、ということができないとゲームにはしにくい。
続きを見ていこう。
タイトル画面だからか、_Replace.csvを利用したやや特殊なボタンになっている。
;選択肢表示
$TITLE_SELECT
PRINTSL "[0] " + GETCONFIGS("システムメニュー0");
PRINTSL "[1] " + GETCONFIGS("システムメニュー1");
$TITLE_SELECT
¶
ここまでの説明だと
$TITLE_SELECT
というのが見慣れない行だ。
処理は基本的に上から下へ流れるのだが、
行ったり来たりさせたり、同じところをグルグル回らせることもできる。
『$好きなラベル名』と書くと、そこに『ラベル』を貼ることができる。
本の重要なところに貼っておく付箋や、チャットツールのピンようなものだ。
『GOTO 好きなラベル名
』と同じ関数内の他の場所に書くと、指名したラベルのところへ戻れる。
ここはロード画面からロードせず戻ってきたとき、
もう一度ボタンを表示するための戻り先として貼られているラベルのようだ。
GOTO
文は可読性を損ないやすいため、入れ子ループから一気に抜け出す場合以外は、
できるだけ使わないほうが良いそうだ。LOOP
文かWHILE
文で置き換えることを推奨されている。
少し難しいかもしれないが理解はできなくてもいいので
『スパゲティプログラム』あるいは『スパゲティコード』などで検索してみよう。
ということなので、繰り返し処理の書き方も教わろう。
よくわからない場合は、わかるまでとりあえずそのままお借りしよう。
ボタン¶
PRINTSL "[0] " + GETCONFIGS("システムメニュー0");
PRINTSL "[1] " + GETCONFIGS("システムメニュー1");
『GETCONFIGS()
』を使用した少々変則的なボタンだ。
PRINTSL
は、
文字を表示してくれる『PRINT
』
文字列式を表示してくれる『S
』
クリックなしで改行してくれる『L
』
を組み合わせた命令だ。
文字を"~~"
で囲み、文字列式に足して表示している。
そして『GETCONFIGS()
』という式中で使える関数を使って、
_Replace.csvのデータを呼び出している。
『GETCONFIGS()
』は『replace.csvの設定項目を整数または文字列で取得』する。
_Replace.csvを開いてみると、
;タイトルでのシステムメニュー表示1
;起動画面での『[0] 最初からはじめる』の文字列部分
;システムメニュー0 , (文字列)
システムメニュー0 , 最初から調教
;タイトルでのシステムメニュー表示2
;起動画面での『[1] ロードしてはじめる』の文字列部分
;システムメニュー1 , (文字列)
システムメニュー1 , 調教の続きを行う
と書かれている。
;が行頭についているところはコメントなので、読み込みされない説明文だ。つまり
システムメニュー0 , 最初から調教
システムメニュー1 , 調教の続きを行う
を置き換えれば、
『最初から調教』を『Game Start』に変えたりできるということだ。
[0]
や[1]
についてはEmueraWikiのPRINTBUTTON
命令に書かれていることを読むと
ボタン表示について全体的に書かれているので把握しやすいかもしれない。
選択結果¶
次を見てみよう。
$TITLE_INPUT
INPUT
IF RESULT == 0
RESETDATA
;ADDDEFCHARAはeramakerの初期化処理を再現するために存在する専用の関数です
;他の場面ではADDCHARAを使用してください
ADDDEFCHARA
;BEGINWORD '= "FIRST"
;CALL MAIN_LOOP
BEGIN FIRST
ELSEIF RESULT == 1
LOADGAME
GOTO TITLE_SELECT
;LOADGAME_EXでLOADを行わずに戻ってきた場合、もう一度選択しなおす。
ELSE
REUSELASTLINE 無効な値です
GOTO TITLE_INPUT
ENDIF
INPUT
¶
INPUT
は、入力を待て、という命令だ。
ボタンを出したら必ずどこかでこれを出す。
でないとゲームが勝手に進んでいくのでプレイヤーはボタンを選べない。
手で入力して0と入力した場合、
入力値として0の指定されたボタンをマウスでクリックした場合、
どちらも同じように0を入力したとみなされる。
なので、マウスでボタンをクリックされる、
あるいは、番号を手入力されてエンターキーを押される、
どちらかの操作をされるまで、待機せよという命令になる。
文字列を受け取りたい場合は
INPUTS
という命令もある。
INPUT 0
と書くと、
何も入力せずエンターキーをクリックしたとき、0が入力される。
『エンターキー押しっぱなしにしたら大量の選択肢に全て0を返して流す』
といった操作が可能になり、テストプレイ時に便利だ。
『$TITLE_INPUT
』は『$TITLE_SELECT
』と同じラベルだ。
無効な値だったとき、もう一度入力待ちするために呼ばれるので
INPUT
の上の行に置かれている。
IF¶
これは『IF文』とか『条件式』とか『分岐』とか『条件分岐』とか呼ばれるものだ。
「もし~なら、~しろ」と命令をする。
ゲームの大半は条件分岐によって作られていると言っても過言ではない。
もし好感度が1000をこえたら恋慕をつける。
もし所持金が1億円をこえたらゲームをクリアする。
などなど。
オープニングで目標を提示する。
プレイヤーがボタンを操作したら、結果としてステータス値を変更する。
条件を達成したらエンディングを表示する。
という流れがゲームの基本処理だ。
使い方その1
IF 条件
条件が成立していたときの内容
ENDIF
使い方その2
IF 条件
条件が成立していたときの内容
ELSE
条件が成立しなかったときの内容
ENDIF
使い方その3
IF 条件その1
条件その1が成立していたときの内容
ELSEIF 条件その2
条件その2が成立していたときの内容
ELSE
条件その1もその2も成立しなかったときの内容
ENDIF
ELSEIF
はいくつでも指定できる。
ちなみに『IF 条件
』の次行に、行頭空欄がある。
ここはタブキーを押している。
IF
文はマトリョーシカのように、IF
文の中に更にIF
文が入ることがある。
入れ子構造とか呼ぶのだが、もしこれが全て行頭から始まっていたら大変わかりにくい。
そこでIF
文の中に書く処理は、必ずタブキーを一回押して行頭を下げる。
1タブ下げたところにまたIF文を書いたら、その処理はまた1タブ行頭を下げる。
といったことをして、入れ子構造をわかりやすくする。
(入れ子はいくら形を整えても複雑なので、避けられるなら避けたほうがいい。
また、完全な新バリアントを作るなら半角スペースの利用も考えられる。
大手最新のコーディングルールではタブを使わず半角スペースを使用するよう指定されていたりして、この場合、スペースの数まで用途に応じて具体的に決まっていたりする。
しかし、整合性がとれていないことが一番わかりにくい。
そのためタブが使用されている既存作品をお借りするときはタブを使ったほうが良い)
行頭の位置を周りの文章よりも下げることを『字下げ』とか『インデント』と呼ぶ。
入れ子のIF
文が大量かつインデントを揃えていないパッチはときどき、製作仲間を発狂させる。
IF
文を書くときは注意しよう。
見たことのある人もいるかもしれないが、eraの場合は
『数百個あるコマンドの数だけ条件分岐がある』になりかねない。
これが途中でどこか一つでもずれると、続きが全部ずれてしまうのだ。
また『ひとつの変数に対し、中身の数字が1のとき、2のとき、3のとき……』
のような条件分岐を行いたい場合は『SELECTCASE
』文で条件式を略すことがおすすめされる。
こちらで紹介してくれている。
システム改造Q&A→基礎知識→IF・ELSEIF
のかたまりはSELECTCASE
文に出来るかも
ちょうど今見ているINPUT
のRESULT
分岐などはSELECTCASE
文にしやすいところだ。
試してみてもいいかもしれない。
RESULT == 0
¶
条件が『RESULT == 0
』になっている。
唐突に出てきた『RESULT
』は、最初から用意されている変数だ。
『INPUT
』でプレイヤーによって選択されたボタンや手入力の入力値は
この『RESULT
』に自動的に保存される。
(INPUT
に限らず、関数の『RETURN なんとか
』を受け取ったりもする)
この『RESULT
』は非常によく使われるので中身が入れ替わりやすい。
なので受け取ったらすぐ、自前で作ったDIM
変数に保存して
そちらを使う癖をつけたほうが良いらしい。
複雑化してる最近のeraではRETURN
系はRESULT
がすぐ迷子になるので
RESULT
で受け取って保存して使うのは不具合の原因にもなりうる。
これを#DIM REF
で定義できる参照型変数で解決できる場面もある。
本来はプライベート変数(LOCAL
変数)は複数の関数では共有できないが、
この参照型変数を引数に指定すれば関数内での代入等が呼び出し元の関数に反映される
できるだけ式中関数を使えるときはそちらで、というアドバイスもこちらに紹介されている。
EmueraWikiの「式中で使える関数」の項には
RESULT
やRESULTS
への代入は行われません
と書かれているが、例外がある。
「CHKDATA()
」「CHKCHARADATA()
」「FIND_CHARADATA()
」がこれにあたる。
また、式中関数内なら絶対にRESULT
が書き換えられないわけでもなく、RESULT
変数を使用する命令を使えば普通に書き換えられてしまう。
CALL
も使ってない、代入したわけでもない、数行のコードなのに何故かうまく動かない、そんな時はRESULT
の誤爆を疑ってみよう。
ここではINPUT
直後の分岐に使われていて、
上書きされる心配はなさそうなのでそのまま進める。
『RESULT == 0
』は『INPUTの入力結果が0だったなら』
ということなので、
『最初から調教する』
が選ばれたら、という意味になる。
RESETDATA
¶
『最初から調教する』が選ばれた場合に行う処理を見ていこう。
RESETDATA
そのまま、データをリセットして欲しいという命令だ。
これを命令しておかないと、すでにゲームで遊んでから
『タイトルに戻る』で戻ってきた場合に、
他のデータが残ってしまったりする。
ADDDEFCHARA
¶
;ADDDEFCHARAはeramakerの初期化処理を再現するために存在する専用の関数です
;他の場面ではADDCHARAを使用してください
と書かれている。
eramakerとの互換性を保つための命令だ。CSVの存在するキャラを一気に登録する。
CSVにキャラクターデータを追加しても、
こうして読み込まなければキャラは追加されない。
バリアントによっては初めからADDCHARA
で設定している場合もある。
空のキャラを作るADDVOIDCHARA
を用意し、後から設定を足してカスタムキャラにする場合もある。
CSV番号は1,3,7
等とばして設定することもできるが、
キャラが登録されるときは詰めて登録される。
CFLAG
とかBASE
といった、初めから用意されているキャラ用のデータを扱うとき
指定するキャラ番号は、CSV番号ではなく、登録された順番のほうになる。
(CSV番号のほうはEmueraWikiなどでも「NO
(Numberの意)」と呼ばれることもある。後者は「登録番号」と呼ばれることもある)
BEGINWORD '= "FIRST"
¶
次の行を見てみよう。
BEGINWORD '= "FIRST"
CALL MAIN_LOOP
今見ている処理は、SYSTEM_FLOW.ERBから抜き出してきたものだ。
SYSTEM_FLOW.ERBは、Emueraでの一連の流れを案内してくれるファイルだ。
『BEGINWORD
』は、処理に必要で作った変数というよりは、
案内しやすくするために作ってくれた変数である。
『BEGINWORD
』が宣言されている場所は、『SYSTEM_FLOW.ERH』だ。
拡張子が『.ERH』になっているファイルは、
関数内だけではなくあちこちの関数で使いたいDIM
の宣言を書くファイルだ。
etc1821フォルダから、SYSTEM_FLOW.ERHをコピーし、
erakanonフォルダのERBフォルダにペーストすれば動くようになるが、
ここでは行わない。
今回はフローをたどろうという話ではなく、バニラ環境を作ろうという趣旨なので
BEGIN FIRST
に書き換えてみよう。
BEGINWORD '= "FIRST"
CALL MAIN_LOOP
を
BEGIN FIRST
にしてみよう。
ゲームを起動して、『[0]最初から調教
』を選んだら、
@SYSTEM_TITLE
をつけ足してから起きていたエラーが消えて
ゲームが始まるようになったはずだ。
ELSEIF RESULT == 1
¶
次の行を見てみよう。
ELSEIF RESULT == 1
CALL LOADGAME_EX
GOTO TITLE_SELECT
;LOADGAME_EXでLOADを行わずに戻ってきた場合、もう一度選択しなおす。
ELSEIF RESULT == 1
は、
[1] 調教の続き
を行う
が選ばれた場合、という意味になる。
CALL XXXX
というのは、関数(@なんとか)を呼び出す命令だ。
『@LOADGAME_EX
』という関数を呼び出して欲しいという意味になる。
こちらも『SYSTEM_FLOW.ERB』内にある関数の呼び出しなので、
『@LOADGAME_EX
』をお借りしたい場合はコピーしてこよう。
Emuera本家のetcフォルダ以外に、eraバリアントには
CCライセンスで解放してくれている関数がたくさんあり、
それらをライセンスごとコピーしてお借りすることで
使わせてもらえることが多い。
1から作る場合でもありがたくお借りできると思う。
バニラデフォルトのシステムをお借りしたい場合は、
ELSEIF RESULT == 1
LOADGAME
GOTO TITLE_SELECT
と書きかえれば動くようになる。
『GOTO TITLE_SELECT
』は『$TITLE_SELECT
』の項でも書いたが
ロードせずタイトル画面に戻ってきたとき、再表示するために戻る命令だ。
ELSE
¶
ELSE
REUSELASTLINE 無効な値です
GOTO TITLE_INPUT
ENDIF
ELSE
はそれ以外、という意味になる。
ここでは案内のためにだろうか『REUSELASTLINE
』という、
最終行を指定した書式付き文字列で書き換える命令で
無効な値であることを表示してくれている。
手入力を無視したい場合は問答無用で戻してしまってもかまわないと思う。
ENDIF
¶
IF
文はENDIF
で終了する。
SIF
文と違って必ず対応するENDIF
が必要なので注意。
GOTO TITLE_INPUT
は、ロードのときと違ってボタンが生きているので
入力待機まで戻るだけのようだ。
よくある誤りを読もう¶
間違いやすいことを書いてくれている。詰まったときのために目を通してみよう。
よくある誤り
おわりに¶
タイトル画面を追加しバニラにつなげるところまで作業した。
eramaker側の処理の調べ方、最新化するための非推奨変数の調べ方、
Emueraの命令や式中関数の調べ方などを案内できただろうか?
書いている本人もいまだにわかっていないことがたくさんある。
わからないことをどう調べたらいいのか、それを知ることが大事だと思う。
慣れたつもりでも盲点は多い。いつまでも初心を失わないようにしたい。
eraは調教シミュレーターなので、本来RPGやマップや戦略はない。
ゲームを作るには、ツールの使い方だけではなく、
レベルデザインや経路探索や思考ロジックなどを知る必要があり、eraはそれらを教えてはくれない。
バニラやツールも含めて、すべて有志のかたがそれぞれに学んで作り出してくれた機能だ。称えたい。
あなたが作りたいものを作る足掛かりになることを願う。
次のページ→ERB製作実践編