プラグインコマンド集を作って、ツクラーフレンドリーについて考える

　こんにちは！　トリアコンタンといいます。
RPGツクールMVはかつてないほどに本職のエンジニアたちの好奇心を刺激したツールのようで、こうしてQiitaにアドベントカレンダーが作られ、連日のようにハイレベルな記事が投稿されています。
　それ自体はもちろん大変喜ばしいことです。ですが、一方で新作を何度重ねても依然として進化していない部分もあります。

　それは**イベントコマンド**です。

　進化していないどころか15年前に発売された2000から比べて退化している部分もあります。例えば画面の自動スクロールを一時的に禁止する「画面の固定」はツクールXPで消えて以降、復活していません。
　ツクラーとはプログラミングなしで**オリジナルのゲームを作りたい**人たちであり、ツクール本来のコンセプトもそこにあります。そして今作、RPGツクールMVでは、そんな不足気味のイベントコマンドを補う魅力的な新機能が用意されています。

　それが**プラグインコマンド**です。

#本稿の目的
1. RPGツクールMVで追加されたイベントコマンド「プラグインコマンド」を使ってイベントコマンドを拡充する。
2. そして複数の小さなプラグインコマンドを集めたプラグイン「プラグインコマンド集」を作ってみる。
3. その過程で、いかにしてツクラー目線で使い勝手のいいプラグインを作るか、コツや方法論を模索する。

#そもそもプラグインコマンドとは？
　プラグインコマンドとは、プラグイン制作者によって独自に定義できるイベントコマンドのようなものです。使う側にとって、既存のイベントコマンドがGUIベースのアプリケーションなら、プラグインコマンドはCUIベースのコマンドといえます。スクリプトと違って直接コードを記述する必要がないので、コマンドさえ覚えてしまえばjavascriptの心得がなくても気軽に扱えるのが特徴です。

