神無月サスケの波瀾万丈な日常

神無月サスケのツイッター(@ktakaki00)を補完する長文を書きます。

MZの可能性。MZサンプル「ルイーゼと秘密の地下室」を主に技術的側面からご紹介

この記事は、ツクールアドベントカレンダー2020の12月9日の記事になります。
12月3日にもツクールMZの紹介のような記事を執筆しておりますので、よろしければそちらもどうぞ。

最初に:ルイーゼと秘密の地下室とは


ツクールMZのサンプルゲームであり、シナリオもシステムも高く評価してくれた皆さんに感謝します。

  • シナリオについては、僕がプロットを書き、ふうきゅう氏がシナリオを書いてくれてます。今作は、僕が今まで封印していた「社会風刺」を5章に取り入れています。これはスタッフの皆さんが「入れるべき」と力説してくれたお礼です。
  • プラグイン関係はほぼ僕、サスケが書きました。どちらかというと理系の僕と、文系的な感性のあるふうきゅう氏、そして作曲のセンスのある氷石彩亜。三者三様ゆえに生み出されたクオリティだと、若干の自負はしています。
  • ゲーム作成の際にMVサンプル(エミールの小さな冒険)と同様、3人でケストナーの児童小説を参考にした部分があります。具体的には「ふたりのロッテ」「点子ちゃんとアントン」を一番重視しました。いずれもルイーゼという名前の登場人物がいたため、今回のサンプルでも、主人公はルイーゼなのです。

「ルイーゼと秘密の地下室」はSteamでも無料でプレイすることが可能です。

もう一本の柱は、氷石彩亜君原案のものだった

偶数章ではフェナック村でのライル達の活躍が見られます。ここで出てくる登場人物(ファリア、タルガなど)は旧アクツクで作成した「フェナックむら ものがたり」(2008年公開)の設定を強く意識していました。このシナリオは、音楽だけでなく、シナリオも書ける氷石彩亜君の仕事でしょう。それらを導入し、さらにシナリオのふうきゅう氏の目にもとまり、彼は積極的に氷石彩亜君のサポートをしていました。僕には音感のセンスが悪いのだけれど、それゆえに作曲方針は氷石君に決めてもらっていました。僕が注文したのは「町のフィールド曲」とか「お店の中の曲」とか「戦闘」といった漠然な要求をしていましたが、氷石君が僕の意図を読んでくれたのは大きいです。

氷石君のサイトの看板娘、クレミナも登場していますが、氷石君はそれ専用のエピソードのシナリオを書きました。特にクリア後の余章のシナリオなどは全て彼の要求に従いました。彼女専用の武器として氷石君は、クレミナには魔法剣、というこだわりがあり、僕も設定を実現するために奮闘しました。、FF5などと異なり、魔法剣呪文を唱えたそのターン敵1体をランダムで攻撃できます(これはステート付加とともに、コモンイベントを呼びだすことで実現しました)。僕、サスケは、魔法剣を導入したことがなかったため、いろんな試行錯誤をしました。
その甲斐あって、ひとまず彼の要望に応えられました。
魔法剣は、使い方によっては、バランスブレイカー的な強さ持ちますが、プレイヤーがそこに辿りつく前に試行錯誤してみてください。

ルイーゼの売り(技術関連)1:比較的賢いオートバトル

今回、タイムプログレッシブ戦闘というのがあり、FFシリーズと同様、リアルタイムで戦闘を行う設定が可能になりました。「新機能を使わないなんてありえない」という理由で、僕もTPBアクティブ、つまりコマンド入力中も敵が襲ってくる、油断ならない仕様になっていますが、今回MZサンプルが6本ありますが(僕も含む)、このうち3人がTPBアクティブを選択したようです。

自動戦闘をどう賢くしたか

今回、NPCが戦闘に参加したり、一般のコマンド入力でも、一番上に「おまかせ」があるなど、戦闘AIの登場が多いので、戦闘AIを賢くすることにも努力をしました。具体的には、ロンチプラグインにもした「SmartAutoBattle.js」がそれです。javascriptに詳しい方は、プラグインの内容を解析してみれば分かると思います。一応「ルイーゼと秘密の地下室」用にカスタマイズしていますが、何度もいろんな形で戦闘を行い、かなり最適化されていると思います。特筆すべきは以下です。

  • コアスクリプトでは勘案されなかった蘇生魔法や使用回数制限なしのアイテムを候補に入れるようにした
  • コアスクリプトでは補助魔法は一切考慮されなかったが、場合に応じてこれらを使うようにした
  • 行動前に入力されたコマンドをチェックし、無効な行動と判断されたらその場でもう一度行動選択を行う。
    • 具体例として、HP回復魔法を選択したが、行動前に別のアクターが回復をしてしまったため、既に選択したコマンドを行っても無意味……などの場合、行動直前に再度計算を行い、行動を変更するようにした。この結果、アクターは詠唱待機(魔法スキルを使う準備)のアニメだったが実際に行動したのは敵への通常攻撃だったりすることがあるが、これが原因である。
    • これを読んで「だったら全て行動直前に行動を決め、入力時には決定しなくてもよいのでは」とお考えになる方もおられるでしょうが、コアスクリプトでは入力後に行動を決めておかないとエラーが出る箇所があるため、このような方針を取っています。
    • メモの設定によって「高優先度で使わせたいスキル」を設定可能にした。前述のとおり、通常のアルゴリズムでは補助魔法をほとんど使わないが、それらの頻度を上げさせることも可能。

