mcpField
G
godot-master

godot-master

github.com/thedivergentai開発9094.5k 回インストール2 週間前に更新
リポジトリ

godot-master について

ゲームやアプリの設計・実装を計画する Godot 開発者向けのエンジニアリング知識ハブです。意思決定フレームワークやワークフロー、分野別スキルの連鎖で構成され、Godot 4.7+ を対象とします。

主な機能

  1. 01アーキテクチャの意思決定フレームワーク
  2. 02状態とシグナルのレイヤーパターン
  3. 03プロジェクトのスキャフォールディング手順
  4. 04ジャンルとプラットフォーム別の案内
  5. 05ノードとデータ型の選択

活用シーン

  1. 01Godot プロジェクトの構成計画
  2. 02新規プロジェクトの骨組み作成
  3. 03ゲームジャンルに合う実装パターンの選択
  4. 04関連する分野別スキルへのタスク振り分け

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/thedivergentai/game-design-agentic-skills --skill godot-master

インストール後、Claude Code で/godot-masterを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
2d-animation-cutout-and-skeletal.md
2d-animation-expert-techniques.md
2d-animation-migration-notes.md
2d-animation-signals-and-frame-events.md
2d-animation.md
2d-physics-area2d-and-queries.md
2d-physics-collision-layers-masks.md
2d-physics-migration-notes.md
2d-physics.md
3d-lighting-environment-and-fog.md
3d-lighting-gi-and-bake-recipes.md
3d-lighting-migration-notes.md
3d-lighting.md
3d-materials-migration-notes.md
3d-materials-pbr-workflows.md
3d-materials.md
3d-world-building-gridmap-and-csg.md
3d-world-building-migration-notes.md
3d-world-building-streaming-and-procgen.md
3d-world-building.md
ability-system-elite-ability-patterns.md
ability-system-migration-notes.md
ability-system.md
adapt-2d-to-3d-migration-notes.md
adapt-2d-to-3d-migration-recipes.md
adapt-2d-to-3d.md
adapt-3d-to-2d-dimension-reduction.md
adapt-3d-to-2d-migration-notes.md
adapt-3d-to-2d.md
adapt-desktop-to-mobile-migration-notes.md

詳細

Godot Master:リードアーキテクト向けナレッジハブ

すべてのセクションは、ナレッジの差分、つまりベースモデルがすでに知っていることと、実際の製品を出荷してきたシニア Godot エンジニアが知っていることのギャップに焦点を当てることで、そのトークンに見合う価値を提供します。

ライブラリの対象 — Godot 4.7+

すべてのドメインスキルのミラーは Godot 4.7+(安定版)を対象とします。エンジンのバージョンアップグレード(1.x/2.x のレガシー版 → 3 → 4 → 4.x の段階的アップグレード)には、godot-version-migration を使用してください。このハブを移行履歴として扱わないでください。

各機能へ案内する際に留意すべき 4.7 の横断的な注意事項:AreaLight3D/HDR → 3D ライティング;Asset Store と Asset Library の違い → エクスポート/プラットフォームモジュール;RichTextLabel の ImageUnit、入力デバイス ID 定数、Jolt の挙動 → 移行ハブのモジュールノート。


🧠 パート 1:エキスパートの思考フレームワーク

「誰が何を所有するのか?」 — アーキテクチャの健全性チェック

システムを書く前に、状態の各要素について、次の 3 つの質問に答えてください。

  • データを所有するのは誰か?(CombatSystem ではなく、StatsComponent が体力を所有する)
  • 変更を許可されているのは誰か?(apply_damage() のような公開メソッドを介して、所有者だけが変更できる)
  • 変更されたことを知る必要があるのは誰か?(health_changed シグナルをリッスンしているすべての人)

すべての状態変数についてこの 3 つすべてに答えられない場合、アーキテクチャには結合の問題があります。これは OOP のカプセル化ではありません。Godot 固有の考え方です。なぜなら、アクセス修飾子ではなく、シグナルシステムそのものが強制の仕組みだからです。

Godot の「レイヤーケーキ」

すべての機能を 4 つのレイヤーに整理してください。シグナルは上方向にのみ伝わり、下方向には伝わりません。

┌──────────────────────────────┐
│  PRESENTATION (UI / VFX)     │  ← Listens to signals, never owns data
├──────────────────────────────┤
│  LOGIC (State Machines)      │  ← Orchestrates transitions, queries data
├──────────────────────────────┤
│  DATA (Resources / .tres)    │  ← Single source of truth, serializable
├──────────────────────────────┤
│  INFRASTRUCTURE (Autoloads)  │  ← Signal Bus, SaveManager, AudioBus
└──────────────────────────────┘

重要なルール:プレゼンテーションはデータを直接変更してはなりません。インフラストラクチャはシグナルのみを介してやり取りします。Label ノードが player.health -= 1 を呼び出しているなら、アーキテクチャは破綻しています。

シグナルバスの階層型アーキテクチャ
  • グローバルバス(Autoload):ライフサイクルイベント(match_started、player_died、settings_changed)にのみ使用します。デバッグの煩雑化が代償となるため、イベント数は 15 未満に抑えてください。
  • スコープ付き機能バス:各機能フォルダーに専用のバスを設けます(例:CombatBus は戦闘ノード専用)。これが、規模を拡大できる折衷案です。
  • 直接シグナル:単一シーン内の親子間の通信に使用します。シーンの境界を越えて使用してはいけません。
🔗 「スマートな相互接続」の指針

