マクロのメリット・デメリットとマクロ化のコツ的なもの【ティラノスクリプト】
ティラノスクリプトには「マクロ」という機能があります。
これは、複数のタグをまとめてひとつのタグとして記述できるというものです。
しかしこのマクロ、プログラムというものに馴染みのない方だと利点や使い方がいまひとつピンとこないかもしれません。
ということで、今回はマクロを使うメリットとデメリット、そしてマクロ化するべき処理やマクロ化のコツなどを書いていきます。
マクロのメリット
まずはメリットを見ていきましょう。
マクロを使うメリットはだいたいこんな感じかなと思います。
複数の処理をひとつにまとめて記述できる
わかりやすいメリットですね。
キャラクターの登場や場面転換など、同じような処理をするものをマクロにすることで使いまわしができるようになります。
これをマクロ化せず、いちいちタグを記述していた場合、毎度その処理をコピペしなければいけません。これは面倒ですよね。
修正が容易
個人的にマクロを使う最大のメリットだと思います。
共通の演出や処理をマクロにすることで、その処理に変更が入った場合でもマクロを変更するだけですべての処理が変更できます。
マクロ化していなかった場合、すべての処理を変更しなければなりません。一括置換などの方法もありますが、Grep検索して置換するよりマクロの一箇所だけ修正する方がずっと楽ですしミスも起きません。
(きちんと管理できれば)スクリプトの可読性が上がる
これはカッコ書きの部分が重要なんですが…
きちんとマクロの命名などを管理できれば、スクリプトファイルが見やすく、わかりやすくなります。
たとえば、場面転換用のマクロを[scene_chage]、キャラクターA登場用のマクロを[a_show]のように、一見してわかる名前をつけてやれば、スクリプト中でそのマクロが出てきたときにもわかりやすい、ということです。
例えば同じ処理をするとして、マクロを使う場合と使わない場合で、以下のように記述の違いがあります。
;場面転換マクロ
[scene_change]
;タグで記述
[free layer=base]
[free layer=0]
[free layer=1]
[free layer=2]
[cm]
マクロで記述した例とそうでない例、どちらが読みやすいでしょうか。
場面転換の都度、この5つのタグをコピペするのと、マクロをひとつ記述するの、どちらが作業の効率化になるでしょうか。
答えは圧倒的にマクロを使う方ですよね。
バグの発生を抑えられる
同じ処理をコピペしない、ということは、バグの発生を抑えられるということでもあります。
複数コピペした同じ処理を修正するときに、ある部分は修正したけど別の部分は修正し忘れた、ということがなくなります。
そして修正箇所が減るということは、その分テストプレイをする箇所も減るということです。
作業効率化
前述したことすべてこの一言に集約できるのですが、マクロというのはスクリプト作業を効率化するためのツールです。
ゲーム制作で時間をかけるべきは単調なコピペ作業ではなく、演出やユーザー体験の向上といったクリエイティブな部分であるべきです。
セリフ末尾の[l]を[p]に書き換える作業なんて即刻やめて、まずはマクロを作りましょう。
マクロのデメリット
何事もメリットがあればデメリットがあります。
マクロにおいてもそれは同様です。
いちいち定義しないといけない
マクロなので当然ですが、最初に定義することが必要です。
定義するマクロの数が増えるだけ定義用のシナリオファイルも長くなっていきますので、可読性を考えると適度に分ける必要は生まれてくるでしょう。
きちんと管理しないと何がなんだかわからなくなる
行き当たりばったりにマクロを作っているとよく起きることですが、似たような名前のマクロが複数できてしまう、というのがあります。
たとえば画面上の画像などを全消しするマクロが[all_delete]、キャラを全退場させるマクロが[delete_all]、なんてなると地獄の始まりです。
また、マクロの命名だけでなく、マクロそのものの設計も考える必要があります。
キャラAを登場させるマクロが[a_show]、キャラAを画面中央に表示させるマクロが[a_show_center]、キャラAを画面右端に表示させるマクロが[a_show_right]…なんてやっていると、マクロがいくらあっても足りません。
きちんとマクロの機能を活用して、効率的なマクロ設計を行いましょう。
マクロを作るためにVBAのマクロを作る、とかやりだしたらそれはマクロ設計がおかしいです。
マクロ化するべき処理とは
さて、ここまでマクロのメリット・デメリットを見てきました。
では実際にマクロを作る…といきたいところですが、その前に「マクロ化するべき処理とは」を考えてみましょう。
原則はこれだけです。
ただ、ちょっと抽象的な説明ではあるので具体例を挙げてみましょう。
①複数回使用する処理
例えば場面転換など、「同じタグの組み合わせ」の処理はこれに当てはまります。
また、「同じタグ、同じパラメータの組み合わせ」もこれです。
たとえばキャラAを表示するときに、[chara_show name=a]といちいち指定するより、[a_show]というマクロを作ってしまったほうが楽になる場合もあります。
②制作中に変更の可能性がある処理
これは、①の前提を満たす場合、という条件がつきます。
一度だけ使う処理なら、いちいちマクロ化せずシナリオにベタ書きで構いませんからね。
複数回使用する処理、かつ変更の可能性がある処理、はマクロ化の優先度が高いです。
ただ、変更の可能性が高い低いというのは、実際に作りはじめてみないとわからないところでもあります。
一応、何本かゲームを作ってみるとどのへんに変更が発生しやすいかわかってこなくもないのですが…
私個人の感覚としては、以下の部分で変更が発生しやすい気がしています。
シーン開始時・終了時の定義は難しいのですが、ひとまずは「背景が切り替わるタイミング」と考えておいてください。
メッセージ開始・終了時とは、これです。
#キャラA
;ここがメッセージ開始時
セリフだよ!
;ここがメッセージ終了時
特にメッセージ終了時は、最初は[l]タグを一括して挿入していたのに、あとから[p]タグに変えることになった…というようなことがありませんか?私はあります。
マクロ化のコツ
マクロ化するべき処理の条件を理解したところで、実際にマクロを作ってみましょう。
ちなみにマクロの作り方・使い方に関して、公式の説明はここにあります。
公式の説明は熟読しておきましょう。
公式ドキュメントなんてなんぼ読んでもいいですからね!
さて、マクロを作るとき、まずはじめに考えるべきは「マクロの粒度」です。
ただ手当たりしだいに似たような処理をマクロ化してはいけません。それは地獄の始まりです。
まずは小さい単位から始めましょう。
基本的なマクロを作る
例えば背景変更の処理です。
[bg storage=test.png time=500]
[bg]タグは、そのまま使ってもいいのですが、画像フェードの時間が初期値では3000ミリ秒となっており、ちょっと遅すぎます。
フェード時間は基本的に500ミリ秒くらいにしたい…というときに、いちいち上記のようにtimeパラメータを指定するのは面倒ですよね。
それくらい別に…と思った方もいるかも知れません。
しかし背景変更は、ノベルゲームにおいてはキャラクターの表情差分変更と並んで頻出する処理です。
ひとつのゲーム中に何十回、もしかしたら何百回出てくる処理の、「time=500」という記述を打つ時間を削ることができれば、明確に作業時間が減ります。
スクリプト作業、ひいてはプログラムにおいては、怠惰はもっとも崇敬するべき美徳です。
楽をする労力を惜しんではいけないのです。
さて、それでは「time=500」を[bg]タグの初期値として持つマクロを作ってみましょう。
こんな感じです。
[macro name=bgi]
[bg storage="test.png" time=500]
[endmacro]
はい、マクロができました!
これで「[bgi]」と打つだけで背景を変更することができます。
「[bg storage="test.png" time=500]」に比べれば、削減できた文字数は数えるまでもありませんね!
パラメータを使ってみる
いやいやいや、ちょっと待ってよ、という方もいるでしょう。
先程のマクロではtimeパラメータの初期値を500に変えましたが、同時にstorageパラメータも固定になってしまっています。
これでは、あるひとつの背景にしか切り替えられませんし、背景の数だけマクロを作ることになってしまいます。
そんなの現実的じゃありませんよね。
そこで知っておきたいのが、マクロの「パラメータ」です。
タグを使うときにも、様々なパラメータを使っていますが、あれと同じ感覚です。
先程の背景変更マクロを書き換えてみましょう。
[macro name=bgi]
[bg storage="%storage" time=500]
[endmacro]
[bg]タグのstorageパラメータに不思議な値が指定されていますね。
この「%storage」とは、「bgiマクロにstorageパラメータとして指定された値」のことです。
つまり、↓のようにマクロを記述すると
[bgi storage="room.png"]
マクロ内では↓のように指定されたのと同じ動きをします。
[macro name=bgi]
[bg storage="room.png" time=500]
[endmacro]
このようにマクロを作ってやることで、背景画像が変わってもいちいち別にマクロを作る必要はなくなります。
パラメータに初期値を設定する
さて、これで[bgi]マクロにstorageパラメータが指定できるようになりました。
しかしこのマクロ、もう少し改善の余地があります。
timeパラメータの値は500で固定ですが、場面によってはもっとゆっくり、あるいは早く背景を切り替えたいときがありますよね。
このように、「基本的にはこの値なんだけど、場合によっては別の値を指定したい」というときは、こうします。
[macro name=bgi]
[bg storage="%storage" time="%time|500"]
[endmacro]
はい、timeパラメータの値がまた不思議な値になっています。
「%time」とは、storageパラメータと同じです。[bgi]タグで指定したtimeパラメータの値、という意味ですね。
それでは、「|500」、これは何か。
これは、[bgi]タグでtimeパラメータが指定されなかった場合にtimeパラメータに指定される値、つまりは初期値です。
ちなみに「|」は、WindowsPCならShiftキーを押しながら「¥」のキーを押すことで入力できます。
これでさらに[bgi]マクロの使い勝手が上がりました!
パラメータに応じて処理を分ける
ここからは応用編です。
例えば、効果音を再生するマクロを考えてみます。
効果音を再生するタグは[playse]タグです。[playse]タグには、音声を再生するバッファを指定できる「buf」パラメータがあります。
通常の効果音を再生するときには0バッファ、環境音などループする効果音を再生するときには1バッファを使用し、効果音同士がバッティングしないようにしたい。
そんなときには、どのようにマクロを作ればいいでしょうか。
単純に、通常の効果音を再生するマクロ、ループ効果音を再生するマクロ、と分けるのも一つの手です。
しかし、効果音を挿入するときに、いちいち「これは通常の効果音だからこのマクロ、こっちはループするからこのマクロ…」という判断が必要になるのはよくありません。ミスのもとです。
マクロは作業効率化のためのものです。作業効率化とは、最終的にはバグの少ない、品質の高いゲームをつくることです。
できれば「効果音再生用マクロ」はひとつにまとめて、マクロ内で「通常の効果音か、ループする効果音か」を判断したいところです。
実際に書いてみると、だいたいこんな感じです。
[macro name=pse]
[if exp="mp.loop=='true'"]
[playse storage="%storage" loop="%loop" buf=1]
[else]
[playse storage="%storage" buf=0]
[endif]
[if]タグでループするとき、しないときで[playse]タグを分けているのがわかると思います。
[if exp="mp.loop=='true'"]
[if]タグで指定している条件式で使っている「mp.loop」とはなんでしょうか。
これは、「pseマクロに渡したloopパラメータの値」です。つまり、「%loop」と同じ意味です。
それでは何が違うのかと言うと、「mp.loop」はJavaScriptで用いる書き方で、「%loop」はティラノスクリプトのタグで使える書き方です。
[if]タグのexpパラメータで指定するのはJavaScript式なので、「mp.loop」という指定方法を使っているわけです。
ちなみに、「mp.loop=='true'」というふうに、「true」をシングルクォーテーションで囲っていますね。
これは、パラメータとして渡される値はすべて文字列になるため、真偽値ではなく文字列として比較しているのです。
まとめ
マクロを使うメリットデメリットから、設計のコツ、実際の作り方まで解説してみました。
いきなり巨大なマクロを作るのは混乱のもとなので、まずは簡単なタグの組み合わせやパラメータの指定から初めて、徐々に規模の大きいマクロが作れるようになれればいいと思います。
そしてマクロを作っていく中で、「この処理をマクロ化することでどれくらい作業が効率化できるか」「このマクロは使いやすいものになっているか」を意識できれば、より良いマクロ設計ができるようになると思います。
最後に…
マクロを作ったら必ずテストをしよう!
サポートをしていただけると私がたいへんよろこびます。 ちなみに欲しい物リストはこちら→https://www.amazon.jp/hz/wishlist/ls/2DBRPE55L3SQC?ref_=wl_share