以上のおかげで「いいタイミングでキャラが回復や蘇生を行ってくれる」など好評をいただいていますが、個人的には、純粋なAIの視点からすると、若干邪道なことをしていると思っています。それは、「○○だったら評価値を○増やす」みたいな「行動によって直接的な数値で評価値を変更する」ことが中心になっているため、数値の増減があまりにも場当たり的なんです。経験則で決めた数値なのですが、真に本格的なAIを作りたいなら、こういう「場当たり的に決めた数値」ではなく、もっときちんとしたアルゴリズムで行動の評価値を決めているでしょう。なのでこのプラグインは、あまりよいお手本ではないことをあらかじめお断りしておきます。

ルイーゼの売り(技術関連)2:太陽や月などの魔石がメニューで合成可能

合成システム自体は、旧作MVにもありましたが、一旦町に戻り、魔法屋でしてもらう形式でした。だったら今回は、メニュー画面からいつでも合成可能にしよう、と考えてやりました。
アイテム合成シーンは、僕によるものですが、これは僕が、ツクールMZでの新機能でのシーンクラス作成に慣れるために作った、と言う側面をあります。シーンをメニューから呼び出せるので、作者である僕自身も、テストプレイの時はかなり入念にデバッグしていました。

このプラグインは、需要があるかも、と思い、ロンチプラグインにも採用しました。ItemCombineScene.js というのがそれですが、合成というより、装備やアイテムを魔石などで強化、といった方がいいと思います。しかし、もっと汎用性の高いアイテム合成プラグインはすぐ出てくるのが容易に予想できていましたので、そちらを使った方がいいかもしれません。

メニューシーンはMVより高機能なのに作成難易度はほぼ同じ

今回、メニューの全てのシーンの右上に「戻る」アイコンが付いています。しかし、これについては一切意識せずにこのシーンを作ることが出来ました。どうやら「戻る」ボタンは、現在アクティブなウィンドウのキャンセルハンドラを呼び出すようになっているのでしょう。つくづく、ユーザーフレンドリーさは失われていないと思いました。

ルイーゼの売り(技術関連)3:シンボルエンカウント

僕はもともとはランダムエンカウント派でしたが、現在ではシンボルエンカウント派になりました。これは、僕が一番ゲーム作りの参考にしているドラクエシリーズがそれを採用するようになったからです。特に7と8は3DSに移植される際に、元がランダムエンカウントだったものをシンボルエンカウントに作り直すという気合の入れよう。「今のトレンドはもはやシンボルエンカウントだ」と思い、前作、ツクールMVの「エミールの小さな冒険」から、シンボルエンカウントです。

シンボルエンカウントプラグインで実現

シンボルエンカウントは、当然ですが、イベントコマンドで実現することも可能です。しかし、ちょっと凝ったことをしたいため、それ専用のプラグインを作りました。ロンチプラグインではない、ルイーゼと秘密の地下室のプラグインフォルダにしか入っていないのですが、SymbolEncountLibMZ.js というのがそれにあたります。MZとついているように、ツクールMVでも同様なプラグインを作っており、基本的にはマイナーチェンジです。

プラグインだといろんなことが出来る

僕が敢えてプラグインを作成した理由に「普段は低位置にいるが、プレイヤーが近づくと音や視界の関係で気づかれて追跡され始める」そして「プレイヤーが一定距離以上離れると諦めて持ち場に戻る」ということがしたかったからです。前者の際には敵シンボルが「!」の吹き出しアイコンを、後者の際には(画面上のことが多いのであまり見た人はいないでしょうが)「くしゃくしゃ」のアイコンを表示し、持ち場に戻っていくことです。

こちらが強くなると敵が逃げ出すようになる

