Miyako の風 〜夢を捨てきれない人たちへ (笑)〜

書いた人: サイロス誠

はじめに

お久しぶりです、サイロスです。1 年以上のご無沙汰*1 になってしまいました。 その間、何を書こうか考えているうちに、RGSS ネタで Ruby 勉強会@関西で発表した際に、「環境がフリーで、Linux でも使えるものを」という話があり、色々考えた結果、自前でライブラリを作ろうと考え、『EGSR』として公開いたしました。途中、タイトルを『Miyako』に変更、更に使い易いインタフェースを目指して邁進中です。

今回は、Miyako の現段階での状況を中心に書いていこうと思います。

歴史 (大陸棚より浅いですが) と背景

Miyako は、最初、『RPG ツクール XP』 に搭載されていたゲームエンジン「RGSS」を「Ruby 勉強会@関西-7」 で発表した際に、フリーの Ruby 勉強用環境としての方向性について話がありました。何とか応用できないかと色々考えていたのですが、ライセンス料などの問題で頓挫、他の方向性を検討した結果、Linux でも使えるフリーのゲーム開発環境を、そして、Ruby を始める人のための取っ掛かりとしても使える教育用環境としても扱える環境の作成を始めました。 ちなみに、当初のタイトルは『EGSR』。Easy Game Scripting by Ruby の略です。名前がMiyako になった今でも、製作ポリシーの一つとして存続しています。

開発を始めるにあたって、Ruby を使って高速なグラフィックやサウンドを扱える『Ruby/SDL』(Ruby/SDL メインサイト) がありましてので、その Ruby/SDL を使ってラッパークラスを作り、気楽にスクリプティングが出来る扱いやすさと、様々なジャンルのゲームに応用できる拡張性を心がけて設計していきました。

その後、「Ruby 勉強会@関西-9」の懇親会で EGSR を紹介した際、他の事にも応用できそうというアドバイスを頂き、そこで、ゲームに特化せず、色々な箇所で扱えるイメージを持てるように、タイトルを、EGSR を作成することになった勉強会の会場、京都にちなんで「Miyako」に変更し、今に至ります。

現在のバージョンは 0.6 です。今回の記事では、バージョン 0.6 を元に解説していきます。

Miyako の特徴

Miyako には、コンテンツ制作を簡潔に実装できるクラスライブラリや Mix-in モジュールを用意しています。

ゲームなどのコンテンツを作成している時に、一番頭を悩ませるのが「シーン管理」です。シーン間の移動など、実装に困る箇所でもあります。 そこで、Miyako では、開発中に丁度バージョン 1.0 が登場した「Ruby on Rails」にヒントを得て*2、「ゲームを作る際のお約束」として大抵使われている「ゲーム開発のタスク」をクラスとして実装できるように実装しました。このような経緯で生まれたのが「Authorモジュール」です。

Author モジュールを Mix-in するクラスを Meditator ととらえて、各シーンをそれぞれ一つのクラスとして考え、シーン用の Template Class を継承して必要なメソッドをオーバーライドする方式をとっていますので、シーン構造を一から構築する必要がありません。 更に、「シーン間の移動」は、クラス名の一部 (Miyako 上では「移動ラベル」もしくは「ラベル」と読んでいます) をシーン終了時に返すことで実装しており、移動そのものは Miyako 内部で処理いたしますので、各シーンの実装だけに絞ることが出来ます。 ラベルは単なる文字列ですので、移動先のチェックが容易になり、デバッグしやすいのも特徴です。 以下に、Author モジュールの構造を図に致しましたので、ご参考ください。

Author_1.png Author_2.png Author_3.png

ちなみに、listup メソッドを使うことによって、実装したシーンの一覧を取得することが出来ますので、表計算ソフトなどを使ってシーン管理するなどといったこともできます。

「エフェクト」クラスは、Ruby/SDL を直接使ってスプライトに装飾を施すクラスです。登場や退場の装飾に、また、キャラクターに属性が付いたときのアイコン追加にお使いいただけます。これも、手始めとして、v0.6 では疑似ラスタスクロールを実装した「RasterScroll クラス」を用意しています。 エフェクトも、基本的にはテンプレートクラスを継承し、4 つのメソッドをオーバーライドすることで実装できるようになっています。概要を以下の図で表してみましたので参考にどうぞ。

