エフアンダーバー

個人開発の記録

RPGツクールでローグライクな雰囲気を醸してみた

夏の終わりにRPGツクールMVのセールをしていたので思わず衝動買い。 おまけでシレンのグラフィックがついてきたので、 これはローグライクゲームをつくれというメッセージだと受け取り、プラグインの製作に取り掛かりました。

実は人生初ツクールです。
前々から気になってはいたもののコスパの面で二の足を踏んでいました。
そんなわけでツクール初心者なので、なにか見当違いなこと書くかもしれませんが、 その辺は温かい目でスルーしてください。

【追記 2016/12/01】続編書きました。

www.f-sp.com

RPGツクールのプラグイン

RPGツクールのプラグインというので、 最初はScratchプラグラミンのようなものを想像していたのですが、 どうやらそのような機能はツクール内では「イベント」として提供されているようです。

ではプラグインとは何を指すのか、 ということで、デフォルトで入っているプラグインを覗いてみたところ飛び込んできたのが次のコード。

var _Scene_Menu_create = Scene_Menu.prototype.create;
Scene_Menu.prototype.create = function() {
  _Scene_Menu_create.call(this);

  // 略...
};

これは・・・プラグイン?

どうも自分の想像していた拡張ポイントにイベントハンドラを設定するような方式ではなく、 好きな関数を置き換えてどうぞという非常に自由度の高いAPIフック的な方式らしいです。

言語は闇の深いJavaScript。 マルチプラットフォームが叫ばれる昨今、選択肢がないので仕方ないといえば仕方ないですが。

しかし、実際にプラグインを書き始めてみるとそんなことよりなによりもドキュメントがないことが非常につらい。 一応ヘルプの付録にリファレンスらしきものがついているのですが、 ほんの一部のクラスしか書かれていない上に、識別子についての説明が一行書いてあるくらいなのでほぼ役には立ちません *1。 実質ドキュメントはソースコードです。 そして、JavaScriptなので定義や参照箇所の自動検出がうまく働きません。

ただそんな状況を鑑みてか、ソースコードは比較的きれいに整理されているため、 当たりをつけて検索をかければ動作がだいたいわかるようにはなっているようです。 まあ、その当たりをつけられるようになるまでがとてつもなくきつかったのですが・・・。

つくったもの

そんなこんなで苦労しながら二週間ほどかけて出来上がったものがこちら。

f:id:fspace:20160922161036g:plain

ローグライクというか、不思議のダンジョンシリーズですね。

本当に雰囲気だけなので、ターン制の仕組みすらできてません。 ダンジョン生成アルゴリズムも簡易的なものです。 マップのメモ欄に<dungeon>と書くと、 マップ読み込み時にダンジョンを生成する仕様になっています。

やったことはこんな感じ。

  • プラグイン製作支援機能
  • デバッグ支援機能
  • ズーム機能
  • 八方向移動
  • 方向転換等の入力制御
  • 円形または矩形の覗き穴エフェクト
  • マップ画面へのHP等の表示
  • オートタイルの配置
  • 簡易ダンジョン生成アルゴリズムの実装

このうち、いくつかはローグライク以外でも使えそうなので一応紹介しておきます (詳細な説明はプラグインのヘルプやサンプルを参照してください)。

プラグイン製作支援機能

どうも標準のプラグイン開発環境が物足りなかったので、 欲しい機能をひとまとめにしたプラグインの製作を支援するためのプラグイン。

追加される機能は次の通り。

  • プラグインの依存および実行順序解決
  • 名前空間およびスコープ
  • シリアライズの拡張

プラグインの依存および実行順序解決

プラグインの機能を細かく分割して書いていると、別のプラグインに依存するプラグインというのがでてきます。 このとき、依存先のプラグインが存在しない場合にエラーをだしたり、 依存先のプラグインよりもあとに実行するようにしたりする必要があるのですが、 現状これをツクールエディタ上以外でやるのは手間がかかります。

そこで、これらを自動で行うための機能を実装しました。 使用方法はプラグイン内でPluginSystem.require('依存先のプラグイン名');と記述し、コールバック関数を登録するだけです。 すべてのプラグイン実行後に依存関係を考慮しながらシステムがコールバック関数を順に実行します。

名前空間およびスコープ

JavaScriptには名前空間がありません。 そのためオブジェクトそのものを名前空間として用いることがあるようなのですが、 これは階層構造を持ち始めると、支援関数なしには扱いづらいです。

そこで、階層構造を持った名前空間を扱うための名前空間オブジェクトと、 それら名前空間に定義されたオブジェクトを展開するためのスコープオブジェクトを定義しました *2。 パフォーマンスの問題はありますが、スコープオブジェクトのextract関数を呼ぶと、 特定の名前空間のオブジェクトがすべてプロパティとして定義されるため記述が楽になります。

シリアライズの拡張

RPGツクールはJavaScript標準のJSONシリアライザを用いたセーブ&ロードの仕組みを持っていますが、 この仕組みにより正しく復元するためにはコンストラクタをグローバルスコープに定義する必要があります。 これは前述の名前空間の機能と非常に相性が悪いです。

