godot-genre-moba について
MOBA開発向けのGodotスキルです。ソロのレーン試作から権威サーバー方式の5v5までを対象に、サーバー検証、ミニオン同期、タワーの標的選択、経路探索、視界制限の構成例を示します。
主な機能
- 01ダメージとアビリティのサーバー権威検証
- 02ミニオン状態の一括同期
- 03タワーの標的優先順位ロジック
- 04視界制限の視線チェック
- 05時間分割経路探索と並列処理
- 06スキルショット表示とデータ駆動アビリティ
活用シーン
- 01ソロ向けMOBAレーン試作の構築
- 02権威サーバー方式5v5のミニオンとアビリティ同期
- 03タワーの標的選択と視界制限の追加
- 04多数ユニットの経路探索負荷の軽減
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ thedivergentai/ game-dev-agentic-skills --skill godot-genre-mobaインストール後、Claude Code で/godot-genre-mobaを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/migration-notes.mdmoba-meta-systems-deep.mdscripts/ability_ui_binder.gdasync_arena_baker.gddecoupled_ability_damage.gdfog_grid_mask.gdfog_visibility_check.gdhero_net_sync.gdhero_state_machine.gdjungle_creep.gdminion_flow_calculator.gdminion_worker_pathfinder.gdreplay_manager.gdserver_minion_sync.gdskill_shot_indicator.gdstatus_effect_data.gdstatus_effect_manager.gdsynced_ability_controller.gdtower_priority_aggro.gdweighted_target_selector.gd詳細
絶対に避けるべきこと(エキスパート向けアンチパターン)
ネットワークと権限
- ダメージ計算やリソースコストについて、クライアントを絶対に信頼しないでください。必ず
multiplayer.is_server()を使用して、権威サーバー上でマナ、射程、命中判定を厳密に検証してください。 - 継続的な移動に
TRANSFER_MODE_RELIABLEを絶対に使用しないでください。ネットワークの輻輳を防ぐため、位置や速度には必ずUNRELIABLEまたはUNRELIABLE_ORDEREDを使用してください。 - ユニットを 60Hz で同期しないでください。
MultiplayerSynchronizerを使って必ず低いティックレート(10~20Hz)にし、視覚的な滑らかさのために 補間/クライアントサイド予測を実装してください。 - 何百ものミニオンに個別のシンクロナイザーを絶対に取り付けないでください。中央のマネージャーを通じて、状態更新を圧縮バイト配列にまとめてください。
- 複雑な Engine オブジェクトを直接同期しないでください。ピア間の同期を確実に行えるよう、状態をプリミティブプロパティまたは Dictionary に必ずシリアライズしてください。
AI とパス検索
- 毎フレームすべてのミニオンに高コストなパス検索を実行しないでください。
get_next_path_position()の呼び出しを複数フレームに分散するため、必ず タイムスライスを使用してください。 _process()内でNavigationAgentのパスを問い合わせないでください。ナビゲーションサーバーや回避システムとのやり取りには、必ず_physics_process()を使用してください。- NavMesh のベイクに複雑なビジュアルジオメトリを使用しないでください。
RenderingServerの停止やエンジンのクラッシュを避けるため、単純なプリミティブを解析してください。 - 大規模マップで
path_search_max_polygonsを低く設定しないでください。上限に達した時点で目的地に到達していないと、エージェントが停止したり、誤った方向に進んだりします。 - 高性能な Fog of War の LOS に
Area2Dを使用しないでください。ノードのオーバーヘッドを避けるため、ノードを使わない物理クエリ(intersect_ray)を必ず使用してください。
ゲームプレイとバランス調整
- タワーの「ダイブ」保護を絶対に忘れないでください。射程内の敵ヒーローが味方ヒーローにダメージを与えたら、タワーは必ず即座にターゲットを切り替えてください(優先順位:味方を攻撃中のヒーロー > ミニオン > ヒーロー)。
- 対抗手段のない「スノーボール」を絶対に許さないでください。競争上の緊張感を維持するため、必ず 逆転の仕組み(キル報奨金、追いつきXP)を実装してください。
- ヒーローのステータスを標準的な Node 変数として管理しないでください。データを分離してメモリ効率を高めるため、必ずカスタムの
Resourceスクリプトを使用してください。 - 共有されている能力 Resource に対して
duplicate(true)を呼び出すことを絶対に忘れないでください。共有 Resource 上のバフを変更すると、すべてのヒーローに影響します。
技術とパフォーマンス
- 状態チェック(例:「stunned」)に標準的な文字列を使用しないでください。ポインター速度の比較には、必ず
StringName(&"stunned")を使用してください。 - Fog of War の巨大なグリッドを float でループ処理しないでください。精度のずれを防ぐため、必ず
Vector2iとTileMapLayerを使用してください。 - 重いワールド/ミニマップ処理をメインスレッドで実行しないでください。60+ FPS を維持するため、複雑な配列演算は必ず
WorkerThreadPoolにオフロードしてください。 - UI のクールダウンをヒーロースクリプトに強く結合しないでください。疎結合なアーキテクチャにするため、必ず Signal Bus または
Callableバインディングを使用してください。 - 浮動小数点数の完全一致(==)を判定しないでください。射程、クールダウン、マナの検証には、必ず
is_equal_approx()を使用してください。
判断ツリー:ソロプロトタイプと権威型5v5
| 目標 | 最初に読み込むもの | スキップ/後回しにするもの |
|---|---|---|
| ソロレーンのプロトタイプ(ヒーロー1体、ローカルのウェーブ、他プレイヤーなし) | tower_priority_aggro.gd, weighted_target_selector.gd, skill_shot_indicator.gd, hero_state_machine.gd | server_minion_sync、完全なフォググリッド、予測 |
| 権威型5v5(専用サーバー/リッスンサーバー) | server_minion_sync.gd, synced_ability_controller.gd, fog_visibility_check.gd + fog_grid_mask.gd, minion_worker_pathfinder.gd | クライアント信頼型のダメージ、ミニオンごとの MultiplayerSynchronizer |
| ピアスキル | godot-multiplayer-networking、godot-navigation-pathfinding、godot-ability-system | このジャンルのスキル内に2つ目のネットワークスタックを作ること |
🛠 エキスパート向けコンポーネント(scripts/)
オリジナルのエキスパートパターン
- skill_shot_indicator.gd - マウス操作による、射程、幅、方向を可視化するターゲティングシステムです。
- tower_priority_aggro.gd - 競技向けの優先ルールに従う、防御塔向けの高度なAIです。タワーダイブ/優先ルールには必須です。
モジュール式コンポーネント
- server_minion_sync.gd - 圧縮バイト配列を使用して、多数のユニットを権威型で同期します。5v5のウェーブには必須です(ミニオンごとに1つのSynchronizerを使うのではありません)。
- fog_visibility_check.gd - 高性能な視線チェックのための物理レイキャストです。フォグマスクの描画前に必須です。
- fog_grid_mask.gd - Vector2iグリッドロジックを使用した、TileMap駆動の視界マスキングシステムです。
- minion_worker_pathfinder.gd - 読み込むタイミング: ウェーブの規模が大きくなり、
_physics_process内での経路探索が困難になった場合に、WorkerThreadPoolで経路探索バッチを処理します。毎フレーム、ミニオンごとに完全なA*を実行するよりもこちらを優先してください。 - weighted_target_selector.gd - 読み込むタイミング: グループごとの重み付き優先度を使って、ヒーロー/ミニオン/タワーのターゲットを取得する場合です(AAおよびシンプルなアグロ)。ダイブのルールにはtower_priorityと組み合わせてください。
- synced_ability_controller.gd - 読み込むタイミング: 権威型環境でのQWER発動です。クライアントはクールダウンUIを予測し、サーバーが検証します。オフラインのプロトタイプではスキップしてください。
- status_effect_data.gd - バフ、デバフ、スタンを定義する軽量なResourceコンテナです。
- status_effect_manager.gd - 個別のステータス効果インスタンスを適用、管理するモジュール式ロジックです。
- decoupled_ability_damage.gd - 安全なダックタイピングパターンを使用した、ヒーロー間の戦闘インタラクションです。
- hero_state_machine.gd - ヒーローのロジック向けに最適化された、StringNameベースのステートマシンです。
- async_arena_baker.gd - 動的なアリーナのナビゲーションメッシュを、バックグラウンドスレッドで安全に更新します。
- ability_ui_binder.gd - シグナルベースでUIを分離し、アビリティのクールダウンを追跡します。
- minion_flow_calculator.gd - WorkerThreadPoolを使用して、経路探索とAI処理を並列化します。
- replay_manager.gd - バイナリ形式の
var_to_bytesでマッチのリプレイフレームを保存します(JSONではありません)。 - hero_net_sync.gd - 低ティックレートで、物理補間とMultiplayerSynchronizerによるヒーロー同期を行います。
- jungle_creep.gd - キャンプのリードFSMです。
leash_radiusを超えると無敵状態でホームへ戻ります。
基本的なゲームサイクル
- レーン:プレイヤーは指定されたレーンでミニオンを倒し、ゴールドと経験値を獲得します。
- トレード:プレイヤーは相手ヒーローとダメージを与え合います。
- ガンク:プレイヤーは敵を奇襲するため、ほかのレーンへロームします。
- プッシュ:チームはタワーを破壊して、マップを開放します。
- 決着:敵のコア/ネクサスを破壊します。
スキルチェーン
| フェーズ | スキル | 目的 |
|---|---|---|
| 1. 操作 | rts-controls | 右クリックで移動、Aムーブ、停止 |
| 2. AI | godot-navigation-pathfinding | ミニオンウェーブ、タワーのアグロロジック |
| 3. 戦闘 | godot-ability-system、godot-rpg-stats | QWERアビリティ、クールダウン、スケーリング |
| 4. ネットワーク | godot-multiplayer-networking | 権限、ラグ補償、予測 |
| 5. マップ | godot-3d-world-building | レーン、ジャングル、リバー、ベース |
| 6. バランス | godot-monte-carlo-balancer | ヒーロー/非対称性のマトリックス(AFKからプロまでを単独で扱うものではありません) |
アーキテクチャの概要
1. レーン/ミニオンウェーブ(権威サーバー方式)
インラインで lane_manager / minion_ai のサンプルを作成しないでください。
必読:server_minion_sync.gd でウェーブ状態をバッチ処理します。エージェント数に応じて WorkerThreadPool が必要な場合は minion_worker_pathfinder.gd、行軍から戦闘へのターゲット選択には weighted_target_selector.gd を参照してください。スポーン間隔はサーバー上でデータ/タイマー駆動にし、クライアントは同期配列から描画します。
2. タワーのアグロロジック
優先順位:味方を攻撃中のヒーロー > 味方ヒーローを攻撃中のユニット > 最も近いミニオン > 最も近いヒーロー。
必読:tower_priority_aggro.gd を参照してください。グループ順位には weighted_target_selector.gd を組み合わせます。
3. 視界の霧
必読:ノードを必要としないLoS判定には fog_visibility_check.gd を参照し、その結果を fog_grid_mask.gd に描画してください。視界の霧の判定に
Area2Dのオーバーラップを使わないでください。
4. スキルショットのアビリティサイクル
「QWER」ターゲティングの実装パターン:
- 待機:入力を待ちます。
- 予告:マウスを押している間、インジケーター(skill_shot_indicator.gd)を表示します。
- 発動:マウスを離したときにヒットボックス/投射物を生成します。マルチプレイヤーでは、synced_ability_controller.gd を経由させます。
- 硬直:短い後隙アニメーション中は、移動と詠唱がロックされます。
主要メカニクスの実装
クリックして移動(RTSスタイル)
カメラから地形に向けてレイキャストします。
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("move"):
var result = raycast_from_mouse()
if result:
nav_agent.target_position = result.position
アビリティシステム(データ駆動)
「ファイアボール」や「フック」を、それぞれ専用のスクリプトを作成せずに定義します。
# ability_data.gd
class_name Ability extends Resource
@export var cooldown: float
@export var mana_cost: float
@export var damage: float
@export var effect_scene: PackedScene
Godot固有のヒント
- NavigationAgent3D:ミニオン同士が積み重ならず、水のように流れて移動できるよう、
avoidance_enabledを使用します。 - MultiplayerSynchronizer:体力、マナ、クールダウンを同期します。クライアントサイド予測を使う場合は、毎フレーム位置を同期しないでください(上級者向け)。
- 視界の霧:フォグテクスチャを使った
SubViewportを使用します。味方がいる場所のテクスチャに「穴」を描画し、このテクスチャを地形シェーダーに投影します。
よくある落とし穴
- スノーボール:勝利チームが短時間で強くなりすぎます。対策:「逆転用の経験値/ゴールド」システム(懸賞金)を実装します。
- 経路探索の遅延:100体のミニオンが毎フレーム経路探索を行います。対策:経路探索の更新を複数フレームに分散します(タイムスライシング)。
- ハッキング:クライアントが「1000ダメージを与えた」と報告します。対策:クライアントは「方向VにスペルQを発動した」と報告し、サーバーがダメージを計算します。
高度なMOBAメタシステム
試合のリプレイ、ネットワークのスムージング、高度なジャングルAIのプロフェッショナルな実装です。
1. 試合リプレイシステム(バイナリシリアライズ)
高性能な試合記録には、var_to_bytes() を使用して状態辞書を圧縮されたバイナリ形式にシリアライズします。ディスクI/Oとファイルサイズを最小限に抑えるため、リプレイにはJSONを使わないでください。
class_name ReplayManager extends Node
var frame_history: Array[PackedByteArray] = []
func record_frame(state: Dictionary) -> void:
# Efficiently convert data to bytes
frame_history.append(var_to_bytes(state))
func save_replay(match_id: String) -> void:
var file := FileAccess.open("user://replays/" + match_id + ".dat", FileAccess.WRITE)
if file:
file.store_var(frame_history) # Stores the whole array as a variant
file.close()
func play_frame(frame_index: int) -> Dictionary:
return bytes_to_var(frame_history[frame_index])
2. ネットワーク経由の補間同期
Godot 4.x に組み込まれている物理補間を使って、ネットワークジッターを目立たなくします。MultiplayerSynchronizer と組み合わせることで、ティックレートが低くても(15〜20 Hz)、ヒーローの移動を滑らかに表示できます。
class_name HeroNetSync extends CharacterBody3D
func _ready() -> void:
# Enable native engine interpolation for visual smoothness
physics_interpolation_mode = Node.PHYSICS_INTERPOLATION_MODE_ON
if is_multiplayer_authority():
setup_synchronizer()
func setup_synchronizer() -> void:
var sync := $MultiplayerSynchronizer
var config := SceneReplicationConfig.new()
# Sync position/rotation via unreliable ordered packets
config.add_property(NodePath(".:global_position"))
sync.replication_config = config
3. ジャングル AI(キャンプへの引き戻し)
ジャングルモンスターのスポーン地点からの距離を監視するステートマシンを実装します。ヒーローに遠くまで引き離された場合、モンスターは「引き戻し」状態に入り、無敵になってホームに戻ります。
class_name JungleCreep extends CharacterBody3D
@export var leash_radius: float = 12.0
@onready var spawn_pos := global_position
func _physics_process(_delta: float) -> void:
var dist_from_home := global_position.distance_to(spawn_pos)
match state:
State.CHASING:
if dist_from_home > leash_radius:
state = State.LEASHING
State.LEASHING:
# Move back to spawn_pos using NavigationAgent3D
nav_agent.target_position = spawn_pos
if global_position.distance_to(spawn_pos) < 1.0:
state = State.IDLE
health = max_health # Reset health on return
専門家向けのヒント:スポーン後に AI がパス検索を行えるようにする前に、ナビゲーションマップの同期が完全に完了していることをNavigationServer3D.map_get_iteration_id()で必ず確認してください。
必須:意思決定ツリーやスクリプトカタログを超える詳細については、moba-meta-systems-deep.mdを参照してください。初回の配線作業では読み込まないでください。まずは同梱の
scripts/を使用してください。
リファレンス
段階的な情報開示:特定の API を調べる場合にのみ公式ドキュメントのリンクを開いてください。 作業を関連分野に引き継ぐ場合は関連スキルを読み込み、スキル群全体を事前に読み込まないでください。
公式ドキュメント
- 高レベルマルチプレイヤー — サーバーで検証するキャストや、信頼性のない移動更新における権限、RPC、転送モードについて説明します。
- MultiplayerSynchronizer — ミニオンごとに同期機能を大量に使うことなく、ヒーローの体力/マナ/クールダウンをプロパティ複製する方法について説明します。
- SceneReplicationConfig — ティックレートを低くしたヒーロー同期と組み合わせる際に、どのプロパティをどの頻度で複製するかについて説明します。
- NavigationAgents の使用 — クリック移動、ミニオンの進軍、衝突回避を使い、レーンの流れを保ちながらユニットが重ならないようにする方法について説明します。
- ナビゲーションメッシュの使用 — アリーナのジオメトリ変更時に、レーン/ジャングル/基地をベイクし、非同期で再ベイクする方法について説明します。
- ナビゲーションパフォーマンスの最適化 — 各ウェーブで数百体のミニオンがパス検索を行う場合の、時間分割処理とエージェントの予算について説明します。
- レイキャスティング — ダイレクトスペースステートのレイを使った、クリック位置の地面判定とノード不要の霧の視線判定について説明します。
- 物理補間の概要 — ネットワーク同期が 10〜20 Hz で動作しているときに、ヒーローの表示を滑らかにする方法について説明します。
- Viewport の使用 — 味方の視界を使って描画する SubViewport の霧マスクとミニマップ投影について説明します。
- 複数スレッドの使用 — メインスレッド以外でミニオンの一括処理を行う WorkerThreadPool のパターンについて説明します。
- リソース —
duplicate(true)を使って、バフが共有テンプレートを書き換えないようにする、能力/状態のResourceデータについて説明します。 - マウスと入力座標 — スキルショットのインジケーターや RTS 形式の移動指示に使う、画面座標からワールド座標への変換について説明します。
関連スキル
前提条件
- godot-project-foundations — レーン、タワー、フォグのクエリ間で一貫性を保つため、物理ティック、レイヤー名、入力マップを事前に設定します。
- godot-multiplayer-networking — MOBAのミニオン/ヒーローのネットワーキング基盤となる、権限管理、RPCの適切な運用、同期予算について説明します。
- godot-navigation-pathfinding — ウェーブやジャングルキャンプ向けのNavigationAgentの回避、ベイク、パフォーマンス要件について説明します。
- godot-input-handling — クリック移動やQWERの詠唱予告に使うアクションマップと、物理ステップでの入力サンプリングについて説明します。
補完
- godot-ability-system — データ駆動型のQWERクールダウン、コスト、エフェクトシーンを、権威側の詠唱検証に組み込みます。
- godot-rpg-stats — ヒーローの成長、アーマー/MR形式の修正値、タワーやアビリティが参照するResourceベースのステータスについて説明します。
- godot-combat-system — クラス間の強い結合を避けながら、スキルショット、通常攻撃、タワーショットに対応するヒット/被ヒットの要件を定めます。
- godot-raycasting-queries — 負荷が高い状況でのフォグの視線判定、ダイブ判定、クリック選択に役立つ、より高度なspace-stateのレシピを紹介します。
- godot-signal-architecture — アビリティUIのバインダーと詠唱バスを疎結合にし、ヒーローの戦闘スクリプト内にクールダウンを置かない構成を実現します。
- godot-3d-world-building — ナビメッシュのベイク面に合致するレーンの通路、ジャングルの形状、コリジョンについて説明します。
- godot-performance-optimization — ミニオンの同期配列やフォググリッドがフレーム時間を圧迫するときの、プロファイリングとバッチ処理について説明します。
- godot-genre-rts — RTSの操作UXをMOBAヒーローに取り入れる際に共用できる、クリック移動、選択、フォグマスクのパターンを紹介します。
下流/利用者
- godot-adapt-single-to-multiplayer — ソロのレーンプロトタイプを、このジャンルで想定されるロビー、権限管理、予測のフローへと発展させます。
- godot-monte-carlo-balancer — ヒーロー間の非対称性、キル報奨金、追いつき用XPのマトリクスを扱います。AFKからプロまでのPvE帯だけでなく、対戦カードごとの勝率をシミュレーションします。
マスター
- godot-master — ライブラリのルーターであり、関連分野と並ぶMOBAのパターンを見つけるためのミラーエントリーです。