エキスパートシステムは、孤立していることではなく、ペイロードの合成によって定義されます。

  • 物理演算 → パフォーマンス:PhysicsServer2D と RenderingServer は、SceneTree のノードによるオーバーヘッドを回避します。1,000 個以上の弾丸やパーティクルを扱う場合に使用すると、O(1) の処理を実現できます。
  • アニメーション → 物理演算:AnimationTree.get_root_motion_position() は、アニメーションによる変位を物理演算の velocity に変換し、複雑な移動時の「足滑り」を防ぎます。
  • データ → リアクティビティ:シリアライズされた Resource オブジェクト(Stats など)は、変更時にシグナルを発行するため、密結合を避けながら UI を自動的に更新できます。
  • アセット → 生成:ResourceLoader の非同期フェーズ中にプリロードする O(1) の Dictionary ベースのキャッシュにより、アイテムや敵の生成時に発生する I/O のひっかかりを防ぎます。
  • モバイル → ビジュアル:ロード画面中に非表示のエフェクトをインスタンス化して GPU シェーダーパイプラインのコンパイルを強制し、実行時のフレームのひっかかりを防ぎます。
  • ネットワーク → 帯域幅:パケットを 100 バイト未満に保つため、同期には JSON/文字列ではなく、PackedByteArray へのビットパッキングを使用します。
  • ジャンルの合成:
    • Shooter:100 倍のパフォーマンスを得るため、RayCast3D ノードではなく、必ず intersect_ray()(直接空間状態)を使用します。
    • RPG:エンドゲームの進行を維持するため、ダメージは base * pow(scaling, level) に従います。
    • RTS:隊形の整合性を保つため、Relative Offset を使って重心を基準にグループを移動させます。
    • Metroidvania:シームレスなルーム切り替えには ResourceLoader.load_threaded_request() を使用します。
    • Platformer:プロフェッショナルな操作感を実現するには、Jump Buffering(約 0.15 秒)と Coyote Time が必須です。
    • Simulation:Tick Manager でバッチ処理を行います。数千のユニットを維持するには、エンティティごとの _process を避けてください。
    • Romance:複雑な物語の分岐を表現するため、Multi-Axial Affection(魅力、信頼、安心感)を使用します。
    • Architecture:シーン間の循環結合をなくすため、Signal Architecture は「シグナルは上へ、呼び出しは下へ」という原則に厳密に従います。

🧭 パート 2:アーキテクチャ上の意思決定フレームワーク

マスター意思決定マトリクス
シナリオ戦略必須スキルチェーントレードオフ
ラピッドプロトタイプイベント駆動型モノリス読む:基礎 → 自動読み込み。ジャンルやプラットフォームのリファレンスは読み込まないでください。素早く開始できますが、スパゲッティ化のリスクがあります
複雑なRPGコンポーネント駆動型読む:コンポジション → 状態 → RPGステータス。マルチプレイヤーやプラットフォームのリファレンスは読み込まないでください。セットアップに手間がかかりますが、無限に拡張できます
大規模オープンワールドリソースストリーミング読む:オープンワールド → セーブ/ロード。パフォーマンスも読み込みます。I/Oが複雑で、10Kユニットを超えると浮動小数点精度の揺らぎが発生します
サーバー認証型マルチプレイヤー決定論的読む:サーバーアーキテクチャ → マルチプレイヤーネットワーク。シングルプレイヤー向けのジャンルリファレンスは読み込まないでください。レイテンシが高くなりますが、チート対策を強化できます
モバイル/Web移植アダプティブ・レスポンシブ読む:UIコンテナ → デスクトップからモバイルへの適応 → モバイルプラットフォーム。UIが複雑になりますが、幅広く展開できます
アプリケーション/ツールアプリコンポジション読む:アプリのコンポジション → テーマ設定。ゲーム固有のリファレンスは読み込まないでください。ゲームとは異なるパラダイムです
恋愛/恋愛シミュレーション好感度エコノミー読む:恋愛 → 会話 → UIリッチテキスト。UIとナラティブの密度が高くなります
秘密/イースターエッグ意図的な難読化読む:秘密 → 永続化。コミュニティの参加を促せますが、デバッグのリスクがあります
収集クエスト探索ロジック読む:コレクション → Marker3Dの配置。プレイヤーの定着と探索意欲を促します
季節イベントランタイム注入読む:イースターのテーマ設定 → マテリアルの切り替え。素早くブランドを演出でき、アセットを汚しません
ソウルライクの死亡システムリスクと報酬のある復活読む:復活/死体回収 → 3D物理。緊張感が高まりますが、プレイヤーにストレスを与えるリスクがあります
ウェーブ制アクション戦闘ペースのループ読む:ウェーブ → 戦闘。緊張感を高め、エンカウントを設計できます
バランス/難易度/エコノミーの進行調整モンテカルロ・バランスラボ読む:リソース → エコノミー → 戦闘/RPGステータス/ウェーブ(必要に応じて) → モンテカルロバランサー → テスト → ビルダー。統計的な厳密さを確保できます。抽象シミュレーションはヘッドレスGodotと照らし合わせて調整する必要があります
サバイバルエコノミー採集ループ読む:採集 → インベントリ。リソースを希少に保ち、ループを持続させます
レース/スピードラン検証ループ読む:タイムトライアル → 入力バッファ → レースジャンル。高い精度を実現し、ゴースト記録への挑戦意欲を促します
ホラー/ステルス緊張感の管理読む:ホラージャンル → ステルスジャンル → オーディオ。雰囲気を作り、プレイヤーを無防備な状態にします
カード/ボードゲームルールの適用読む:カードゲームジャンル → ターンシステム。状態が決定論的ですが、UIの負荷が高くなります
シミュレーション/RTSバッチ処理読む:シミュレーションジャンル → RTSジャンル → パフォーマンス。多数のユニットを扱い、O(1)のロジックを実現します
HDR/シネマティックなビジュアルディスプレイパイプライン読む:3Dライティング → デスクトッププラットフォーム → シェーダーの基礎。プロジェクト設定でビューポートのHDRを有効にします。プラットフォームごとにトーンマッピングを調整する必要があります
矩形エリアライトAreaLight3D読む:3Dライティング → 3Dマテリアル。発光マテリアルとGIのハックよりもAreaLight3Dを優先してください。最高品質で使用するにはForward+レンダラーが必要です
モバイルのタッチ操作ネイティブジョイスティック読む:モバイルプラットフォーム → デスクトップからモバイルへの適応。組み込みの仮想ジョイスティックを使用します(4.7+)。プラグインへの依存を減らせます
アドオン/アセットの探索Asset Store読む:プロジェクトの基礎 → ビルドのエクスポート。Asset StoreはAsset Libraryに置き換わります。ストアのUIはベータ版のため、アドオンごとにライセンスを確認してください
エージェントの視覚確認/ビジュアルQAキャプチャ → WebP → 評価基準読む:エージェントビジョン。スクリーンショットアセット、ウィンドウ/領域/画面、または一時的なエディターブリッジでキャプチャし、その後、構造化レビューを行います。ジャンルのリファレンスは読み込まないでください。ホスト側のみで実施します。Autoloadに追加せず、ステージング済みアドオンとして残さないでください
「Nodeを使わない場合」の判断

専門家だけが行う判断の中でも、特に大きな影響を与えるものです。Godotのドキュメントでは、「あらゆるものにノードを使うのは避ける」と明記されています。

