この記事は先日Twitterで軽くまとめた情報のドキュメント化です。制作者向けの話で、しかもえっらい長いので、ツクラーじゃない人はスルー推奨。

現状「RPGツクールMV製エロゲは遅い!」と噂になっていて、MV製であるというだけで避けられる状況になってきました。これちょっと、将来MV製ゲームを出したいウチのサークル的にもヤバいので解決策がないか探していたんですが、Twitter上の会話でヒントっぽいものがあったので、そこから仮説を立てて方法を模索したところ、どうやらGame.exeの軽量化に成功したらしいので、やり方をまとめておきます。

2016-12-31 若干修正 よりNw.jsの標準に近い方法に微調整し、不要ファイルが残る可能性が排除されました。
2016-12-31 追記 RPGツクールMVの古いバージョン(v1.2.x以前)ではセーブファイルがexeと同じドライブの直下に出来てしまう問題が発生することがわかりました。v1.3.4以降にアップデートしてから実施するよう注意して下さい。
2017-01-07 追記 Chromium50以降はXP/Vistaはサポート外となったため、Nw.jsの方もVista以前では起動しないようです。対応OSからVista以前を外し、Win7以降対応という仕様で配布するようにしてください。
2017-01-11 追記 最新版Nw.jsで開発者ツールを開く方法を追加。
2017-01-17 ENIGMAを使わないファイル隠蔽法をこちらにまとめました。

どれぐらい効果があるのか

最初に、この軽量化メソッドを施すとどれぐらい効果があるのか気になると思うので、人柱となって頂いたBLACK PANDA様新作『堕ち姫ルーシア物語』で検証した際のファーストインプレッションをご紹介すると、こんな感じでした。

――といった感じで、かなり劇的な効果が上がることが確認できました。特に、exe版の動作がブラウザでの動作より明らかに遅いような場合には、ほぼ確実にブラウザと同等の速度が実現できるということがわかりました。



軽量化の手順

RPGツクールMVのWindows用Game.exeは、実は正体はNw.jsというアプリケーションプラットフォームそのものです。Nw.jsではHTML5の表示とJavaScriptの実行にGoogle Chromeブラウザの表示エンジンと同じChromiumを使っているのですが、MVの動作が重いのは、実はこのChromiumのバージョンが古いことが原因でした。※1

そこで、出力した自作ゲームのGame.exeをごそっと最新のものに上書きアップデートしてしまうことで、最新Chromiumのパワーで高速化してしまおうというのがこのメソッドの意図です。

Nw.jsの最新安定版を入手

まずはNw.jsの公式サイトへ行って最新安定版を入手してきます。Windows用の32bit版の方です。64bit版だと、32bit OSを使っているユーザーの手元で起動しません。

Nwjs101
Nwjs102

ファイルのダウンロードが終わったら入手したzipファイルを適当なフォルダに解凍しておきましょう。

Nwjs103
Nwjs104
Nwjs105

プロジェクトをWindows用にデプロイ

次に、自分のプロジェクトをWindows用にデプロイしておきます。アセットが暗号化されていても正常に動作できますので、必要に応じて暗号化しておいてください。

Nwjs106
Nwjs107

ゲームデータをNw.jsにコピー

次に、解凍しておいたNw.jsをフォルダごとコピーして複製を作成します。この複製したフォルダが最終的に配布するゲームのフォルダになります。

Nwjs121

デプロイしたゲームのフォルダから[www]フォルダpackage.jsonを選択し、複製Nw.jsフォルダへコピー(または移動)します。

Nwjs122
Nwjs123

ゲームをデプロイしたフォルダはもはや必要ないので消してしまって、代わりに複製したNw.jsフォルダを自分のゲームのフォルダ名に変更します。

Nwjs125

複製Nw.jsフォルダ内のnw.exeが新しいゲームの起動ファイルになります。ダブルクリックして正常に起動することを確認したら、Game.exeなど分かりやすい名前に変更しておきましょう。

Nwjs124


アイコンの変更

