鳥小屋.txt

主に自作ゲームをつくったりしているよ。制作に関することやそうじゃないことのごった煮ブログ

Webエンジニア的なツクールプロジェクト構成

注意:フツーにツクールを使う人の参考にはなりません

前提

RPGツクール

RPGツクールMV / RPGツクールMZ はHTML5ゲームを作成できるツールです。
RPGの基本システムが実装された「コアスクリプト」と呼ばれるものと、エディタで生成したマップやキャラクター情報などのJSONファイルをWebで公開することで、PC・スマートフォンなどでHTML5なRPGを動かすことができます。

ツクールのJS面はシンプル

RPGツクールは初心者でも扱える&買い切りのツールということもあってか、内部には特にトランスパイルやバンドルをするための仕組みは持たず、ツクールMVでは完全なES5、ツクールMZでもベースはES5で一部ES6(ES2015)の記法を含む程度になっています。

買い切りの製品の中に、変にbabelなどを含んでしまうと古いバージョンをいつまでも使い続けないといけなくなったりと長期的には不都合のほうが多そうなため、個人的にはこの仕組みは好印象です。
ゲームは年単位で作る人もいますからね。ツールのマイグレーションとか個人クリエイターの仕事ではないのです。

いや、まぁ強いて言うならちょっと window 直下に色々生やし過ぎだよ~とかはありますが……せめてjQuery達みたいに window.RPGMaker とかに閉じ込めてくれると嬉しかった。

また、プラグインという仕組みがあります。
プラグインと言っても何か大げさな仕組みがあるわけではなく、追加のJSファイルを読み込ませることでエディタ内にパラメータ項目を追加したり、ゲーム起動時に追加のJSファイルを読み込ませることができるような単純なものです。
個人的には「プラグイン」というよりは「MOD」みたいな感じかなぁという印象があります。

本題

シンプルだからってシンプルに使わないといけないわけじゃねぇよな!!(?)

一応、僕はWebエンジニアでもあるので、各種制作の管理をする上では「いつものツール達」を使うことができるほうが便利です。

ツクール本体がシンプルであってくれるおかげで、その外側に環境を構築することは容易です。
ディレクトリ構成や各種ツールなど、自分用にいろいろ試行錯誤しながら構築してきたものについて、ある程度結論がまとまりつつあるため、自分の中のノウハウの整理を兼ねて、今回ブログ記事にまとめてみることにしました。

なお、あくまでこの記事のやり方は「僕のやり方」でしかありません
そもそも本来のツクールの使い方・使われ方からは逸脱してるでしょう。

環境は使う人やチームによって適切なものを準備するべきです。
この記事はあくまで「僕のケース」という前提でお願いします。

なお、今回は僕が作っている中で一番新しいゲームである「貴方が狼カードデス!」の構成を紹介します。

利用ツール

主に以下のようなものを使います。

  • git
    • バージョン管理のため
  • TypeScript
    • ゲーム用のプラグインの記述のため
  • Webpack
    • ゲーム用のプラグインのバンドルをするため
    • TSのトランスパイルは、最近は esbuild-loader を使って試しています

なお、あくまで「ツクール用のプラグイン」のため、 webpack-dev-server などは利用しません。
ファイルとして出力されていないとツクールのエディタから読み込めないため、ベタに webpack watchしています。

また、エディタには IntelliJ IDEA を利用しています。
もうテリジェー無しにコードが書けない体になってしまった……

プロジェクトのディレクトリ構成

プロジェクトのディレクトリ構成について、tree コマンドの結果を加工したものを以下に掲載します。

.
├── .browserslistrc
├── .deployment-zip.js
├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── .ncurc.json
├── .prettierignore
├── .prettierrc
├── app/
├── extensions/
├── node_modules/
├── resources/
├── scripts/
├── src/
├── index.html
├── package.json
├── tsconfig.json
├── webpack.config.js
└── yarn.lock

単一のJSプロジェクトが含まれる構成のようにしています。

app/ ディレクトリ

