RPGツクールMVプロジェクトをバージョン管理したい話

この記事は [RPG ツクールMV Advent Calendar 2016](http://www.adventar.org/calendars/1732) の 8 日目の記事です。

こんにちは、残念なことに自分ではまったく RPG をツクっていない人です。
どちらかというと Web 系エンジニアとして、エンジンが js になった RPG ツクール MV のことが気になっていて、たまにチラ見しているという感じですね。

ですので、今回の記事もツクラー視点というかプログラマー寄りなお話になってしまっている点をご容赦ください。

# JSON、最高

個人的に RPG ツクール MV で良くなったと感じている点に、RPG ツクールの本体（以下「ツクールエディタ」）から参照・編集することになるデータの利用性が向上したことがあります。
具体的には、プロジェクトフォルダの `data/` 以下に生な各種データが JSON でずらっと並んでいる、という構成になった点ですね。

```
$ ls -l data/

-rw-r--r--  1 stak  staff    1000 12  8 22:22 Actors.json
-rw-r--r--  1 stak  staff  382236 12  8 22:22 Animations.json
-rw-r--r--  1 stak  staff     710 12  8 22:22 Armors.json
-rw-r--r--  1 stak  staff   13657 12  8 22:22 Classes.json
-rw-r--r--  1 stak  staff     376 12  8 22:22 CommonEvents.json
-rw-r--r--  1 stak  staff    1890 12  8 22:22 Enemies.json
-rw-r--r--  1 stak  staff    1756 12  8 22:22 Items.json
-rw-r--r--  1 stak  staff     104 12  8 22:22 MapInfos.json
-rw-r--r--  1 stak  staff    4505 12  8 22:22 Skills.json
-rw-r--r--  1 stak  staff    4675 12  8 22:22 States.json
-rw-r--r--  1 stak  staff    6444 12  8 22:22 System.json
-rw-r--r--  1 stak  staff  246742 12  8 22:22 Tilesets.json
-rw-r--r--  1 stak  staff    1517 12  8 22:22 Troops.json
-rw-r--r--  1 stak  staff     899 12  8 22:22 Weapons.json
```

このような感じ。

以前まではデフォルトだった（気がする）暗号化・アーカイブ化が素の状態のプロジェクトデータ時点では行われなくなったため、中が丸見えで困るという声もあるようですが、それについては配布用に良い感じにする策があればよい話。
開発フェーズにおいては、ツクールエディタ外からも利用しやすいフォーマットが用いられていることは単純に嬉しいことです。

例を挙げれば、ゲーム内の色々なところに出てくるとある表現を、やっぱり別の表現に置換したいわ、と思ったとき、これらの json に対して grep で置換をかける、といったことが手軽に行えますね（あらかじめ表現を変数展開の形で書いてあればこんな置換不要ですが、後から変更したい部分に気づくパターンも多いと思います）。
このように、ツクールエディタの力だけで頑張るのがつらい状況が発生したとき、外部から手軽に補助できる環境であることは、開発者にとって安心感があります。

この時点でとりま JSON は最高です。

# バージョン管理、最高

そして何より、ツクールエディタで編集する主要なデータが JSON というテキスト形式であるならば、
**RPG ツクールプロジェクトを、良い感じにバージョン管理して開発**できる！！

適切にログを残し、変更差分をたどることができるような現代的バージョン管理ができれば、

- なんでこの敵こんな設定にしてたんだっけ？
- 昔のバージョンのパラメータに戻したい……バックアップに残ってるかなぁ？
- 外出中ノート PC で作業したデータで上書きしたら、マップ巻き戻っちゃった？

このようなソワソワした開発とは秒でオサラバです。
RPG ツクールもついにこの神域に足を踏み入れた。最高かよ……。

# そんな風に思っていた

時期が僕にもありました。では現実を見てみましょう。

<img width="1196" alt="diff" src="https://qiita-image-store.s3.amazonaws.com/0/60517/c3d05ca2-89ac-57d8-32c0-b50beefba4f7.png">

！？！？！？

ちなみに、この diff は、ゲームの**タイトルを変更しただけ**の diff です。
これじゃ差分、見る気しない。

タイトル変えただけでこれですからね。
会話イベントの演出を強化した差分とか、追えるわけがない。

まあ一応、行内の差分だって調べることはできますし、変更履歴が残せることは残せてますが、「最高」と思ったテンションはどっかへ行きましたよね。遠くへね。
友人に追加を依頼したエクストラエネミーのプルリクを GitHub 上でレビューする、みたいなモダン開発フローも白昼夢で終わりましたね。

# 諸悪の根源

詳細な状況としては下記の通りですので、宜しくご査収ください。

1. ツクールエディタが保存する JSON、フォーマットされておらず行指向 diff と相性悪い
2. フォーマットしておいても、ツクールエディタからの次回保存時には、元に戻される（それはそうだ）
3. ひとつの JSON ファイルが担当する情報量が多すぎ
    - 例えば Map001.json の中には、そのマップのメタ情報、タイル、全イベント内容まで含まれている

で、まあエンジニアなら問題を解決しろやという話がありますので、取り組んでいた内容が以下です。

# ぼくのかんがえた解決策

1. に対して: pretty フォーマットされた JSON をバージョン管理できればよい
2. に対して: ツクールエディタ側での保存を受け、自動的に変換処理が走ればよい
3. に対して: JSON を部分ごとにファイルシステム上に展開する仕組みがあればよい

この目的のために、[gulp-json-fsmap](https://github.com/stak/gulp-json-fsmap) という gulp プラグインを書きました。

gulp って何みたいな話は割愛させて頂きますが、
`data/` 以下を watch しておいて、ツクールエディタからの保存を検知したら、このプラグインで元 JSON を良い感じに分解しつつフォーマットして、バージョン管理用の JSON を生成する、という流れです。

余裕があれば、これを実際に使いやすいテンプレ設定や、ツールの形にまとめてご提供したかったのですが、
ちょっと今日時点ではそこまで至らず、ひとまず動いてますよというご報告まで。

# 動作

RPG ツクール MV の `data/` 以下の JSON に対してであれば、JSON の構造に対してファイルシステムへの対応を、次のように定義します。

```json
{
  "Actors": ["*data/Actors/Actor%{id3}_%{name}"],
  "Animations": ["*data/Animations/Anim%{id3}_%{name}"],
  "Armors": ["*data/Armors/Armor%{id3}_%{name}"],
  "Classes": ["*data/Classes/Class%{id3}_%{name}"],
  "CommonEvents": ["*events/common/common%{id3}_%{name}"],
  "Enemies": ["*data/Enemies/Enemy%{id3}_%{name}"],
  "Items": ["*data/Items/Item%{id3}_%{name}"],
  "MapInfos": "maps/info",
  "Map[0-9][0-9][0-9]": {
    "_": "maps/meta/%{basename}_%{mapName}",
    "data": "maps/tile/%{basename}_%{mapName}",
    "events": ["*events/%{basename}_%{mapName}/%{id3}_%{name}"]
  },
  "Skills": ["*data/Skills/Skill%{id3}_%{name}"],
  "States": ["*data/States/State%{id3}_%{name}"],
  "System": "data/System",
  "Tilesets": ["*data/Tilesets/Tileset%{id3}_%{name}"],
  "Troops": ["*data/Troops/Troop%{id3}_%{name}"],
  "Weapons": ["*data/Weapons/Weapon%{id3}_%{name}"]
}
```

そして、この設定をもとに gulp-json-fsmap に仕事をさせると、

<img width="327" alt="tree" src="https://qiita-image-store.s3.amazonaws.com/0/60517/b2440279-da21-010a-f7b6-d80d5b7c40e7.png">

このようにフォルダ構造やファイル名が良い感じになった JSON ファイル群が生成されます。
もちろん各 JSON の中身もフォーマットされていますので、diff も見やすいです。

こいつをバージョン管理すれば、最高という感じが取り戻せますね！

# ぐだぐだ言ってないでゲームを作れよ、ハゲ

えー…… RPG ツクールはプログラマーでなくても誰でも手軽に RPG をつくれる素敵ソフトウェアです。
皆さんはこのようなヤクの毛刈り（効率化という名の回り道）に終始せず、さくっとゲームを作っていきましょう。

ということで、次回はめっちゃゲーム作っている感じが強いお題で、 kuroudo119 さんです。