godot-genre-metroidvania について
Godot のメトロイドヴァニア開発者向けの設計・アーキテクチャガイドです。能力ゲート、ルーム遷移、永続化、マップの霧を扱い、進行状況の一元管理やスレッド読み込み、安全に戻れる探索経路を重視します。
主な機能
- 01能力とワールド進行の一元管理
- 02能力による進行ゲート
- 03スレッドによるルーム先読みと安全な切り替え
- 04Vector2i グリッドのマップ霧
- 05ジャンプバッファと能力ステート部品
活用シーン
- 01能力解放型の探索ルート構築
- 02部屋をまたぐ収集品・ボス状態の保存
- 03マップの霧とルーム遷移の実装
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ thedivergentai/ game-dev-agentic-skills --skill godot-genre-metroidvaniaインストール後、Claude Code で/godot-genre-metroidvaniaを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/expert-metroidvania-patterns.mdmigration-notes.mdscripts/ability_state_machine.gdability_unlock_resource.gdbackground_room_streamer.gddecoupled_hazard_logic.gdfast_travel_system.gdfast_wall_detector.gdmetroid_game_state.gdminimap_fog_manager.gdminimap_fog_revealer.gdminimap_fog.gdpersistent_progression_system.gdplatformer_jump_buffer.gdprogression_gate_manager.gdprogression_manager.gdroom_metadata.gdsafe_scene_switcher.gdsave_station_broadcast.gdsmooth_room_camera_transition.gd詳細
絶対にしてはいけないこと(専門家向けのアンチパターン)
ワールドデザインと探索
- プレイヤーが閉じ込められる「ソフトロック」を絶対に発生させないでください。一方通行の経路(「バルブ」)から入った場合、現在の能力で必ず脱出できるようにしてください。常にフェイルセーフな脱出経路を設計してください。
- 空の行き止まりを絶対に作らないでください。プレイヤーが遠方のエリアまで引き返す場合、必ず収集アイテム、ロア、または通貨を獲得できるようにしてください。空の部屋は設計上の失敗です。
- 引き返す行為を単なる繰り返しにしないでください。プレイヤーが移動能力(ダッシュ/テレポート)を獲得するにつれて、以前のエリアをより速く移動できるようにしてください。序盤の長い経路を迂回するショートカットを開放してください。
- 「手がかり」なしで重要な経路を隠さないでください。特徴的なランドマーク、独特な照明、または環境ストーリーテリングを使って、プレイヤーが頭の中に地図を描けるようにしてください。
- 目的が1つだけの能力を絶対に設計しないでください。移動と戦闘の両方に使える機能を必ず実装してください(例:隙間を越え、攻撃を回避する「ダッシュ」)。
永続化とマッピング
- 部屋の永続状態の保存を絶対に忘れないでください。プレイヤーが宝箱を開けたりボスを倒したりした場合、その状態は部屋を離れて戻ってきても必ず保存されていなければなりません。
- 相互に接続された部屋を
load()で同期的に読み込まないでください。シームレスな切り替えには、必ずResourceLoader.load_threaded_request()を使用してください。 - ローカライズされた部屋のスクリプト内でグローバルな進行状況を管理しないでください。グローバルな能力フラグとワールド状態には、必ずAutoload Singletonを使用してください。
- グリッド座標(ミニマップ/フォグ)に浮動小数点型を使わないでください。精度の揺らぎを防ぐため、必ず
Vector2iを使用してください。 - バックグラウンド読み込みスレッドからSceneTreeを直接操作しないでください。必ず
call_deferred()を使用してください。
物理演算と操作
_process()内でジャンプの軌道やダッシュを計算しないでください。カクつきを防ぐため、必ず_physics_process()を使用してください。move_and_slide()の前にCharacterBody2Dの速度へdeltaを掛けないでください。これはエンジン内部で処理されます。- 入力バッファリングのために
_physics_process()内でis_action_just_pressed()をポーリングしないでください。必ず_unhandled_input()でイベントを取得してください。 - 高頻度の能力チェックに標準の文字列を使わないでください。ポインター速度で比較できるよう、必ず
StringName(&"dashing")を使用してください。 - 更新を通知するためにすべてのノードを反復処理しないでください。効率的な一斉通信には、必ず
SceneTree.call_group()を使用してください。 - アクティブな部屋やプレイヤーのノードを
free()で削除しないでください。セグメンテーションフォールトを避けるため、必ずqueue_free()を使用してください。
🛠 専門家向けコンポーネント(scripts/)
推奨される読み込み順(必読)
- 永続化/フラグ — metroid_game_state.gd + persistent_progression_system.gd
- 能力の定義/ゲート — ability_unlock_resource.gd + progression_gate_manager.gd
- 部屋のストリーミング/切り替え — background_room_streamer.gd + safe_scene_switcher.gd
- マップのフォグ — minimap_fog_manager.gd(オーケストレーター)とミニマップフォグ/フォグ可視化ノード
専門家向けの独自パターン
- ミニマップフォグ - 訪問済みの部屋を追跡し、グローバルなセーブデータを通じて永続化する、グリッドベースのフォグ・オブ・ウォーです。
- progression_gate_manager.gd - 能力で制限される進行(ロック/キー)とワールドの永続化を一元管理します。
- metroid_game_state.gd - ワールド/能力/収集アイテムの状態をAutoload形式で管理する必須のスクリプトです(ローカルなgame_stateチュートリアルを貼り付けないでください)。
- ability_unlock_resource.gd - ゲートから参照される、アンロック可能な能力を定義する必須のResourceです。
- minimap_fog_manager.gd - 進行状況/セーブと同期するVector2iフォグを統括する必須のスクリプトです。
モジュール式コンポーネント
- platformer_jump_buffer.gd - 高精度な移動を実現する、モジュール式のコヨーテタイムとジャンプバッファリング。
- background_room_streamer.gd -
ResourceLoaderを使用した、スレッドセーフなバックグラウンドでのルーム事前読み込み。 - safe_scene_switcher.gd - ルーム間のワールド状態を安定して切り替える、遅延シーン遷移パターン。
- minimap_fog_revealer.gd - プレイヤーの位置と同期する、Vector2i ベースのフォグ・オブ・ウォー解除ロジック。
- persistent_progression_system.gd - グローバルな能力/収集アイテムのフラグを追跡する Autoload パターン。
- ability_state_machine.gd - 移動/戦闘状態に対する最適化された
StringNameパターンマッチング。 - fast_wall_detector.gd - パフォーマンスを最適化した壁検出を行う、
PhysicsServerの直接クエリ。 - save_station_broadcast.gd - セーブ時のインタラクションで、グループベースのエンティティリセットと回復を行うロジック。
- decoupled_hazard_logic.gd - 汎用的なダメージインタラクションのための、インターフェース形式のパターン。
- smooth_room_camera_transition.gd - シームレスなルーム移動を実現する、Tween ベースのカメラ制限補間。
コアループ
- 探索 → ロックによって行く手を阻まれる
- 発見 → 重要な能力/ボス
- 獲得 → 新たな移動/戦闘ツール
- 戻り探索 → ショートカット+複数用途の能力
- 進行 → 新たなバイオームが開放される
スキルチェーン
| フェーズ | スキル | 目的 |
|---|---|---|
| 1. キャラクター | godot-characterbody-2d, godot-state-machine-advanced | 精密な移動+能力状態 |
| 2. ワールド | godot-tilemap-mastery, godot-scene-management | ルーム、バイオーム、スレッド化された遷移 |
| 3. システム | godot-save-load-systems, godot-ability-system | ゲート/収集アイテムを永続化し、キーをアンロック |
| 4. UI | godot-ui-containers, godot-inventory-system | マップ/インベントリ/HUD |
| 5. バランス | godot-monte-carlo-balancer | ソフトロックのリスク、戻り探索の距離 |
アーキテクチャ(スクリプトファースト — インラインのレシピはなし)
1. ゲーム状態と永続化
必須: metroid_game_state.gd + persistent_progression_system.gd。ルームがグローバルな能力フラグを所有することはありません。ルームのメタデータには resource_local_to_scene を使用し、インスタンス化されたルーム間で収集アイテムの状態が共有されないようにします。
2. ルーム遷移とファストトラベル
必須: background_room_streamer.gd + safe_scene_switcher.gd。
ファストトラベルでは NEVER の要件(スレッド化された読み込み+遅延スワップ)に従う必要があります。ResourceLoader.load() や同期的な change_scene は使用しないでください。
class_name FastTravelSystem extends Node
var _pending_path: String = ""
var _spawn_id: StringName = &""
func travel_to_room(scene_path: String, spawn_id: StringName) -> void:
_pending_path = scene_path
_spawn_id = spawn_id
var err := ResourceLoader.load_threaded_request(scene_path)
if err != OK:
push_error("Fast travel request failed: %s" % scene_path)
return
set_process(true)
func _process(_delta: float) -> void:
var status := ResourceLoader.load_threaded_get_status(_pending_path)
if status == ResourceLoader.THREAD_LOAD_IN_PROGRESS:
return
set_process(false)
if status != ResourceLoader.THREAD_LOAD_LOADED:
push_error("Fast travel load failed: %s" % _pending_path)
return
var packed := ResourceLoader.load_threaded_get(_pending_path) as PackedScene
# SceneTree work must be deferred — never from a worker thread
call_deferred("_swap_room", packed, _spawn_id)
func _swap_room(packed: PackedScene, spawn_id: StringName) -> void:
GlobalState.target_spawn_id = spawn_id
get_tree().change_scene_to_packed(packed)
3. 能力によるゲート制御
必須: ability_unlock_resource.gd + progression_gate_manager.gd + ability_state_machine.gd。ゲートは Autoload から StringName の能力を照会します。ルームのスクリプトに能力の文字列をハードコードしないでください。
4. マップ/フォグ
必須: minimap_fog_manager.gd。セルには Vector2i のみを使用してください。
設計原則(Dreamnoid より)
- 能力の多用途性 — 移動と戦闘の両方に使用
- 練習ルーム — ペナルティを与える前に教える
- ランドマーク — 明示的なマーカーなしで頭の中にマップを描けるようにする
- アイテムのミニストーリー — カットシーンを長々と挟まずに伝承を描く
よくある落とし穴
- 一方通行の弁によるソフトロック — 現在の能力で脱出できる方法を必ず設計する
- 戻り探索の冗長さ — ショートカットを用意し、アンロック後は移動を速くする
- 何もない行き止まり — 離れた場所への道には必ず報酬を用意する
- 同期ルーム読み込み — NEVER に違反するため、スレッド化されたリクエスト+遅延スワップを使用する
専門知識(必要に応じて)
LLM の知識不足に関するルール: 一般的なエージェントが読む前には知らない情報であれば、リファレンスを読み込んでください。専門的な追加情報は決して削除しないでください。
- expert-metroidvania-patterns.md — 基礎となる教育内容を復元します(アーキテクチャ、理由、実装の深さ)
- room_metadata.gd
- progression_manager.gd
- fast_travel_system.gd
リファレンス
段階的な情報開示:特定の API を調査するときにのみ公式ドキュメントのリンクを開いてください。関連するスキルは、隣接する分野に振り分けるときに読み込みます。スキル全体をあらかじめ読み込まないでください。
公式ドキュメント
- CharacterBody2D の使用 — コヨーテジャンプ/入力バッファ付きジャンプやダッシュでの移動における
move_and_slide、床の検出、速度のルール。 - アイドル処理と物理処理 — ジャンプの軌道、ダッシュ、壁滑りは
_physics_processで処理し、入力コールバックで入力バッファを取得します。 - InputEvent — 物理処理のティック間でジャンプ/アビリティの入力が失われないようにする
_unhandled_inputの入力バッファリング。 - バックグラウンド読み込み — 隣接する部屋を読み込み、急なカクつきを避けるための
ResourceLoader.load_threaded_request。 - シーンを手動で変更する — 遅延された部屋の切り替え、スポーンするドア ID、退出する部屋の安全な
queue_free。 - ゲームの保存 — セッションをまたいでアビリティ、開いたゲート、収集アイテム、訪問済みのマップセルを保持します。
- シングルトン(Autoload) — 部屋間でアビリティのフラグが競合しないよう、進行状況/ゲーム状態をグローバルに管理します。
- リソース — アビリティのアンロック定義と部屋のメタデータを、複製時も安全な
.tresデータとして扱います。 - Tilemap の使用 — ミニマップの霧の表示とグリッドによる部屋の追跡に使う
TileMapLayerとVector2iのセル。 - Camera2D — シームレスなカメラの部屋間遷移に使う、部屋ごとの
limit_*境界とトゥイーンによる境界の引き継ぎ。 - Area2D の使用 — シーンを強く結合せず、body_entered を使ってドア、セーブ地点、ハザードのトリガーを実装します。
- グループ — ツリー全体を走査する代わりに、セーブ地点から回復/リスポーンの通知を行う
call_group。
関連スキル
前提条件
- godot-project-foundations — 部屋のストリーミングとグローバルな進行状況管理を積み重ねる前に、オートロード、シーンのレイアウト、プロジェクト設定を整えます。
- godot-characterbody-2d — 緻密なプラットフォーマーの移動処理は、アビリティで制限される移動(ダッシュ、壁滑り、二段ジャンプ)の基盤です。
- godot-tilemap-mastery — ゲームプレイ用の衝突判定、ランドマーク、ミニマップの霧グリッドに使う、レイヤー化された TileMap/TileMapLayer の作成。
- godot-autoload-architecture — 部屋側で重複させてはならない、アビリティのフラグとワールドの状態保持に関するシングルトンの管理パターン。
補完スキル
- godot-scene-management — スレッド化されたロードキューと遅延ルーム切り替えにより、相互接続されたマップでの引っかかりを防ぎます。
- godot-save-load-systems — 長時間の探索セッションを通じて、収集アイテム、ボスのフラグ、訪問済みセルを保持できる堅牢なスキーマを扱います。
- godot-camera-systems — 基本的なCamera2Dの境界を超える、ルーム制限、RemoteTransformによる追従、トランジションの仕上げを扱います。
- godot-ability-system — ゲートやステートマシンが「鍵」として参照する、アンロック可能な移動・戦闘アビリティを扱います。
- godot-state-machine-advanced — 入れ子になった
if/elifの肥大化を避けながら、ダッシュ/壁滑り/二段ジャンプを実現する階層型プレイヤーステートを扱います。 - godot-2d-physics — 壁検出やソフトロックを防ぐバルブのためのレイヤー、Area2Dドア/ハザード、直接的な空間クエリを扱います。
- godot-inventory-system — マップ報酬やアビリティ獲得UIに反映する、収集アイテム/キーアイテムの追跡を扱います。
下流/利用側
- godot-monte-carlo-balancer — ゲートと報酬密度を調整可能にしたうえで、アビリティのアンロック順、引き返し距離、ソフトロックのリスクをシミュレーションします。
- godot-genre-platformer — アビリティによる制限を取り除く際に、メトロイドヴァニアの移動が基盤とする、純粋な操作感のパターンを扱います。
- godot-signal-architecture — ability_unlocked/gate_opened/map_revealedのバスにより、HUDやルームが進行状況を所有せずに監視できるようにします。
マスター
- godot-master — ライブラリのルーター兼ミラー化されたモジュールのエントリです。関連するスキルを探すときや、ドメインスキルの編集後に共有スクリプトのミラーを同期するときに使用します。