神無月サスケの波瀾万丈な日常・はてなブログ編

神無月サスケのツイッター(@ktakaki00)を補完する長文を書きます。

RPGツクールVX AceのRGSS3を読み解く

本日12月1日、そろそろRPGツクールVX Aceの体験版が出る頃ですね。

僕は今回、サンプルゲームを作らせていただいたこともあり、早い時期からVX Aceを触らせてもらったのですが、ツクールWebで徐々に公開されているような機能を見て、「これは上級者向けの強力なVXだ」と感銘を受けていました。

そんな『RPGツクールVX Ace』ですが、これまで、RGSS3についてはあまり情報がありませんでした。これは、RGSS3を変更して起きたことについてはエンターブレイン側は未サポートということもあり、なかなか紹介がしづらいという事情があるんだと思います。そこで今回、VXでRGSS2もそうでしたが、いちユーザーとして、僕がRGSS3を解析、紹介してみようと思います。

これから書く多くのことは体験版をいじれば分かることでしょうが、これから体験版をいじるかどうか考えている人、体験版を使ってもよくわからないという人は、ぜひ参考にしてください。

まず最初にお断り

  • この文章は、体験版ではなく、開発中の最終バージョン(リリース直前版)をもとに書いています。このため、体験版とは若干異なる場合があります。
  • 正確性については最大限の努力を期すようにしましたが、それでも間違いや、思い込み、僕の考えによるバイアスがある部分は否定できません。あくまで参考程度にとらえ、気になった部分は実際に体験版をいじって確認していただくのがベストだと思います。
  • この文章は神無月サスケが勝手に書いています。この文章のことでエンターブレインに問い合わせたりしないでくださいね、念のため。

それでは参りましょう。

Rubyのバージョンが新しく1.9になり、高速化、多機能化した

RGSS3で最初に特筆すべきは、ベースとなるRubyのバージョンが、これまでの1.8から、1.9に上がったことでしょう。ヘルプで確認すると、1.9.2が使われています。

Rubyが1.8から1.9にバージョンアップすることによっての主な変更点は詳しいサイトがあるためそちらに任せますが、最大の変更点は、内部アーキテクチャを一新することで高速化が実現できたということです。

高速化はとても嬉しい要素です。ツクールXPからVX、VX Aceとバージョンアップするにつれて、実装された機能が多くなり、それにつれて処理も多くなりました。XPからVXの機能向上によるPCの要求スペックが上がっていました。今回のVXからVX Aceも、実装された機能が格段に多くなり、それによって極端に重くなることが懸念されそうなところでした。しかし、Ruby1.9 の導入による軽量化は、この懸念から大いに救ってくれたといえるでしょう。かくして、VX Aceは多機能なのに、それほど重たくならずに済んでいます。

また、Ruby1.9には、それまでになかった新しい機能とそれによる文法が多数導入されています。例えば、スレッドを扱った Fiber クラスというのが導入されており、今回のプリセットスクリプト(プロジェクトに最初に準備されているスクリプトのことをこう呼びます)では、1.9の新機能をふんだんに取り入れて効率化を図っています。このあたりは後述します。

RGSS2素材は使えない。しかしRGSS3は素材が作りやすい

さて、次は、プリセットスクリプトについてです。(プリセットスクリプトは、F11を押してスクリプトエディタを開くと見ることが出来ます。)

ざっと見て分かるのは、RGSS2の時と全然違うということです。RGSS1の素材がRGSS2で使えなかったように、今回のRGSS3も、RGSS2との互換性はありまん。素材屋さんは新たな素材を作る必要があるし、素材ユーザーにとっても、素材が浸透するまではVXとRGSS2を使い続ける必要があるかもしれません。

しかし、朗報があります。RGSS3は、とても素材が作りやすい形式になっています。なぜなら、RGSS2以上に、多くの機能がメソッド化されており、これでもかというほど、細かくメソッド化されているのです。

細かくメソッド化することのメリットは何か。それは、メソッドを上書きすることが減り、メソッドに追加する形でエイリアスを作成することで機能が追加しやすくなるのです。これはすなわち、他の素材との競合が減ることを意味します。