そしてこのプラグインの売りは、強くなってから序盤のダンジョンにいくなど、敵がプレイヤーが強すぎると判断した時、プレイヤーから離れていく、つまり逃げる動作を取るようになることです。そこで問題になるのが「いかにプレイヤーと敵の強さを比較するか」ですが、僕は素早さ(敏捷性)にスポットを当てました。僕のゲームでは、素早さはどのキャラでも一律レベルに比例して上がっていくため、敵グループとプレイヤーそれぞれ素早さの平均を取り、プレイヤーが8以上素早いと逃げ出す、というアルゴリズムになっています。

自分用に作ったが意外と利用者が多かったのに驚いた

さて、このプラグインは前述の通り、最初はMV用に作りましたが、「こんな設定が複雑な物、誰も使うまい」と思っていたのですが、意外にも採用している事例を見ました。MZ版に関しても興味がある人がいるらしく、「ヘルプを読んでも設定方法が分からない」という意見をムノクラ様(ツクプラMZなどの運営管理者)などからご報告いただいたこともあります。特に、0x01など、16進数リテラルをどう設定するのか、という点が多かったです。これについては、2進数に直して、合計の値を取ることで設定できるのはプログラマのほぼ常識の為、「どうせ使う人いないから」と説明を怠った部分です。「16進数 2進数 変換」などのキーワードで検索すれば出てきます。例:検索すると16進数から2進数の変換方法が出てきました。

このプラグインの機能ではなくランダム移動する敵も作った

MVの「エミールの小さな冒険」では、宝箱の近くに敵を配置し、全てアルゴリズムで制御していましたが、実況を見ると、戦闘を全て避けて初期レベルのまま第1ダンジョンをクリアしたものがありました。実は第2ダンジョンの入り口すぐに中ボスがいるのですが、初期レベルでは到底倒せません。その方の実況がそこで止まっていたのは、ここで挫折したからだと思います。この反省を生かし、今回はランダム移動(プレイヤーに近づく)し、強制的にエンカウントしやすい敵も作りました。僕はゲームバランスを取る時、「全敵シンボルと1回ずつ戦った」状態を想定して作っていたので、エンカウントを避けていた人は、後半苦労したんじゃないかな、とは思っています。

ルイーゼの売り(技術関連)4:数々のダンジョンギミック

僕は長年ゲームを作ってきましたが、ツクールMVのころから「自分のゲームにはダンジョンギミックが足りない」と思い、様々なダンジョンギミックや謎解きを追加するようになりました。これは、ドラクエシリーズが毎回悩ませてくれるギミックを毎回ダンジョンに盛り込んでいたからです。サガシリーズのように、成長システムで悩ませるゲームにはあまりギミックは必要ないと思われますが、シナリオ重視なら入れないと、と気づかせてくれました。

今回のMZサンプル「ルイーゼと秘密の地下室」ではMVサンプル(エミールの小さな冒険)で使用したギミックは原則入れていません。マンネリを避けたかったからです。

全ては紹介しきれないので、特筆性があるものなどを中心にいきます。

一筆書きが可能な絵が掲げられている部屋のみ有効

恐らくこれが、皆さんが最初に経験するパズルだと思います。いろんな図形が書かれていて、それが一筆書き出来るかどうか……。間違った部屋に入ると敵がうじゃうじゃいる地下に落とされますが、あまり悪い反響は聞かなかったところを見ると、皆苦労はしなかったんじゃないかな、と思います。

なお、「一筆書きが可能かどうか」については、実は必要十分条件があり「オイラーグラフか半オイラーグラフであれば可能、それ以外は不可能」となってます。これを知っている方なら楽勝だったでしょう。オイラーグラフの説明については、検索するとこのサイトを見つけました。オイラーグラフについて

左右のリージョンにあるタイルの数値の合計を同じにする


※画面は開発中のものです。
最初のダンジョンで、2、3、6、7の数値が書かれたタイルがあり、二つのリージョンに合計が同じ数になるようにせよ、というものがあり、その後、難易度が増したものも登場しましたね。算数が苦手な方は戸惑ったかもしれません。
これらの数値タイルは、基本的に動かせる岩と同じ仕組みを使っているので、何も難しいことはありません。MVの初心者講座の記事と全く同じことをしています。

「同じ数値になったか判定」については、これはプラグインを使っています。各イベントコマンドのメモに、など、数値を書き、「valueタグを持つ全てのイベントがいずれかのリージョンにある」「それぞれのリージョンのイベントのvalueの数値の合計が同じである」という判定を行っています。これはルイーゼのプロジェクトのプラグインフォルダにあるNumberPuzzle.jsで行っているので、興味のある方はご参考にどうぞ。