├── app/
│   ├── audio/
│   ├── css/
│   ├── data/
│   ├── effects/
│   ├── fonts/
│   ├── game.rmmzproject
│   ├── icon/
│   ├── img/
│   ├── index.html
│   ├── js/
│   ├── movies/
│   └── package.json

これはRPGツクールが扱うプロジェクトディレクトリです。
RPGツクールで新規プロジェクトを作成した際に作成するディレクトリに app という名前をつけて、ここに設置しています。
ここに含まれる package.json もRPGツクールが生成するもので、僕が直接編集することはありません。

そのため、基本的には app ディレクトリの中身はRPGツクールのエディタを通じて編集されます。
最終的にはこの app ディレクトリの中身をWebで公開する形となります。
一般的なWebフロントのリポジトリにおける public とか static みたいなディレクトリと同様の扱いです。

extensions/ ディレクトリ

├── extensions/
│   ├── bannerPlugin.js
│   └── eslint/

開発ツール用の拡張機能などを入れる場所です。
現在は eslint の独自ルール設定や、ミニマムな webpack のプラグインを置く場所として使っています。

resources/ ディレクトリ

├── resources/
│   ├── json/
│   └── scripts/

ゲーム中で利用するリソースファイルの一部が入っています。

さすがにPhotoshopのPSDファイルなどを git 管轄に含めたくないため、そういった画像や動画などのリソースは別の場所で管理していますが、シナリオ用のテキストファイルだったり、ちょっとした設定値の含まれているJSON/YAMLファイルが git で管理したいためこのディレクトリに含めています。

例えば、上記の構成では scripts/ ディレクトリの中にシナリオデータのMarkdownファイルが入っており、変換スクリプトを通じてRPGツクール向けのJSON化して、 app/ ディレクトリに出力する……のような使い方をしています。

以下のようなmarkdownファイルでシナリオを書くと……

![se](se_damage)

> ひより,surprise
> ええ?! ちょっと待ってよ\c[2]ユーシ君\c[0]!
> それはおかしいよ!

![addState](hiyori,self_teller)

> ひより,angry2
> だって、\c[2]ヒヨちゃん\c[0]が\c[2]占い師\c[0]だもん!
> \c[2]ユーシ君\c[0]が\c[2]占い師\c[0]なわけないもん!

以下のようなRPGツクールのイベントコマンド仕様のJSONファイルが生成されます。

{
    "code": 250,
    "indent": 0,
    "parameters": [
    {
        "name": "se_damage",
        "volume": 45,
        "pitch": 100,
        "pan": 0
    }
    ]
},
{
    "code": 101,
    "indent": 0,
    "parameters": [
    "",
    0,
    0,
    2,
    "ひより,surprise"
    ]
},
{
    "code": 401,
    "indent": 0,
    "parameters": [
    "ええ?! ちょっと待ってよ\\c[2]ユーシ君\\c[0]!"
    ]
},
{
    "code": 401,
    "indent": 0,
    "parameters": [
    "それはおかしいよ!"
    ]
},
{
    "code": 356,
    "indent": 0,
    "parameters": [
    "addState hiyori self_teller"
    ]
},
{
    "code": 101,
    "indent": 0,
    "parameters": [
    "",
    0,
    0,
    2,
    "ひより,angry2"
    ]
},
{
    "code": 401,
    "indent": 0,
    "parameters": [
    "だって、\\c[2]ヒヨちゃん\\c[0]が\\c[2]占い師\\c[0]だもん!"
    ]
},
{
    "code": 401,
    "indent": 0,
    "parameters": [
    "\\c[2]ユーシ君\\c[0]が\\c[2]占い師\\c[0]なわけないもん!"
    ]
}

この辺りはまた別途記事に書いてみてもいいかもですね。

scripts/ ディレクトリ

├── scripts/
│   ├── convert-character.js
│   ├── convert-yaml.mjs
│   ├── generate-scripts.mjs
│   ├── scaffold-scripts.js
│   └── update-scriptList.js

主にちょっとした処理をするためのスクリプトコードを置く場所です。
前述の Markdown のシナリオをツクール用の JSON に変換するコードなども、ここに置いています。