実際やってみたらすぐ気づいたと思うのですが、Nw.jsの最新版に上書きすると、Game.exeのアイコンはツクールMVのものではなくなってしまいます。まあ別にツクールMVのアイコンがそれほどデザインいいかと言ったらだいぶ微妙なので、どうでもいいっちゃいいんですが、nw.exeのアイコンのままでも何者なのかよくわからないので、せっかくですからアイコンも自分の作品オリジナルのものに変更してしまいましょう。

Resource Hacker™をインストール

exeファイルのリソースをいろいろアレしてくれるツールがあるのでインストールしてしまいましょう。ダウンロードはこちらから。

Nwjs201

適当なフォルダにインストールしておいて起動します。

アイコンを置き換える

Resource Hacker™を起動したら、デプロイ先のnw.exe(リネームしていればGame.exe)を開きます。ドラッグ&ドロップで放り込むだけで読み込んでくれます。

左のツリービューから[Icon Group]となっているノードをダブルクリック、表示されるアイコンのIDをひとつ左クリックで選択したら右クリックしてコンテキストメニューを表示し、メニューから[Replace Icon]を選びます。

Nwjs203
Nwjs204

新しいアイコンを読み込む

ダイアログボックスが表示されるので、[Open file with new icon]ボタンを押して、exeファイルに埋め込みたいアイコンのicoファイルを選びます。ダイアログにアイコンが表示されるので、右のリストビューから"IDR_MAINFRAME"となっているIDを選択して[Replace]ボタンを押します。

Nwjs205
Nwjs206
Nwjs207

なお、ここでは説明用に元のMVのGame.exeからアイコンぶっこ抜いて使いましたが、これは配布物でやっちゃダメです。ツクール規約が禁じているリバースエンジニアリングにあたります。

exeファイルを上書き保存する

IDR_MAINFRAMEのアイコンが変わっていることが確認できたら、メニューバーの[File]→[Save]を選択して変更内容をexeに上書き保存します。Resource Hacker™は自動的にバックアップファイルを作成してくれるので、リリース前に消しておくのを忘れないように注意して下さい。

Nwjs208
Nwjs209
Nwjs210

なお、アイコンをexeに保存してもすぐ表示に反映されるわけではありません。Windowsのシステムが一度表示したアイコンはファイルパスと関連づけてメモリ上に記憶しているので、ファイルの内容が変わっていても再起動したりしないと表示が変わりません。すぐ表示の変更を確認したい場合は、exeが格納されているフォルダの名前を変更するといいでしょう。

Nwjs211


最新版Nw.jsで開発者ツールを使う(2017-01-11追記)

この方法の欠点のひとつとして、ツクール本体(エディタ)から[ゲーム]→[テストプレイ]を選んだときに起動するGame.exeは相変わらず古いままで、最新Nw.jsのデバッグが出来ないという点があります。上記で導入したNw.jsはリリースビルドなので、DevTools(開発者ツール)は組み込まれておらず、[F8]を押してもコンソールが表示されません(もちろんユーザーに配布するバージョンで表示されたら困るわけですが)。

しかし、制作者側の環境でも実行が遅くデバッグも最新Nw.jsで行いたいとか、旧Game.exeと最新Nw.jsでは挙動が違うらしいプラグインがあってデバッグしたいといった際に、DevToolsが表示できないのは不便でしかたありません。そこで、ツクール本体の[テストプレイ]を経由せず、DevTools付きの最新版Nw.jsを起動する方法もご紹介しておきます。

最新版Nw.jsのSDKビルドでデプロイしたゲームをテストプレイする

DevToolsが表示されないのは、単に使っているNw.js(nw.exe)がリリース用で、開発用のバージョンではないためです。なので、Nw.jsの方を開発用(SDK版)にすれば、最新版でもDevToolsを表示してデバッグすることができます。

まず、Nw.jsの公式サイトへ行って最新安定版の「SDK」と書いてある方のバージョンをダウンロードしてきます。適当なフォルダに解凍しておいて下さい。

301