Author_4.png

しかし、今後を考えると、いくら汎用とはいえどもそれが足枷となって開発効率が損なわれるならばそれは本望ではありません。 そこで、Miyako v0.6 から「Miyako Extension (miyako_ext.rb)」を追加しています。ここで、ジャンル毎に特化したクラスライブラリを用意することになります。今後は、この Miyako Extension をメインの開発に移す予定ですが、皆さんも是非ともそれぞれのジャンルに応じた Miyako Extension を作成してみてください。Miyako Extension については次章で……。

Miyakoの概要

Miyako は、「Miyako API」「Miyako Extension」という2つの構成要素で成り立っています。

miyako_structure.png

「Miyako API」では、ジャンルに囚われないゲーム製作するため、必要最低限の機能を持たせたクラスライブラリを用意しています。たとえば、ウィンドウを表示するのみ (表示するメッセージの実装は利用者任せ) の「Window クラス」、マップチップによるスクロールが出来る (マップ上で起こるイベントの実装は利用者任せ) ができる「Map・MapFast クラス」などがあります。必要最低限以外の箇所のみ実装し、利用者が改変・拡張する可能性が高い箇所は利用者に任せる方針を取っています。勿論、Sprite クラスなどもこの「Miyako API」に属しています。参考のために、以下に Miyako API のクラス階層図を載せておきます。

class_list.png

しかし、ここで疑問が沸き起こりました。Miyako 開発当初の理念のひとつに「Ruby 勉強のため、そのとっかかりを無くすため」というものがありますが、このままではどこから手を付けたらよいのか分からないのではないか、そうなると、最初の理念に矛盾してしまう。しかし、やはり拡張の余地は残しておかないと自由なゲーム開発に支障が出るのではというディレンマがありました。そこで、気楽にゲーム開発を行うために追加したのが「Miyako Extension」です。

Extension では、汎用的にゲーム製作に応用できる「Miyako API」とは違い、特定ジャンルに都合の良いクラスも用意しています (たとえば、「MessageBox クラス」はビジュアルノベル向けですし、「Dice」クラスは懐かしのゲームブックを実装するために用意したものです)。

しばらくは、僕自身がビジュアルノベルやゲームブック、アドベンチャーゲームを作りたいので、それに応じた Extension の拡張になると思います (自分の趣味でかよ!)。この記事を読んでいただいた方で、「アクションゲームに適した拡張ライブラリを作ってみたけど……」「やっぱこれでシミュレーションを作りたかったので用意してみました」という方がいらっしゃればご連絡ください。今後の開発の参考にしたいと考えています。

extended_class_list.png

Miyako のウィークポイント

……やっぱり、これ書かなきゃいけないですよねぇ……これ。弱点について。 もうお分かりかと思いますが、

処理速度

です。 この状態で、出来る限り処理の効率化を図ったのですが……なかなか思うようにいきませんです、ハイ。 汎用ゲーム制作ソフトを目指したつもりが、高機能とのトレードオフに悩まされました。得意分野となるのは、フレームレートをあまり気にする必要のないゲームになってしまうと思います。

後は YARV に期待です。ね、ささださん (何気にプレッシャー)!

Miyako の歩き方

さて、ここからは Miyako でのスクリプティングについて紹介していきます。 すぐに Miyako が利用可能な状態という前提で説明していきます。

インストールがまだという方は、以下の URL からダウンロードしてくださいませ。

まず、Miyako のスクリプトを格納するためのディレクトリを作成します。名前は、作ろうと思っているコンテンツに沿った名前にすると後々判別がやりやすくなります。

続いて、作ったディレクトリに、miyako.rb や miyako_ext.rb、システムフォント (標準は mikachan.ttf)、ウィンドウ部品画像、サイコロ画像等をコピーします。今回は Miyako Extension を使わないので miyako.rb とシステムフォントのみコピーします。

続いて、スクリプトファイルを作成し、$LOAD_PATH の設定をした後、miyako、必要ならmiyako_ext を読み込みます。今回は Miyako Extension を使わないので miyako.rb のみ読み込みます。

 require 'miyako'