**プラグインコマンドの入力フォーム**
![ScreenShot04377.png](https://qiita-image-store.s3.amazonaws.com/0/103744/3d91c118-b1dc-a448-df55-0eb6f5c6a13f.png)
テキストボックスがひとつだけ。

　プラグインコマンドのイベントが実行された場合、最初に呼ばれるのが「command356」です。
与えられたパラメータを半角スペースでsplitして、最初の1要素をcommand、残りの要素をargsに格納し、Game_Interpreter.prototype.pluginCommandを呼んでいます。

```javascript:rpg_objects.js
Game_Interpreter.prototype.command356 = function() {
    var args = this._params[0].split(" ");
    var command = args.shift();
    this.pluginCommand(command, args);
    return true;
};
```
デフォルトでは何も実装されていない。

```javascript:rpg_objects.js
Game_Interpreter.prototype.pluginCommand = function(command, args) {
    // to be overridden by plugins
};
```

#試しに簡単なものを作ってみる

　実際に新しいイベントコマンドをプラグインコマンドから作ってみましょう。今回は、HTML5のVibration APIを使用して、PS版RPGツクール4のイベントコマンド「バイブレーション」を復活させます。使い方は以下の通り非常にシンプルです。

- navigator.vibrate(1000);

　ただしAndroidのChromeやFirefoxでしか動作しません。(2015年12月時点)
　この処理をプラグインコマンド「VIBRATION」で実行できるようにするために、Game_Interpreter.prototype.pluginCommandを再定義します。

```javascript
(function () {
    var _Game_Interpreter_pluginCommand      = Game_Interpreter.prototype.pluginCommand;
    Game_Interpreter.prototype.pluginCommand = function (command, args) {
        _Game_Interpreter_pluginCommand.call(this, command, args);
        if ((command || '').toUpperCase() === 'VIBRATION') {
            if(navigator && navigator.vibrate) navigator.vibrate(args[0]);
        }
    };
})();
```

　実際にプラグインコマンドに記述する内容はこうなります。

- VIBRATION 1000

　このプラグインコマンドを実際にAndroid端末（筆者の場合はXperia Z3Compact）のChromeで実行したところ、ちゃんと端末が1秒間だけ震えるのが確認できました。
　なお、今回は簡潔に説明するためにコマンド名を「VIBRATION」と分かりやすい名称にしましたが、実際のコマンド名は競合の可能性を考慮し、慎重に決める必要があります。

#ツクラーフレンドリーを考える
　さて、前置きが長くなりましたがここからが本題です。せっかくプラグインを作成しても使って貰えなければ意味がありません。ゲーム制作者がユーザーフレンドリーについて考えるように、プラグイン制作者が考えるのがツクラーフレンドリーです。以下について考えてみましょう。

1. 複数のプラグインコマンドをひとまとめにして「プラグインコマンド集」にする
2. プラグインコマンドの動作や仕様は、できるだけツクールの既存のイベントコマンドに似せる
3. 制御文字を使ってパラメータにゲーム変数を使用できるようにする
4. 利用規約（ライセンス）を明記する

　1.について、プラグインを使う側にとってみれば導入するプラグインの数は少ないに超したことはないです。管理が面倒になる上、競合したときの対応が大変だからです。よってプラグインコマンドを呼び出さない限り普段の動作と変わらないようなプラグイン（先ほどのVIBRATIONのようなもの）は「プラグインコマンド集」として纏めてしまいましょう。

　2.について、「VIBRATION」の例では以下のような対応が考えられます。既存のイベントコマンドと動作が似ていれば迷うことなくコマンドを使うことができるはずです。

- コマンド名を全角文字（日本語）にする
- ミリ秒ではなく、フレーム(1/60秒)単位で指定できるようにする
- バイブレーションが完了するまでウェイトのオプションを付ける

　コマンド名が全角というのは抵抗があるかもしれませんが、既存のイベントコマンドは全て日本語です。多言語対応については英語、日本語で同じ機能のコマンドを別途用意するという手もあります。加えて全角スペースや全角数字も考慮できればより親切ですが、この辺は考え方次第ですね。

　3.の制御文字については特に重要です。制御文字とは文章の表示のイベントコマンドで使用できる機能で、\V[n]などと記載することでゲーム変数やアクター名などのパラメータを文章中に埋め込むことができるものです。既存のイベントコマンドの様々なパラメータについて変数指定が出来ないことは多くのツクラーにとって不満の種でした。

**制御文字の種類**
![ScreenShot04378.png](https://qiita-image-store.s3.amazonaws.com/0/103744/630cfaf5-a6de-5532-1d45-0c3dec11eae4.png)

　このうち置き換えに関係しているのは、\V[n], \N[n], \P[n], \G, \\ですね。では、その変換処理はどこに記述されているのでしょうか？　rpg_windows.jsの278行目にありました。正規表現を使ってtextに含まれる\V[n]などを実際のゲーム変数に置換しています。

```javascript:rpg_windows.js
Window_Base.prototype.convertEscapeCharacters = function(text) {
    text = text.replace(/\\/g, '\x1b');
    text = text.replace(/\x1b\x1b/g, '\\');
    text = text.replace(/\x1bV\[(\d+)\]/gi, function() {
        return $gameVariables.value(parseInt(arguments[1]));
    }.bind(this));
    text = text.replace(/\x1bV\[(\d+)\]/gi, function() {
        return $gameVariables.value(parseInt(arguments[1]));
    }.bind(this));
    text = text.replace(/\x1bN\[(\d+)\]/gi, function() {
        return this.actorName(parseInt(arguments[1]));
    }.bind(this));
    text = text.replace(/\x1bP\[(\d+)\]/gi, function() {
        return this.partyMemberName(parseInt(arguments[1]));
    }.bind(this));
    text = text.replace(/\x1bG/gi, TextManager.currencyUnit);
    return text;
};
```

　ゲーム変数の変換処理を2回行っているのは、制御文字の入れ子（\V[\V[1]]など）に対応するためです。ヘルプには記載がないようですが、意外と凝ったこともできるようですね。余談ですが、RPGツクール2000にあった「変数Aの番号の変数」を操作対象にするコマンドもRPGツクールXP以降失われました。

　とはいえ、この処理はWindow_Baseクラスのメソッドとして記述されていて、通常の方法では呼び出すことができません。ウィンドウの描画に直接関係ないユーティリティ的な処理がWindow_Baseに含まれているのは釈然としませんが、仕方がないのでこのコードをプラグインから直接呼び出せる箇所に転記しましょう。すると、先ほどの「VIBRATION」で以下のような記述が可能になります。

 - VIBRATION \V[1]

　これで、振動時間をゲーム変数から取得できるようになりました。パラメータをゲーム変数で指定できる。たったそれだけのことで作り手が想像もしなかった使い方をしてくれるものです。なので、既存のイベントコマンドのパラメータを変数指定できるようになるだけでも大きな意味があります。

4.について、ライセンスや利用規約がきちんと明記されていると使う側にとっても何がOKで何がNGなのかが分かりやすいので安心して使うことができます。なお、ツクールの公式見解ではMITライセンスが推奨されています。(2015年12月時点)

#まとめ
　javascriptとHTML5で動作するRPGツクールMVは作り方次第でなんでも実現できてしまいます。しかし今回はあくまでも裏方に徹する意義というものを強調すべく、プラグインコマンド集というかたちを採らせて頂きました。ツクールXP以降、失われたイベントコマンドもこの方法で大半は復活させることができるはずなので、需要がありそうなものからボチボチ拡充していこうと思います。
　もちろんエディタを作っている側、つまり公式にもっと頑張って欲しいという思いもありますが、まあそれは深く追及しないでおきましょう^^

　お読みいただきありがとうございました。