ClaudeCodeとCodexにコーディングを全て任せて商用レベルのUnityゲーム開発を行う【前編】
こんにちは、Liseと申します。
現在のゲーム開発現場では恐らく、どんな会社でもどんなプロジェクトでも、ClaudeCodeやCodexを利用した開発のAI補助を行っていたり、ゲームジャム等のイベントで「試しにAIに小規模なゲームプログラミングをさせてみよう」みたいな動きがあると思います。
しかし既にAIを活用しているエンジニアでも、どうしても心の中に心配としてあるのが、
「ゲーム開発や設計を丸ごとAIに投げることが出来ないのか?」 というテーマだと思います。
この投稿はそんな「一からゲーム開発をAIで行って見た」というチャレンジの備忘録になります。
作業したリポジトリ
総評・結論を最後にまとめたので、それだけみたい人は一番下までスクロールしてください。
注意点
私個人の学習スタンスとして、学習する対象以外の要素(例えば公開されているUnity用事前プロンプトやサードパーティのAI用の開発ツール)を極力減らしたバニラな状態で作業を行い、
自分なりの改善サイクルを実施し、私の中で一定の結論を出してからサードパーティ製のツールを評価する・・・ということをしています。
これはAIそのものやツールを正しく評価するために、基準を自分の中に構築するための行為で、物事の本質を掴むために必要なことだと私は考えていますが、ぶっちゃけ非効率なので「なんでこんなことしてんだコイツ」と思いながら読んでほしいです。
(Xで「ClaudeCodeをゲームスタジオ化するツール」がどうのとか、トークンを湯水のように使えば実現するのか?みたいな私の中で疑念の残る話題がちょくちょくありました)
どんなゲームを作るか
WebGLでのハイパーカジュアルなゲーム開発は私の中である程度実証出来ているので、
今回は商用としてSteamで売ることが出来るようなガチ品質のゲーム開発を目指し、Unityを利用したゲームを作ります。
とはいえアクションゲームを作り始めると、人間による操作感・好き嫌いなど個人の好みが出てしまうため、データのやり取りが重要なシミュレーションゲームを作ろうと思いました。
ゲーム内容のサマリ
- プレイヤーは冒険者ギルドを運営するシミュレーションゲーム
- 冒険者は自動的にスポーンし、自動的にダンジョンを探索し、自動的に帰還し、冒険者ギルドにアイテムや素材を納品し、武器や消耗品を購入して再びダンジョンの探索を行う
- プレイヤーは冒険者ギルドの施設を拡充し、冒険者を支援することでダンジョンがより深いフロアまで探索出来るようにすること目指す
- ダンジョンの内部はプレイヤーがカメラを自由に移動させて見ることが出来る
- 細かいゲームジャンルとしてもう少し区分けすると、放置ゲー・クリッカーゲーに近い拡大再生産というジャンル
割とオーソドックスで想像しやすいテーマと連想しやすいシステムです。
使用するツールと技術スタック
少し前にLighthouseというUnityフレームワークを開発したので、これを利用して作ろうと思います。
概要だけ簡単に紹介すると、中規模~大規模なゲーム用のシーン基盤とそれを支えるミドルウェア群で、これに乗っかって開発すれば作業者はコンテンツ開発だけで済むということ目指したアーキテクチャフレームワークです。
今回はAIにコンテンツ開発を行ってもらって、シーンのライフサイクルや画面遷移、アセット管理とかダイアログ管理など、めんどくさい所は全部Lighthouseに任せるというスタンスで進めます。
そしてもう一つ、unity-cli-loopというツールを導入します。
これはUnityの操作をCLIからある程度操作できるようにしたもので、つまりUnityのスクリプトビルドやエラーログの収集・分析などがAIだけで完結するようになります。
例えば
AI「作業が完了しました。実行して確認してみてください」
ユーザー「実行したら●●というエラーがでました」
AI「エラーの原因を修正しました。実行して確認してみてください」
...
というユーザーの作業が不要になります。
開発サイクル
ゲームはAIが得意そうなクリーンアーキテクチャで作ります。
クリーンアーキテクチャとは依存方向を統一した基盤設計のことで、
非エンジニアにもわかりやすく例えると「プロダクトはUnityの機能を利用するが、Unityはプロダクトの機能を知らないし利用出来ない」みたいな関係をプロダクト内の機能単位でも細かくやろう、という考え方です。
この考え方をちゃんと実践すると、ゲームがどれだけ大規模になっても関係性が明瞭になり、破綻しにくくなります。
ゲーム開発サイクルとして、
- ClaudeCodeがmdファイルに次の作業内容を書く
- ユーザーがmdファイルの内容を確認し、問題があれば修正を依頼する
- 問題なければClaudeCodeにmdファイルの内容を実装してもらう
というシンプルなサイクルで進めます。
1回目のチャレンジ
ブランチ名は dev-test/claude-code-only
https://github.com/lisearcheleeds/DungeonInn/tree/dev-test/claude-code-only
まずはClaudeCodeでどれだけやれるか見てみたかったので、ClaudeCodeだけでゲームの設計・実装・テスト・動作確認を行わせようと思いました。
・・・というのはウソで、「Lighthouseがあれば後はClaudeCodeだけでゲーム作れるだろ」と思って最初で最後のチャレンジだと思って試みました。
入力したプロンプトは以下です。
DungeonInn ゲーム仕様書
バージョン: 1.0.0
対象フレームワーク: Lighthouse (VContainer / UniTask / R3)
Unity バージョン: Unity 6 (URP)
1. ゲームコンセプト
ダンジョン入口付近の村で、冒険者向けの宿屋を経営するシミュレーションゲーム。
プレイヤーは宿屋の店長として資金を稼ぎ、土地を拡張し、冒険者の満足度を高めながら宿屋を発展させる。
2. ワールド設計
2.1 グリッドシステム
基本単位: 1ブロック = 1m の立方体
地形・建築物: すべてグリッド座標で位置を決定
動的オブジェクト(キャラクター等): グリッドに拘束されず自由移動
デフォルトマップサイズ: 1000 × 1000 × 1000 ブロック
マップサイズ: 設定ファイルで自由に変更可能(WorldConfig で管理)
2.2 レイヤー構造
レイヤー名 Y座標範囲 説明
地上 Y >= 0 村・宿屋エリア
地下1階 Y = -1〜-20 ダンジョン最上層(弱)
地下2階 Y = -21〜-40
地下3階 Y = -41〜-60
地下4階 Y = -61〜-80
地下5階 Y = -81〜-100 ダンジョン最下層(強)
2.3 カメラ
視点: 神の視点(クォータービュー・自由回転)
操作: 画面中心のブロックを軸に移動・回転・ズーム
キャラクター視点への切り替えは スコープ外(将来機能)
...
プロンプト全文:
仕様書となるプロンプトを渡した後、何度かやり取りするとシーンが作成され、それらしいクラスが徐々に出来てきます。
実行してみて「おお、それっぽいのが動いててカメラも操作出来るじゃん!」と喜んだのは一瞬でした。
作業の続きを見ていると、ClaudeCodeは「ゲームを実行したのに画面が真っ暗なまま」というバグを延々と調査し続けていました。
まぁこういうこともあるかとClaudeCodeの処理を止めて私自身で問題を確認してみた所、3D画面を表示するCameraのPriorityが-1になっていて、他のCameraとの兼ね合いで画面が真っ暗になっているようでした。
(unity-cli-loopはスクショを撮影して画像分析することで画面がどのような状態か評価するところまで自己完結出来ます。スゴイ!)
この問題はフレームワークの機能をちゃんと利用していれば踏まないはずで、
他にもユーザー入力(カメラのWASD移動)をフレームワークの入力レイヤーシステムを利用せずに InputKey.*.isPressed を直接利用していたり、AssetScope機能を利用せず直接Resouces.Loadしていました。
AI用のReferenceを用意したのですが、正しく読み込まれていないか、もしくは従っていないという状態であることを発見し 「●●を参照すること」みたいな言い回しだと弱いのだ と始めて実感しました。
その後も作業を続けていると徐々にデバッグに時間がかかるようになり、ClaudeCodeの4回目のLimitに達した所で「この効率では一生終わらないかも」と考え作戦を変えることにしました。
2回目のチャレンジ
ブランチ名は dev-test/claude-code-and-codex
1回目のチャレンジでの失敗・反省点はドキュメント不足とデバッグ効率の悪さです。
- フレームワークの各機能を活用すべきシチュエーションをAIが把握していない
- Lighthouseパターン集としてdocsを追加することで対策
- https://github.com/lisearcheleeds/DungeonInn/blob/dev-test/claude-code-and-codex/docs/lighthouse-patterns.md
- コーディングルールがファイルによってバラバラ。統一されていない
- デバッグ効率の悪さ
- 一番の問題点
- ユーザーが指摘しても直さずに他の原因を探ろうとすることや、そもそもフレームワーク関係なくUnity関連の勘所の悪さが目立つ
デバッグ効率の悪さを改善するために、「アンチパターン集」みたいなのをバグを踏むたびに作っても良いのですが、AIの本来の強みではない気がします。AIの強みを否定するような戦略になるため、あまり採用したくありません。
そこで、2回目のチャレンジでは、巷でスゴイと噂されている「ClaudeCodeに監督・設計をさせて、Codexにコーディングさせる」というスタイルで開発を行います。
Codex単体でのコーディングも考えたのですが、プロジェクト全体を把握しながら開発する以上、ClaudeCodeよりコンテキストウィンドウが少ないCodexには難しいと判断しました。
(この後の3回目のチャレンジで試してみたら、実際にはそんなに差があるようには見えませんでしたが)
参考
また、ClaudeCodeとCodexは直接お互い呼び出せないので、mdファイルにプロンプトを書いてもらってそれをお互いに投げ合うという形式で進めます。
発火はunity-cli-loopにその機能があったのでそれを利用します。
(ただし、これはちゃんと調べたらClaudeCode上からCodexを呼び出せるという話があったので実際は出来るのかもしれません)
人間とAIのように何らかの意思決定のためにSenderと高頻度にやり取りを行う必要はAI同士にはないと考えたので、Task.md/Review.mdという単位でファイルを作り、ClaudeからCodexに「作業を依頼する」という形式で進めようと思いました。
ただし、ClaudeCodeは全体設計を見張る以上、インターフェースは知っている必要があります。
ClaudeCodeはクラスの概要・インターフェースだけを作り、具体的な実装はCodexに行わせるという分担にします。
1回目のチャレンジでClaudeCodeが解決出来なかったCameraのPriority問題について、Codexが解決できる能力を持っているのであればこの分担形式は有効に働くはずです。
しかし・・・
問題がいくつかあったので整理すると
-
ClaudeCodeとCodexの方針が喧嘩する
- 基本的な設計のバグを指摘して修正するところまで可能
- ClaudeCodeが「これはCodexには向いてない作業です」とか言い出す
- ある意味望んでいたものではあるので許容
-
やりとりが長い
- ClaudeCode単体で1分で終わる作業がCodexにやらせた後ClaudeCodeがレビューして・・・と往復が発生し、3倍ぐらいの時間がかかる
- ユーザーの方針決定が絡んでないので、大量にトークン使って出来あがったものを見て投げ直しが発生する
-
バグに詰まっている時にユーザーに応答が帰ってこない
- バグが解決するまでClaudeCodeとCodexがプロンプトをずっと投げ合う
- バグの解消精度はそこそこ上がっていそう
- 3回まで往復が発生したらユーザーにコントロールを返してくださいという命令は無かったことにされる
-
設計品質・コード品質の低さ(Domain/UseCaseの粒度がおかしい)
- 1回目のチャレンジから薄々気付いていたが、ClaudeCodeが生成するDomain設計やマスタ設計の品質が悪い
- 特にmutableなオブジェクトとimmutableなオブジェクトを一緒に管理してるケースが多々あり、状態を持つオブジェクトと定数(語弊ある表現)を持つオブジェクトは分けるという事をしない
- 例えば、キャラクターの名前や最大HPと、現在HPや位置情報などを同じオブジェクトで持っていたりする
- 前者は不変のデータ、後者は実行中に変化する状態を表現したデータであり、本来は別オブジェクトとして分離すべきもの
- これが混在すると「名前だけ参照したい」処理が「現在HPや位置情報」まで知っている必要が生まれ、本来依存するはずのなかったシステム同士が結びついてしまう
- 結果、技術的負債となり機能の拡張や修正を行う時に本来必要のない情報を生成したり、必要のない依存が発生して本来実装出来るはずの機能が実装出来ない状態に陥る
- ハイパーカジュアルやゲームジャムで作るような小規模なゲームなら問題ないが、ちゃんとしたゲームを作るなら確実に技術的負債になる
ClaudeCodeやCodexのLimitに4回ほど達した所まで作業を行い、進捗や品質を鑑みた所感としては「ちゃんと学習すれば使えるかも?」となりました。
4つ目はコード品質としては割と深刻な問題ですが、物理的な問題ではないのでAIへのルール付けでなんとかなります。
ちゃんと定義した同じルールの下で作業させることで、ClaudeCodeとCodexのコミュニケーション効率が良くなり、全自動で大規模なゲームでも作ることが出来るかもしれません。
ただ、「どのように言語化して、どんな形でドキュメント化するのか、どうやって作るのか」の労力が非常に大きくなりそうです。
3回目のチャレンジ
ブランチ名は develop
https://github.com/lisearcheleeds/DungeonInn/tree/develop
そもそもコード品質のバロメーターはプロジェクトによってコンテクストが大分変わります。
プロジェクトAでは良い品質とされていたコードが、プロジェクトBでは悪い品質のコードと評価されたりします。
ClaudeCodeやCodexはプロジェクトA,Bだけじゃなくて世界中のGitHubから学習していると思うので、「良いコード書いて」とプロンプトを投げた所で、ユーザーのプロジェクトで良いとされる品質のコードになるかは微妙な所です。
これを解決するにはその指針をドキュメント化してプロジェクトに配置するのが適切ですが、私がチマチマルールを1つずつ定義すると漏れがありそうで怖いです。
そこで発想を変えて、まず手本とするためのゲームプロジェクトを作り、その過程で発生した私からのレビュー・指摘内容を抽象化・言語化して、他プロジェクトでも汎用的に利用出来る「バイブル」を作成するという戦略を試そうと思いました。
AIが生成した設計・コードを私がレビューすることで、「AIが生成するコード」から「(私が望む)良いコード」へのベクトルがわかるはずです。
冒頭の「バニラな状態で作業と改善のサイクルを行う」という方針もここに生きてきます。
ちゃんとコードレビューするViveCoding
1回目、2回目のチャレンジはコードのレビューまでしていませんでしたが、今回からは私がAIのコードをレビューします。
そして実装順序の改善も行います。
私はこれまで「ゲームの状態を評価するためにゲームを実行する」という前提で作業順序を組み立ててきました。
しかしこれはよく考えると極めて非効率です。
なぜならこのワークフローは「ステークホルダーにゲーム開発の進捗を見せるために見えるところから実装する」という組織の都合が由来だからです。
Unityでゲーム開発を始めると、まず最初に「キャラクターを表示しよう」とか言われることがありますが、私の経験上それが非効率なワークフローの最初の一歩です。
キャラクターを表示してしまうと開発中、その表示する機能を維持し続ける責任が生まれ、関連する機能を作るたびにそれをメンテナンスするコストが発生します。
犬を早く飼いたいからって飼育環境が整っていないのにお出迎えするのと同じです。
1,2回目のチャレンジの失敗の結果から導き出した効率の良いワークフロー、
「エンジニアが最高効率・最速・最適な設計のゲームを作るために行うべき最初の作業」の結論は、
「 データオブジェクトを最初に一通り設計すること 」です。
そもそもアクションゲームや物理エンジンによる体験が重要なゲームでない限り、ゲームロジックの本質はUnityとは関係ないところで動きます。
頭の中でデータ構造を一通り構築して、それをAIにコード化してもらうというのが最初のステップだと考えました。
つまり最初にAIに出すべきプロンプトは
「まずキャラクターの画像を表示して」
ではなく
「まずDomainのオブジェクトを全て出して」
です。
Domainのデータオブジェクト、UseCase、Master、Event、Factoryなどを全て作って、
その後に作ったGameLoopの動作確認をする時に始めてUnityの機能を利用するという流れだと、最も無駄のないプロジェクトワークフローになります。
機能の接続を維持しながらゲームを作るのは効率が悪いので、最初にパーツを全て作っておいて最後に組み立てる、といったイメージです。
自動車の工場は相当効率化が進んでいると思いますが、それに近いイメージを持ちました。
(まぁ自動車と違って設計図なんて無いんですが)
それまでは、Unityのテストを利用すれば動作確認用のシーンなども不要です。
実際にやってみる
前置きが長くなりました。
ワークフローが変わっただけで実際にやることは前のチャレンジまでと変わらないので、実際に実装を進めてみた感想を中心に述べていきます。
1. Domainの生成
ClaudeCode/Codexが生成したDomainオブジェクトへのレビュー・指摘内容を抽象化・言語化してmdファイルにさせるという話です。
結論だけ記載すると、最初のDomainの設計に対してレビューを何回か行ってそれをドキュメント化した結果、非常に効率と品質がよくなりました。
「冒険者」「モンスター」「冒険者ギルドの施設」などのいくつかのDomainオブジェクトの設計レビューを行い、それをmdファイルにガイドラインとして恒久的なルールとして置いた所、
他のDomainオブジェクト「アイテム」「武器」「装備」などの後続のDomainオブジェクトも同じ品質で生成してくれるようになりました。
ClaudeCode/Codex両方で差を確認しましたが、ほぼ同じ品質です。
これぐらいのスコープだと性能をフルに発揮出来るのかもしれません。
2. UseCaseの生成
Domainと同じく、UseCaseもチャレンジ1、2では同じ責務を持つ対象が違う処理が別の箇所に書かれていたり共通化されていませんでしたが、UseCaseの実装もほぼ期待以上の品質の高さです。
Domainのデータ構造に引っ張られたのでしょうか?
私からのレビューが何回かありましたが、エッジケースなのでガイドライン化する項目はほぼありませんでした。スゴイ
3. Master/Factoryの生成
Domainオブジェクトを生成するためにMasterとFactoryを作ってもらいました。
MasterもDomainと同じくClaudeCodeが生成してくれたマスタ設計に少し修正が必要でしたが、これもほぼエッジケースでしょう。
Adventuerer(冒険者)/Monster(モンスター)をまとめたActorという概念がここで生まれて共通化することが出来ました。
バランスとしては最初に人間がDomainとMasterを握って、UseCaseとFactoryを作るという順序で実装すれば、この後のフェーズは組み立てるだけなので問題なさそうな雰囲気です。
データ構造の品質が担保されているので恐らく使う側で変な作りになりようがないのかもしれません。
4. ゲームサイクルの作成
Actorの戦闘システムや攻撃処理、冒険者の冒険サイクルなどデータ構造にも影響のある複雑なシステムは、
DomainやUseCaseの作成時に一緒に伝えておき、mdファイル化しておくといいかもしれません。
人が共通認識・常識だと思っている要素は、自分の人生経験の中で無意識に形成されたものが多く、プロンプトとして言語化するのが難しいです。
データ構造への修正指摘をするタイミングで「あ、そういう想定ではないんだよな」と思う事が多々ありました。
例えるなら、地方出身の人が東京に来て方言を使って指摘されて「え、これ方言だったんだ」ってなる現象と似てます。言われるまで気付きません。
これを人間が最初にプロンプト化するのは無理かもしれません。
その他
- チャレンジ1,2のcommitをこまめにしていなかったのでほぼ比較出来ないのですが、チャレンジ3のcommitのログを見るとAdditiveに比べてDeletionは非常に低めです
- これはもう少し開発実装を進めて最終的にどうなるか見てみたい所
- https://github.com/lisearcheleeds/DungeonInn/tree/develop/Client
- このワークフローはシステムの開発とコンテンツの制作を分けられるというメリットがあります
- Domain/Usecase設計時に必要なコード品質の上昇はこのようなmdファイルになりました
- これを利用すれば(私基準の)良いとされるコード品質の設計がAI単独でも行えそうです
- https://github.com/lisearcheleeds/DungeonInn/blob/develop/docs/domain-usecase-design-guidelines.md
総評・結論
「ClaudeCode/Codexにコーディングを全て任せてUnityゲーム開発は出来る」
ただし、その土台作りを安定して作るためには、ある程度の規模の会社でちゃんと利用出来るものを求めるならシニアエンジニア2~3人のチームを2か月ほど拘束する必要がありそうです。
- プロジェクト固有のコード品質ガイドラインの策定
- フレームワークのAI向けリファレンスの整備(あれば)
- ワークフローの確立と検証
実際にゲームプロジェクトを作って実証実験する所まで行うとおよそ2か月と見ています。
前編で得られた教訓としては
- 「データ構造を先に設計する」 知見
- 「コード品質ガイドラインをレビューから逆算して作る」 戦略
が有用だということがわかってよかったです。