はじめまして。ピグエデンでパズル部分を担当しているhoshiと申します。
今回はパズル開発の観点から、開発で出てきたポイントと実施しているテスト・運用について紹介させていただきます。

ピグエデンについて

まず、ピグエデンについて紹介させてください。
ピグエデンは、パズルをクリアしてデコアイテムを集め、自分だけのガーデン(お庭)をつくる、パズル×箱庭ゲームです。
アプリはUnityで作成しています。

パズルパートは、お花モチーフのピースを揃えて消していくマッチ3ルールでさまざまなお題をクリアしていきます。
箱庭パートでは、自分だけのお庭が与えられ、自由に模様替えを楽しむことができます。模様替えに必要な家具アイテムは、パズルをクリアして入手できます。
プレイヤーはガーデナー(庭師)となり、豊富に用意された家具アイテムを組み合わせ、世界にひとつしかない個性的なガーデンづくりを目指す。
といったゲームで4/23にリリースされたばかりです。是非遊んでみてください。


パズルステージデータの作成について

まず、パズルのステージですが、以下のようなステージ作成ツールで担当者が作成します。

ステージ作成ツールテストプレイ

テストプレイもツール上で行えるので変更とテストプレイを繰り返してステージの精度を上げていき、 JSON形式でステージデータをファイル出力します。
※運用の都合上、ファイルでステージデータのやりとりをしています。


パズルの開発でのポイント

今回、俗に言うマッチ3パズルを開発してみてなのですが以下がポイントとして挙がってきました。

仕様が複雑で細かい

動作パターンやギミックによってかなりの組み合わせがあり、仕様がとても複雑です。
例えば、以下の2つはピースがL字にマッチしたときにSPピースが含まれているケースです。

例1

L字マッチ例1
  • Aのピースを下に動かす
  • 青いピースがL字でマッチし、BのSPピースが発動
  • L字マッチなので丸いSPピースが生成されるが、BのSPピースの効果(横一列消去)に巻き込まれて即発動(わかりづらいですが丸い光の部分です)

例2

L字マッチ例2
  • Aのピースを下に動かす
  • 青いピースがL字でマッチし、AのSPピースが発動
  • AのSPピースの効果で横一列消去
  • L字マッチなのでBの丸いSPピースが生成される

このようにマッチ時に動かすピースの種類によってSPピース発動/SPピース生成のタイミングに違いがあったりします。
こういった細かい仕様がかなり多く、全てを把握するのはけっこう大変です。

パズルの仕様・動作が伝わりづらい。

前述のような仕様を仕様書(テキスト)だけで残すとしたら、

マッチ時のSPピース生成で、マッチを構成するピースにSPピースが含まれる場合、SPピースを動かした場合のSPピース生成は、動かしたSPピースの効果発動後に行われ、動かしたSPピースの効果を受けない。

といった感じでしょうか。これだと多分伝わらないですね。。

このように、テキストだけで仕様や動作を伝えるのはかなり難しいです。(とはいえ、ある程度の概要は仕様書として残さないとダメですが。)
上の2つの例のように、画面のキャプチャと仕様の比較対象も併せてなんとか伝わるかなぁという感じですが、毎回キャプチャを撮っていくのは仕様変更時のメンテナンスも含めると運用コストはかなり高いです。
またこのように複雑な仕様が多く、伝えるのが難しいとなると各所からの仕様問い合わせ、テストチームにテストを依頼する場合などのコミュニケーションコストが大きくなることも予想されます。

改修時のリスクが高い

複雑な仕様で、仕様書もわかりづらい。
となると改修時に意図しない箇所に影響があり動作が変わってしまうことやデグレの発生が懸念されます。リリース後の改修で意図せずにパズルの基本ルールの動作が変わってしまうのはだいぶマズイです。
またメンバーの異動もよくあることなので、属人化せずに誰でもコードを触れるようにしておきたい。


テストの導入

前置きが長くなりましたがここから本題のテストについてです。
前述のポイントへの対応としてテストの導入を行いました。

テスト環境とテスト対象

開発環境のUnityバージョンの関係もあり、テストフレームワークとしてUnityTestToolsのIntegrationTestを使用しました。
また、テストの対象は一旦、パズルの盤面データのみを対象としています。なので本来のIntegrationTestとは少し使い方が異なるかと思いますのでご留意ください。