そこで、指定したクラスのコンストラクタを記憶し、 任意のクラスをシリアライズ可能にする機能を実装しました。 ついでに、"onSerialize"や"onDeserialize"という名前の関数プロパティを定義しておくと、 シリアライズ前やデシリアライズ後に自動的に呼び出されるようにしました。

デバッグ支援機能

RPGツクールにはもちろん入力を取得するための機能が備わっているのですが、 これらはゲーム実行のためにチューニングされており、 デバッグ時にちょっとした操作をするためのトリガーとしては使いづらい仕様です。

そこで、登録したコマンドを任意のタイミングで呼び出すための仕組みを実装しました。 ゲーム実行中にタブキー(変更可)を押すと、コマンド入力のためのボックスが現れます。 そこにコマンドを入力してエンターキーを押すと、コマンドが実行されます。 簡単な履歴機能も付いています。

f:id:fspace:20160922161035g:plain

ズーム機能

RPGツクールにもズーム機能はついているのですが、 これは指定した点を原点に拡大縮小する機能であり、何かに注目するときのズームとしては不適です。

作成したプラグインの提供するズーム機能は、 指定した点が画面中央に来るように画面を拡大縮小するものです。 何かに注目してほしい場合にはこちらを使うと直感的に正しくなると思います。

ちなみにどちらのズームも座標指定はスクリーン座標で行います。 これは、マップ座標に対応しようとすると、マップ画像の生成部分にまで影響が及んでしまうためです (特にプラグインでこれをやるとなると他のプラグインとの競合が発生しやすくなります)。

f:id:fspace:20160922161034g:plain

八方向移動

RPGツクールでは基本的に四方向にしか移動できません。 これはグラフィックの制作コストを抑えるという意味でよい規格化ではあるのですが、 ローグライクゲームをつくる上では非常に困ります。

作成したプラグインではこの四方向移動の制限を取っ払います。 しかし、当然斜め方向のグラフィックがないため見た目は奇妙になります。 少しでも斜めを向いているように見せかけるため、剪断変形のオプションを用意していますが、 まともな見た目にしたいのであれば、さらに改造して斜め方向のグラフィックを表示する必要があります。

このプラグインを適用するとキャラクターの向きを取得した際に八方向の値が返るようになります。 これはAPI仕様の変更であり、他のプラグインの挙動を破壊しやすいため注意が必要です。

方向転換等の入力制御

RPGツクールが想定するゲーム中において、移動と時間の流れというのは特に関係がありません。 しかし、ローグライクゲームでは移動した分だけ時間が進みます。 そのため、慎重な移動操作が要求されます。

作成したプラグインでは操作ミスを防ぐための制限や特殊な入力方法を提供します。 コントロールキーを押しながら、方向キーを入力すると移動はせずに方向転換のみ行います。 コントロールキーとシフトキーを同時押ししている状態で方向キーを入力しても上下左右へ移動しなくなります。 すなわち、八方向移動が可能な場合には斜め移動のみ可能になります。 タッチ入力でプレイヤーから一歩以上離れた位置をタップしても移動しなくなります。

ソースコード

正直、未完成品なので公開する意味もあまりないのですが、 もしかすると副産物のほうには需要があるかもしれないのでGitHubに上げておきます。

github.com

ライセンスはMITです。 ざっくり言うと、著作権表示とライセンス文章(へのリンク)を書いてくれれば自由に使っていいよ、 ただし何も保証しないし何が起きても責任はとらないよ、というライセンスです。

著作権表示とライセンス文章はプラグイン内のコメントに含めておいたので、特に気にしなくても勝手に入るはず。 READMEなんかに書く必要もありません (というか、私的に大事なのは免責のあたりなので最悪含まれてなくてもかまいません)。

開発について

とりあえずここまでで開発中止にしようかな、という感じです。

簡単にできそうなら最後まで作ってもよかったのですが、 やるべきことをいろいろと考えていたらまだひと月以上はかかりそうだったので・・・

収入になりそうなら続きを書くのも悪くないのですが、 いかんせん需要がわからないので闇雲に続けるわけにもいかず。

おわりに

正直もともとRPGツクールを画一的と馬鹿にしていたところがあったのですが、 結構プラグイン次第でどうにでもなりそうですね。 ただこのプラグイン製作のハードルが高いのが、実際のツクール製ゲームの幅が狭くなりがちな理由なのかもしれません。 あとは、デフォルト素材を多用する製作者の怠慢とかもあるか・・・

今後はプラグイン製作中にメモした内容とかを公開しようかなと思ってます。 この記事があまりに人気がないようだったらやめますが。



執筆時のRPGツクールMVのバージョン:1.3.1

*1:マップのdataプロパティに「マップデータの三次元配列」的なことが書かれているのを見たときは唖然とした(ちなみに実体は謎の整数の一次元配列)

*2:正直これを「スコープ」と呼ぶのが正しいのか怪しいところですが、他にいい名前が思いつかなかったので