akashic製ゲームのビジュアルテストツールアップデートとPlaylog


この記事は、Akashic Engine Advent Calendar 2019の23日目の記事です。(インフルエンザを発症してしまった影響で遅刻してしまいました。。)

はじめに

この前紹介しましたakashic製ゲームのビジュアルテストを行うためのツールをバージョンアップした話をしていきます。今回はツールについて知っていることを前提に説明していきますので、ツールについて知らない方は以下の記事を参照していただければと思います。

また、ツール(akashic-contents-reftest-runner)とツールを動かすためのライブラリ(akashic-contents-reftest-helper)のリポジトリは以下の通りです。

変更内容と使い方

ゲームを自動実行するためのシナリオをsandbox.config.jsから取得していましたが、代わりにplaylog.jsonというファイルから取得します。
これまでのrunnerでは実行タイミングによってスクリーンショットの取得時に何フレームかずれることもあったのですが、playlog.jsonを利用することによっていつ実行しても同じタイミングでスクリーンショットが取得できるようになりました。

次に新たにアップデートしたrunnerとhelperの利用法についてですが、どちらも以下の方法に従ってインストールしなおします。

runnerについては前回の説明と同様に実行することが可能ですが、helperをインストールしたテスト対象のゲームではいくつかの修正が必要になります。
まず、テスト対象のゲームのエントリポイントを以下のように変更します。

- var reftestHelper = require("@dera-/akashic-contents-reftest-helper");
- reftestHelper.init(scene); // このファイル中で定義しているsceneを引数として渡す
+ require("@dera-/akashic-contents-reftest-helper");

これまではhelperの機能を利用するためにhelperのinit()を呼び出す必要があったのですが、今回のバージョンアップではそれが不要となりました。

playlog.jsonの内容

次に、playlog.jsonに記述する内容についてですが、大まかには次のように記述します。

{
    "tickList": [
        0, // 開始フレーム数(number)
        700, // 終了フレーム数(number)
        [
            [0, [Event, ...], null], // 0番目の要素にはフレーム数を、1番目の要素にはその時に起こすEventを記述
            ...
        ]
    ],
    "startPoints": [
        {
            "frame": 0, // 開始フレーム数(number)
            "timestamp": 1575475970578, // 開始unix時間(number)
            "data": {
                "fps": 30,
                "startedAt": 1575475970578
            }
        }
    ]
}

このようにゲームの開始フレームから終了フレームまでを定義して、さらにその間に発生するEventを定義することができます。
このデータ構造はゲームの実行ログ(Playlog)を表していて、akashic-cli-serveに--debug-playlogオプションでこのデータを指定して流すことによって、毎回フレーム単位でPlaylog通りの操作をする様子を映像のようなものとして取得することができます(runnerの新しいバージョンではまさにakashic-cli-serveのこのオプションを利用しています。)。

Event

ここではEventについての説明をしていきますが、以下の説明はPlaylogリポジトリのREADMEからのほぼ抜粋ですので、詳細はそちらを参照してください。
Event はゲーム中で発生する出来事を表すデータで、以下のものを定義することができます。

EventCode イベント
0x0 プレイヤー参加
0x1 プレイヤー離脱
0x2 時間の記録
0x20 汎用的なデータ
0x21 ポイントダウン
0x22 ポイントムーブ
0x23 ポイントアップ
0x40 操作プラグイン

Event 共通のデータ・フォーマットは以下のようになります。

Index オプショナル 説明
0 number NO EventCode
1 number NO プライオリティ
2 string NO プレイヤーID

インデックス2番以降は各イベントのデータがセットされます。
以下では、ビジュアルテストのシナリオとして使うことになるであろうEventについて説明していきます。

MessageEvent (0x20)

汎用的なデータを表すイベントを表します。

Index オプショナル 説明
3 any NO 汎用的なデータ

ビジュアルテストツールでは、スクリーンショットの取得やゲーム終了といったシナリオ実行のためにこのイベントを使います。
それらシナリオ実行時のデータの型は以下のようになります。

{
    type: "scenario";
    command: {
        name: "screenshot" | "finish"; // screenshotでスクリーンショットの取得、finishでゲーム終了
        options?: any; // nameがscreenshotの時、{filename: "出力ファイル名"}を指定する必要があります。nameがfinishの時、何も値を指定する必要はありません。
    };
}

PointDownEvent (0x21)

ポイントダウンイベントを表します。

Index オプショナル 説明
3 number NO ポインターID
4 number NO X座標
5 number NO Y座標
6 number YES エンティティID

PointMoveEvent (0x22)

ポイントムーブイベントを表します。

Index オプショナル 説明
3 number NO ポインターID
4 number NO X座標
5 number NO Y座標
6 number NO ポイントダウンイベントからのX座標の差
7 number NO ポイントダウンイベントからのY座標の差
8 number NO 直前のポイントムーブイベントからのX座標の差
9 number NO 直前のポイントムーブイベントからのY座標の差
10 number YES エンティティID

PointUpEvent (0x23)

ポイントアップイベントを表します。

Index オプショナル 説明
3 number NO ポインターID
4 number NO X座標
5 number NO Y座標
6 number NO ポイントダウンイベントからのX座標の差
7 number NO ポイントダウンイベントからのY座標の差
8 number NO 直前のポイントムーブイベントからのX座標の差
9 number NO 直前のポイントムーブイベントからのY座標の差
10 number YES エンティティID

playlog.jsonをより簡単に取得する方法

ここまでplaylog.jsonの書き方について説明してきましたが、Akashic Sandboxという公式で提供されているデバッグツールにPlaylogを取得する機能がありますので、その使い方を説明します。

  1. Akashic Sandbox をお使いのPCにインストールしていない場合はnpm install -g @akashic/akashic-sandboxでインストールします。
  2. Playlogを取得したいゲーム上でAkashic Sandboxを起動します。起動方法について詳細はこちらを参照してください。
  3. Akashic Sandbox起動後、しばらくゲームをプレーします。
  4. その後、画面右側の歯車アイコンをクリックして、「Replay」タブを選択して、「今までのリプレイ情報を保存」ボタンを押します。
  5. 「保存されているリプレイ情報一覧」に現在のタイムスタンプ名のPlaylogが出現しますので、ファイル出力ボタンで保存します。
  6. ファイル名がunixタイム.jsonになっているので、playlog.jsonにリネームしてそのゲームのディレクトリに置いておきます。

ただし、ここで取得できるplaylog.jsonにはスクリーンショット取得やゲーム終了といったシナリオ実行のためのMessageEventは一切記載されていないので、直接追記する必要があります。

まとめ

ここまでアップデートしたrunnerとhelperの利用法と併せてPlaylogについて簡単に説明してきました。
playlog.jsonの記述が若干煩雑ではありますが、Akashic Sandboxを利用することによって比較的容易にplaylog.jsonを生成することもできます(その場合でもスクリーンショットの取得やゲーム終了のためのMessageEventの追記は必要ですが)。
playlog.jsonさえ生成できれば、前バージョンより高精度のテストが可能になるかと思います。