種類使用する場面コスト専門的なユースケース
Objectカスタムデータ構造、手動メモリ管理最も軽量です。.free()を手動で呼び出す必要があります。カスタム空間ハッシュマップ、ECSのようなデータストア
RefCounted一時的なデータパケット、自動削除されるロジックオブジェクト参照がなくなると自動的に削除されます。DamageRequest、PathQuery、AbilityEffect — シーンツリーを必要としないロジックパケット
Resourceインスペクターに対応したシリアライズ可能なデータRefCountedより少し重くなります。.tresの入出力を処理します。ItemData、EnemyStats、DialogueLine — デザイナーがインスペクターで編集する必要があるあらゆるデータ
Node_process/_physics_processが必要、シーンツリー内に存在する必要がある最も重くなります — ノードごとにSceneTreeのオーバーヘッドが発生します。フレームごとの更新や空間トランスフォームが必要なエンティティに限ります

専門家向けのパターン:すべてのロジックパケットとデータコンテナにRefCountedサブクラスを使用します。空間ツリー内に存在しなければならないものに限り、Nodeを使用します。これにより、複雑なシステムのシーンツリーのオーバーヘッドを半減できます。


🔧 パート3:コアワークフロー

ワークフロー1:プロフェッショナルな足場づくり

空のプロジェクトから、本番環境に対応したコンテナまで。

必須 — ファイル全体を読むこと:基礎

  1. クラスの種類ではなく、機能(/features/player/、/features/combat/)ごとに整理します。player/フォルダーには、プレイヤーのシーン、スクリプト、リソース、テストを格納します。
  2. 読むこと:シグナルアーキテクチャ — 15個未満のイベントを持つGlobalSignalBusオートロードを作成します。
  3. 読むこと:GDScriptの習得 — Project Settings → GDScript → Debuggingで、untyped_declaration警告を有効にします。
  4. 基本の.gitignore、エクスポートプリセット、入力マップには、**プロジェクトテンプレート**を適用します。
  5. Godot CLIを使ってシーン階層をプログラムで生成するには、Builder(create_scene.py、add_node.py、save_scene.py)を使用します。

注意

ワークフロー1で絶対にしてはいけないこと

  • ロジックスクリプトでres://パスを絶対に使わないでください。リソースを移動しても有効な状態を保つには、@export_fileまたは@export_dirを使用します。
  • _init()で子ノードを初期化するのは絶対に避けてください。シーンツリーの準備ができていません。_ready()または@onreadyを使用します。
  • Physics Ticksに「デフォルト」のプロジェクト設定を絶対に使い続けないでください。一貫性を保つには60に設定するか、適応型ロジックにはEngine.physics_ticks_per_secondを使用します。
  • デバッグのために_process()内でprint()を絶対に使わないでください。フレーム時間の急増を避けるには、Debuggerまたはpush_error()を使用します。

足場づくりの際に、戦闘、マルチプレイヤー、ジャンル、プラットフォームのリファレンスを読み込まないでください。

ワークフロー 2:エンティティのオーケストレーション

モジュール化され、テスト可能なキャラクターを構築します。

必須の順序 — すべて読むこと:Composition → State Machine → CharacterBody2D または Physics 3D → Animation Tree エンティティの作業では、UI、Audio、Save/Load のリファレンスを読み込まないでください。

  • ステートマシンは InputComponent に問い合わせます。入力を直接処理することはありません。これにより、リファクタリングなしで AI とプレイヤーを切り替えられます。
  • ステートマシンが処理するのは遷移のみです。ロジックはコンポーネントに配置します。MoveState が MoveComponent に動作するよう指示し、その逆にはしません。
  • すべてのエンティティはF6 テストに合格する必要があります。「現在のシーンを実行」(F6)を押してもクラッシュしないことを確認してください。クラッシュする場合、そのエンティティにはシーン外部の依存関係があります。

注意

ワークフロー 2 で絶対にしてはいけないこと

  • 絶対に parent.do_thing() を呼び出さないでください。親が変更されると、エンティティが壊れます。代わりにシグナル request_action を発行してください。
  • 絶対に移動に _process を使用しないでください。可変リフレッシュレートのモニターでのちらつきを避けるため、_physics_process を使用してください。
  • 絶対にアニメーション名をハードコードしないでください。AnimationPlayer で簡単に名前を変更できるよう、StringName 定数または Resource マップを使用してください。
  • 絶対に絶対パスで get_node() を使用しないでください。ツリーのリファクタリングに耐えられるよう %UniqueName を使用してください。
ワークフロー 3:データ駆動型システム

リソースを介して Combat、Inventory、Stats を連携させます。

必須の順序 — すべて読むこと:Resource Patterns → RPG Stats → Combat → Inventory

  • Resource を継承する ItemData.gd を 1 つ作成します。スクリプトを 100 個作る代わりに、これを 100 個の .tres ファイルとしてインスタンス化します。
  • HUD は Player を直接参照しません。Signal Bus 上の player_health_changed をリッスンします。
  • すべての @export Resource 変数で「Local to Scene」を有効にするか、_ready() で resource.duplicate() を呼び出してください。これを怠ると、Part 8 の Bug #1 の原因になります。

注意

ワークフロー 3 で絶対にしてはいけないこと

  • 絶対にSignal Bus で Node の参照を渡さないでください。オブジェクトは解放されるため、長期的な追跡には RID または ID のほうが安全です。
  • 絶対に実行時にコードから .tres ファイルを変更しないでください(ディスク上のファイルが変更されます)。変更前に必ず .duplicate() を使用してください。
  • 絶対に検索頻度の高い処理に Array を使用しないでください。O(1) で検索できる StringName キーの Dictionary を使用してください。
  • 絶対にアイテム数や正確なリソース管理に float を使用しないでください。int を使用し、表示用にスケーリングしてください。
ワークフロー 4:永続化パイプライン

必須:Autoload Architecture → Save/Load → Scene Management

  • Dictionary マッピングを使用してシリアライズします。新しいフィールドを追加しても古いセーブファイルが壊れないよう、.get("key", default_value) を使用してください。
  • プロシージャルワールドでは、マップ全体ではなく Seed と変更内容の Delta-List を保存します。100MB のワールドを 50KB のセーブデータにできます。

注意

ワークフロー 4 で絶対にしてはいけないこと

  • 絶対に Object や Node のインスタンス全体を保存しないでください。一時的なポインターが含まれています。データを Dictionary またはカスタム Resource に抽出してください。
  • 厳密な型付けが必要なデータ(例:Vector2)に 絶対に JSON を使用しないでください。構造化された Godot 型には var_to_bytes または ConfigFile を使用してください。
  • オートセーブのためにメインスレッドを絶対にブロックしないでください。大きな Dictionary のシリアライズには Thread または WorkerThreadPool を使用してください。
  • エクスポート済みプロジェクトで res:// に絶対に保存しないでください。永続データには必ず user:// を使用してください。
ワークフロー 5:パフォーマンスの最適化

必須:デバッグ/プロファイリング → パフォーマンスの最適化

