ターン制RPGを作るときに知っておきたい「ロジックと演出の分離」

はじめまして。
ランカースのプログラマーの尾関です。

弊社は「世界樹の迷宮」「ロストヒーローズ」など、ターン制RPGの開発を得意としています。そこで、今回はターン制RPGを作る際に、知っておくと開発が楽になるプログラムの技術を紹介します。

■ターン制ゲームに共通すること

これはターン制RPGに限らないことですが、ターン制のゲームはたいてい、入力した結果が「遅れて」発生します。例えば、一般的なRPGでは、プレイヤー側のキャラクター全員のコマンド入力が完了した後、それに対する結果が再生されます。

このようなコマンドを入力した後の結果として、

というような行動結果が再生されることになります。ユーザはこの結果を見て、次のターンどうするかを考えるのが、ターン制RPGの醍醐味となります。
ここで、ゲームにおける狩人の処理の流れを見てみます。

  1. 狩人の行動開始演出の再生
  2. 攻撃力アップスキル発動演出の再生
  3. 攻撃力アップ演出の再生
  4. 狩人の攻撃力を20上昇する

通常のゲームであれば、「攻撃力がアップした」というメッセージを表示するだけではなく、誰が行動し、そのキャラが何をしているのかをわかりやすく表現するために「演出」を行います。この「演出」は、エフェクトに限らず、キャラクターのモーションやサウンドの再生を含みます。

ただ、それら演出を除いた部分で、ゲームルールに本当に必要な処理は「4. 狩人の攻撃力を20上昇する」だけです。この部分を「ロジック」と呼び、これを「演出」から分離を行うことで効率的に開発を行うことができる、というのが今回の主題となります。

■なぜ「演出」と「ロジック」を分離するべきなのか?

先ほどの狩人の処理を、そのままswitch文で実装すると以下のようなコードになります。

なぜこのように書く必要があるのかというと、演出は「再生の完了を待つ」必要があります。そのため演出の完了を待つタイミングが存在し、状態用の変数(ここではm_Step)を保持する必要があります。
この記述方法は処理の流れを把握しやすいのですが、変更に弱いという欠点があります。

例えば、ゲームデザイナーから以下の修正要望が発生したとします。

このような変更が発生した場合、覚醒後スキルの演出が追加となり、先ほどのswitch文の途中にその処理を挟み込む必要があります。
このようなswitch文は、挟み込む場所を探すのが面倒ですし、前後の処理が不自然にならないよう注意して追加する必要があり、なかなか大変です。

そこで、「演出」と「ロジック」を分離すると修正処理が簡単になります。

■「演出」と「ロジック」の分離
「演出」と「ロジック」の分離は以下のように行います。
キャラをActorクラスとします。

  1. Actorのパラメータを一時的なActorにコピー
  2. テンポラリで計算を行い演出データを生成
  3. 演出キューを上から順に実行 (Actorへのパラメータ反映も同時に行う)

演出とロジックの分離

先ほどのswitch文で修正が困難な理由は、「演出の完了待ち」がところどころに挟まるためです。
そのため、「演出」と「ロジック」を最初にまとめて計算し、「演出の完了待ち」を後で行う、というアプローチに変更しています。

このように修正することで、以下のように書くことができます。

switch文や、演出完了待ちがなくなり、コードの見通しが良くなりました。
これで、もし演出を追加することがあっても、簡単に修正を行うことができるようになります。

ただ、実際には、演出データクラスの定義や、生成した演出キューを再生する処理が必要になったりするため、全体のコード量は増えます。しかし、一度仕組みを作ってしまえば、処理の追加や入れ替えがとても楽にできるようになります。

■最後に
このやり方は、正確には「演出」と「ロジック」を分離できていませんが、基本的な考え方は演出の再生タイミングに依存せずにロジックの計算を行う、というものです。
なお、この考え方はすべてのターン制ゲームに応用することができます。
例えばローグライクを作るときでも、プレイヤーがアイテムを投げた際に「投げたアイテムがどの敵に当たるのか」「敵に当たって何ダメージ入るのか」「その後の敵はどのように行動するのか」ということをすべて事前計算して演出データを生成し、あとは演出データを再生するだけ、という作りにしておくと処理の入れ替えや演出の待ち時間の調整などがとてもやりやすくなります。

Tweet about this on TwitterShare on Facebook0Share on Google+0

コメント投稿は締め切りました。