gds-e2e-scaffold について
gds-e2e-scaffoldは、ゲーム QA エンジニア向けに、既存ゲームプロジェクト用のエンジン別 E2E テスト基盤を生成するスキルです。テストフィクスチャ、シナリオ・入力支援、非同期アサーション、サンプルテストを作成します。
主な機能
- 01Unity、Unreal、Godotを検出
- 02E2Eテスト基盤を生成
- 03シナリオ・入力支援を作成
- 04非同期アサーションを追加
- 05E2Eサンプルテストを作成
- 06セットアップ文書を生成
活用シーン
- 01ゲームプロジェクトのE2Eテスト構築
- 02ゲームシステムに合わせたテスト支援の調整
- 03生成した基盤の使用例の提示
- 04テストの実行・拡張方法の文書化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ bmad-code-org/ bmad-module-game-dev-studio --skill gds-e2e-scaffoldインストール後、Claude Code で/gds-e2e-scaffoldを入力して読み込まれたか確認します。
同梱ファイルchecklist.mdcustomize.toml
詳細
E2E テストインフラストラクチャのスキャフォールドワークフロー
目標: 既存のゲームプロジェクトに完全な E2E テストインフラストラクチャをスキャフォールドします。信頼性が高く、保守しやすいエンドツーエンドテストに必要な基盤として、テストフィクスチャ、シナリオビルダー、入力シミュレーター、非同期アサーションユーティリティを作成します。これらはすべて、プロジェクト固有のアーキテクチャに合わせて調整されます。
あなたの役割: E2E テストアーキテクチャを専門とする、シニアゲーム QA エンジニアとして振る舞います。E2E テストでは、プレイヤーの一連の行動を最初から最後まで検証します。適切なインフラストラクチャがなければ、テストは壊れやすく、手に負えないものになります。テストをひとつも書き始める前に適切な基盤を構築し、これを防ぐことがあなたの役目です。ユーザーと協力してアーキテクチャを理解し、ゲームのドメインに適したインフラストラクチャを生成してください。
規約
- ベアパス(例:
template.md)はスキルのルートディレクトリを基準に解決されます。 {skill-root}は、このスキルがインストールされているディレクトリ(customize.tomlがある場所)を指します。{project-root}は、プロジェクトの作業ディレクトリから親ディレクトリをたどり、最初に見つかる_bmad/を含むフォルダーを指します。{skill-name}は、スキルディレクトリのベース名を指します。
起動時
ステップ 1:ワークフローブロックを解決する
実行:uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow
スクリプトが失敗した場合は、次の 3 つのファイルを base → team → user の順に読み込み、リゾルバーと同じ構造マージルールを適用して、workflow ブロックを自分で解決してください。
{skill-root}/customize.toml— デフォルト{project-root}/_bmad/custom/{skill-name}.toml— チームによる上書き{project-root}/_bmad/custom/{skill-name}.user.toml— 個人による上書き
存在しないファイルはスキップします。スカラーは上書きし、テーブルはディープマージします。code または id をキーとするテーブル配列では、一致するエントリを置き換え、新しいエントリを追加します。それ以外の配列はすべて追加します。
ステップ 2:先頭に追加するステップを実行する
続行する前に、{workflow.activation_steps_prepend} の各エントリを順番に実行します。
ステップ 3:永続的な事実を読み込む
{workflow.persistent_facts} の各エントリを、ワークフローの実行中に保持する基礎コンテキストとして扱います。file: で始まるエントリは、{project-root} 配下のパスまたはグロブです。参照先の内容を事実として読み込んでください。それ以外のエントリは、そのまま事実として扱います。
ステップ 4:設定を読み込む
{project-root}/_bmad/gds/config.yaml から設定を読み込み、次の項目を解決します。
user_namecommunication_language
ステップ 5:ユーザーに挨拶する
{user_name} に、{communication_language} で挨拶します。
ステップ 6:末尾に追加するステップを実行する
{workflow.activation_steps_append} の各エントリを順番に実行します。
起動は完了です。activation_steps_prepend または activation_steps_append にエントリがあった場合は、続行する前に、すべてのエントリを順番どおりに実行したことを確認してください。すべての起動ステップが完了するまで、メインワークフローを開始しないでください。
ワークフローのアーキテクチャ
これは、自律的な実行のためにインラインワークフローパターンを使用します。
- 重要なアーキテクチャ分析を最初に行い、ステップを順番に実行します
- エンジンの検出とドメインの調査に基づいて、生成するコードを決定します
- 生成したインフラストラクチャファイルは、すべて生成時にディスクへ書き込みます
- 動作するサンプルテストで、インフラストラクチャが正しく機能することを確認します
トリガー
ESe2e-scaffoldscaffold e2ee2e infrastructuresetup e2e
事前確認要件
重要: 続行する前に、以下の要件を確認してください。いずれかを満たさない場合は、処理を中止してユーザーに案内してください。
- テストフレームワークが初期化済みであること(先に
test-frameworkワークフローを実行してください) - ゲームの状態を管理するクラスを特定できること
- メインのゲームプレイシーンが存在し、機能していること
- 既存の E2E インフラストラクチャがないこと(
Tests/PlayMode/E2E/またはエンジンに相当するパスを確認してください)
パス
installed_path={skill-root}validation={installed_path}/checklist.md
入力(ユーザーから収集、または自動検出)
| 入力 | 説明 | 必須 | デフォルト |
|---|---|---|---|
game_state_class | 主要なゲーム状態管理クラス名 | はい | — |
main_scene | コアゲームプレイが行われるシーン名 | はい | — |
input_system | 使用中の入力システム | いいえ | auto-detect |
ナレッジフラグメント
続行する前に {installed_path}/knowledge/e2e-testing.md を読み込みます。ステップ 1 で検出した後、エンジン固有のフラグメントを読み込みます。
- Unity:
{installed_path}/knowledge/unity-testing.md - Unreal:
{installed_path}/knowledge/unreal-testing.md - Godot:
{installed_path}/knowledge/godot-testing.md
実行
エンジン固有のプロジェクトファイルを確認して、ゲームエンジンを検出します。 - Unity:`Assets/`、`ProjectSettings/`、`*.unity` シーン - Unreal:`*.uproject`、`Source/`、`Config/DefaultEngine.ini` - Godot:`project.godot`、`*.tscn`、`*.gd` ファイル 適切なエンジン固有のナレッジフラグメントを読み込みますコアシステムを特定します。
1. ゲーム状態マネージャー — ゲーム状態を保持する主要クラスです。次のものを探します:GameManager、GameStateManager、GameController、GameMode。初期化メソッド、準備完了状態のプロパティ、保存/読み込みメソッドを記録します
2. 入力処理 — Unity New Input System と Legacy、Unreal Enhanced Input と Legacy、Godot 組み込みの Input、またはカスタム抽象化レイヤー
3. イベント/メッセージシステム — イベントバス、C# イベント/デリゲート、UnityEvents、Godot Signals
4. シーン構造 — メインゲームプレイシーン名、読み込み方式(加算/単一)、ブートストラップ/初期化フロー
ScenarioBuilder 用のドメイン概念を特定します。 - 主要エンティティ:ユニット、プレイヤー、アイテム、敵など - ステートマシンの状態:ターンフェーズ、ゲームモード、プレイヤー状態 - 空間システム:グリッド/ヘックス上の位置、ワールド座標、領域 - リソース:通貨、体力、マナ、弾薬など
既存のテスト構造を確認します。Tests/PlayMode/E2E/(またはエンジンに相当するもの)がすでに存在する場合は、処理を停止し、どのように進めるかユーザーに確認します。
<action>`GameE2ETestFixture.cs` 基底クラスを生成します。プレースホルダーをカスタマイズします。
- `{Namespace}` = 検出したプロジェクト名前空間
- `{MainSceneName}` = 検出したメインゲームプレイシーン
- `{GameStateClass}` = 特定したゲーム状態管理クラス
- `{IsReadyProperty}` = ゲームの初期化完了を示すプロパティ(例:`IsReady`、`IsInitialized`)
フィクスチャでは、シーンの読み込み/アンロード、ゲームの準備完了状態の待機、GameState/Input/Scenario へのアクセス、クリーンアップの保証、失敗時のスクリーンショット撮影を処理する必要があります。</action>
<action>フルーエント API を備えた `ScenarioBuilder.cs` を生成します。ステップ 1 で分析したゲームのドメインモデルに基づいて、特定したエンティティに応じた具体的な設定メソッドを 3~5 個追加します。基底メソッドとして `FromSaveFile(string fileName)` を含めます。`#region State Configuration` ブロックに、パターンを説明する TODO コメントとともにドメイン固有のメソッドを追加します。</action>
<action>`InputSimulator.cs` を生成します。New Input System が検出された場合:
- `InputState.Change` と `StateEvent.From` を使った `ClickWorldPosition(Vector3)`、`ClickScreenPosition(Vector2)`、`ClickButton(string)`、`DragFromTo(Vector3, Vector3, float)`
- キーボード用の `PressKey(Key)`、`HoldKey(Key, float)`
- ユーティリティメソッドの `Reset()` と `RefreshCamera()`
Legacy Input が検出された場合は、UI イベントのトリガーを使った、より簡易なバージョンを生成します。</action>
<action>`AsyncAssert.cs` 静的ユーティリティクラスを生成します。以下を含めます。
- `WaitUntil(Func<bool>, string, float)` — 条件を待つ基本機能
- `WaitUntilVerbose(...)` — 定期的なデバッグログ出力付き
- `WaitForValue<T>(...)` — 特定の値を待つ(完全一致)
- `WaitForValueApprox(...)` — 許容誤差を指定して float/double を待つ
- `WaitForValueNot<T>(...)` — 値が変わるのを待つ
- `WaitForNotNull<T>(...)` と `WaitForUnityObject<T>(...)`
- `AssertNeverTrue(...)` — あることが起きないことをアサートする
- ユーティリティメソッド `WaitFrames(int)` と `WaitForPhysics(int)`
</action>
`Source/{ProjectName}/Tests/E2E/` 以下に、同等のインフラストラクチャファイルを生成します。
- `GameE2ETestBase.h/.cpp` — 基本テストクラス
- `ScenarioBuilder.h/.cpp` — フルーエントなシナリオ設定
- `InputSimulator.h/.cpp` — 入力の抽象化
- `AsyncAssert.h` — 条件を待つユーティリティ
- `{ProjectName}E2ETests.Build.cs` — ビルド設定
`tests/e2e/infrastructure/` 以下に、同等のインフラストラクチャファイルを生成します。
- `game_e2e_test_fixture.gd`
- `scenario_builder.gd`
- `input_simulator.gd`
- `async_assert.gd`
すべてのインフラストラクチャファイルをディスクに書き込みます
インフラストラクチャを使い、その動作を実証する、実行可能な E2E テストを作成します 次の3つのテストを含む `ExampleE2ETest.cs` を生成します。 1. `Infrastructure_GameLoadsAndReachesReadyState` — 基本フィクスチャ、GameState、Input、Scenario がすべて null ではなく、ゲームが準備完了状態になることを検証します 2. `Infrastructure_InputSimulatorCanClickButtons` — ユーザーがカスタマイズできるコメント付きの例を含め、入力シミュレーションのパターンを示します 3. `Infrastructure_ScenarioBuilderCanConfigureState` — ドメイン固有の例をコメント付きで含め、ScenarioBuilder の使い方を示します クラスに `[Category("E2E")]` 属性を適用します。 同じ3つの検証パターンを網羅する、エンジンに適した場所と言語で同等のサンプルテストを生成しますサンプルテストファイルをディスクに書き込みます
E2E のルートディレクトリに `README.md` を作成し、以下を記載します。 - クイックスタート(GameE2ETestFixture の継承、Scenario/Input/AsyncAssert の使用) - Given-When-Then 構造を使ったテスト例 - GameE2ETestFixture、ScenarioBuilder、InputSimulator、AsyncAssert のコンポーネント説明 - ディレクトリ構造の説明 - テストの実行方法(エディター UI とコマンドライン) - ベストプラクティス(時間ではなく条件を待つ、テストごとに1つのジャーニーを実行する、説明的なアサーションを使う) - 拡張ガイド(Scenario メソッドの追加、Input メソッドの追加) - よくある問題のトラブルシューティング表 `README.md` をディスクに書き込みます `{validation}` チェックリストを読み込み、すべての成果物が揃っていることを確認します ユーザーに次の概要を提示します。## E2E Infrastructure Scaffold Complete
**Engine**: {Unity | Unreal | Godot}
**Version**: {detected_version}
### Files Created
[Directory tree of all created files]
### Configuration
| Setting | Value |
|---------|-------|
| Game State Class | `{GameStateClass}` |
| Main Scene | `{MainSceneName}` |
| Input System | `{InputSystemType}` |
| Ready Property | `{IsReadyProperty}` |
### Customization Required
1. ScenarioBuilder: Add domain-specific setup methods for your game entities
2. InputSimulator: Add game-specific input methods (e.g., hex clicking, gesture shortcuts)
3. ExampleE2ETest: Modify example tests to use your actual UI elements
### Next Steps
1. Run `Infrastructure_GameLoadsAndReachesReadyState` to verify setup works
2. Extend `ScenarioBuilder` with your domain methods
3. Extend `InputSimulator` with game-specific input helpers
4. Use `test-design` workflow to identify E2E scenarios
5. Use `automate` workflow to generate E2E tests from scenarios
次を実行します:`uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow.on_complete` — 解決された値が空でない場合、終了前の最後のターミナル指示としてその内容に従います。