デバッグしたいプロジェクトをデプロイしたら、デプロイしたフォルダをまるごと、ダウンロードしたSDK版Nw.jsのnw.exeにドラッグ&ドロップします。

303

最新版のNw.js環境下でデプロイしたゲームが起動します。[F12]を押すとDevToolsが起動します(ツクールMV同梱の旧版Game.exeとはキーが変わっています)。

304

編集中のプロジェクトフォルダの内容でデバッグするには

上記の方法だといちいちデプロイしなければならず面倒臭いので、編集中のプロジェクトフォルダの内容を最新版Nw.jsで起動できるようにしておく方法もあります。

まず、一度デプロイしておいて、出力先フォルダからpackage.jsonというファイルを編集中のプロジェクトフォルダにコピーします。

311

プロジェクトフォルダに複製したpackage.jsonをテキストエディタで開きます。

312

ここではBracketsを使っていますが、プレーンテキストを編集できれば何でもいいのでメモ帳でも構いません。package.jsonを開いたら、www/と書いてあるところが2カ所あるので、この部分を消します。下の画像を参考にしてください。

313

編集後、上書き保存したら準備完了です。以後は、プロジェクトフォルダをnw.exeにドラッグ&ドロップすることでゲームを起動できるようになっているはずです。SDK版で起動すればDevToolsを表示して利用することも可能です。



その他もろもろ

パッゲージ化について

アセット類をまとめて単体のexeファイルに埋め込んでしまうシングル・パッケージ化についてですが、いくつかの方法が考えられます。

ENIGMA VIRTUAL BOX
まずMVのマニュアルに掲載されているENIGMA VIRTUAL BOXを使う方法があります。まだ検証はしていませんが、バーチャルマシンによるサンドボックス化なので、理屈の上では上手くいくはずです。
Nw.jsの標準手順
Nw.jsには標準でアセットをzipにパッケージ化する方法と、exeと結合する方法があり、ドキュメントにも記載されています。(2017-01-18追記)別記事にやり方をまとめました。
Crosswalkなど他のWebViewを使う方法
新しめなバージョンのChromiumを搭載した他のフレームワークを使ってもここで紹介したメソッドと同等のことは可能だと思います。むしろマルチプラットフォーム展開を考えているなら、Nw.jsではなく、最初からCrosswalkなどでChromiumのバージョンを統一しておく方がいい結果が出ると思います。
(2017-01-19追記)さたける(@satakerugames)さんからご指摘いただいた情報を追記。Nw.js以外のWebViewだと[F5]での再起動やローカルファイルシステムへのセーブがそのままでは動かないのでプラグイン等の導入が必要とのこと。セーブの方はローカルファイルに拘らなければWebStorageに保存されると思うのですが、セーブファイルが出来て欲しい場合はNode.jsモジュールなどが配布されていたら利用するといいかもしれません。再起動の方は各WebViewごとに導入方法が違う(あるいは無い場合もあるかも)と思います。

これをやれば他に高速化の必要はないの?

これについてはプロジェクトによるとしか言いようがありません。というのも、ツクールMVはプラグインの作り方や使い方次第でアホみたいに負荷があがる可能性があるからです。まあこれまでのツクールもそうだったんですが、ツクールMVはコアスクリプト自体やや品質に不安がありまして。

たとえば、スクリプトの側からゲーム変数の値を弄る標準的な方法としてよく紹介される$gameVariables.setValue()というメソッドがあります。

ツクールMVのスクリプトで変数の操作を行う方法

ところが、これ一歩使い方を間違えると負荷がガンガン上がる危険なメソッドでもあるんですよ。

【ツクールMV Tips】ゲーム動作軽量化に潜むsetValueと$gameMap.refresh()の罠

んなこたぁフレーム更新でやれ!! ってゲーム組み慣れた人なら誰だって思うようなおかしな仕様が、こんな風にサラッと紛れてたりするんですね。なので、ツクールMVはもともと、

  • スクリプト組めない人はプラグインを慎重に厳選。同じ機能のプラグインがあったら出来るだけ負荷のないものを選ぶ。
  • スクリプト組める人なら、もうあらゆるメソッドの呼び出しチェーンの隅々まで目を皿のようにしてチューニングする覚悟が必要。