……あ! これを先を言っておかないと! Miyako では、スクリプトで使用する文字コードを UTF-8N (BOM 無し UTF-8) を想定しています。これは、文字描画をするとき、UTF-8N での使用が前提となっているためです。

続いて、スクリプトの雛形を作りましょう。Miyako のスクリプトは、全て Miyako モジュール下にある (これは単なる便宜上の話ですが……クラス名にモジュール名を書く必要が無くなりますので……) ので、module ブロックを記述します

 module Miyako
  :
 (本文)
  :
 end

これから地でスクリプトを書いても良いのですが、最初にまとめて説明しておいたほうが良さそうなので、Author モジュールを Mix-in する形で実装していきましょう。クラス名は、「RubymaTest」にしておきます。

 module Miyako

   class RubymaTest
     include Author

   end

 end

続いて、シーンクラスを記述していきます。クラス名は、最初のシーンということで「Scene_first」とでもしておきましょう。更に、シーンクラスの基本クラス、Script クラスを継承しておきます。

 module Miyako

   class RubymaTest
     include Author

     class Scene_first < Script
     end

   end

 end

最後に、シーンを実行するために、RubymaTest クラスのインスタンスを作成し、run メソッドを呼び出します。run メソッドの引数には、Scene_first クラスから「Scene_」を省いた "first" です。この文字列を Miyako 上では「ラベル」と呼びます (実は、「Scene」はプレフィックスで、Author モジュールのモジュール変数 @@class_prefix を変更することで、プレフィックスを「Paragraph」や「Area」に変更できますそのとき、ラベル first に対応するクラス名は「Paragraph_first」「Area_first」になります)。

 module Miyako

   class RubymaTest
     include Author

     class Scene_first < Script
       (ここにシーン本文を記入)
     end

   end

   rt = RubymaTest.new
   rt.run("first")

 end

これで、シーンの雛形が完成しました。 これから、シーンを定義していきましょう。まずは、ゲームパッドの 1 番目のボタン (Zキー) を押せば終了するスクリプトを組んでみましょう。これは、Scene_first クラスの update メソッドをオーバーライドすることで実装できます。

 class Scene_first < Script
   def update
     return nil if Input.pushed?(Input::BTN1)
     return @now
   end
 end

Input.pushed? は、「指定したボタンかキーが押されたときに true を返す」モジュールメソッドです。もし1番目のボタンが押されたら nil を返すようにしています。

update メソッドの返却値は、移動先のラベル (つまり、クラス名のプレフィックスに続く文字列) を指定しますが、そのとき、nil を返したときは、rt インスタンスの run メソッドを脱出します。つまり、スクリプトを終了します。

次の「return @now」は、同一クラスの update メソッドを繰り返しためのものです。実行しているインスタンスの属しているクラスのラベルと返却値が等しいなら、update メソッドを繰り返し実行します。つまり @now は、現在実行しているインスタンスが属するクラスのラベルを指しているわけです。

さて、ここまで組んでみたら実行してみましょう。すると、真っ黒な画面が現れます。 これは、Miyako が起動して、キー入力を待っている状態です。このとき、1 番のボタンか Z キーを押すと終了すれば、スクリプトが無事記述できていることになります。

screen.png

これで、基本的な流れは終了です。後は、グラフィックを表示させたり、操作したりすることで実装できます。

グラフィックスを用いた例として、Miyako v0.6 のサンプルスクリプトで、「るびま」の第5回で掲載した RGSS 用のサンプルスクリプトを Miyako に移植したものがありますので、Author を使って書き直しいたしました。今回はこれを掲載します。

 #! /usr/bin/ruby
 # Miyako サンプルスクリプト
 # 「るびま」で掲載した RGSS 用スクリプトの Miyako 版 (Author 使用)

 require 'miyako'

 module Miyako

 setTitle("るびまサンプル・Miyako版")

 class Spr
   def initialize(name, vp)
     @final = false
     @sp = Sprite.load(name)
     @sp.setViewPort(vp.x, vp.y, vp.w, vp.h)
     @sp.x = 0
     @sp.y = 0
     @sp.visible = true
     @stride = 8
   end

   def rect
     @sp.rect
   end

   # 画面の端っこにぶつかっていないかのチェックも行う
   def adjustment(n, min, max, size)
     if n < min
       min
     elsif n + size > max
       max - size
     else
       n
     end
   end

   def update
     br = @sp.rect
     sr = @sp.viewPort
     # 移動量の算出
     dx, dy = Input.triggerAmount

     @sp.x = adjustment(@sp.x + dx * @stride, sr.x, sr.w, br.w)
     @sp.y = adjustment(@sp.y + dy * @stride, sr.y, sr.h, br.h)
   end
 end

 class RubymaSample
   include Author

   class Scene_main < Script
     def initialize(n)
       super # 必須!
       # 表示範囲は画面一杯
       @sp = Spr.new("ruby.png", Rect.new(0, 0, 640, 480))
     end

     def update
       return nil if Input::quit? || Input::pushedEscape? || Input.pushed?(Input::BTN2)
       @sp.update()
       return @now # 必須!
     end

   end
 end

 rs = RubymaSample.new
 rs.run("main")

 end