実際、僕もサンプルゲームで何箇所かRGSS3スクリプトをいじってみましたが、準備されたメソッドを軽くエイリアスし、処理を追加するだけで事足りました。RGSS2でも、少なからずあった素材の競合の問題が、さらに減ることが期待されると実感しました。

搭載された多数の機能はプリセットスクリプトで実現されている

今回ツクールWebで紹介されているような機能は、全てRGSS3のスクリプトで実装されています。

例えば必殺技ゲージ(TP)、隊列歩行に、大人数パーティーと並び替え、最強装備、「特徴」を使った汎用性の高い装備やアイテムや魔法の作成(例えば、装備中だけ特定の魔法を覚える装備が簡単に作れる)、これらの複雑な機能が、全てプリセットスクリプトで実装されているのです。

また、隊列歩行や必殺技ゲージは、ON/OFFの切り替えが可能です。必殺技ゲージが使いたくないときは、オプションでそう設定すると、バトル画面でTPが表示されなくなります。

これらの中には、既にRGSS2で素材として出回っていたものも少なくありません。しかし、プリセットスクリプトに組み込まれていると、安定性が違います。このため、これらの機能が欲しくて、さらに素材を組みたいという場合、VXで素材の競合が面倒だという人は、VX Aceを使って、素材の競合を減らした制作が可能になると言えます。

プリセットスクリプトの目指したもう一つの方向性:軽量化

さて、プリセットスクリプトを眺めていて、僕が気づいた点があります。それは、多くの場所で、以前に比べて処理の軽量化を意識して組まれているというという点です。

例えば、ピクチャの表示。RGSS1では、最大50枚のピクチャを表示可能ということで、ピクチャを表示しなくても、常に50個のスプライトを作成し、ピクチャが表示された場合に備えていました。これはシステムに若干の負荷がかかることでした。RGSS3では、ピクチャが表示される際にスプライトを作り、必要な時だけスプライトを存在させることで、いらないスプライトを作らず、軽量化を図っています。

この「要らないスプライトは作らない」という方針は、例えば天候スプライトでも言えます。RGSS1の RPG::Weather クラスは常に最大数の40個のスプライトを作って準備していましたが、RGSS3のSpriteset_Weather クラスは、必要に応じてスプライトを作成、消去しています。