基本的に面倒くさいことを手でやりたくないので、単純処理は手でやらずにササッとスクリプトを書いてここに置くようにしています。

よくやるのはキャラクターの立ち絵画像とかですかね。
表情ごとにレイヤー分けて出力した画像をゲーム用のサイズに縮小して、ゲームに読み込む際の位置指定ファイルを準備する……みたいな作業は絶対に手でやりたくないため、 node-canvasTexturePacker などを使って画像の加工をするスクリプトを書いています。

src/ ディレクトリ

├── src/
│   ├── @types/
│   ├── data/
│   ├── libs/
│   └── modules/
│   │  ├── _share/
│   │  ├── Achievement/
│   │  ├── BattleTalk/
│   │  ├── Choice/
│   │  ├── Config/
│   │  ├── Core/
│   │  ├── CutIn/
│   │  ├── Effect/
│   │  ├── LoadScript/
│   │  ├── Message/
│   │  ├── Result/
│   │  └── Title/
│   ├── boot.ts
│   ├── header.js
│   └── index.ts

このゲーム専用のプラグインのコードを入れるディレクトリです。
コードは TypeScript で記述しています。

index.ts がエントリーポイントになっており、最終的に1つのプラグインが出力されます。
現実にはゲーム用の機能は複数あるのですが、最終的に出力するプラグインを分ける意味があまりないため、 src/modules/ 以下に各機能ごとにディレクトリを作成し、index.ts からすべて読み込む形にしています。

なお、今作は画面数が少ないためやっていませんが、ゲームによっては起動時に読み込ませる必要がない画面などは dynamic import を使用することでゲーム中に必要になるまで読み込みを行わないようにしたりする場合もあります。

※注:ツクールの既存の挙動を変更するようなものはゲーム起動時に読み込む必要があるため、分けられるものはそれほど多くないです

header.js は webpack でビルド時にファイルの先頭に差し込むコメントが書かれたファイルです。
RPGツクールではプラグイン内にコメントとしてアノテーションを記載することで、エディタ内で専用のパラメータやコマンドを定義する仕組みを持っており、それを利用しています。

本当はこのヘッダのアノテーションも手で書かずに自動化したいなと思っているのですが、ぶっちゃけそんなに書く機会がないためやりかけで放置しています……><;

/index.html

プロジェクトルートに index.html を置いています。
が、これは公開用のHTMLではなく、僕がローカルで動作確認をするためのものです。

上記は別のゲームのものですが、ゲームによってはデバッグ用にパラメータを渡すことで開始シーンを変える……みたいな仕組みを入れており、そのパラメータを指定するためのUIなどを含むデバッグ用のHTMLになっています。
毎回タイトル画面から始まると面倒くさい~~みたいなことはよくありますからね……

おまけ:デプロイメント

RPGツクールにはデプロイメント機能がついており、ゲームディレクトリの中からパッケージに不要なファイル(例えば desktop.ini とかセーブデータとか)を削除してまとめて出力してくれる機能があります。

が、めんどくさいので僕は @rutan/deployment-zip というオレオレツールを使っています。
gitignore 的な指定方法で省くファイルを指定できるため、デバッグマップみたいな製品には含めたくないテストデータも自分で指定して含めないようにできるほか、zipファイルとして出力されるため ゲームアツマールPLiCy などへの投稿がカンタン!

……え、ツクールにはゲームアツマールにワンボタンでアップロードできる機能もあるから、そっちのほうがカンタンじゃないかって? HAHAHA!()

おわり

以上、僕のツクールプロジェクトの構成でした。

今回は全体の構成についてサラッと紹介しました。
ちょっとだけ触れたスクリプト類の話や、自分のゲーム用のプラグインをどう書いているの?という話はそれ単体で記事になってしまいそうなので、また別の機会に書けたらいいなと思います。

去年は「○○を公開しました!」みたいなブログしか書けなかったため、今年は制作の様子だったりといったものも記事にできるといいなーと思っています。

……が、Ruたん飽きっぽいからな! ぜんぜん書かなかったらごめんね!