RGSS 版との大きな違いは、それぞれの処理の立場が分かりやすくなっていることと、以前は配列を使っていた移動キー入力による移動量の設定をクラスライブラリレベルで実装していることでしょうか。

Scene_main クラスの initialize メソッドで、ruby.png からスプライトを作成し、update メソッドで、入力に応じたスプライトの移動を行っています。ウィンドウの「×」ボタンを押す、ESC キーを押す、2番目のボタン (X キー) を押すことで終了します。

このスクリプトでは、Scene_main クラスの initialize メソッドで引数を渡して super を呼んでいますが、これは、@now 変数が "main" ラベルを指すようにしているので super を忘れないようにお願いします。

あとは、それほどトリッキーなコーディングはしていませんので説明は省略します (笑、ってか、これ RGSS の解説でもやったぞ……) が、今回はサンプルコードをイメージファイル付きでダウンロードできるように致しました。

サンプルコードダウンロード

今後の展望 (淡め)

現在、Miyako はゲーム製作メインで開発を進めていますが、将来的にはプレゼンテーション向けのクラスライブラリを開発できたらなぁと思っています。Sprite クラスを応用した Shape クラス (プレゼンで良くある図形を簡潔に描画するためのクラス) 等の実装も考えています (いつ実現するかは分かりませんが……)。 他は、有志の方々の拡張ライブラリや製作ゲームの紹介をする Wiki なんかを用意できればと思っています。

あと、こういうのを作ったわけですから、やっぱり何らかのゲームを作ってみたいですね。最初はビジュアルノベルかゲームブックを。そのために Ruby Extension を (しつこいので略)。

最後に

今回、Miyako についてサラッと紹介していきましたが、いかがでしたでしょうか? 今のところ、まだ実装上問題がある箇所がありますが (いや、めっちゃあるやろ!)、今後も扱いやすく、勉強の参考になる (かなぁ……) ように心がけていきたいと思いますので、ご意見・ご要望・応援のお便りを、E-mail・Skype 等でお待ちしています。

EGSR 開発の動機となったのは、「ここまで Ruby を使って行けたのも、皆さんのご助力のおかげ。そろそろ何らかの形で Ruby で恩返ししたいなぁ……」という気持ちが心の隅っこにあったためです。しかも、コンテンツ制作クラスライブラリという、趣味と実益を兼ね備えた形で貢献できつつあるのは僕自身にとって有意義に感じています。 まだまだ完成とはほど遠いですが、暖かく見守っていただきますよう、よろしくお願いいたします。

「剣の師である父にこう言われました   己の剣の技を人のために役立てよ と」 五条都 *3

自己紹介

RGSS の時は京都の南端でしたが、今は別の場所でなんやかんやとやっております。ちなみに、僕が住んでいるところはこないだ政令指定都市になったところです (バレバレ)。今や市民から区民ですよ! 引っ越ししてないのに (笑)。 最近は本業やら Miyako やらでテンテコマイです。勉強会が終わったら休息したい……。 あと、昔趣味でイラストを描いていたのですが、Miyako の開発で結構イラストが必要になって再びイラスト熱が高じています。ついでに自筆のイラストを載せておきます (ヲイ)。

jigazo.png

  • E-mail : cyross at po.twin.ne.jp
  • Skype 表示名 : cyross