なお、そういう計算方法をしているため、恐らく複数の答えがあることもあると思います。制作者側が意図しない組み合わせで正解になる可能性もあると思います。

桂馬飛びパズル


第2章のボス直前に出てくるパズル。桂馬飛びするイベントを動かして、4つのスイッチを全部押すとクリア、というものですが、こちらも割と好評でした。これはルイーゼのプロジェクトの中のKnightMoveEvent.jsで実現しています。キーボードのみでも、マウスやスマホのタッチでも、両対応しています。

プラグイン中級者なら、大体作れそうな難易度のギミックなので、細かくは説明しませんが、このパズルが作られた経緯は、ふうきゅう氏が書いたシナリオに「桂馬飛びを使ったパズルを」とあったので、直感で作ったものです。桂馬(チェスのナイト)は移動先が8か所しかないため、移動先を表現するスプライトを表示するのはあまり難しくありませんでした。

滑る床

第4章でパーティーが二手に分かれた際、アントンのパートで出てきます。あとクリア後の余章でも出てきますね。僕はプラグインをわざわざ作って実現したのですが、ゆわかさんがイベントコマンドだけでやる方法をアドベントカレンダーの6日に載せており、明らかにこっちの方が作りやすく、ああ、僕はイベントコマンドはまだまだ上級者を名乗れない、と思った次第です。

なお、僕が作った滑る床パズルは、難易度が高かった、という声も聞かれました。でも、僕としてはドラクエ5の妖精の城のパズルでもあったため、若干難しくてもいいだろう、みたいな感じで強行しました。

二度乗ると崩れて下の階に落とされるタイルのパズル

これもドラクエ5か何かで見たことがあるものをそのまま採用したもので、ゲームでは第5章のラスボス前の最後のギミックでしたね。

※画面は開発中の物です。

これもプラグインでないと実現できないと思われます。ルイーゼのプラグインのフォルダにあるBrittleFloor.jsで実現していますが、実現には、イベントではなく、マップデータの該当箇所のタイルIDを直接書き換える、という、かなりトリッキーなことをしています。これはあまり推奨される使い方ではないと思うのですが、実際にきちんと動いたのできっと今後のバージョンでも動いてくれると思います。

なお、第2章にある、「特定の色のスイッチに触れると、同じ色のタイルが全て消える」も、マップデータを直接書き換えることで実現していますが、それもうまく作用しています。

ところで、実際にゲームで採用されているパズル、結構難易度高めに作ったつもりですが、プレイ実況を見ていると、あまり悩まずにすんなり解けていた人が多かったのが意外でした。

三原色のパズル


※画面は開発中の物です。
これはプラグインなしで、スイッチの判定だけで実現しています。

このパズルは3章のボスキャラの前で採用されましたが、最初にα版を編集部に納品した際、「テストプレイヤーが誰一人解けなかった」というご意見をいただき、急遽、ヒントをくれる存在を追加しました。最初から全部話すのはよくない、ということで、3段階でヒントを提供し、最後のヒントは答えそのものを言わせたつもりですが、それでも難しい、という意見も拝受しております。

実際、RPGアツマール版でのコメントを見ていても、このパズルのマップで「難しい」という意見がかなり多く、ちょっと難しくしすぎたかな、と反省しています。

ルイーゼの売り(文系関連):シナリオテキストの改善

イベント打ち込みは、主にふうきゅう氏と僕の二人で手分けしました。些細なミスこそあれど、大きな問題が起きなかった奇跡に感謝。
そして一通りβ1版が仕上がった頃、ふうきゅう氏は僕の台詞にも色添えを添えてくれました。ルイーゼのシナリオで悪い評価を寡聞にして聞いたことがありませんが、やはりそれも、ふうきゅうマジックと言っていいでしょう。いいスタッフに目覚めて僕は幸せ者です。

ルイーゼの売り(音楽関係):氷石彩亜君のこだわり

MVサンプル「エミールの小さな冒険」では「汎用的に使えるように敢えてテーマを設定しませんでした。しかし今回の「ルイーゼと秘密の地下室」では、氷石イズム、すなわち、多くの曲でメインメロディがベースになって、一通りの曲を作りたいと話したので、即OKしました。

僕としては、これが氷石君がやりたいことなんだと思い、BGMやMEの選定は熟慮して決めました。どんな感じなのかは、実際にプレイしていただけると分かると思います。

終わりに

他にも探せばいろいろ出てきそうですが、特に印象に残っている物をピックアップしました。この記事を読まれた中で、JavaScriptに詳しい、ゲームが作りたい、という方は、ツクールMZのサンプルゲームのプラグインを解析してくれれば、参考になるでしょう。