AIはGodotのコードを高速に書けます。同時に、Godot 4プロジェクトでGodot 3のコードを書いたり、存在しないAPIを幻覚として生み出したり、物理ボディを間違ったコールバックで動かしたり、エンジンが2年前に非推奨にしたパターンでシグナルを配線したりもします。
問題はAIがGodotが苦手だということではありません。問題は、AIがGodotについて自信満々に間違っていて、しかもエンジンをすでに知らない人にはそれが正しく見えることです。コードはコンパイルできます。ゲームは動きます。そして最悪のタイミングで何かが壊れ、原因がわからなくなります。
Godot自身のメンテナーもこれを指摘しています。エンジン本体へのAI生成プルリクエストはメンテナーにとって繰り返し発生する負担になっており、コントリビューターが自分のコードを理解している、あるいはテストしているのかさえ疑われる事態になっています。エンジン自身のリポジトリでそれが起きているなら、御社のリポジトリでも起きています。
以下は、コードレビュー中に私たちがAI生成のGodotコードで最もよく目にする5つの間違いです。各例には、AIが何を書いたか、なぜそれが正しく見えるのか、なぜ壊れるのか、そしてレビュアーが何を見抜くべきかを含めています。
注:以下の例は、Godotリポジトリ全体で一貫して検出しているパターンに基づいて再現したテストケースです。実際のAIの間違いのカテゴリを表しており、テスト用のフィクスチャ上で示しています。
1. Godot 4プロジェクトにGodot 3.x時代の移動コード
AIが書くもの:
extends KinematicBody2D
var velocity = Vector2.ZERO
func _physics_process(delta):
velocity = move_and_slide(velocity, Vector2.UP)
なぜ正しく見えるか: これは教科書通りのGodot 3の移動コードです。2020年から2022年までのあらゆるチュートリアルが、まさにこの書き方を教えています。構造はきれいで、変数名も筋が通っており、Godotに不慣れな人には何もおかしなところがないように見えます。
なぜ壊れるか: KinematicBody2DはGodot 4でCharacterBody2Dに改名されました。move_and_slide()はもはや引数を取りません。代わりに、ノード組み込みのvelocityプロパティから値を読み取ります。公式移行ガイドはこれを主要な破壊的変更として挙げています。
レビュアーが見抜くべきこと: 間違ったノードタイプ。間違ったメソッドシグネチャ。プロジェクトはKinematicBody2Dとmove_and_slide()まわりのクラスおよびメソッドエラーで失敗しますが、変更が大きなPRの中に埋もれていると、Godot 3/4の改名との関連は、その移行を知らない人には明白ではありません。
修正:
extends CharacterBody2D
func _physics_process(delta):
velocity = Vector2.ZERO # set before input handling
# ... input logic ...
move_and_slide()
2. 幻覚または改名されたAPI
AIが書くもの:
var marker = Position2D.new()
var sprite = Sprite.new()
なぜ正しく見えるか: Position2DとSpriteは実在するGodotのクラスです。長年存在してきました。何千ものチュートリアル、Stack Overflowの回答、フォーラムのスレッドに登場します。
なぜ壊れるか: どちらもGodot 4で改名されました。Position2DはMarker2Dになりました。SpriteはSprite2Dになりました。古い名前は存在しません。移行ドキュメントにはこのような改名が何十件も列挙されています。4.0以前のコンテンツで学習されたAIモデルは、自信を持って古い名前を使います。
レビュアーが見抜くべきこと: Godot 4.xのクラスリファレンスに載っていないノードクラス名すべて。Surmado Code Reviewは差分を現在のGodotドキュメントと照合するため、改名されたクラスは自動的にフラグが立ちます。
3. _process()内での物理移動(_physics_process()ではなく)
AIが書くもの:
extends CharacterBody2D
func _process(delta):
velocity.x = Input.get_axis("left", "right") * speed
move_and_slide()
なぜ正しく見えるか: コードは正しいGodot 4のノードとメソッドを使っています。入力処理はきれいです。deltaも利用可能です。動作もします。
なぜ壊れるか: _process()は描画されるフレームごとに実行されます。_physics_process()は固定レート(デフォルトで秒60回)で実行されます。_process()内でCharacterBody2Dを動かすと、ハードウェアごとに移動速度が不安定になり、フレーム落ち時にジッターが発生し、衝突検出も信頼できなくなります。公式ドキュメントは明確に、物理関連の処理は_physics_process()に属すると述べています。
レビュアーが見抜くべきこと: _process()内にあるmove_and_slide()、move_and_collide()、または直接的なvelocity操作すべて。これは5つの中で最も危険な間違いです。なぜならコードはテストでは動作し、実際の条件下でのみ失敗するからです。
4. 文字列ベースのシグナル接続
AIが書くもの:
func _ready():
$Button.connect("pressed", self, "_on_button_pressed")
なぜ正しく見えるか: これはGodot 3でシグナルが動作していた方法です。チュートリアル、講座、YouTubeの解説動画はこのパターンを広く教えています。
なぜ壊れるか: Godot 4はCallableベースのシグナル接続を使います。文字列のメソッド名を使う3引数のconnect()は非推奨です。新しい構文は次の通りです。
func _ready():
$Button.pressed.connect(_on_button_pressed)
古いスタイルは一部のケースでは今でも動作するかもしれませんが、コンパイル時の検証を失います。後でメソッド名を変更すると、文字列接続はパース時にエラーを出さず、実行時に静かに壊れます。Godot 4のシグナルドキュメントはCallable形式を推奨しています。
レビュアーが見抜くべきこと: Godot 4プロジェクト内にある.connect("signal_name", target, "method_name")パターンすべて。これは古いチュートリアルに由来するAI生成コードの信頼できる目印です。
5. Unity流の思い込みと壊れやすいシーンツリーのパス
AIが書くもの:
func _ready():
var hud = get_parent().get_node("HUD")
var player = get_node("../../Player")
health_bar = get_node("../UI/HealthBar")
なぜ正しく見えるか: コードが想定する通りにシーンツリーが見えている限り、動作します。パスは解決します。ノードは存在します。
なぜ壊れるか: Godotのアーキテクチャは、どこにでもインスタンス化できる組み合わせ可能なシーンを中心に構築されています。親や兄弟へのハードコードされたパスは、固定されたツリー構造を前提としています。ノードを移動したり、シーンを再親化したり、別のコンテキストで再利用したりすると、パスは静かに壊れます。Godotにおける実践的なルールは「子は下、シグナルは上」です。子は自身の子に直接アクセスし、上方向にはシグナルで通信します。親や兄弟へのアクセスにはハードコードされたパスではなく、エクスポートされた参照やグループクエリを使うべきです。
レビュアーが見抜くべきこと: get_parent()、get_node("..")、あるいはツリーを上方向にたどるあらゆるパス。これらは設計上壊れやすく、Unityのコンポーネントモデル(GetComponentInParentが一般的で当たり前に使われる)からAIが持ち込むパターンです。
リンターがこれを見抜けない理由
Godotの組み込み警告システムやgdscript-toolkitのようなツールは、フォーマット、未使用変数、一部の型の問題を検出します。有用なので使うべきです。
しかし、Godot 4プロジェクトにおけるバージョン違いのAPIは検出しません。_process()と_physics_process()の誤用も検出しません。御社のSTANDARDS.MDが「親パスのナビゲーションは禁止」「常にCallableのシグナル接続を使う」と定めていることも知りません。それらはレビューレベルで検出すべきものであり、リント(構文チェック)レベルのものではありません。
そこが自動コードレビューが埋めるギャップです。リンター(構文をチェックする)と人間のレビュアー(アーキテクチャをチェックする)の間に位置し、中間層を担います。すなわち、このコードはこのエンジンバージョン、これらの標準、このプロジェクトに対して正しいか、という問いです。
すべてのPRでこれらを検出する
Surmado Code Review for Godotは、GitHubプルリクエストへのすべてのプッシュで実行されます。差分を公式Godot 4.6ドキュメント、御社のリポジトリコンテキスト、そして御社のSTANDARDS.MDと照合します。検出するのは以下です。
- バージョン間違い(Godot 4プロジェクト内のGodot 3パターン)
- 幻覚または改名されたAPI
- ライフサイクルの誤用(
_processと_physics_process) - 非推奨のシグナルパターン
- 壊れやすいシーンツリーの思い込み
- 御社の標準で定義したそのほか何でも
月10件のPRまで無料。100件まで月額$15。座席単位の料金なし。
AIの助けを借りてGodotゲームを作っているなら、AIが著者です。レビュアーには別の頭脳が必要です。
Surmado Code Review for Godotを導入する(無料) →
Godotが初めての方へ。GDScoutに聞いてみてください。Godot 4.6について平易な英語で何でも答えます。無料で、公式ドキュメントからの引用付きです。
質問と回答
Godot向けの最良のAIコードレビューツールは何ですか? Surmado Code Review for Godotは、差分を公式Godot 4.6ドキュメント、リポジトリコンテキスト、チームのSTANDARDS.MDと照合する自動PRレビューツールです。バージョン間違い(Godot 4プロジェクト内のGodot 3パターン)、幻覚APIの使用、ライフサイクルの誤用、非推奨のシグナルパターン、壊れやすいシーンツリーの思い込みを検出します。月10件のPRまで無料、100件まで月額$15です。
Godot 4コードにおけるAIのよくある間違いは何ですか? Godot 4コードで最もよく見られるAI生成の間違いには、改名されたGodot 3のノードタイプの使用(CharacterBody2Dの代わりにKinematicBody2D)、Godot 4ではもう受け付けないmove_and_slide()への引数渡し、物理移動を_physics_process()ではなく_process()に配置すること、Callableベースの接続の代わりに非推奨の文字列ベースのシグナル接続を使うこと、シーンが再利用されたときに壊れる親/兄弟ノードパスのハードコードなどがあります。
Surmado Code ReviewはGDScriptに対応していますか? はい。Surmado Code ReviewはGodotプロジェクトにおけるGDScriptとC#の両方をサポートしています。レビューは公式Godot 4.6ドキュメントに基づいており、汎用のAIコードレビューツールが見逃すエンジン固有の問題にフラグを立てます。
Surmado Code ReviewはGDScriptのリンターとどう違いますか? GDScriptのリンターやGodotの組み込み警告システムは、構文エラー、フォーマットの問題、未使用変数、一部の型の問題を検出します。Surmado Code Reviewはより高いレベルの問題、すなわちバージョン違いのAPI、ライフサイクルコールバックの誤用、非推奨パターン、壊れやすいシーンツリーのアーキテクチャ、チームのSTANDARDS.MD違反を検出します。リンターとコードレビューは補完関係にあります。リンターはルールを強制します。コードレビューはコンテキストを評価します。
AI生成のGodotコードはリントを通過しても間違っていることがありますか? はい。AI生成のGodotコードは、リントを通過しエラーなくコンパイルされても、間違ったエンジンバージョンのパターン、ライフサイクルコールバックの誤用、実行時の失敗を引き起こすシーンツリーの思い込みを含んでいることが頻繁にあります。例えば、CharacterBody2Dの移動を_physics_process()ではなく_process()に配置すると、リントも通り、コンパイルも動作もしますが、異なるハードウェアやフレームレート間で挙動が不安定になります。