openai-develop-web-game について
コーディングエージェントがウェブゲームを小さな変更単位で構築し、繰り返し検証するためのスキルです。Playwrightを使い、スクリーンショット、テキスト状態、操作を確認する手順を定めています。
主な機能
- 01ゲーム機能の段階的な実装
- 02Playwrightによる操作ループテスト
- 03スクリーンショットとテキスト状態の確認
- 04決定論的な時間ステップフック
- 05progress.mdによる進捗管理
- 06操作とインタラクションの検証
活用シーン
- 01ウェブゲーム機能の段階的な実装
- 02自動操作によるゲーム変更の確認
- 03ゲーム画面と状態出力の照合
- 04操作と勝敗状態の遷移テスト
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ trailofbits/ skills-curated --skill openai-develop-web-gameインストール後、Claude Code で/openai-develop-web-gameを入力して読み込まれたか確認します。
同梱ファイルreferences/action_payloads.jsonscripts/web_game_playwright_client.js
詳細
Web ゲームを開発する
ゲームを小さなステップで作り、変更のたびに検証します。各イテレーションは、実装 → 操作 → 一時停止 → 観察 → 調整の流れで進めます。
スクリプトとリファレンスは {baseDir}/ 以下にあります。
ワークフロー
- 目標を決める。 実装する機能または動作を1つ定義します。
- 小さく実装する。 ゲームを前進させる最小限の変更を加えます。
- 統合ポイントを確保する。 テストループが状態を読み取れるよう、単一のキャンバスと
window.render_game_to_textを用意します。 window.advanceTime(ms)を追加する。 Playwright スクリプトでフレームを確実に進められるよう、決定論的なステップ用フックを強く推奨します。これがないと、自動テストが不安定になることがあります。- progress.md を初期化する。
progress.mdがある場合は、まず読み込み、元のユーザープロンプトが先頭に記録されていることを確認します(Original prompt:をプレフィックスとして付けます)。前のエージェントが残した TODO と提案も記録します。ファイルがない場合は作成し、更新を追記する前に、先頭にOriginal prompt: <prompt>と記載します。 - Playwright が利用可能か確認する。
playwrightが利用可能であることを確認します(ローカル依存関係またはグローバルインストール)。不明な場合は、まずnpxを確認します。 - Playwright テストスクリプトを実行する。 意味のある変更を加えるたびに
$WEB_GAME_CLIENTを実行する必要があります。必要な場合を除き、新しいクライアントを独自に作成しないでください。 - ペイロードのリファレンスを使用する。 キーを推測せず、操作は
$WEB_GAME_ACTIONSに基づいて行います。 - 状態を調べる。 操作をまとめて行うたびに、スクリーンショットとテキスト状態を取得します。
- スクリーンショットを確認する。 最新のスクリーンショットを開き、想定どおりに表示されているか確認します。問題があれば修正し、スクリプトを再実行します。正しくなるまで繰り返します。
- 操作と状態を確認する(複数ステップを重視)。 重要なインタラクションをすべて徹底的に試します。それぞれについて、引き起こされる一連の複数ステップ(原因 → 中間状態 → 結果)を考え、最初から最後まで動作することを検証します。
render_game_to_textが画面上に表示される状態を反映していることも確認します。ずれがあれば修正して再実行します。
重要なインタラクションの例:移動、ジャンプ、射撃/攻撃、インタラクト/使用、メニューでの選択/確定/キャンセル、一時停止/再開、再スタート、リクエストで定義された特殊能力やパズル操作。複数ステップの例:敵を撃つと体力が減り、体力が0になると敵が消えてスコアが更新される。鍵を集めるとドアが開き、レベルを先に進める。 - エラーを確認する。 コンソールエラーを確認し、新たに発生した問題は最初のものから修正してから次に進みます。
- シナリオごとにリセットする。 個別の機能を検証するときは、テスト間で状態が引き継がれないようにします。
- 小さな差分で繰り返す。 一度に1つの変数(フレーム数、入力、タイミング、位置)だけを変更し、安定するまで手順7〜13を繰り返します。
コマンドの例(操作が必要です):
node "$WEB_GAME_CLIENT" --url http://localhost:5173 --actions-file "$WEB_GAME_ACTIONS" --click-selector "#start-btn" --iterations 3 --pause-ms 250
操作の例(インライン JSON):
{
"steps": [
{ "buttons": ["left_mouse_button"], "frames": 2, "mouse_x": 120, "mouse_y": 80 },
{ "buttons": [], "frames": 6 },
{ "buttons": ["right"], "frames": 8 },
{ "buttons": ["space"], "frames": 4 }
]
}
テストチェックリスト
リクエストに対して新たに追加した機能と、ロジック変更の影響が及ぶ可能性のある領域をテストします。問題を特定して修正し、解消されたことを確認するためにテストを再実行します。
テスト項目の例:
- 主要な移動/インタラクション入力(例:移動、ジャンプ、射撃、確定/選択)。
- 勝利/敗北または成功/失敗への遷移。
- スコア/体力/リソースの変化。
- 境界条件(衝突、壁、画面の端)。
- メニュー/一時停止/開始のフローがある場合。
- リクエストに関連する特殊な操作(パワーアップ、コンボ、能力、パズル、タイマー)。
レビューするテスト成果物
- Playwright の実行で生成された最新のスクリーンショット。
- 最新の
render_game_to_textの JSON 出力。 - コンソールのエラーログ(先に新たに発生したエラーを修正してから続行してください)。
Playwright スクリプトの実行後、最新のスクリーンショットを実際に開いて目視で確認してください。生成するだけでは不十分です。画面に表示されるべきものがすべて実際に表示されていることを確認してください。スタート画面だけでなく、新たに追加された機能をすべてカバーするゲームプレイ中のスクリーンショットも撮影してください。スクリーンショットを正とし、何かが欠けていれば、ビルドにも欠けているものとして扱ってください。ヘッドレスまたは WebGL のキャプチャに問題があると思われる場合は、Playwright スクリプトをヘッドありモードで再実行し、もう一度確認してください。スクリーンショットとテキストの状態が正しくなるまで、修正と再実行を短いサイクルで繰り返してください。修正を確認したら、重要な操作とコントロールをすべて再テストし、正常に動作すること、変更によるリグレッションがないことを確認してください。リグレッションがあれば修正し、操作、テキストの状態、コントロールがすべて期待どおりに動作するまで、すべてのテストを繰り返してください。コントロールを徹底的にテストしてください。ゲームが壊れている状態は許容できません。
ゲームの基本ガイドライン
キャンバスとレイアウト
- ウィンドウの中央に単一のキャンバスを配置することを推奨します。
ビジュアル
- 画面上のテキストは最小限に抑え、プレイ中に重ねて表示するのではなく、スタート画面またはメニュー画面に操作方法を表示してください。
- デザイン上の意図がない限り、暗すぎるシーンは避けてください。重要な要素を見やすくしてください。
- CSS の背景に頼らず、キャンバス上に背景を描画してください。
テキスト状態の出力(render_game_to_text)
現在のゲーム状態を表す簡潔な JSON 文字列を返す window.render_game_to_text 関数を公開してください。テキストには、ビジュアルがなくてもゲームをプレイするのに十分な情報を含めてください。
最小限の例:
function renderGameToText() {
const payload = {
mode: state.mode,
player: { x: state.player.x, y: state.player.y, r: state.player.r },
entities: state.entities.map((e) => ({ x: e.x, y: e.y, r: e.r })),
score: state.score,
};
return JSON.stringify(payload);
}
window.render_game_to_text = renderGameToText;
ペイロードは簡潔にし、画面上または操作可能な要素を優先してください。全履歴ではなく、現在表示されているエンティティを優先してください。 座標系に関する明確な注記(原点と軸の方向)を含め、プレイヤーの位置と速度、アクティブな障害物や敵、収集アイテム、タイマーやクールダウン、スコア、および適切な判断に必要なモードや状態のフラグなど、プレイヤーに関係する状態をすべて記録してください。大きな履歴は避け、現在関連性があり、画面上に見えているものだけを含めてください。
時間ステップ用フック
Playwright クライアントが制御された間隔でゲームを進行できるよう、決定論的な時間ステップ用フックを用意してください。window.advanceTime(ms)(またはゲームの更新ループに処理を委譲する薄いラッパー)を公開し、存在する場合はゲームループで使用してください。
Playwright のテストスクリプトは、このフックを使って自動テスト中にフレームを決定論的に進めます。
最小限の例:
window.advanceTime = (ms) => {
const steps = Math.max(1, Math.round(ms / (1000 / 60)));
for (let i = 0; i < steps; i++) update(1 / 60);
render();
};
全画面切り替え
- 単一のキー(
fを推奨)で全画面のオンとオフを切り替えます。 - 全画面表示中に
Escを押すと解除できるようにしてください。 - 全画面表示に切り替えたときは、キャンバスと描画をリサイズし、ビジュアルと入力のマッピングを正しく保ってください。
進捗の記録
まだ存在しない場合は progress.md ファイルを作成し、作業の進行に合わせて TODO、メモ、注意点、未解決事項を追記してください。別のエージェントがスムーズに引き継げるようにしてください。
progress.md がすでに存在する場合は、先に読み込み、冒頭にある元のユーザープロンプトも含めて確認してください(別のエージェントの作業を引き継いでいる可能性があります)。元のプロンプトは上書きせず、そのまま保持してください。
機能の追加、バグの発見、テストの実行、判断の記録など、作業に意味のある区切りごとに progress.md を更新してください。
作業の最後に、次のエージェント向けの TODO と提案を progress.md に残してください。
Playwright の前提条件
- プロジェクトにすでに
playwrightの依存関係がある場合は、ローカルのものを優先してください。 - Playwright が利用できるか不明な場合は、
npxがあるか確認してください。command -v npx >/dev/null 2>&1 npxがない場合は、Node/npm をインストールしてから Playwright をグローバルにインストールしてください。npm install -g @playwright/mcp@latest- 明示的に指示されない限り、
@playwright/testに切り替えないでください。クライアントスクリプトを使用してください。
スクリプト
$WEB_GAME_CLIENT(インストール時のデフォルト:{baseDir}/scripts/web_game_playwright_client.js)— 仮想時間のステップ実行、スクリーンショットのキャプチャ、コンソールエラーのバッファリングに対応した Playwright ベースのアクションループです。--actions-file、--actions-json、または--clickを使って、アクションの一連の操作を渡す必要があります。
参照資料
$WEB_GAME_ACTIONS(インストール時のデフォルト:{baseDir}/references/action_payloads.json)— アクションペイロードの例(キーボード+マウス、フレームごとのキャプチャ)です。一連の操作を作成する際に使用してください。