という初心者にまったく優しくないツールだったりするわけです。なので、このメソッド以外にも軽量化は常に意識しながらツクった方がいいですよというお話。


F.A.Q.

商用利用でも問題ないでしょうか?
Nw.jsの再配布はMITライセンスというユルめのライセンスに基づき許可されていますので商用利用も可能です。というか、元々ツクールMVのGame.exe自体が中身Nw.jsそのものなので、これで商用利用に問題あったらツクールMV自体最初から使えないと言うことになります。
ツクールの利用規約的に問題は発生しないのでしょうか?
特にリバースエンジニアリングなどを行っているわけではないですし、また制作したゲームを配布する際にもツクール規約には抵触しないはずです。もしこのメソッドが規約に抵触するなら、ツクールMVのマニュアルに掲載されているCrosswalkやApache CordovaによるAndroidやiOSへのデプロイも同様に規約違反ということになり、ツクールMVは「スマホにも配信可能」という特徴を公称できなくなります。
何か不具合が起きるようなことはないのでしょうか?
絶対にとは言い切れませんが、まず起きないと思います。これで何か不具合が起きるなら、現行のChromeでMV製ブラウザゲームを遊んでも同じ不具合が起きるからです。その場合、ツクールMVが「ブラウザゲームを制作可能」と公称している以上、不具合を直すべきなのは我々制作者では無く、ツクール開発部です。
(2016-12-31追記)なんて偉そうなこと言ってたのに、MVのコアスクリプトが古い(v1.2.x以前)と問題が発生することが発覚※2。v1.3.4以降では問題ないことを確認しているので、このメソッドを実施する前に、MVを最新版にアップデートしておいて下さい。

セーブパス再配置プラグイン(2017-01-01)

セーブパスが変わってしまい、かつプラグインなどの兼ね合いでコアスクリプトをアップデートできない人用に、超簡単なものですが、セーブパスを再配置できるプラグインを作りました。

SavePathRelocation.js

リンク先からプレーンテキストファイルにコピペして使って下さい。



謝辞

最後に、今回のメソッドは別に自分がひとりで発見したというわけではなく、いろいろな方の協力やちょっとした発言がヒントになって実現しています。特に、現在のMVで使われているNw.js(chromium)のバージョンが古くブラウザで動作させた方が速いことを指摘されていたこま(@koma_neko)さん、具体的な方法を一緒に考えてくれた俺だよ!!俺!!!(@fftfantt)さん、えびせん(@EviHoge)さん(えびせんワークス)、最新作を快く人柱に使わせて下さったタクポン(@otakpon)さん(BLACK PANDA)ほか、ご協力下さった方々に改めて感謝の意を表したいと思います。




※1…実際に調査してみたところ、Nw.jsバージョン0.12.3のnw.exeのアイコンをMVのものと入れ替えてバイナリdiffをかけたら完全一致しました。なので、MVではNw.jsバージョン0.12.xを採用しており、Chromiumのバージョンは41ということになります。現行が55(2016-12-29現在)なので、性能に違いが出てしまったようです。ただ、今後もChromiumの最新版を適用し続けていくべきかというと話は別で、現状JavaScriptエンジンの効率化・速度向上はほぼ頭打ちになりつつあると言われています。Nw.jsがバージョンアップするたびにソフトをメンテし続けていくといった必要性はあまりないでしょう。

※2…RPGツクールMV v1.3.0~1.3.3の間のどこかの時点でセーブ先フォルダを決定する関数(StorageManager.localFileDirectoryPath() @rpg_manager.js)の内容が換装されたようです。古いバージョンのスクリプトを最新のNw.jsで実行すると、nw.exeを起動したドライブのルートフォルダ以下にセーブフォルダが作成されます。v1.3.4以降ではNode.jsのAPIを使用する仕様に変更されているので、これ以降のバージョンなら(仕様がまた変わらない限り)正しく動作します。