また、RGSS2までにはなかった、「画面内にいるか」というメソッドが新たに導入されています。( Game_Event#near_screen )このメソッドは、キャラクターの画面外にいるキャラクターには自律移動を行わないために、導入されています。これまでは画面外にいるキャラでも自律移動の処理を行っていたため、広いマップで自律移動するキャラが多かったら重たくなっていましたが、その処理が省かれる分軽量化されることになります。

この他にも多数の見えにくい部分での軽量化が施されているようです。

これは歓迎すべきことですが、一方で軽量化を施すことというのは、スクリプトが若干複雑化することと表裏一体にあります。それゆえに単純で皆が理解、改変がしやすいスクリプトを目指した以前のRGSS1では軽量化は最小限にとどめられていたのですが、今回は大々的に行われているようです。
これは、プリセットスクリプトはいじらないで、素材作成に専念して欲しいという制作者側の意図を考えると、自然なことでしょう。

よりオブジェクト指向的に構造化された(きれいなプログラム)

そして今回のコード全体に言えるのは、上級者向けになっているということです。

まず最初に感心するのは、オブジェクト指向を究極まで突き詰めたクラス構造です。

かつてRGSS1の時代によく言われていたのは、「オブジェクト指向の詰めが甘い。自分ならこうする」と言って、例えば複数のシーンクラスの根底となる Scene_Base クラスを自作して改良している人をたまに見かけました。このように、これまでのスクリプトは解読しやすい代わりに、構造の最適化は徹底されていませんでした。構造の最適化が行われていないということは、同じようなコードがあちこちに散見されるということです。この問題は、RGSS2 ではかなり解決されました。 Scene_Base クラスも導入され、同じようなデータ構造や処理を持つクラスのスーパークラスが作成されました。(例えば、アイテムと魔法の共通のスーパークラスとして、RPG::ItemBase が作成されるなど)

今回のRGSS3は、RGSS2にもまして、その方向が強化されています。例えばGame_Character クラスのスーパークラスとして Game_CharacterBase が導入されています。また、専門的な処理をする部分のためにあらたにモジュールが準備されています。ファイルで読み書きする処理をまとめた DataManager モジュール、シーンの変移を管理する処理をまとめた SceneManager モジュール、バトルの処理のうちベースとなる処理部分をまとめた BattleManagerモジュールがそれです。

このように高度に構造化することによって、より美しいプログラムになったと言うことが出来ます。オブジェクト指向プログラマも一度参考のために見ておく価値のあるプログラムだと言うことが出来ます。

高度に洗練された表現を導入したコード

もうひとつ、上級者向けになったと感じたのは、それぞれのメソッドの内部の細かい表現についてです。

XPからVXの時にコメントがほとんどなくなり、上級者向けになったと感じましたが、今回は、簡略化のために専門的な記法や、様々な機能(クラスやメソッド)を使いこなしており、クラスやメソッドをひとつひとつ解読していくのは、これまで以上に、骨が折れる作業になることは間違いありません。

なぜそこまで難解にしたのか。それは、スクリプトの簡略化にあります。簡略化した方が、プログラムの行数も減りますし、その分処理も少なくなる。軽量化しやすくなる。それに、解読は難解になるが、ひとたびメソッドやクラスの意味が分かれば、逆に理解がしやすくなる、というわけです。

実際、ヘルプのスクリプト入門にも、メソッドが増えたりして難解になっていることについて、「最初は戸惑うでしょうが、使っていくうちに、この形が一番だと思えるようになります」といった意味の表現がありました。

そう。慣れるまでが大変なのですが、慣れてしまえば、解読は楽になりますし、それ以上に素材を作るのもこれまでのスクリプトより楽になることでしょう。

ここで、今回表現された高度な表現の例を見ていきましょう。

Ruby1.9の新機能を導入(例:Fiberクラス)

まずは、前述の Ruby1.9 で新たに導入された Fiber クラスです。RGSSリファレンスの標準ライブラリの中に説明があります。ヘルプから引用すると『ノンプリエンプティブな軽量スレッド (以下ファイバーと呼ぶ) を提供します。』とのことです。簡単な説明がしてあります。プリセットスクリプトの中でこの機能が使われているのは、主にInterpreterクラス、つまりイベントコマンドの実行の中なのですが、僕も未だに完全には理解しきれていません。

配列など基礎的なデータに対する新たなメソッドを多用

また、新たに導入されたと思われるメソッドが多用されています。例えば、inject というメソッドです。これは ヘルプを検索すればEnumerable モジュールのメソッドと分かります。配列の各要素の間に共通の演算子を挟みたいときに使うと便利なメソッドらしいです。このメソッドを使うことによって、他の手法を使うより簡潔に表現しているのです。この他にもRGSS2までには見られなかったメソッドが多数ありますが、ヘルプのリファレンスには使われているメソッドはほぼ書かれているため、分からないのを見つけたらリファレンスで検索するようにすれば問題ないでしょう。

Ruby文法を高度に活かした表現

そして、基本的な文法を使った高度な表現も見られます。例えば次です。皆さんは理解できるでしょうか。


@cache ||= {}
RGSS2までをやってRubyに慣れていた人でも、面食らった人は少なくないでしょう。これは今回 Cache モジュールに出てくる文法ですが、あまりに難解なのでヘルプの「スクリプト入門」の解読編の「nilガード」で詳しく説明されています。回答は、以下と同じなのです。

if @cache != nil
@cache = @cache
else
@cache = {}
end
こう書くと5行必要な処理を、1行で済ますために高度な記法を使っているのです。

結論:慣れるまでが大変だが慣れると良さが分かる

これらの高度な記法を使うと、プログラムの行数を減らすことが出来るのです。慣れるまでは解読が大変でしょうが、慣れてくれば楽になるでしょう。

このようにRGSS3は敷居が高そうだが大丈夫なのか

というわけで、今回は若干敷居が高いかな?と思うRGSS3ですが、実際、RGSS2を使いこなした方にも、ちょっと最初は難しく感じるかもしれません。

RGSSが初めての方でも、Rubyか他のオブジェクト指向言語(C++, JavaPythonなど)をやったことがある人なら、それほど苦労せずに入っていけるでしょう。もっとも、前述の通りRGSS2に比べると難解な表現が多く、ヘルプが手放せないでしょうが挫折することはないでしょう。

逆にもし、プログラミングが初めてで、それでも他の人が作った素材を使うのではなく1からスクリプトをやりたい!という方がいましたら、その人にはお勧めできません。RGSS3はそういう人には若干難解かもしれません。もっとも、後述するスクリプト入門があるので、それを見ながら少しずつやっていけば何とかなるかもしれませんが、よりよいのは、「RPGツクールXP」を使うことです。こちらは、機能を絞っており、自分でスクリプトをいじることを前提にしているため、かなりシンプルになっています。自分の目的に応じて、使い分けてください。

まずはスクリプト入門をやってみましょう

さて。RGSS3を本格的に始めるにあたって、最初に見ていただきたいのは「スクリプト入門」です。

基礎編

スクリプト入門はこれまでにもありましたが、これまではRubyに慣れた人は文法を説明する「基礎編」は飛ばしていた人も少なくないのではないでしょうか。今回は若干仕様が変わった部分もあるので、Rubyに慣れた人でも、流し読みでいいから読んでおく事をおすすめします。

特に、「コンソールの表示」という機能が最初に説明されており、これはデバッグ用の文字列を表示させるコンソールです。これまでデバッグは p 関数でメッセージボックスを表示させていましたが、今回この関数はこのコンソールに表示させる関数となりました。このあたりの基礎はぜひおろそかにせずにしてほしいと思います。

基礎編の他の部分は Ruby の基礎的な構文を紹介しているので流し読みでかまいませんが、「画像の表示」だけは RGSS 独特の機能の解説なので目を通しておくことをおすすめします。

解読編

「解読編」でプリセットスクリプトを読み解いていくわけですが、ここは必読です。RGSS3になり、仕様が相当変わったため、RGSS2に慣れた人でも、必読です。

いくつか例を挙げます。

まず、ウィンドウの管理で、「ハンドラ」という概念が新たに導入されています。コマンドごとにシンボルを割り当て、そのシンボルと実行内容を結びつけることで実行するというものです。これでコマンド数の増減やコマンド名の変更に柔軟に対応できることになります。これはスクリプトを読んでも分かりづらく、少しいじっているうちに何となく分かってくる感じなので、習うより慣れろの感覚で行くといいでしょう。

また、シーンクラスの変更も大きいです。これまではシーンの遷移には $scene に値を入れることでシーンを変更していましたが、今回は SceneManager モジュールのメソッドを呼び出すことでシーンを遷移させる形式に変更になりました。goto, call, return の3つのメソッドがあり、特にcall と return を使うことで「以前のシーンに戻る」という処理が簡単になりました。

実践編

そして今回新たに、「実践編」が追加されました。

「アイテム消費スキルの作成」や「景品所の作成」など、簡単にスクリプトをいじって出来る拡張が説明されています。これを見ていると少し分かったような気持ちになれます。

なお、余談ですが、スクリプト入門の作成には僕も少し関わっており、「テレポートアイテムの作成」という項目は僕のリクエストにより入れられたものです。サンプルゲームに必要だったから入れてもらったのですがヘルプに載っているのは残念ながら乗り物未対応でした。仕方がないから僕がスクリプトをいじって乗り物対応にしたのですが、それほど困難ではなかったです。RGSS3の拡張性を感じました。

その他、RGSS3の可能性

RGSS3のメインを見ると、以下の1行だけが書かれています。


rgss_main { SceneManager.run }

これは、rgss_main という関数にブロックを与えて呼び出しているのですが、ヘルプの説明では以下のようになっています。


{ }で囲った部分を一度だけ実行しますが、その途中で F12 キーによってゲームのリセットが行われたときは最初に戻るという処理を行います。

つまり、これまではF12が押された場合は強制的にタイトル画面に戻っていましたが、F12が押されたときの挙動を変えることが可能になるということらしいです。さすがに僕はここまで高度なことにはついていけないのですが、RGSS3を使いこなしたい人にとっては、面白い機能なのではないでしょうか。

このようにRGSS3は使いこなしたい人には面白い機能がたくさんあります。興味のある人はじっくり取り組んでみてはいかがでしょう。