診断を優先するアプローチ(決して闇雲に最適化しないでください):

  1. スクリプトの処理時間が長い → 組み込みの Profiler でプロファイリングします。何百ものノードで _process が呼び出されていないか確認します。単一マネージャーパターンまたは Server API に切り替えます(Part 6 を参照)。
  2. ドローコールが多い → 繰り返しのジオメトリには MultiMeshInstance を使用します。ORM テクスチャでマテリアルをバッチ化します。
  3. 物理演算によるカクつき → コリジョンをプリミティブ形状に簡略化します。2D Physics または 3D Physics を読み込みます。移動処理に _physics_process ではなく _process を使用していないか確認します。
  4. VRAM の過剰使用 → テクスチャを VRAM 圧縮に切り替えます(デスクトップでは BPTC/S3TC、モバイルでは ETC2)。PNG を未圧縮のまま出荷してはいけません。
  5. 断続的なフレームスパイク → 通常は GC パス、同期的な load()、または NavigationServer の再計算が原因です。ResourceLoader.load_threaded_request() を使用します。

注意

ワークフロー 5 の禁止事項

  • 決して _process 内で get_nodes_in_group() を使用しないでください。毎フレーム O(n) の処理が発生します。配列を _ready() でキャッシュしてください。
  • 決して「Stay」ロジックに Area2D シグナルを使用しないでください。定期的に get_overlapping_bodies() を呼び出すか、マネージャーレベルで PhysicsServer のチェックを使用してください。
  • 決してプロファイリングの前に最適化しないでください。ドローコールが 2000 回あり GPU の処理を妨げているなら、スクリプトの 1ms は問題ではありません。
  • ホットパスでは決して load() を使用しないでください。必ず preload を使用するか、非同期読み込みには ResourceLoader を使用してください。
ワークフロー 6:クロスプラットフォーム対応

必須:入力処理 → デスクトップからモバイルへの対応 → モバイルプラットフォーム 必要に応じて以下も読む:デスクトッププラットフォーム、Web プラットフォーム、コンソールプラットフォーム、VR プラットフォーム。

  • すべての入力タイプを正規化されたアクションに変換する InputManager オートロードを使用します。Input.is_key_pressed() を直接読み取ってはいけません。コントローラーとタッチに対応できなくなります。
  • モバイルのタッチターゲット:物理サイズで最低 44px にします。ノッチや切り欠きのあるデバイスでは、Safe Area のロジックとともに MarginContainer を使用します。
  • Web エクスポート:Godot の AudioServer は最初の再生前にユーザー操作を必要とします(ブラウザーのポリシーによる制約です)。「クリックして開始」画面で対応します。

注意

ワークフロー 6 の禁止事項

  • 決して機能の検出に OS.get_name() を使用しないでください。「SteamDeck」のようなサブセットに対応するには、OS.has_feature("mobile") またはカスタム機能タグを使用します。
  • 決して特定のアスペクト比を前提にしないでください。必ず Anchor ノードと組み合わせて Expand または Keep Aspect を使用します。
  • 決してGLES3/Compatibility の代替パスなしで、デスクトップ専用シェーダー(複雑な深度サンプリングなど)をモバイル/Web で使用しないでください。
  • デスクトップビルドで physical_keycode を無視してはいけません。これにより、キーボード配列(AZERTY/QWERTY)が移動操作に影響しないようにできます。
  • サニタイズされていない文字列を決して JavaScriptBridge.eval() に渡さないでください。これにより、Web ビルドでのスクリプトインジェクションを防げます。sanitize_js_string() ヘルパーを使用してください。
ワークフロー 7:プロシージャル生成

必須:プロシージャル生成 → タイルマップを極める または 3D ワールド構築 → ナビゲーション

  • 決定論的な生成を行うため、固定の seed を設定した FastNoiseLite リソースを必ず使用してください。
  • メインスレッドで NavMesh をベイクしないでください。NavigationServer3D.parse_source_geometry_data() と NavigationServer3D.bake_from_source_geometry_data_async() を使用してください。
  • 無限ワールドでは、チャンクの読み込みは必ず WorkerThreadPool を使用してバックグラウンドスレッドで行ってください。シーンのチャンクをツリー外で構築し、メインスレッドで add_child.call_deferred() を呼び出してください。

注意

ワークフロー 7:絶対にしてはいけないこと

  • 「背景」のノイズに対して、ノードを絶対にインスタンス化しないでください。数千個の小さなディテールには、MultiMeshInstance または _draw 内の描画ループを使用してください。
  • 1つの変更のためにマップ全体を絶対に再生成しないでください。実際に変更された部分だけを更新する「ダーティチャンク」システムを使用してください。
  • concave_polygon_shape を使用する場合、メッシュ生成と同じフレームにコリジョンを絶対に配置しないでください。物理スレッドが停止します。
  • すべてのユニットについて、パス検索を毎フレーム絶対に実行しないでください。target_position をタイマーで更新する NavigationAgent を使用してください。
ワークフロー 8:マルチプレイヤーアーキテクチャ

必須 — 読んでください:シングルプレイヤーからマルチプレイヤーへ → ネットワーキング → サーバーアーキテクチャ シングルプレイヤーのジャンル別ブループリントは読み込まないでください。

  • クライアントは入力を送り、サーバーは結果を計算します。クライアントがダメージ、位置の差分、インベントリの変更を決定することは絶対にありません。
  • サーバーによる再同期を伴うクライアントサイド予測を使用してください。ローカルで予測し、サーバーのスナップショットに基づいて修正します。最大約 150ms のレイテンシを隠蔽できます。
  • Godot 4 では、MultiplayerSpawner がレプリケーションを処理します。グローバルではなく、シーンごとに設定してください。

注意

ワークフロー 8:絶対にしてはいけないこと

  • 検証せずに rpc_id(1, ...)(クライアントからサーバー)を絶対に信頼しないでください。ハッキングされたクライアントは damage = 999999 を送信できます。
  • _process のトランスフォームを直接絶対にレプリケーションしないでください。Input ベクトルをレプリケーションし、両側で移動をシミュレートしてください。
  • 高頻度パケット(移動)に TCP を絶対に使用しないでください。UDP/ENet を使用し、補間でパケットの損失に対処してください。
  • すべての投射物を絶対に同期しないでください。ビジュアルにはクライアントサイド予測を使用し、「発射」イベントのみを RPC で送信してください。
  • ReflectionProbe、VoxelGI、SDFGI の比較:プローブは低コスト/静的、VoxelGI は中程度のコスト/ベイク済み、SDFGI は高コスト/動的です。プラットフォームの予算に応じて選択してください(パート 5 を参照)。
