新規ゲームへの対応手順
はじめに
新規ゲームに対応するためには、Collision Checker のソースコードを適切に書き換える必要があります。 そのための準備として、以下のことを行ってください。
Python/costom/
フォルダ以下にあるalfort
フォルダもしくはunity_demo
フォルダのコピーし、フォルダ名を対象のゲーム名(もしくはプロジェクトコード)にリネームします。- ツールが対象とするコードは
Python/costom/__init__.py
で切り替えるようになっています。Python/costom/__init__.py
内の各 import 文の対象フォルダを 先ほどリネームしたフォルダ名に置換します。 - マップスキャンで得られたスキャンデータ類 (
/Python/map_data/{ゲームID}
フォルダ以下) をPython/data/{ゲーム ID}_{テスト ID}/
以下に配置します。
各種データの用意
- コリジョンチェックの実行結果を可視化するためのツール内で表示するゲーム内マップ画像を用意します。 テストを行いたいマップ単位で別々の画像を用意してください。
- 画像が用意できたら
Python/res/
以下に配置してください。 また、テストを行いたい各マップのコード名 (以降マップ ID と呼びます) を決め、 画像のファイル名が{マップID}.{拡張子}
となるようにしてください。 以降、このマップ ID を Collision Checker を含めた各ツールのコード内で使用することになります。 また、このマップ ID は Map Scanner でも扱われますが、既に Map Scanner 側で決められている場合はそちらに合わせてください。 - 事前準備 を参照し、手順 1~5 を済ませます。
コード変更箇所
custom/{ゲーム ID}/custom_util.py
ゲーム固有の汎用関数が定義されているコードです。
copy_savefile()
- 指定したマップ用のセーブデータを
Python/data/{バージョン ID}/{マップ ID}
フォルダからゲーム側のセーブデータフォルダにコピーする関数です。
ゲームに応じてコピー先を適切なパスに指定してください。 Unreal Engine であれば、コピー先となるセーブデータフォルダはWindowsNoEditor/{ゲームのコード名}/Saved/SaveGames/
以下にあると思われます。
また、ゲームによってセーブデータの仕様が異なる場合があるため、適切な処理を行ってください。 例えば、サンプルゲームではセーブデータのロードには「ファイル名が可変であるセーブデータ本体」と「ファイル名が不変である SharedData.sav」の 2 種類のファイルが必要となります。 - また、当関数の返り値を以下の仕様に合わせてください。
None
(セーブデータのファイル名が一定 or セーブデータが存在しないゲームの場合)- 読み込むべきセーブデータを一意に特定できる何らかの文字列 (セーブデータのファイル名が一定でないゲームの場合)
- 指定したマップ用のセーブデータを
custom/{ゲーム ID}/state_machines.py
テスト中にプレイヤーキャラクターが取る行動のうち、ゲーム固有のものが記述されているコードです。
class CustomDebugMoveState
>move()
- 実際にデバッグ移動を行う時の操作を定義する関数です。
どのボタン or スティックを使えば移動できるかはゲームによって異なるため、仕様に合わせて適切に記述してください。
この関数は上記の
step
関数を経由して毎フレーム呼ばれるものであるため、 1 フレーム単位での操作方法を記述しなければならないことに注意してください。
- 実際にデバッグ移動を行う時の操作を定義する関数です。
どのボタン or スティックを使えば移動できるかはゲームによって異なるため、仕様に合わせて適切に記述してください。
この関数は上記の
svrun_client_logic.py
テスト実行時のクライアントエージェントの挙動を司るコードです。
class CollisionTestUtility
>init_game()
- ゲームの起動、及びリセット後に行われる処理です。
テスト開始前に行うべき操作や設定 (タイトル/ロード画面の突破、無敵化などの各種デバッグオプション設定) を自動操作で実現するために、
クラス
DebugLauncher
で定義した関数群を適切な順序で組み合わせて登録してください。 クラスDebugLauncher
に関する説明は後述のcustom/{ゲームID}/debug_launcher.py
の項を参照してください。
- ゲームの起動、及びリセット後に行われる処理です。
テスト開始前に行うべき操作や設定 (タイトル/ロード画面の突破、無敵化などの各種デバッグオプション設定) を自動操作で実現するために、
クラス
多くの場合、このソースコードを変更する必要はないと考えています。
custom/{ゲームID}/debug_launcher.py
の変更のみで対応できない場合に変更してください。
custom/{ゲーム ID}/debug_launcher.py
ゲーム固有(ここではサンプルゲーム固有)のタイトル画面/ゲーム内メニュー/デバッグメニューの操作アルゴリズムが記述されているコードです。
主にテスト開始前の設定に必要な操作や、テスト中に必要な操作のうちアウトゲーム的な部分に相当します。 ここで必要とされるコードの変更は、ほとんどがゲームによって全く異なると考えられ、決まった手順を書くことはできません。 ゲームの仕様を調べ、それに合うように適切なルール化を行ってください。
Order
派生クラス群- 各種メニュー操作を細かな単位に分解したものが定義されています。ゲームに合わせて適切なものを用意してください。例として Alfort では以下のものが用意されています。
- 特定の項目 (引数と一致する文字列) を選択する
- メニューの開閉を行う
- 指定したボタンを 1 回押す など
- 各種メニュー操作を細かな単位に分解したものが定義されています。ゲームに合わせて適切なものを用意してください。例として Alfort では以下のものが用意されています。
class CustomDebugLauncher
- 上記で定義した細かな単位の操作を組み合わせ、特定のことを行うのに必要な一連の操作を定義してください。
各操作に対応する関数には、ゲームと非同期で操作を行う
XXXX_async
と、ゲームと同期して操作を行うXXXX_sync
が存在します。 既存のコードを参考にして両方用意してください。例として Alfort では以下のものが用意されています。- セーブデータをロードするために必要な一連のパッド操作
- 特定のデバッグ機能を ON/OFF するために必要な一連のパッド操作 など備考
class Order
及びOrder
を継承しているクラスの多くは Playthrough Tester、Map Scanner と共通して使えるため、 他のツールで既に変更対応が済んでいればコピペするだけでよいです。 ただし、他のツールでは必要のない操作が Collision Checker では必要となることも考えられるので注意してください。 なお、これらのクラスはsvrun_client_logic.py > CollisionTestUtility > init_game()
をはじめとした同コード内の各所やresult_viewer.py > Main_Model > run_exe()
からDebugLauncher.instance.XXXX
を経由する形で呼び出されています。
step()
base/base_debug_launcher.py
で定義されている DebugLauncher.step() ではゲームから毎フレーム送信される情報を参照し、現在ゲームプレイ画面 or タイトル画面などの非ゲームプレイ画面にいるのかを判定しています。
その処理では不十分であれば、必要に応じてこの判定ルールをゲームに応じて適切に設定してください。備考基本的にはゲームから現在どのレベルにいるのかという情報が送信されるはずなので、それを元に場合分けすれば大丈夫です。
- 上記で定義した細かな単位の操作を組み合わせ、特定のことを行うのに必要な一連の操作を定義してください。
各操作に対応する関数には、ゲームと非同期で操作を行う
utils/assert_window_watcher.py
ゲームのウィンドウを常に監視し、ポップアップウィンドウが出現したら自動で閉じるためのコードです。
サンプルゲームでは現在は使用されていませんが、今後エラー状況の記録が必要になる場合を想定しサンプルとして実装してあります。 なお、以下で説明する変更対応を行っても動かない可能性が考えられるため、ゲーム毎にカスタマイズしてください。
__set_foreground_handler()
# ウィンドウのタイトル名が XXX から始まる
とコメントにある通り、if name.find('Alfort') >= 0:
の部分で監視対象となるゲームのウィンドウ名の先頭文字列を指定してください。
get_window_handle()
handle = win32gui.FindWindow(32770, "ASSERT")
の部分で、第 2 引数を自動で閉じたいウィンドウの名前を指定してください。 また、第 1 引数に閉じたいウィンドウのウィンドウクラスを指定してください。備考ウィンドウ クラスについて - Win32 apps
https://learn.microsoft.com/ja-jp/windows/win32/winmsg/about-window-classes
Unreal Engine 側の変更
こちらの資料に従って CollisionTest プラグインの導入を行ってください。