Amazon Q CLIと歩んだゲーム開発の道のり - レートリミットまでの軌跡
はじめに
Amazon Q CLI でゲームを作ろう Tシャツキャンペーンが開催されていたのでゲームを作ってみました。
現在の生成AIなら、簡単なゲームはワンショットで作れることは周知の通りです。例えば、テトリスのようなものであれば「テトリスを作ってください」と指示をするだけである程度のものは作れてしまいます。
なので今回は少しだけ複雑なゲームを作ろうとしたときにどうなるのか、というのを検証してみることにしました。
私がWeb系のフロントエンドエンジニアのため、Vite+Phaserで作成しています。とはいえゲーム作成経験がないのでPhaserの知識はなかったため、技術的な指示はほとんどしていません。
ゲーム自体はレートリミットに到達してしまったためかなり中途半端な状態になってしまったことが心残りですが、キャンペーン上のルールとしてAmazon Q CLIのみでゲームを作成することが条件になっていため、デバッグ用のコードもそのまま残っています。手動でのコード修正はキャンペーンルール上問題ないのかわからず、膨大なコードを手動で修正するのは大変そうだったためです。
レートリミットに到達してしまった関係上、GitHub Pagesへのデプロイするにあたり発生していたビルドエラーを解決するための軽微なコード修正のみ手動で行っています。
完成したゲーム
さめがめベースのパズルゲームを作成しました。単純なブロック消しゲームではなく、ステージ制・ガチャシステム・アイテム装備など、複数の要素を組み合わせた複雑なゲームシステムを実装しています。
Github
公開ページ
上記でプレイできます。妙な線があるページの線はキーボードのDで非表示にできます。デバッグ用に出力させていたものがそのままになってしまったため残ってしまいました。
ローディング | メイン | ガチャ | ガチャ結果 |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
アイテム一覧 | アイテム選択 | ゲーム | ゲームクリア |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
作ったゲームについて
斬新なゲームをつくれるほどアイディアを持っているわけではないので、ゲームのベースはさめがめにしました。ただシンプルにさめがめを実装するのはそれこそ「さめがめを作ってください」で終わってしまうので、ここではあえて複雑なルールにするためいくつかの機能を実装しすることを目標にしました。
- Stage制にしてStageをクリアすると次のStageに進む
- 通常のブロックだけではなく妨害ブロックが登場する
- Stageをクリアしたときに入手できるゴールドでガチャが引ける
- ガチャでStageクリアを有利にするためのアイテムが入手できる
- アイテムを使用すると妨害ブロックを破壊したりブロックを入替可能で、ゲームを有利に進めることができる
細かい仕様についてはMarkdownで3000行ほどあるためこちらには記載しきれません。GitHub上のルールファイルに記載しています。
- 00-basic.md: 日本語使用・動作確認・テスト変更の基本ルール
- 01-game-base.md: さめがめオーシャンゲームの基本仕様とルール
- 02-game-code.md: TypeScript・Phaserを使ったコード設計仕様
- 03-debug-layout.md: UI実装時のデバッグレイアウト表示ルール
- 04-equipment-system.md: アイテム装備・使用システムの独立性ルール
- 05-basic-rules.md: ブロック構造・論理状態管理の基本ルール
- 06-game-scene.md: 画面遷移とシーン管理の仕様
docs
にあるマークダウンを含め、ルールファイルもAmazon Q CLIと作成したものです。そのため度々ルールに矛盾が生じ、かなり苦労しました。ドキュメントが多ければ多いほど、全体を通した整合性の確認をとることが難しかったです。
Amazon Q CLIの導入
こちらは導入について案内する記事ではないので簡単に記載すると次の通りです。
- Homebrewでインストール
- Amazon Qがアプリケーションの中にインストールされているのでGUIを起動する
- (Proのみ)「Amazon Q Developer Pro (月額19ドル) をメンバーアカウントでサブスクライブ利用してみた」の記事を参考にサブスクライブ利用する
- ターミナルで
q chat
を入力
料金については公式サイトをご確認ください。
Amazon Q CLI 基礎知識
モデルのデフォルト
モデルのデフォルトがClaude 3.7 Sonnetになっています。
開始直後 /model
を入力してモデルをClaude Sonnet 4に変更することをおすすめします。
ルールファイル
.amazonq/rules
ディレクトリのMarkdownファイルで定義できます。
コンテキストは /context add
でも追加可能で、次の画像でprofileに追加されているのはコマンド経由で追加されたものになります。個人でのみ使うものについてはこちらで追加するのが良さそうです。
コンテキストウィンドウの管理
/usage
で現在消費しているコンテキストウィンドウが確認できます。
コンテキストウィンドウはClineの場合、50%までに抑えて利用することが推奨されています。それ以上のコンテキストウィンドウを消費していると、意図していないコードを書くことが多くなるため、そのような場合には /compact
、あるいは/clear
でも問題ありません。
自分の環境では/compact
に失敗することがしばしばあり、タスクも細かく分割していたため基本的にはclear
を使っていました。
会話についてはディレクトリベースの永続性があるため、/clear
をメインで利用していてもあまり困ることはありませんでした。
画像の読み込み
画像が読み込みできるはずなのですが、自分の環境では読み込ませることに一度も成功しなかったため使いませんでした。
この画像のように失敗を伝えてくれると良いのですが、失敗しているのにこちらの指示から貼ったであろう画像を推察して解答をしているような雰囲気を感じることがありました。
今回の開発プロセス
- Amazon Q CLIと壁打ちをしながら、ルールファイルを作成
- ルールから作成順序を決めるため
docs/todo.md
にタスクを作成 - タスクの手順通りに作成
- 妨害ブロックがうまく実装できなかったため、ルールファイルの見直し
- ルールファイルの更新
- 既存コードを全て破棄し、タスクの手順通りに作成
- レートリミットに到達して終了
このような手順で作成しました。
実装のコツと工夫
デバッグ用のアウトプット
このゲームはパズルゲームなので、意図しない動作はほとんどパズルゲームの画面です。
先述の通り画像の読み込みが上手くいかなかったため、アスキーアート表現でパズルの状態をログを出力させることによってAmazon Q CLIにゲームの盤面を伝えていました。また特に便利なのはバグが発生しているときはログをコピペするだけで問題を伝えることができる点でした。ログが正しく出力できてさえいればそれだけで多くのバグを修正できました。
またレイアウトについての指示も同様の理由で難しかったため、デバッグ用のラインを表示させてレイアウトの指示を出していました。エリアに名前をつけたことで具体的な細かい指示を出しやすく、画像を読み込むことができていてもエリアに名前をつけて指示を出すというのはわりと良さそうに感じました。
パズルゲームをアスキーアートで表現する
パズルゲームをアスキーアートで表現することで、ゲームに登場する妨害ブロックの仕様をうまく伝えることができました。次はその一例になります。
初期状態:
a b c d
+-----------------+
0 | __B __R __B __Y |
1 | __R __R __R __Y |
2 | __B __R __Y __Y |
3 | __Y __Y __R __R |
+-----------------+
ユーザーがb0をタップ:
a b c d
+-----------------+
0 | __Y |
1 | __B __B __Y |
2 | __B __Y __Y |
3 | __Y __Y __R __R |
+-----------------+
/.amazonq/rules/05-basic-rules.md
に大量のルールが記載されています。
逆にこのルールファイルがなく、テキストのみの説明だとこの妨害ブロックの実装がまったくうまくいきませんでした。今回の開発プロセスにある「妨害ブロックがうまく実装できなかったため、ルールファイルの見直し」でおこなった見直しがこのアスキーアート表現でした。
ただこのアスキーアート表現、アスキーアート表現のインプットはうまくいくのですがアスキーアート表現のアウトプットになると何故かまともに出力できなかったため、Markdownにあるルールのほとんどが手動でアスキーアート表現を作成したうえで、それを指示によって追記させたものになります。
課題と反省点
ルールの肥大化
ルールファイルがゲームという題材であることもありかなり肥大化してしまいました。そのため/clear
直後であっても初期値からそこそこのtokenを消費した状態からスタートすることになります。
ゲームなのですべての情報をルールとして与えたほうが良いと思ったのですが、作っていく過程であるタスクをしているときに必要なゲームルールはそれほど多くないということに気づきました。例えばパズルのゲーム盤面でゲームを作っているときに、ガチャのルールだったり画面遷移のルールの知識はおそらく必要ないはずです。
そのためルールはあくまでコーディングのルールだけに絞って、ゲーム上のルールはdocs
配下のMarkdownに記載して必要な単位で読み込ませても良かったように感じました。
【改善案】
- ルールはコーディングのルールのみに絞る
- ゲーム仕様は
docs
配下に分離し、必要なときだけ読み込ませる - 機能別にルールファイルを細分化し、
/context add
で動的に追加する
何度も指示しても実装できない内容を、繰り返し指示だけで実装させようとする
指示をだしていくうえで、うまく実装できないことは多々あります。
UIではスクロール可能なエリアで、これは最終的に実装せずにデザインを変更することで対応しました。こういったそこまで難しくないありふれたUI実装の指示で実装できない場合には、Pagerにするなど早めに別の代替手段を考えるべきだったと感じています。ムキになって何度も指示をしても事態を好転させることはありませんでした。
ゲーム機能での実装になると良かった工夫の部分にも記載しましたが、ルールファイルにアスキーアート表現がない状態では何度繰り返し指示をしてもまったく意図した妨害ブロックの実装はできませんでした。ここでもやるべきことは繰り返し指示をだして試行錯誤することではなく、与えている基本的なゲームルール自体を見直すことだったと感じています。
ただゲーム機能においてはどうしても実装できなかったため一部諦めた機能も存在しています(妨害ブロックの鋼鉄ブロック)。どの程度で諦めるかの判断もかなり難しいと感じます。コードをほとんど見ることがなかったので難易度が読めませんでした。
【改善案】
- 複数回試行して実装できない場合は、アプローチを変更する
- 実装困難な機能は仕様を簡略化する判断をする
テストコード
ある程度のテストがあることは安心できるのですが、どれだけルールに記載していてもテストそのもの書き換えたり、テストを通すだけの条件文を追加してテストだけを通すといったことをしはじめます。特にAuto Approveにしていると、ハマればハマるだけコンテキストウィンドウを消費していくので、仕方ない結果かもしれません。
また特にAIに書かせたテストが膨大になってくるとそもそもテストの整合性が取れているかわからないため、テスト自体に不整合がないかどうかのレビューがかなり辛かったです。今回理解しているTypeScriptでもしんどかったので、これがあまり理解していない言語だったと考えるとここのレビューはできなかったと感じます。
間違ったテストコードが生成されると、そこから開発が停滞するデメリットも大きいので、最初にレビューしきれないほどのテストコードが書かれてしまっていると危険な匂いを感じます。スモールステップでテストを追加していても、最終的にテストが増えてくると整合性のレビューは難しいので悩ましいところです。複雑なゲームであればそもそもドキュメントや指示に矛盾が生じてしまうケースもありそうです。
【改善案】
- テストが通っても、抜け道を使われていないか必ず確認する
- 最初から巨大なテストコードを出力させない
AIに仕様のドキュメントを生成させる難しさ
3000行の仕様については先述の通りAIと作成したものになりますが、何度繰り替えしてもドキュメント内の矛盾をうまく整理できませんでした。人間のレビューは行数が増えるほど難しくなるので、修正指示もあいまいになりがちです。
これについては、どこのドキュメントに何を書くかを明確に指示を与えることで解消できたのではないかと感じます。ClineのMemoryBankがそうなっているので、もう少し早く気付きたかったです。
【改善案】
- ドキュメント構造を事前に設計し、各ファイルの役割を明確にする
- ドキュメント間の依存関係を明示し、矛盾チェックのルールを設ける
- ClineのMemoryBank形式を参考に、構造化されたドキュメント作成ルールを策定する
まとめ・感想
使っていて感じたことは、ドキュメントや指示に不足あるいは不備があるにもかかわらず、指示だけでその状況をなんとかしようとしてかなり時間を浪費してしまった部分がありました。そのため工数が私のもっているイメージと全く合わず、時間がかかりそうだと感じていたアニメーションまわりはほとんど工数がかからず、本当に指示だけでいい感じになるので感動しました。
ドキュメントもかなり重要で、ドキュメントから抜けていることは明らかに不足していてもこちらに確認をすることなくそのまま実装されてしまうので、エッジケースの漏れや指示通りではあるけどまったく意図していない結果が出力されるケースも少なくありませんでした。
ドキュメントの作成では小-中規模のゲームであっても無計画に作らせてしまうとドキュメントに矛盾が生じてしまいます。そのためClineのMemoryBankを出力するためのドキュメントのようにドキュメントを書くルールを作って管理すると良さそうに感じました。
普段はClineでPlanモードから始めてそれなりに設計を相談してからコードを書いてもらうことが多いので、今回のようにコードをまったく確認しない手法をとると事前に計画を練らせてコードを提出されても、レビュー側の人間がコードの理解がほとんどできないため、特にそう感じることが多かったです。逆にドキュメントを抜けや漏れなく完璧にするというのは複雑性が増すほど不可能に近い気がしているので、今後のAIの進歩を楽しみにしています。