ワークフロー 9: レスポンシブ UI とエキスパートテーマ設定 (監査済み)

必須チェーン: UI コンテナ → UI テーマ設定 → リッチテキスト → トゥイーン

  1. F6 の原則: すべての UI シーンは単独でテスト可能でなければなりません。MOUSE_FILTER_STOP は背景にのみ使用し、子には PASS を使用します。
  2. 余白の確保: 手動のパディングではなく、add_theme_constant_override("separation", X) を使用します。
  3. 適応型スケーリング: モバイル/デスクトップのブレークポイント対応の切り替えには responsive_layout_builder.gd を使用します。
  4. ライフサイクルの安全性: 同じフレームで新しい子へスクロールしないでください。scroll_vertical を変更する前に await get_tree().process_frame を実行します。
  5. データ統合: Resource-to-UI バインディングを使用します。UI ノードはステートレスな投影レイヤーでなければなりません。

注意

ワークフロー 9 の NEVER リスト

  • 絶対ピクセルオフセットを NEVER 使用しないでください。4K や小さなモバイル画面では UI が読めなくなります。Container のサイズ指定を使用してください。
  • MarginContainer を NEVER 深くネストしないでください。インスペクターが使えなくなります。プロジェクト全体のマージンには単一の Theme リソースを使用してください。
  • UI ボタンをゲームプレイロジックに NEVER 直接接続しないでください。UI が「シグナル」を送信し、PlayerController が受信します。これにより UI 削除時のクラッシュを防ぎます。
  • UI 要素をターゲットへ移動するために _process() を NEVER 使用しないでください。カクつきやフレームレート依存を避けるために Tween を使用してください。
  • 透明なコンテナの mouse_filter を STOP のまま NEVER にしないでください。背後のすべてのクリックを「食べて」しまいます。
  • res:// プレフィックスと安全な拡張子 (.tres、.res、.theme) を検証せずに、パスに対して動的な load() を NEVER 使用しないでください — 任意のコード/リソースの実行を防ぎます。
ワークフロー 10: シネマティックライティングと VFX (監査済み)

必須チェーン: 3D ライティング → パーティクル → 3D マテリアル → シェーダー

  1. GI の選択: 屋内には VoxelGI、オープンワールドには SDFGI。両方を重複させた状態で NEVER 出荷しないでください。
  2. シャドウの予算: 影を落とす DirectionalLight は最大 2 つ。モバイルのフィルには fake_gi_bounce.gd を使用します。
  3. VFX のライフサイクル: Timer よりも finished シグナルを使用します。非同期の GPU ストールを避けるため、restart() で再実行します。
  4. 最適化: GPU キャッシュとテクスチャスロットを節約するために ORM Texture パッキング (AO/Rough/Metal) を使用します。
  5. バッチング: 数千のインスタンスにわたるマテリアルのバリエーションを、ドローコールのペナルティなしで実現するために Instance Uniforms を使用します。

注意

ワークフロー 10 の NEVER リスト

  • CollisionShape ノードを NEVER スケーリングしないでください。物理のジッターを避けるため、Shape リソースを厳密にスケーリングしてください。
  • カットアウトメッシュ (葉/フェンス) に TRANSPARENCY_ALPHA を NEVER 使用しないでください。ソートのアーティファクトを防ぐために ALPHA_SCISSOR を使用してください。
  • ゲームプレイ中に CSG ノードを NEVER アニメーション化しないでください。高コストな CPU ジオメトリ再計算が強制されます。
  • 2D ライクなゲームにリアルタイムのグローバルイルミネーション (SDFGI/VoxelGI) を NEVER 使用しないでください。DirectionalLight2D と CanvasModulate に留めてください。
  • Camera3D の near/far プレーンを NEVER 無視しないでください。不適切な設定は大規模なワールドで Z ファイティングを引き起こします。
ワークフロー 11:プログラムによるシーン構築(Builder)

必須:Builder バッチ操作または複雑なプロシージャルな足場の構築にのみ使用してください。 大規模な CLI 自動化を行う場合は、スタンドアロンの godot-builder スキルを優先してください。

  1. ステップ 1:ディスクに触れる前に、ノード階層を紙または Markdown に書き起こします。
  2. ステップ 2:create_scene.py を使用して、ルートノードと .tscn のパスを定義します。
  3. ステップ 3:子ノードには add_node.py を使用します。シリアライズ時に保持されるよう、すべてのノードに owner を設定してください。
  4. ステップ 4:シーンが問題なく読み込まれることを確認するため、必ず run_project.py または launch_editor.py を呼び出してください。
  5. エキスパートのルール:Builder で 構造(ノード、名前、継承)を構築し、GDScript で 動作を構築します。

注意

ワークフロー 11:絶対にしてはいけないこと

  • 絶対に、階層を設計せずに add_node.py をいきなり実行しないでください。スパゲッティ状のシーンになります。
  • 絶対に、スクリプトやシーンのプロパティで絶対ファイルシステムパスを使用しないでください。res:// のみを使用してください。
  • 絶対に、Shape リソースを割り当てずに CollisionShape2D/CollisionShape3D を追加しないでください。ノードだけでは何も機能しません。
  • バッチでシーンを書き込んだ後、run_project.py/launch_editor.py による検証を絶対に省略しないでください。
セキュリティ:境界マーカーと検証

エージェントがファイルを書き込む前に、信頼できないシーン/データのテキストを取り込む場合:

  1. 境界マーカー:分析を <<<CONTEXT_START>>> と <<<CONTEXT_END>>> で囲みます。
  2. サニタイズ:ノード名には英数字とアンダースコアのみを使用します。パスは res:// で始まる必要があります。
  3. 検証:変更前にシーンが存在することを確認します。

🚫 パート 4:エキスパートが絶対にしてはいけないこと