先にテストが動いているのを見てもらうとこんな感じ。
(既存のテストケースのなかからいくつか抜き出したものになります)

ざっくりいうと、

  • テストしたい状態のステージ盤面を読み込み
  • テストしたい操作を実行させる
  • 結果を検証する

を繰り返す自動テストになります。

テストケースの作成

では、どのようにテストケースを作るかについて。
下図の赤枠部分がテストケースとして必要になるものです。

テストケースの作成概要図

テストケース(データ)作るのが面倒だとテスト運用が上手く回らないという過去の経験も踏まえて、なるべく簡単にテストケースを作れるようにしています。
具体的にはテストケース単位に以下の3つを用意します。

ステージデータ

テスト用のステージデータです。前述のステージ作成ツールで作成します。
テスト実行時にこのデータを読み込んでパズルの盤面を再現します。

チェック用データ

こちらも前述のステージ作成ツールでのテストプレイ時に以下を保持/出力して作成します。

  • 操作(どこをどう動かしたか)
  • 操作後の各種ステータス
    • ターン数
    • クリア目標進捗
    • スコア
    • チャージ状態
    • 盤面の各グリッドの状態(ピースの種類や障害物の強度など)
    • etc…

操作単位のデータをリストで持っており、こちらを元にテスト時に盤面の操作を行い、各種ステータス/盤面のグリッドのデータと突き合わせてテストの正誤を判定します。

テストクラス

クラス作成ウィンドウ

Sceneのロード/アンロード、盤面の生成、操作、検証といった処理を持つベースクラスを継承したクラスを作成します。固有の処理をしたい場合は、オーバーライドして行います。
UnityのEditorWindow上からの操作で作成できるようにしてあり、操作としては前述のステージデータとチェック用データの配置してあるディレクトリを選択するだけになります。

以上のように、

  • ツールで盤面作成(ステージデータ作成)
  • テストプレイ(チェック用データ作成)
  • EditorWindow上でディレクトリ選択(テストクラス作成)

でテストケースを作成できるようにして、手間と複雑さをなるべく省くようにしています。

テストの実行

テスト実行の流れは以下になります。

テスト実行概要図
  • パズルSceneをロード。
  • ステージデータを元に盤面生成。
  • チェック用データに持っている操作を行う。
  • 操作後、チェック用データに持っている「操作後の各種ステータス」と突き合わせてチェック。
  • 操作とチェックを繰り返す。
  • 全ての操作とチェックが終わったらパズルSceneをアンロード。
  • 次のテストケースを実行。

という感じで実行されます。
ちなみに、排出ピースやクリア時の残ターンのSPピース置き換えといったランダム箇所はテストケース作成時とテスト実行時に制御を入れて、同様の動作になるようにしてあります。

テストケースは各種ピースやギミックの組み合わせ、操作パターンを網羅して(したつもりで)作成しており、改修とテスト実行をセットにすることで、複雑な仕様を完全に把握していなくても改修による想定外の影響やデグレ等が防げ、改修内容に問題がないか判断がつきます。
なので、新しいメンバーも開発に入りやすく、結果として属人化しなくなることも見込めるかと思います。(テストの効果として改めて言うことでもないかもしれませんが。)


仕様の伝達精度とテストチームでのテスト実施

次に、仕様の伝わりやすさ向上のための取り組みとテストチームでのテスト実施方法について紹介させてください。

ざっくり概要は以下になります。

仕様動画とテストチーム概要図

動画で仕様を伝わりやすく

テストケースはパターンを網羅して作成しており、テスト実行時の動画をキャプチャして残すことで仕様が伝わりやすくなるようにしています。
上図の赤枠部分になります。QuickTimeでキャプチャして、FFmpegでテストケース毎に分割というあまりいけてない構成なのですが、テストケース単位に動画を残しています。(開発環境のUnityバージョンの関係上、Recorderが試せていないのですが、今後導入できたらと考えています)
たとえば、仕様の問い合わせ等あった場合、テキストだけで仕様を伝えるのはなかなか難しいので該当するテストの動画も渡してなるべく簡潔に伝わりやすいようにやりとりを行っています。

