Godotには標準的なコードレビューチェックリストがありません。エンジンにはスタイルガイド、警告システム、そしてエンジン貢献者向けのPRレビューガイドラインがあります。ですが、小さなチームや一人でゲームを作ってGitHubにコードをプッシュしている場合、「マージ前にこれを確認する」という定番のリソースはありません。
これがそのリソースです。
以下の各チェックは公式のGodot 4.6ドキュメントに基づいています。特定のドキュメントページを参照するチェックにはリンクを付けています。チェックリストは、Godotのプルリクエストで最もよく見られる問題をカバーする6カテゴリに分かれています。特にAI支援開発を使うプロジェクトでは、バージョン違いのパターンや、もっともらしいが壊れているコードが頻繁に現れます。
マージ前に使ってください。印刷してください。リポジトリのCONTRIBUTING.mdに入れてください。あるいは、リポジトリにSurmado Code Reviewを導入して、Scoutに差分を自動チェックさせてください。
1. バージョンの正しさ
このコードは本当にGodot 4向けに書かれているか?
これはAI支援を使うプロジェクトにとって最優先のカテゴリです。LLMは何年分ものGodot 3のチュートリアル、フォーラムの回答、ドキュメントで訓練されています。Godot 4のプロジェクトでも、自信満々にGodot 3のコードを生成してきます。公式の移行ガイドには数百件のリネームと破壊的変更が記載されています。組み込みのプロジェクトコンバーターがその多くを検出しますが、Godot自身のドキュメントも、アップグレードされたスクリプトにはおそらくまだエラーが残り、アップグレードの多くは手作業のままだと警告しています。
移行後でも、AIは新しいファイルに古いパターンを再導入することがあります。このカテゴリはレガシーコードと、間違ったバージョンから学習した新しいAI生成コードの両方を捕捉します。
チェック:すべてのノードクラス名は最新か? リネームされたクラスをスキャンしてください。最もよくあるものは以下の通りです。
KinematicBody2D→CharacterBody2DKinematicBody→CharacterBody3DPosition2D→Marker2D、Position3D→Marker3DSpatial→Node3DSprite→Sprite2D
完全なリネーム一覧は移行ドキュメントにあります。
チェック:メソッドのシグネチャは最新か? よく使われる複数のメソッドがシグネチャを変更、あるいはリネームされました。
move_and_slide()は引数を取らなくなりました。ノードの組み込みプロパティvelocityから読み取ります。(CharacterBody2Dドキュメント)instance()→instantiate()set_shader_param()→set_shader_parameter()map_to_world()→map_to_local()(GridMapおよびTileMap)change_scene()→change_scene_to_file()Thread.start(self, "__method", args)→Thread.start(__method.bind(args))Thread.is_active()→Thread.is_alive()
チェック:シグナル接続はコーラブル構文を使っているか?
古いconnect("signal_name", target, "method_name")パターンは非推奨です。Godot 4はコーラブルベースの接続を使います。
# Old (Godot 3)
button.connect("pressed", self, "_on_button_pressed")
# Current (Godot 4)
button.pressed.connect(_on_button_pressed)
コーラブル形式はコンパイル時の検証を提供します。文字列ベースの接続は、メソッド名を変更すると実行時に静かに壊れます。(Signalドキュメント)
チェック:定数とシグナル名は最新か?
色定数の形式が変わりました(例:Color.palegreen → Color.PALE_GREEN)。一部のシグナル名もリネームされました(例:CanvasItem.hide → hidden)。移行ドキュメントのリネーム表を確認してください。
2. ライフサイクルコールバック
コードは正しいコールバックで実行されているか?
このカテゴリは最も危険です。間違ったコールバックのコードはコンパイルされ、実行され、動いているように見えるからです。実際のフレームレートの違い、物理演算のエッジケース、ハードウェアの違いなど、実際の条件下で失敗します。Godotの通知ドキュメントは、どのコールバックがどの目的に使われるべきかを明確に説明しています。
チェック:物理演算による移動は_physics_process()にあるか?
_process()はレンダリングされるフレームごとに実行され、フレームレートに依存します。_physics_process()は固定レート(デフォルトで1秒に60回)で実行されます。move_and_slide()、move_and_collide()を呼び出す、あるいは物理ボディのvelocityを直接操作するコードは_physics_process()にあるべきです。(物理演算の導入)
チェック:入力は正しい場所で処理されているか?
離散的なイベント(キー押下、ボタンクリック)には_input()または_unhandled_input()が望ましいです。継続的な状態(キーが押されたままかどうか)には、Input.is_action_pressed()を使った_process()または_physics_process()が適切です。物理演算による移動にしか必要ないのに_process()で毎フレーム入力をポーリングするのは、AI生成コードによくあるパターンです。
チェック:_ready()は継続的な作業ではなくセットアップを行っているか?
_ready()はノードがツリーに入るときに一度実行されます。子は親より先に_ready()を実行します。初期化が兄弟ノードや親ノードの準備完了に依存する場合、await owner.readyを使うか、セットアップ呼び出しを遅延させることを検討してください。
3. シグナルの衛生
シグナルがコードを疎結合に保っているか?
Godotのシグナルシステムは、オブジェクトが互いを直接参照せずにイベントに反応できるようにします。実務上のルールは「呼び出しは下へ、シグナルは上へ」です。親ノードは子のメソッドを直接呼び出せますが、子は上方向にシグナルで伝えるべきです。AI生成コードは、子が親や兄弟に手を伸ばすことで、これに頻繁に違反します。
チェック:親への直接参照ではなくシグナルが使われているか?
子ノードが何かが起きたことを親に通知する必要がある場合、シグナルを発行するべきです。親がそのシグナルに接続します。子はget_parent().some_method()を呼び出すべきではありません。
チェック:シグナル接続は正しい場所にあるか?
イベントを気にするノードが接続を所有すべきです。一般的には、親ノードが_ready()で子のシグナルに接続します。ツリーの深くネストされた部分や離れた部分でシグナルを接続するのは避けてください。
チェック:必要なときにシグナルは切断されているか?
ノードが動的に追加・削除される場合、残ったシグナル接続がエラーや予期しない動作を引き起こすことがあります。disconnect()やqueue_free()によるクリーンアップが必要かどうかを確認してください。
4. シーンツリーのアーキテクチャ
コードは固定されたツリー構造を前提としているか?
Godotはどこにでもインスタンス化できる合成可能なシーンを中心に構築されています。ハードコードされたパスや親への参照はこの合成可能性を壊します。シーン構成のドキュメントは、再利用可能なサブシーンは自分の置かれている環境の詳細を必要とせずに動作するべきだと述べています。
チェック:スクリプトは..で上方向にナビゲートしているか?
get_node("..")、get_parent()、../../Playerのようなパスは脆弱です。シーンが親を変更されたり、別のコンテキストで再利用されたり、再構成されたりすると壊れます。ノードとシーンインスタンスのドキュメントは、..を避けることがベストプラクティスだと述べています。
チェック:ハードコードされたパスの代わりに@export参照を使うべきか?
@export var target: Nodeはエディターで参照を配線できます。ツリーの再構成を乗り越え、依存関係を明示的にするため、get_node("../Player")より堅牢です。
チェック:直接参照の代わりにグループを使うべきか?
グループを使うと、パスを知らなくてもノードにタグ付けしてアクセスできます。get_tree().get_nodes_in_group("enemies")は名前で子を反復処理するより堅牢です。
チェック:親子関係に意味があるか? ドキュメントは、親子関係は実際の包含関係を表すべきだと述べています。親を削除しても子を削除すべきでない場合、その子はツリーの別の場所にあるべきかもしれません。AIは意味的な正しさよりも利便性のためにノードをネストすることがよくあります。
5. 型安全性と警告
プロジェクトはGodotの組み込み安全ツールを使っているか?
GDScriptは静的型付けをサポートし、組み込みの警告システムを持っています。どちらも任意ですが、実行時の驚きを大幅に減らします。ドキュメントは、静的な型がコードを実行せずにエラーを検出し、エディターのオートコンプリートを改善すると述べています。
チェック:関数のパラメータと戻り値の型は注釈されているか?
# Untyped (works but risky)
func take_damage(amount):
health -= amount
# Typed (catches errors at parse time)
func take_damage(amount: int) -> void:
health -= amount
ベストプラクティスはオール・オア・ナッシングです。ドキュメントは、同じプロジェクト内で型付きコードと型なしコードを混在させると混乱を招くと警告しています。
チェック:警告は真剣に受け止められているか? Godotの警告システムは未使用の変数、到達不能なコード、実行時エラーにつながりかねないパターンを検出します。警告はプロジェクト設定でエラーに昇格させられます。プロジェクトがすべての警告を無視していると、バグが隠れます。
チェック:@warning_ignoreアノテーションは正当か?
Godotは@warning_ignore("unused_variable")のようなアノテーションをサポートしています。それぞれが意図的なものであるべきで、ノイズを消すための手段ではありません。レビュー中は、この無視が実際の問題を隠しているのか、それとも意図的な例外なのかを問いかけてください。
6. リソース管理
コードは物事を安全に読み込み、作成し、解放しているか?
Godotのリソースシステムは強力ですが、特に読み込み、インスタンス化、クリーンアップの周辺でAIがよく間違えるパターンがあります。
チェック:load()とpreload()の使い分けは意図的か?
preload()はコンパイル時に読み込まれ、定数の文字列パスを必要とします。load()は呼び出された行で実行されます。常に必要なリソースにはpreload()を使ってください。条件付きまたは動的に読み込むリソースにはload()を使ってください。AIは柔軟性が高いという理由でload()をあらゆる場所で使う傾向がありますが、これは不要な実行時読み込みを生み出します。
チェック:パックされたシーンは正しくインスタンス化されているか?
Godot 4では、保存されたシーンはPackedSceneリソースです。ノードツリーを作成するにはinstantiate()(Godot 3の名前であるinstance()ではなく)を呼び出します。インスタンス化されたシーンがadd_child()でツリーに追加されているか確認してください。
チェック:ノードは安全に解放されているか?
特別な理由がない限りqueue_free()を使ってください。free()はノードを即座に破棄し、それへの参照は即座にnullになります。queue_free()は現在のフレームの終わりまで待つので、より安全です。ドキュメントはqueue_free()をデフォルトとして推奨しています。
チェック:オートロードは控えめに使われているか?
オートロードはグローバルにアクセス可能ですが、依然としてシーンツリー内のノードです。実行時にfree()やqueue_free()で削除してはいけません。エンジンがクラッシュします。AI生成コードは、オートロードを使い捨てのマネージャーとして扱うことがあります。グローバルな状態が本当にグローバルである必要があるのか、リソースやグループにできないかをレビューしてください。
このチェックリストがカバーしないもの
このチェックリストはコードレビュー、つまり正しさ、アーキテクチャ、パターンをカバーします。以下の代わりにはなりません。
- リンターとフォーマッター。
gdscript-toolkitやGodotの組み込み警告のようなツールは、構文、フォーマット、未使用変数、一部の型の問題を検出します。これらを使ってください。相互補完的です。 - プレイテスト。 コードレビューは構造的な問題を捕捉します。「これはしっくりこない」や「ジャンプがふわふわしすぎる」は捕捉しません。それはテストの仕事です。
- アーキテクチャ設計。 このチェックリストは「アーキテクチャは健全か?」を問います。どのアーキテクチャを使うべきかは教えません。それにはGodotのベストプラクティスセクションを読んでください。
チェックリストを自動化する
このリストをPRごとに手動で確認することもできます。あるいは自動化することもできます。
Surmado Code Review for Godotは、GitHubプルリクエストへのすべてのプッシュを、公式のGodot 4.6ドキュメント、リポジトリのコンテキスト、御社のSTANDARDS.MDと照らし合わせてチェックします。バージョンの間違い、ライフサイクルの誤用、非推奨のパターン、脆弱なシーンツリーパス、そして御社が定義したカスタムルールを検出します。
月10 PRまで無料。100 PRまでなら月額$15。シート課金なし。
チェックリストは何をレビューするかです。Surmado Code Reviewは、差分をずっと眺めることなくすべてのPRでそれをレビューする方法です。
Surmado Code Review for Godotを導入する(無料)→
特定のGodot APIやパターンについて確信が持てませんか?公式の4.6ドキュメントに基づいてGDScoutに聞いてみてください。無料で、出典付きです。
質問と回答
GDScriptのコードレビューチェックリストはありますか? はい。GDScriptコードレビューチェックリストは6つのカテゴリをカバーしています:バージョンの正しさ(Godot 3対4のパターン)、ライフサイクルコールバック(_process対_physics_process)、シグナルの衛生、シーンツリーのアーキテクチャ、型安全性と警告、リソース管理です。各チェックは公式のGodot 4.6ドキュメントに基づいています。
Godotのコードレビューで何を確認すべきですか? Godotのコードレビューでは、バージョンの正しさ(Godot 4プロジェクトにGodot 3のパターンがないか)、正しいライフサイクルコールバックの使用、コーラブルベースのシグナル接続、脆弱な親パスのない合成可能なシーンツリーのアーキテクチャ、静的型付けと警告の遵守、安全なリソース読み込みとノードのクリーンアップを検証すべきです。GDScriptコードレビューチェックリストは、公式ドキュメントへのリンク付きで各カテゴリの具体的なチェックを提供します。
Godotにはコードレビューツールがありますか? Godotの組み込みツールには、構文と型のエラーを検出するGDScript警告システムと静的型付けサポートがあります。PRレベルのコードレビューには、Surmado Code Review for Godotが、公式のGodot 4.6ドキュメントとチームのSTANDARDS.MDに照らしてGitHubプルリクエストをチェックします。リンターがカバーしないバージョンの間違い、ライフサイクルの誤用、非推奨のパターン、アーキテクチャの問題を検出します。月10 PRまで無料です。
AI生成のGodotコードで最もよくある間違いは何ですか? 最もよくある間違いは、リネームされたGodot 3のノードタイプとメソッドシグネチャの使用、_physics_process()ではなく_process()に物理演算による移動を配置すること、非推奨の文字列ベースのシグナル接続の使用、脆弱な親・兄弟ノードパスのハードコード、コンパイル時リソースにpreload()ではなくload()を使うことです。これらのパターンはリンティングを通過し、エラーなくコンパイルされますが、実行時の失敗や一貫性のない動作を引き起こします。
コードレビューチェックリストはGDScriptリンターとどう違いますか? GDScriptリンターは構文エラー、フォーマットの問題、未使用変数、一部の型の問題を検出します。コードレビューチェックリストはより高いレベルの懸念を評価します:これは正しいエンジンバージョンのAPIか、移動コードは正しいコールバックにあるか、シグナル接続は最新か、シーンツリーのアーキテクチャは合成可能か、コードはプロジェクト固有の標準に従っているか。リンターとコードレビューは相互補完的です。
STANDARDS.MDとは何ですか? STANDARDS.MDは、チームがコードレビューで強制するコーディング標準を定義するMarkdownドキュメントです。Surmado Code Reviewでは、STANDARDS.MDは設定ファイルを編集するのではなく、SurmadoのAIエージェントであるScoutとの対話を通じて作成されます。このドキュメントには、「CharacterBodyの移動には常に_physics_processを使う」や「get_node(‘..’)による親パスナビゲーションは禁止」といったGodot固有のルールを含められます。