各ルールには、一見わかりにくい理由、つまり実際のリリース経験を通じてのみ学べる理由が含まれています。

  1. 決して get_tree().root.get_node("...") を使用しないでください — 絶対パスは、祖先ノードの名前変更や親の変更が一度でもあると機能しなくなります。%UniqueNames、@export NodePath、またはシグナルベースの検出を使用してください。
  2. ループ内や _process 内で決して load() を使用しないでください — 同期的なディスク読み込みは、メインスレッド全体をブロックします。小さなアセットにはスクリプトの先頭で preload() を、大きなアセットには ResourceLoader.load_threaded_request() を使用してください。
  3. 外部参照が存在する間は決して queue_free() を実行しないでください — 参照を保持している親ノードや配列は、「Deleted Object」エラーを引き起こします。_exit_tree() で参照をクリーンアップし、解放する前に null を設定してください。
  4. ゲームプレイのロジックを決して _draw() に記述しないでください — _draw() はレンダリングスレッドで呼び出されます。ゲーム状態を変更すると、_physics_process との競合状態が発生します。
  5. 1000 個以上のオブジェクトが重なり合う場合、決して Area2D を使用しないでください — 各オーバーラップチェックには O(n²) のブロードフェーズコストがかかります。弾幕パターンには ShapeCast2D、PhysicsDirectSpaceState2D.intersect_shape()、またはサーバー API を使用してください。
  6. コンポーネントから外部状態を決して変更しないでください — HealthComponent が $HUD.update_bar() を呼び出す場合、HUD を削除するとゲームがクラッシュします。コンポーネントはシグナルを発行し、リスナーが応答方法を決定します。
  7. _physics_process 内で決して await を使用しないでください — await は実行を一時停止するため、物理ステップでフレームがスキップされます。シグナルをトリガーとして、非同期処理を別のメソッドに移してください。
  8. 頻繁に実行される辞書の検索で String キーを決して使用しないでください — String のハッシュ化には O(n) かかります。O(1) のポインター比較ができる StringName(&"key")または整数の列挙型を使用してください。
  9. 解放済みオブジェクトへの Callable 参照を決して保持しないでください — クラッシュが無言で発生したり、エラーがスローされたりします。_exit_tree() でシグナルを切断するか、CONNECT_ONE_SHOT を使用してください。
  10. 1000 個以上のエンティティに _process を決して使用しないでください — _process の呼び出しごとに、ノード単位の SceneTree オーバーヘッドが発生します。データ構造体の配列を反復処理する単一の Manager._process(データ指向パターン)を使用するか、サーバー API を直接使用してください。
  11. 解放される可能性があるノードで決して Tween を使用しないでください — Tween の実行中にノードが queue_free() されると、エラーが発生します。_exit_tree() で Tween を停止するか、SceneTree にバインドしてください:get_tree().create_tween()。
  12. _process 内で RenderingServer や PhysicsServer にデータを要求しないでください — これらのサーバーは非同期で動作します。ゲッター関数を呼び出すと同期的な停止が発生し、パフォーマンスが大幅に低下します。これらの API は、頻繁に実行される処理で意図的に書き込み専用として設計されています。
  13. 初期化順序のバグを取り繕うために call_deferred() を決して使用しないでください — アーキテクチャ上の問題(ツリー順序への依存)を隠してしまいます。明示的な初期化シグナルまたは @onready を使って、実際の依存関係を解決してください。
  14. 循環するシグナル接続を決して作成しないでください — ノード A が B に接続し、B が A に接続する状態です。最初のシグナル発行時に無限ループが発生します。メディエーターパターン(シグナルバス)を使って循環を断ち切ってください。
  15. 継承を決して 3 階層より深くしないでください — 3 階層を超えると、super() の呼び出しチェーンのデバッグが非常に困難になります。代わりにコンポジション(子 Node)を使って動作を追加してください。
  16. 物理演算が多いジャンル(FPS/ARPG)では、ヒット判定や移動に決して _process を使用しないでください。フレームレートに左右されない衝突判定を実現するため、必ず _physics_process を使用してください。
  17. 永続的なゲーム状態(Health、XP、Inventory)について、クライアントを権威のある情報源として決して信頼しないでください。Server-Auth または Secure Checksums のみで処理してください。
  18. 実行時に高頻度で行うチェックには、標準の文字列を決して使用しないでください。O(n) のハッシュ化を避けるため、必ず StringName(&"active")を使用してください。
  19. ユニット数の多いゲーム(RTS/MOBA)で、RVO の回避処理を毎フレーム手動で行わないでください。NavigationAgent の内部スレッド処理に任せてください。
  20. プロシージャル生成や重い I/O のために、メインスレッドを決してブロックしないでください。必ず WorkerThreadPool に処理を委譲してください。
  21. 固有のインスタンスで使用するリソース(例:敵のステータス)では、Local-to-Scene を決して無効にしないでください。無効にすると、すべてのインスタンス間で共有メモリのバグが発生します。
  22. 通貨に float を決して使用しないでください。複雑な経済システムでの精度のずれを防ぐため、必ず整数のセント単位を使用してください。
  23. physics_frame より前に target_position を決して設定しないでください。ナビゲーションマップは _ready() 中には準備できていません。
  24. 大きな切り抜きサーフェス(葉など)に TRANSPARENCY_HASH や ALPHA を決して使用しないでください。パフォーマンスとソートのため、ALPHA_SCISSOR を使用してください。
  25. CollisionShape ノードを決してスケーリングしないでください(Node2D/3D のスケール)。予測できない物理法線やジッターを避けるため、シェイプハンドルを使用するか、リソースのサイズを変更してください。
  26. is_on_floor() が true のときに重力を決して適用しないでください。微小なジッターが発生し、床へのスナップが妨げられます。垂直速度を必ず 0 または小さな定数にリセットしてください。
  27. 動的シグナル(キャプチャするラムダ)の切断を決して忘れないでください。Godot はローカル変数をキャプチャするラムダを自動で切断できないため、解放済みオブジェクトでクラッシュが発生します。
  28. モバイルのタッチ操作にマウスイベントを決して使用しないでください。信頼性の高いマルチタッチ対応のため、必ず InputEventScreenTouch と InputEventScreenDrag を使用してください。
  29. モバイルで Forward+ レンダラーを決して使用しないでください。GPU のボトルネックやバッテリー消費を避けるため、必ず Mobile または Compatibility レンダラーを使用してください。
  30. マウスの回転量を Transform に直接決して加算しないでください。ジンバルロックや精度の低下を防ぐため、Yaw/Pitch の変数を別々に保持してください。
  31. 実行時に高頻度で行うチェックに標準の String を決して使用しないでください。O(n) のハッシュ化オーバーヘッドを避けるため、必ず StringName(&"active")を使用してください。
  32. ゲーム状態(Health、Inventory)についてクライアントを決して信頼しないでください。クライアントはアクションを提案し、サーバーが検証してブロードキャストすることで、不正行為を防ぎます。
  33. 移動の更新に Reliable RPC を決して使用しないでください。高レイテンシー環境での Head-of-Line ブロッキングを防ぐため、UnreliableOrdered を使用してください。

📊 パート 5:パフォーマンス予算(具体的な数値)