テストチームでのテスト実施

ピグエデンではアプリのリリース(バージョンアップ公開)前に動作テストをテストチームに実施してもらっています。
想定できる箇所のテストは前述のテストで賄えるはずなので、主に端末差分がありそうな箇所をiOS/Androidの複数バージョン・端末で確認してもらいます。
この時、テスト仕様をテキストだけで伝えるのはやはり厳しく、また、テスト担当者の方も変更になることあると思うので、コミュニケーションコストは大きくなりそうです。
そこで、テスト専用アプリの作成とテスト動画でコスト削減を図っています。
上図の青枠部分になります。

  • テスト実行時にテストチーム依頼対象のステージのリストを記述したファイルを出力。
  • テスト専用アプリのビルド時に該当のステージデータを含めてビルド。
  • テスト担当者にテスト専用アプリをインストールしてもらう。
  • 該当するテストケースの動画を検証用動画としてテスト担当者に渡す。
  • テスト担当者にはアプリの動作が検証用動画と同じか?だけ見てもらう。

これによりテスト仕様書の作成・メンテナンスやコミュニケーションのコストを下げられたのではないかと思います。
また、テストの観点はアプリの動作が検証用動画と同じか?だけなので、もしもテスト担当の方が変わったとしてもほぼ事前知識無くチェックして頂くことが可能になります。

※テストチームへの依頼対象とするかは、前述のテストクラス生成時にチェックボックスで選択できるようにしてあります。

クラス作成ウィンドウ

チェック用データの一括再作成

ここからはちょっと余談的な話です。
現時点でテストケースは600件以上あり、もしもスコアの計算式のような全てのテストケースに関わるような箇所の仕様変更が入ってしまった場合、全てのテストケース(チェック用データ)を修正する必要があります。
600件以上のテストケースを手作業で作り直すのはツラすぎるし、動かすピースを間違えたなどの操作ミスで本来の意図どおりのテストにならない可能性もあります。
そこでチェック用データの一括再作成もできるようにしています。
処理の流れとしては、テスト実行とほぼ同じで実行後にチェック用データを書き出し直しています。

チェック用データの一括再作成
  • パズルSceneをロード。
  • ステージデータを元に盤面生成。
  • チェック用データに持っている操作を行い、「操作後の各種ステータス」を保持
  • 全ての操作を行う。
  • チェック用データを書き出し直し。
  • パズルSceneをアンロード。
  • 次のテストケースを実行。

このように、多くのテストケースに影響のあるような仕様変更は一括で再作成し、手作業での時間とミスを無くすようにしています。
とはいえ、そもそもの改修の検証は充分に必要です。改修にミスがある状態で一括再作成をしてしまうと、誤ったテストケースが大量にでき、障害につながってしまうという恐ろしい状況になってしまいます。。
また、全ての仕様変更に適用できるものではないので、実行には充分に注意が必要になります。(と、自分への戒めも込めて)


課題

前述の通り、現状テストケースが600件以上あり、全てのテストケースを実行すると2時間弱掛かるという課題があります。
なんらか複数インスタンスでテストを分散実行できるようにし、処理時間の削減をしたいところです。
ただ、インスタンス毎にUnityのライセンスが必要ということもあり、現在は開発者各自のPCでテストを実行してる状態です。
今後、機能追加とともにさらにテストケースが増えていくと思われるので早めに解消したい問題です。


最後に

こういった開発の場合、仕様の複雑さがゲーム自体の面白さや幅の広さにつながっていく部分もあるので、仕様が複雑になるのはある程度仕方がないかと思います。
ただ、その中で改修によるデグレ等のリスクや運用コストを如何に下げられるかというのが大事で、出来る限り早い時期に取り組むことが必要と感じました。

ピグエデンはリリースしたばかりで、サービス自体も運用手段もまだまだ改善点はたくさんある状態ですので、より良くしていけるように取り組んで行ければと思います。
また、バグ等発見された場合はテストケースに追加させていただきますので、お問い合わせいただけると非常に助かりますmm

hoshi
2012年中途入社。サーバサイドエンジニアをしばらくやった後、WebフロントとかUnityとかやってます。