私は趣味で Rmake という RPG 作成ソフトを開発しています。このソフトを開発する際に使っている手法を紹介します。


■ 問題
○ 背景
Rmake では、ゲーム実行中に以下のような一連の命令を実行する処理を行います。

1197830076_20071217_01.png

1. 街の中で道を歩く「村人」に話しかける
2. 文章を表示する「こんにちは。今日もいい天気だね。この街には慣れたかい?」
3. はい/いいえの選択
4.a 「はい」を選択した場合
4.a.1 文章を表示する「それはよかった。」
4.b 「いいえ」を選択した場合
4.b.1 文章を表示する「そうか。困ったことがあったら言いなよ。」

以下の画像は、この一連の処理(イベント)を実現するためのエディタ画面(イベントエディタ)です。右側の「コマンドリスト」から実行したい命令(例「文章を表示する」)を選択して、「命令一覧」というツリー構造に命令を追加していきます。ツリー上のノードをダブルクリックするとそれぞれの命令を編集するエディタを開くことができます。

1197830100_20071217_02.png

この命令のツリーをオブジェクト図に起こしたものは以下のとおりです。



○ どのような問題があるのか
このようなアプリケーションは、「文章を表示する」「はい/いいえの選択」というような命令の種類が多ければ多いほどその価値が高まっていきます。(作れるゲームの種類が増えていくためです。)したがって、命令を追加する手間が少なければ少ないほど良いことがわかります。そこで、命令を一つ追加する場合の開発手順を見てみます。

1. 命令(Order)クラスを実装する
2. 命令エディタを実装する
3. 使用可能な命令をリストに表示する
4. 命令エディタを命令に応じて呼び出す処理を修正する
if (order.orderType == TextWindowOrder) 
{
	textWindowEditor.Show(order);
}
else if (order.orderType ==...


5. 実行(Processor)クラスを実装する
6. 実行クラスを命令に応じて呼び出す処理を修正する
if (order.orderType == TextWindowOrder) 
{
	textWindowProcessor.Execute(order);
}
else if (order.orderType ==...


参考として、命令、命令エディタ、実行クラスの関係を記述したクラス図を載せます。



影響範囲はそれほどではないとは言え、それなりに手間がかかります。3、4、6 を自動化することができれば、二つの利点を得ることができます。
(1) 命令の追加コストを下げることができる
(2) プラグインなどで命令の実装を外出しすることができる

○ どのような実装にするか?
方針としては、以下のようになります。

・ 命令クラス「TextWindowOrder」というクラスがある場合、実行クラス「TextWindowProcessor」を自動的に呼び出す。
SelectProcessor クラスの SelectProcessor() メソッドを参照。

・ 命令クラス「TextWindowOrder」というクラスがある場合、エディタクラスで属性「OrderEditor(typeof(TextWindowOrder))」を持つクラスを自動検索して、呼び出す。
OrderEditorLoader クラスの GetOrderEditor() メソッドを参照。

・ 命令クラス「TextWindowOrder」というクラスがある場合、イベントエディタのコマンドリストに自動的に選択可能な命令を追加する。
OrderSelectListPanel クラスの ShowOrderList() メソッドを参照。

総じて言えば、命令のクラス名からリフレクションを使って、実行クラスやエディタクラスを自動的生成するようになっています。

○ 改善後の命令追加時の開発手順
(A) 開発手順が効率化された
1. 命令(Order)クラスを実装する
2. 命令エディタを実装する
3. 実行(Processor)クラスを実装する

(B) 外部 DLL を読み込む機構を作れば、一連の命令を外部プラグインから読み込めるようになった

一部、属性(アノテーション)も使っているのですが、クラス名のルールを守ることで、実装コストを省力化する一種の「Convention over Configuration」が実現されています。いま時のアプリとしてはそれほどとんがった実装ではないというか、割とレトロな実装だと思います。それにしても、いまさらながらリフレクションは便利だと感じました。(動的言語なら、はるかに柔軟に書けますけど。)

○ 補足
この命令クラス、実行クラス、エディタクラスの仕組みは、「魔法」や「アイテム」の実行でも利用されています。

Rmake のソースコードはこちらから取得できます。
http://svn.kodougu.net/rmakeretro/trunk/

UML の図の作成は Kodougu を使用しています。

Posted by あかさた
最近のエントリ
最近の読書メモ