指標モバイルの目標デスクトップの目標専門家向けメモ
ドローコール数< 100(2D)、< 200(3D)< 500植生や破片には MultiMeshInstance を使用します
三角形数表示中は < 100K表示中は < 1M500K を超える場合は LOD システムが必須です
テクスチャ VRAM< 512MB< 2GBVRAM 圧縮:ETC2(モバイル)、BPTC(デスクトップ)
スクリプト実行時間フレームあたり < 4msフレームあたり < 8msホットループを Server API に移動します
物理ボディ数アクティブなものが < 200アクティブなものが < 1000大量シミュレーションには PhysicsServer の直接 API を使用します
パーティクル数合計 < 2000合計 < 10000GPU パーティクルを使用し、visibility_aabb を手動で設定します
オーディオバス数同時に < 8同時に < 32オーディオシステムのバスルーティングを使用します
セーブファイルサイズ< 1MB< 50MBプロシージャルワールドにはシード + 差分パターンを使用します
シーンの読み込み時間< 500ms< 2sResourceLoader.load_threaded_request()

⚙️ パート 6:Server API — 専門家向けのパフォーマンス向上策

これは、ほとんどの Godot 開発者が学ぶことのない知識です。シーンツリーがボトルネックになったら、Godot の低レベル Server API を使ってシーンツリーを完全に回避します。

Server API に切り替えるタイミング
  • 10K 以上の描画インスタンス(スプライト、メッシュ):Sprite2D/MeshInstance3D ノードの代わりに、RID を使って RenderingServer を使用します。
  • スクリプトからの操作を伴う弾幕系/パーティクルシステム:Area2D ノードの代わりに、PhysicsServer2D でボディを作成します。
  • 大量の物理シミュレーション:ラグドール群、破片、または流体のようなシミュレーションには、PhysicsServer3D を直接使用します。
📊 パフォーマンス比較:SceneTree と Server API

SceneTree を回避すると、ノードのライフサイクル管理、シグナルの伝播、仮想関数(_process など)の呼び出しに伴う大きな CPU オーバーヘッドを排除できます。

指標SceneTree(ノード)Server API(RID)専門家向けの理由
オブジェクト数の上限約 1,000~5,00050,000 以上SceneTree の走査コストは O(n) です。サーバーでは O(1) の RID による直接ハンドルを使用します。
メモリオーバーヘッドノードあたり約 2KB~10KBRID あたり < 200 bytesノードはツリーの状態、シグナル、インスペクターのメタデータを保持します。RID は不透明な 24 バイトのハンドルです。
CPU 時間高い(仮想関数呼び出し)最小(直接 API)ノードではインスタンスごとに _process を呼び出す必要があります。サーバーは C++ で操作をまとめて処理します。
スレッド処理メインスレッドのみ本質的にスレッドセーフほとんどの Server API はスレッドセーフです(Project Settings で有効にする必要があります)。
ガベージコレクション自動(RefCounted)手動(割り当て/解放)サーバーでは手動のライフサイクル管理(RID の作成/削除)が必要です。

専門家向けメモ:RID を使うと、未加工のデータを管理し、エンジンのコアロジックと直接やり取りできます。SceneTree の管理処理がボトルネックとなる弾幕系、大量の植生、複雑なプロシージャルシミュレーションにおいて、これは主な「切り札」となります。

RID パターン(専門家向け)

Server API は RID(Resource ID)を介して通信します。RID はサーバー側オブジェクトへの不透明なハンドルです。重要なルール:

# Create server-side canvas item (NO node overhead)
var ci_rid := RenderingServer.canvas_item_create()
RenderingServer.canvas_item_set_parent(ci_rid, get_canvas_item())

# CRITICAL: Keep resource references alive. RIDs don't count as references.
# If the Texture resource is GC'd, the RID becomes invalid silently.
var texture: Texture2D = preload("res://sprite.png")
RenderingServer.canvas_item_add_texture_rect(ci_rid, Rect2(-texture.get_size() / 2, texture.get_size()), texture)
Server を使ったスレッド処理
  • シーンツリーはスレッドセーフではありません。一方、Server API(RenderingServer、PhysicsServer)は、Project Settings で有効にすればスレッドセーフです。
  • シーンチャンク(インスタンス化 + add_child)をワーカースレッド上で構築できますが、ライブツリーに追加するには必ず add_child.call_deferred() を使う必要があります。
  • GDScript の Dictionary/Array:スレッド間の読み取りと書き込みは安全ですが、サイズ変更(append、erase、resize)には Mutex が必要です。
  • 同じ Resource を複数のスレッドから同時に読み込むことは絶対に避けてください。読み込みスレッドは 1 つだけ使用します。

🧩 パート 7:エキスパート向けコードパターン

一般的なアーキテクチャおよびゲームプレイシステムのエキスパート向け実装です。


🔥 パート 8:Godot 4.x の注意点(ベテラン向け)

  1. @export のリソースはデフォルトで共有されます:複数のシーンインスタンスが、すべて同じ Resource を共有します。_ready() で resource.duplicate() を使用するか、「Local to Scene」チェックボックスを有効にしてください。これは、Godot 4 で初心者から最も多く報告されているバグです。
  2. シグナルの構文はエラーなく失敗します:connect("signal_name", target, "method")(Godot 3 の構文)はコンパイルされますが、Godot 4 では何も行いません。signal_name.connect(callable) を使用する必要があります。
  3. Tween は Node ではなくなりました:create_tween() で作成され、作成元のノードのライフタイムに紐付けられます。そのノードが解放されると、Tween も破棄されます。永続的な Tween には get_tree().create_tween() を使用してください。
  4. PhysicsBody のレイヤーとマスク:collision_layer は「自分が何者か」を表します。collision_mask は「何を検出するか」を表します。両方に同じ値を設定すると、自身との衝突が発生するか、検出に失敗します。
  5. 高頻度処理での StringName と String:StringName(&"key")はポインター比較を使用します(O(1))。String は文字比較を使用します(O(n))。_process 内で辞書のキーを扱う場合は、必ず StringName を使用してください。
  6. @onready のタイミング:_init() の後に、_ready() の実行中に処理されます。コンストラクターの実行時にセットアップする必要がある場合は、_init() を使用してください。ツリーへのアクセスが必要な場合は、@onready または _ready() を使用してください。両者を混在させると、null が発生します。
  7. サーバークエリによる停止:_process 内で RenderingServer または PhysicsServer の getter 関数を呼び出すと、パイプラインの同期フラッシュが発生します。これらのサーバーは非同期で動作するため、データを要求するとサーバーが追いつくまでパイプライン全体が停止します。
  8. move_and_slide() の API 変更:衝突が発生したかどうかを示す bool を返します。Velocity は引数ではなく、プロパティになりました。move_and_slide() を呼び出す前に、velocity = dir * speed を設定してください。

