Imported from wtnb75/test123 (
AGENTS.md). Install upstream withnpx skills add wtnb75/test123. Copyright stays with the author.
AGENTS.md
このファイルは人間とエージェントの共通ルールです。
1. 目的
- Phaser.js で作るブラウザゲームを、壊さず継続的に改善する
- Vite ベースの静的サイト出力を安定して維持する
- ESLint と Vitest を品質ゲートとして運用する
- テストカバレッジ 90% 以上を維持する
2. 対象範囲
- このファイルが置かれたディレクトリ配下すべて
- サブディレクトリ配下のゲームロジック、描画、入力処理、ビルド設定、テスト
2.1 ディレクトリ構成
- 複数ゲームを同一リポジトリで管理する
- ゲームごとに独立したサブディレクトリを作成して管理する
- 既存ゲームはこの構成方針の参照実装として扱う
- 新規ゲームも同様に、ゲーム単位のディレクトリを作って追加する
- 各ゲームの依存関係・設定・テストは原則としてそのゲームのディレクトリ内で閉じる
2.2 ゲームディレクトリ作成コマンド
- 新規ゲーム作成は
npm create @phaserjs/game@latestを直接使わず、必ずリポジトリルートの以下タスクを使うtask newgame PACKAGE=<game-dir>
- 例
task newgame PACKAGE=game-memory-cards
- ゲームごとに専用ブランチを作ってから作業する(
mainに直接コミットしない)- 新規ゲーム追加:
mainからfeat/<game-dir>を作成(同名が既に存在する場合は-2・-3等の空いている名前を使う。中身が分からない既存ブランチを無条件で再利用・上書きしない) - 公開後の修正(バグ修正・バランス調整・機能追加など): 変更内容に応じて
fix/<game-dir>-xxx/balance/<game-dir>-xxx/feat/<game-dir>-xxxのように種別を表すprefixを付けた別ブランチを、その都度mainから新規に作成する(最初のブランチを使い回さない) - 1ゲームの追加・修正は1PRにスコープを絞る。他の作業中の変更と混在させない
- 新規ゲーム追加:
- このタスクは内部で
pnpm create @phaserjs/game@latest <game-dir>を実行したうえで、以下をまとめて行うpackage.jsonをbase.json(モノレポ共通設定)とマージし、依存関係をpnpm-workspace.yamlのcatalog:参照に統一するtsconfig.json/eslint.config.mjs/vitest.config.ts/vite/config.{dev,prod}.mjsを配置する(いずれもscaffold/配下の共通設定を参照する薄いファイル。共通の vitest 設定はカバレッジ90%閾値つき)pnpm-workspace.yamlのpackages:とTaskfile.ymlのGAMES(コメントアウト状態)に登録する
task newgame実行後、必ず以下を行う<game-dir>/package.jsonのdescriptionをゲーム内容に合わせて書き換えるpnpm installを実行してロックファイルを更新するtask game:favicon PACKAGE=<game-dir>を実行し、テンプレート既定のpublic/favicon.pngをゲーム名から生成した identicon(jdenticon)に置き換える- 公開一覧(トップページ)に載せる準備ができたら
Taskfile.ymlのGAMES該当行のコメントアウトを外す
2.3 オプション指定ルール
task newgameのPACKAGE=にはフォルダ名のみを指定する(テンプレート種別・Bundler 選択などは内部でWeb Bundler->Viteに固定される)- 言語は TypeScript を用いる(既存ゲームはすべて TypeScript)
- 新規ゲーム作成後は、ルートの
.gitignore共通ルールに合うよう除外設定を確認する
2.4 アイデア仕様ファイル
- 各ゲームの仕様は、ゲームディレクトリ配下の
docs/spec.mdに記述する - 新規ゲーム作成時は
docs/spec.mdを最初に作成してから実装に入る - 仕様変更時は
docs/spec.mdを先に更新し、実装・テストを追従させる
docs/spec.md の必須項目:
- ゲーム名(仮称可)
- コンセプト(1-3 行)
- ターゲットプレイヤー
- コアループ(プレイ中に繰り返す行動)
- 操作仕様(入力デバイスと主要操作)
- 画面・Scene 構成
- ルール(勝利条件、失敗条件、スコア条件)
- パラメータ表(サイズ・速度・時間・個数・確率・スコア係数など、ゲーム性に関わる数値とその初期値)
- MVP 範囲(初版で作る範囲)
- 非MVP範囲(今回は作らない範囲)
- 技術要件(Phaser/Vite/ESLint/Vitest での実装方針)
- テスト観点(最低限の単体テスト対象)
- 完了条件(受け入れ条件)
- 実装裁量(仕様に書かず実装側の判断に委ねる事項。書き漏れと意図的な委任を区別するため)
spec.md は会話の文脈を知らない実装者がそれだけで実装できる粒度で書く。 プレイヤーから見える挙動・数値のうち、仕様にも実装裁量にも無いものは仕様の不足として扱う。
公開後の拡張で仕様が大きくなる場合に備え、spec は docs/spec.md と、その ## 拡張 節からリンクされた docs/spec/*.md 群で構成してよい(すべてを合わせて spec とみなす)。
- 独立した要素(新モード・ステージ群・独立したシステム・新 Scene)は
docs/spec/<slug>.mdに分け、既存要素の変更・小さな追加はdocs/spec.mdを直接書き換える - 各ファイルは常に現在の仕様を表す(差分や履歴を積み重ねない)。frontmatter は
docs/spec.mdにのみ置く - 詳細(分割ファイルの必須項目など)は
game-specスキルを参照
3. 作業前チェック
- 変更の目的を 1 つに絞る(1 変更 1 目的)
- 既存の操作感(入力レスポンス、速度感、UI 遷移)を壊さない
npm run buildで静的サイトが生成できることを前提にする- ESLint と Vitest の運用方針を満たす実装にする
4. 実装規約
4.1 基本方針
- 大きな設計変更より、段階的な改善を優先する
- 仕様変更時は README またはテストを同時に更新する
- 各ゲームの README.md に、ゲームの目的・ルール・操作方法が分かる説明を必ず記載する
- 無関係なリファクタリングを同じ変更に混ぜない
4.2 Phaser.js 実装
- Scene の責務を分離する(初期化、進行、結果表示など)
preload,create,updateの責務を混在させない- 毎フレーム処理は最小限にし、不要なオブジェクト生成を避ける
- ゲーム状態は明示的に管理し、グローバル汚染を避ける
- 入力イベントは重複登録を防ぎ、Scene 終了時に後始末を行う
4.3 Vite / 配布
- 配布物は静的サイトを前提とし、
vite build成果物で動作確認する - 実行時に Node.js サーバー専用機能へ依存しない
- 画像・音声などのアセットパスはビルド後の解決を壊さない
4.4 コード品質(ESLint)
- lint エラーは 0 件で完了扱いとする
- 例外的な無効化コメントは理由を明記し、最小範囲に限定する
- 可読性のため、関数は短く保ち、意図が読める命名を優先する
4.5 テスト(Vitest)
- 単体テストは Vitest で実装する
- テスト名は挙動が分かる形式にする(何をすると何が起きるか)
- 境界値・異常系・再現しやすい回帰ケースを優先する
- 時刻・乱数・外部依存は注入またはモックで再現性を確保する
- カバレッジ目標は 90% 以上(ステートメント、分岐、関数、行)
5. 変更提案の出し方
- 変更理由を 1-3 行で説明する
- 影響範囲(ゲーム挙動、ビルド、lint、テスト)を明示する
- 未確認事項がある場合は前提条件として先に共有する
6. 完了条件
- 少なくとも以下を実行してから提案する
npm run lintnpm run testnpm run test:coveragenpm run build
- Vitest のカバレッジ結果が 90% 未満の場合は、未到達分岐を特定してテストを追加する
- 目標未達のまま提案する場合は、未達理由と補完計画を変更説明に明記する
7. 禁止事項
- lint/test/build の失敗を残したまま完了扱いにしない
- 失敗時の挙動を黙って変更しない
- 不要な依存追加や大規模フォルダ構成変更を無断で行わない
8. 推奨 npm scripts
以下が未定義なら追加を推奨する。
lint: ESLint 実行test: Vitest 実行test:coverage: Vitest カバレッジ実行build: Vite ビルド(定義済み)
9. ヘッドレスブラウザでの動作確認(Docker + Playwright)
- 単体テストでは検証できない見た目・操作感(速度感、当たり判定の体感、演出)は、可能な限り実ブラウザで確認する
- サンドボックス環境に headless Chromium の依存関係が無く直接は動かせない場合でも、
dockerが使えるなら Playwright の公式イメージ(mcr.microsoft.com/playwright:<tag>。Chromium 同梱、事前キャッシュされていることが多い)で代替できる - 手順
- 確認したいゲームのディレクトリで dev サーバーを起動する(例:
npm run dev -- --port <PORT> --host 0.0.0.0) - エージェントセッション自体が Docker コンテナ内で動いている場合の注意: QA 用コンテナに
--network hostを指定しても、それは dockerd 側ホストのネットワークを指すのであって、このセッションのlocalhostには届かない- 自セッションが属する Docker ネットワークを先に調べる:
hostnameでコンテナIDを取得し、docker inspect <そのID> --format '{{json .NetworkSettings.Networks}}'でネットワーク名と自分の IP を確認する - QA 用コンテナは
--network hostではなく、自セッションと同じネットワーク名を指定して起動する:docker run -d --name <name> --network <自分と同じネットワーク名> mcr.microsoft.com/playwright:<tag> sleep infinity - dev サーバーへは
localhostではなく自セッションの IP(例http://192.168.x.x:<PORT>)でアクセスする
- 自セッションが属する Docker ネットワークを先に調べる:
- ホストのファイルを直接コンテナへ bind mount (
-v) しない。dockerd が別VM/別マウント名前空間で動いている環境では、bind mount したパスがコンテナ内で空ディレクトリになる(サイレント失敗)。スクリプトの受け渡しや結果の回収はdocker cpで行う - Playwright イメージにはブラウザ本体のみプリインストールされているため、コンテナ内で
npm install playwright@<バージョン>(イメージのタグと合わせる)を実行してから使う - Phaser などキャンバス描画のゲームは結果を DOM から読めないため、
page.screenshot()で撮ったスクリーンショットをdocker cpで取り出し、目視で確認する(クリア/ゲームオーバー等の判定も同様) - 確認が終わったら QA 用コンテナ(
docker rm -f <name>)と dev サーバープロセスを必ず後片付けする
- 確認したいゲームのディレクトリで dev サーバーを起動する(例:
10. 開発ワークフロー(Claude Code スキル)
Claude Code を使う場合、2〜9節のゲーム開発フローは .claude/skills/game-* と
してスキル化されている。各スキルは task game:status 系タスク
(scripts/game-status.sh、docs/spec.md のフロントマターに進捗を記録)を
使って現在の進捗を追跡するので、次に何をすべきかは基本的に機械的に判断できる。
段階と対応スキル:
| 段階 | スキル | 内容 |
|---|---|---|
| アイデア | game-idea |
コンセプト・コアループ・MVP範囲をユーザーと対話して固める(ファイルはまだ作らない) |
| 初期化 | game-init |
feat/<game-dir> ブランチを作成し task newgame でディレクトリをスキャフォールド(2.2節) |
| 仕様 | game-spec |
docs/spec.md を作成・改訂する(2.4節)。仕様変更のたびに呼ばれ、公開後の改訂ならブランチも新規に作る |
| 実装 | game-impl |
承認済みの spec.md に対して Phaser.js コードを実装(4節) |
| テスト | game-test |
Vitest 単体テストをカバレッジ90%以上で追加(4.5節) |
| 品質ゲート | game-check |
lint/test/coverage/build を通す(6節) |
| コードレビュー | game-codereview |
/code-review 相当のレビュー → 指摘の採否をユーザーが決める → 修正、を指摘が出なくなるまで(最大3周)ループする |
| ビジュアルQA | game-qa |
Docker + Playwright で実ブラウザの描画・操作感を確認(9節) |
| 見た目・UI調整 | game-polish |
エフェクト、入力へのフィードバック、動線・操作の分かりやすさを改善する。spec→impl→test→check→codereview→qa をループする(ゲームバランスに関わる数値は扱わない) |
| バランス調整 | game-balance |
実際に遊んで、仕様通りでも面白くない点を調整する。気に入るまで spec→impl→test→check→codereview→qa→polish をループする |
| 公開 | game-publish |
Taskfile.yml の GAMES に登録し、その変更だけにスコープを絞ったPRを作成する |
| 拡張 | game-extend |
公開済みゲームに足す要素を1件選び、目的・コアループへの効き方・変えないもの・spec の置き場所を対話で固める(ファイルは作らない)。合意後は game-spec の公開後改訂から spec→…→publish をもう一度通す |
- 迷ったら
game-nextを実行するだけでよい。現在どのゲームのどの段階が未完了 かを自動判定し(task game:detect/task game:next)、該当スキルへ自動で 進む。全段階が完了した(公開済みの)ゲームでは、game-extend(拡張)かgame-balance(再調整)を案内する - 段階の間では止まらない。各スキルは完了時に
game-nextへ戻り、ユーザーの 承認・判断が要る箇所(spec の承認、codereview の採否、polish/balance の 選択、publish の確認など)か、段階が失敗してdoneにならなかったときだけ 止まる。承認に答えれば続きから自動で再開する - 複数ゲームを並行して進めている場合、
game-nextはカレントブランチ名 (feat/<game-dir>など。2.2節)を最優先の手がかりに対象ゲームを判定する - 全ゲームの進捗一覧は
task game:dashboardで確認できる - 後から追加された段階(
codereview/polish)のキーを持たない既存ゲームは、 その段階をスキップ扱いにする。次にgame-specで改訂したときにキーが 追加され、以降はその段階も通る - 各スキルは段階を完了する前に
game-review STAGE=<段階>でレビューする。 全段階のレビュー観点はgame-reviewに集約されており、「次の段階が推測 なしに着手できるか」を基準にする- spec / impl / test は成果物を次段階が直接使うため、会話の文脈を持たない サブエージェントがレビューする(spec は「この spec(spec.md とリンク先) だけで実装できるか」の実装者ドライラン)
- それ以外の段階はチェックリストによるセルフレビュー
- 指摘は blocker / should / nit に分け、段階を止めるのは blocker のみ。 ユーザーへの質問は 1 回にまとめ、レビューの往復は最大 2 回とする
以上。
