godot-combat-system について
godot-combat-systemは、Godotでダメージ、体力、ヒットボックスなどを実装する開発者向けの戦闘システムスキルです。型付きDamageDataとコンポーネント構成を軸に、よくある戦闘処理の問題を避ける方法を示します。
主な機能
- 01型付きDamageDataリソースとダメージフラグ
- 02ダメージ処理と無敵時間を備えたHealthComponent
- 03ヒットボックスとハートボックスの接続
- 04範囲攻撃、ヒットストップ、ダックタイピングのパターン
- 05任意のコンボ、テレメトリー、デバッグ用スクリプト
活用シーン
- 01耐性やクリティカル情報を含む型付きダメージの実装
- 02近接攻撃や飛び道具のヒット判定時間の構築
- 03一時的なAreaノードを使わない範囲攻撃の実装
- 04戦闘イベントの確認やネットワークダメージの検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ thedivergentai/ game-dev-agentic-skills --skill godot-combat-systemインストール後、Claude Code で/godot-combat-systemを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/elite-combat-patterns.mdmigration-notes.mdscripts/combat_logger.gdcombat_state.gdcombat_system_patterns.gdcombo_system.gddamage_data.gddamage_popup.gdhealth_component.gdhitbox_component.gdhitbox_hurtbox.gdhitbox_visualizer.gdnetworked_damage_manager.gd詳細
絶対にしてはいけないこと
- 直接ダメージを参照する方法(
target.health -= 10)は絶対に使わないでください — アーマー、耐性、無敵時間を迂回してしまいます。必ずDamageDataとHealthComponent.take_damageを使用してください。 - 無敵時間(i-frame)を絶対に忘れないでください — そうしないと、複数回ヒットする形状が物理フレームごとにヒットします。ヒットが成功した後、短い無敵時間を適用してください。
- ヒットボックスを絶対に常時有効にしないでください — AnimationPlayer のトラックまたは時間指定コードで有効化/無効化してください。常時監視すると、意図しないヒットが発生します。
- 物理ベースのヒット判定にグループを絶対に使わないでください — 衝突レイヤー/マスク(C++ フィルター)を優先してください。グループは補助的なロジックであり、物理判定のゲートではありません。
- DamageData オブジェクトなしでダメージシグナルを絶対に発行しないでください — 数値だけでは、種類、ソース、ノックバック、クリティカルの情報が失われます。
- 属性ダメージの種類に生の文字列を絶対に使わないでください —
enum/@export_flagsのビットフィールドを使用してください。文字列"physical"は、このスキル自体の契約に違反します。 - ターゲットの検証に try/catch を絶対に使わないでください — GDScript に例外はありません。
has_method(&"take_damage")/isチェックを使用してください。 OS.delay_msec()でヒット硬直を絶対にハードコードしないでください — OS スレッドをブロックします。トゥイーン/Engine.time_scaleとignore_time_scaleタイマーを使用してください。_process()内で RigidBody にインパルスを絶対に適用しないでください —_physics_process/_integrate_forcesを使用してください。- プレイヤースクリプト内で UI のライフバーを絶対に結合しないでください —
health_changedを発行し、HUD 側で受信してください。 - 死亡したエンティティの CollisionShapes を絶対に有効なままにしないでください — 死亡時に
set_deferred("disabled", true)を実行してください。 - CollisionShapes を絶対に不均等にスケールしないでください — ノードのトランスフォームではなく、形状リソース(
radius、size)をスケールしてください。 - 基本戦闘ステータスにインスタンス化したノードを絶対に使わないでください —
Resource/RefCountedのコンテナを優先し、インスタンスごとにduplicate()してください。 - 高頻度で使う状態名に標準文字列を絶対に使わないでください —
StringName(&"attacking")を優先してください。 - 共有 Resource のステータスに対して
duplicate()を絶対に忘れないでください — テンプレートを共有すると、ヘルスプールも共有されます。
基本手順(必須)
- damage_data.gd — ダメージの種類を表す
enum/フラグを備えた、型付きのDamageDataResource(String 要素は使用しません)。 - health_component.gd —
take_damage、無敵時間のゲート、health_changed/diedシグナル。 - hitbox_hurtbox.gd / hitbox_component.gd — Area によるヒットボックスからヒットボックス受けへのダメージ伝達。
- combat_system_patterns.gd — ダックタイピング、ヒットストップ、ノードを使わない範囲攻撃、フレーム同期。
シーン内に Hitbox/Health/Combo/Ability のチュートリアルを再度インラインで記述しないでください。アビリティは godot-ability-system に振り分け、godot-composition に従ってコンポーネントを組み合わせ、FSM には godot-state-machine-advanced を使用してください。
判断ツリー
| タスク | 読み込むもの | 読み込まないもの |
|---|---|---|
| ダメージペイロードを定義する | damage_data.gd | String の damage_type フィールド |
| HP と無敵時間 | health_component.gd | 直接の health -= n |
| 近接攻撃/飛び道具の判定領域 | hitbox_hurtbox.gd / hitbox_component.gd | 常時監視する Area |
| 範囲攻撃/ヒットストップ/ダックタイピング | combat_system_patterns.gd | ティックごとに一時的な Area を生成すること |
| アビリティのクールダウン/スキルバー | godot-ability-system | ここに AbilityManager の長大な解説をインラインで記述すること |
| コンボバッファー | godot-input-handling + ステートマシン | _input にヒット判定ロジックを埋め込むこと |
ダメージタイプの契約(絶対にしてはいけないことに準拠)
# From damage_data.gd — prefer this shape everywhere
enum DamageType { PHYSICAL = 1, FIRE = 2, ICE = 4, LIGHTNING = 8, POISON = 16 }
@export_flags("Physical", "Fire", "Ice", "Lightning", "Poison")
var damage_types: int = DamageType.PHYSICAL
ヒットボックスは DamageData(または同じフラグから構築した同等の AttackData)を渡す必要があります。"Physical" 文字列を渡してはいけません。
利用可能なスクリプト
- damage_data.gd — 必須 DamageData リソースとタイプフラグ。
- health_component.gd — 必須 Health と無敵時間の基本パターン。
- hitbox_hurtbox.gd — Area の戦闘処理を接続する前に必須。
- hitbox_component.gd — 3D Area のヒットボックス用コンパニオン(フラグに準拠)。
- combat_system_patterns.gd — AoE/ヒットストップ/ダックタイピングに必須。
- combo_system.gd — ウィンドウ型コンボバッファ(コンボがない場合は読み込まないでください)。
- combat_state.gd — 軽量な戦闘 FSM ゲート。
- damage_popup.gd — ダメージラベルを浮かび上がらせるトゥイーン(本番環境ではプールを使用)。
- combat_logger.gd — 戦闘テレメトリーを JSON でバッチ処理。
- networked_damage_manager.gd — サーバー検証用のダメージ RPC シェル。
- hitbox_visualizer.gd — 衝突デバッグカラーを切り替え。
上級者向けの追加項目(簡潔に)
- 戦闘テレメトリー: combat_logger.gd で JSON のフラッシュをバッチ処理します。
- 権威サーバーによるダメージ処理: networked_damage_manager.gd — クライアントがリクエストし、サーバーが検証します。
- ヒットボックスのデバッグ: hitbox_visualizer.gd と
SceneTree.debug_collisions_hint。 - コンボ/ポップアップ/FSM: combo_system.gd、damage_popup.gd、combat_state.gd。
テレメトリー、ネットワーク経由のヒット、コンボ、およびインラインチュートリアルを移動した場合は必須です:elite-combat-patterns.md。最初の DamageData と HealthComponent の実装では読み込まないでください。
参考資料
段階的な情報開示: 実装する API(Areas、レイヤー/マスク、Resources、シグナル、タイマー、アニメーションのヒットウィンドウ)の公式ドキュメントだけを確認してください。隣接するシステムを接続する際は関連スキルを開き、関連資料一式を事前にすべて読み込まないでください。
公式ドキュメント
- Area2D の使用 — ヒットボックス/ハートボックスを使った戦闘では、CharacterBody の移動クエリではなく、Area の重なり検出(
area_entered/監視)を使用します。 - 物理の概要 — ヒット判定のフィルタリングにはコリジョンレイヤー/マスクを優先してください。グループは処理速度が遅く、高頻度の戦闘処理で物理マスクの代わりにはなりません。
- Area2D — 2D のヒット領域では、
monitoring/monitorable、area_entered、チーム/勢力のフィルタリング用のレイヤー/マスクビットを使用します。 - Area3D — 3D の
HitboxComponent/ハートボックス領域でも、3D レイヤーとシェイプを使って同じ Area の重なりモデルを使用します。 - CollisionShape2D — 物理サーバーをステップの途中で変更しないよう、攻撃用シェイプの有効/無効には
set_deferred("disabled", …)を使用してください。ノードを不均一にスケールしてはいけません。 - PhysicsShapeQueryParameters3D — 一時的な Area ノードを生成せずに、
PhysicsDirectSpaceState3Dのintersect_shapeを使って、ノードを必要としない範囲攻撃/爆発を実装できます。 - AnimationPlayer — アニメーショントラック(またはメソッド呼び出し)からヒットボックスの有効時間を制御し、攻撃が常時監視状態にならないようにします。
- リソース —
DamageData/戦闘ステータスはデータ(Resource/RefCounted)として保持し、共有テンプレートはインスタンスごとにduplicate()して、敵同士で体力プールを共有しないようにします。 - シグナルの使用 —
health_changed/died/ダメージイベントを発行して、プレイヤースクリプトに体力バーを結合せずに、HUD と VFX が購読できるようにします。 - SceneTreeTimer —
Engine.time_scale = 0の後にヒットストップを行う場合は、create_timer(..., ignore_time_scale=true)を使用する必要があります。そうしないと、時間を元に戻すタイマーもワールドとともに停止します。 - Tween — 中断可能なヒット硬直/フラッシュ VFX では、連続してヒットした際にフラッシュアニメーションを重ねるのではなく、Tween を停止して作り直します。
- 高レベルマルチプレイヤー — ダメージ処理はサーバー権威型にします。クライアントがヒットを要求し、サーバーが検証して
@rpc経由で確認した後にtake_damageを適用します。
関連スキル
前提条件
- godot-2d-physics — Area のレイヤー/マスク、
CollisionShape2Dの遅延無効化、スペースクエリは、ヒットボックス/ハートボックスのフィルタリングを支える物理基盤です。 - godot-signal-architecture — 戦闘コンポーネントを UI や AI リスナーから分離できるよう、ダメージ、体力、死亡のシグナルの所有権を明確にする必要があります。
- godot-composition — 戦闘処理を巨大な Character スクリプトに組み込むのではなく、子ノードとして
HealthComponent/HitboxComponentを使う方法を優先してください。 - godot-resource-data-patterns —
DamageData、属性フラグ、戦闘ステータスは Resource/RefCountedデータに保持し、スポーン時に安全にduplicate()してください。
補完
- godot-ability-system — アビリティの解決結果は、このスキルのダメージ/ターゲティングのパイプラインに渡されます。アビリティのメタデータは
DamageDataと分けて管理してください。 - godot-rpg-stats — 防御力、耐性、クリティカル率、修正値のスタックは、体力を書き込む前に
take_damageに渡されます。 - godot-animation-player — 攻撃アニメーションは、コンボのためのヒットボックス有効時間、キャンセルフレーム、硬直を管理します。
- godot-state-machine-advanced — IDLE/ATTACKING/BLOCKING/STUNNED の戦闘状態は、
can_actを制御するキャラクター FSM にまとめます。場当たり的な bool の寄せ集めは避けてください。 - godot-input-handling — コンボバッファーと攻撃アクションは、入力コールバックにヒット処理を埋め込むのではなく、アクションマップから戦闘/コンボシステムを呼び出すようにしてください。
下流/利用側
- godot-monte-carlo-balancer — DamageData、無敵時間、クールダウン、クリティカル曲線を調整可能にした後、モンテカルロシミュレーションで出荷前に DPS/TTK の範囲を検証します。
- godot-multiplayer-networking — 予測ヒット、ラグ補償、権限チェックは、DamageData とサーバー検証 RPC の分離を土台に構築します。
- godot-genre-action-rpg — アクション RPG の戦闘ループは、このスキルを土台として、ヒットボックス、アビリティ、ステータス、進行システムをジャンルに合わせて組み立てます。
マスター
- godot-master — ライブラリのルーターであり、ミラー化されたモジュールのエントリーポイントです。関連スキルの検索や、Domain Skill の編集後に共有スクリプトのミラーを同期するときに使用します。