📂 パート 9:モジュールディレクトリ(99 の設計図)

重要

現在のワークフローに必要なモジュールのみを読み込んでください。パート 2 の決定マトリックスを使って、たどるべきチェーンを判断してください。

アーキテクチャと基盤

基盤 | コンポジション | アプリのコンポジション | シグナル | オートロード | 状態 | リソース | テンプレート | アナリスト | 監査担当 | ビルダー

バージョンアップグレード(外部ハブ): godot-version-migration — 全履歴ルーター(旧バージョン、3→4 のブリッジ、4.0→4.7 の段階的移行)。ここには複製されていません。

GDScript とテスト

GDScript の習得 | テストパターン | デバッグ/プロファイリング | パフォーマンス最適化

2D Systems

2D Animation | 2D Physics | Tilemaps | Animation Player | Animation Tree | CharacterBody2D | Particles | Tweening | Shader Basics | Camera Systems

3D Systems

3D Lighting | 3D Materials | 3D World Building | Physics 3D | Navigation/Pathfinding | Procedural Generation | Raycasting

Gameplay Mechanics

Abilities | Combat | Dialogue | Economy | Inventory | Questing | RPG Stats | Turn System | Audio | Scene Transitions | Save/Load | Secrets | Collections | Waves | Harvesting | Time Trials | Revival | Monte Carlo Balancer

UI & UX

UI Containers | Rich Text | Theming | Input Handling | Seasonal Theming | Agent Vision

Connectivity & Platforms

Multiplayer | Server Logic | Export Builds | Desktop | Mobile | Web | Console | VR

Adaptation Guides
Genre Blueprints (Exhaustive)

Action RPG | Shooter | Shooter FPS | RTS | MOBA | Rogue-like | Survival | Open World | Metroidvania | Platformer | Fighting | Stealth | Sandbox | Horror | Puzzle | Racing | Rhythm | Sports | Battle Royale | Card Game | Visual Novel | Romance | Simulation | Tower Defense | Idle Clicker | Party | Educational


🐛 Part 10: Expert Diagnostic Patterns

「見えないノード」バグ

症状:ツリー内にノードが存在するのに、描画されません。 エキスパートによる診断手順:visible プロパティ → z_index → 親の CanvasLayer が誤ったレイヤーにある → modulate.a == 0 → カメラの near クリップ面の背後にある(3D) → SubViewport.render_target_update_mode が設定されていない → CanvasItem がどの CanvasLayer にも属していない(すべての背後に描画される)。

「入力が食われる」バグ

症状:クリックやキー入力が断続的に無視されます。 エキスパートによる診断:対象に重なっている別の Control ノードの mouse_filter = STOP。または、モーダルな PopupMenu が未処理の入力を消費している。あるいは、別のスクリプトの _unhandled_input() が get_viewport().set_input_as_handled() を呼び出している。

「物理演算のジッター」バグ

症状:キャラクターが接触面で振動します。 エキスパートによる診断:Safe Margin が大きすぎます。または、移動に _physics_process ではなく _process を使っている(補間の不一致)。あるいは、スポーン時にコリジョンシェイプが重なっている(互いに押し合い、ずれたままになる)。

「メモリーリーク」

症状:プレイ中に RAM が着実に増加します。 エキスパートによる診断:queue_free() を呼び出しても、Array/Dictionary 内に参照が保持されています。または、後処理をせずに CONNECT_REFERENCE_COUNTED でシグナルを接続しています。Profiler の「Objects」タブを使って、孤立したインスタンスを見つけてください。親を持たない Node インスタンスを検索してください。

「フレームスパイク」

症状:FPS は滑らかなのに、定期的に低下します。 エキスパートによる診断:GDScript の GC パス。または、大きなリソースを同期的に load() している。あるいは、NavigationServer が再ベイクしている。または、サーバー API のクエリが停止している(_process 内で RenderingServer からデータを要求している)。組み込みの Profiler でプロファイルし、関数単位のスパイクを探してください。


🚀 Part 11: クイックスタート — Unity(C#)から Godot(GDScript)へ

Unity エコシステムから移行するシニアエンジニア向けの考え方の転換です。

1. ノードと GameObject/コンポーネント

Unity では、GameObject は Component のコンテナです。Godot では、すべてが Node です。

  • Unity:GameObject + Transform + MeshFilter + Script。
  • Godot:スクリプトをアタッチした MeshInstance3D ノード(それ自体が Transform と Mesh です)。
  • エキスパート向けの転換:ノードのコンポジションを使います。「Health Component」が必要なら、「Health」という名前の Node または Area3D を子として追加します。ロジックのみのコンポーネントには RefCounted を使い、メモリーを節約します。
2. シーンは入れ子にできる Prefab

Godot に「Prefab」がないのは、すべてのシーンが Prefab だからです。

  • シーンを別のシーン内に、無限にインスタンス化できます。
  • エキスパート向けの転換:再利用可能な各システム(Player、Enemy、UI Button)は、それぞれ独自の .tscn ファイルにします。これにより、「後順走査」(親より先に子の準備が完了する)が実現します。
3. シグナルとイベント/アクション

Godot の Signal システムは、オブザーバーパターンのネイティブ実装です。

  • Unity:event Action OnDeath;。
  • Godot:signal died。
  • エキスパート向けの転換:シグナルは第一級の機能です。Inspector に表示され、動的に、またはエディターから接続できます。Unity のシングルトンマネージャーに相当するグローバルイベントには、「Signal Bus」パターン(Autoload)を使います。
4. クラス拡張としてのスクリプト

ノードにスクリプトをアタッチすると、そのスクリプトはノードそのものになります。

  • Unity:GetComponent<MyScript>()。
  • Godot:スクリプトはノードのクラスを 継承します(例:extends CharacterBody3D)。
  • エキスパート向けの転換:型付き GDScript(var x: int = 5)を使うと、コンパイル速度が向上し、エディターの補完機能も利用できます。型がコンパイル時に判明している場合、型付き GDScript は最適化されたオペコードを使用します。
5. メモリー管理:ガベージコレクションによる停止なし

「GC スパイク」が発生する場合がある Unity の C# とは異なり、GDScript は参照カウントを使います。

  • エキスパート向けの転換:オブジェクトは参照されなくなった時点で解放されます。これによりパフォーマンスが予測可能になり、大規模な Unity プロジェクトでよく見られる断続的な「カクつき」を避けられます。
6. StringName とパフォーマンス

Unity ではパフォーマンスのために int や Enum を使います。Godot では StringName を使います。

  • エキスパート向けの転換:辞書やシグナル検索で定数時間(O(1))のポインター比較を行うには、&"name" を使います。

参考資料

コメント