@thedivergentai/godot-combat-system
Expert patterns for combat systems including hitbox/hurtbox architecture, damage calculation (DamageData class), health components, combat state machines, combo systems, ability cooldowns, and damage popups. Use for action games, RPGs, or fighting games. Trigger keywords: Hitbox, Hurtbox, DamageData, HealthComponent, combat_state, combo_system, ability_cooldown, invincibility_frames, damage_popup.
| name | godot-combat-system |
| description | Expert patterns for combat systems including hitbox/hurtbox architecture, damage calculation (DamageData class), health components, combat state machines, combo systems, ability cooldowns, and damage popups. Use for action games, RPGs, or fighting games. Trigger keywords: Hitbox, Hurtbox, DamageData, HealthComponent, combat_state, combo_system, ability_cooldown, invincibility_frames, damage_popup. |
NEVER Do
- NEVER use direct damage references (
target.health -= 10) — Bypass armor, resistances, and i-frames. AlwaysDamageData+HealthComponent.take_damage. - NEVER forget invincibility frames (i-frames) — Multi-hit shapes otherwise tick every physics frame. Apply a short invuln window after a successful hit.
- NEVER keep hitboxes active permanently — Enable/disable with AnimationPlayer tracks or timed code; permanent monitoring causes ghost hits.
- NEVER use groups for physics-based hit filtering — Prefer collision layers/masks (C++ filter). Groups are secondary logic, not the physics gate.
- NEVER emit damage signals without a DamageData object — Raw numbers lose type, source, knockback, and crit context.
- NEVER use raw strings for elemental damage types — Use
enum/@export_flagsbitfields. String"physical"violates this skill’s own contract. - NEVER use try/catch to validate targets — GDScript has no exceptions. Use
has_method(&"take_damage")/ischecks. - NEVER hardcode hitstun with
OS.delay_msec()— Blocks the OS thread. Use tweens /Engine.time_scale+ignore_time_scaletimers. - NEVER apply RigidBody impulses in
_process()— Use_physics_process/_integrate_forces. - NEVER couple UI lifebars inside the Player script — Emit
health_changed; HUD listens. - NEVER leave CollisionShapes active on dead entities —
set_deferred("disabled", true)on death. - NEVER scale CollisionShapes non-uniformly — Scale the shape resource (
radius,size), not the node transform unevenly. - NEVER use instanced Nodes for base combat stats — Prefer
Resource/RefCountedcontainers;duplicate()per instance. - NEVER use standard strings for high-frequency state names — Prefer
StringName(&"attacking"). - NEVER forget
duplicate()on shared Resource stats — Shared templates = shared health pools.
Golden Path (MANDATORY)
- damage_data.gd — typed
DamageDataResource withenum/ flags for damage types (no String elements). - health_component.gd —
take_damage+ i-frame gate +health_changed/diedsignals. - hitbox_hurtbox.gd / hitbox_component.gd — Area hit delivery into hurtboxes.
- combat_system_patterns.gd — duck-typing, hit-stop, nodeless AoE, frame sync.
Do NOT re-inline Hitbox/Health/Combo/Ability tutorials in scenes. Route abilities to godot-ability-system; compose components per godot-composition; FSMs via godot-state-machine-advanced.
Decision Tree
| Task | Load | Do NOT Load |
|---|---|---|
| Define damage payload | damage_data.gd | String damage_type fields |
| HP + i-frames | health_component.gd | Direct health -= n |
| Melee/projectile volumes | hitbox_hurtbox.gd / hitbox_component.gd | Permanent monitoring Areas |
| AoE / hit-stop / duck-type | combat_system_patterns.gd | Spawn temp Areas every tick |
| Ability cooldowns / skill bar | godot-ability-system | Inline AbilityManager novels here |
| Combo buffers | godot-input-handling + state machine | Embedding hit logic in _input |
Damage Type Contract (aligned with NEVER)
# 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
Hitboxes must pass DamageData (or equivalent AttackData built from the same flags), never "Physical" strings.
Available Scripts
- damage_data.gd — MANDATORY DamageData Resource + type flags.
- health_component.gd — MANDATORY Health + i-frames golden path.
- hitbox_hurtbox.gd — MANDATORY before Area combat wiring.
- hitbox_component.gd — 3D Area hitbox companion (flags-aligned).
- combat_system_patterns.gd — MANDATORY for AoE / hit-stop / duck-typing.
- combo_system.gd — windowed combo buffer (Do NOT Load if no combos).
- combat_state.gd — lightweight combat FSM gate.
- damage_popup.gd — floating damage label tween (pool in production).
- combat_logger.gd — batched combat telemetry JSON.
- networked_damage_manager.gd — server-validate damage RPC shell.
- hitbox_visualizer.gd — toggle collision debug colors.
Elite Deltas (keep short)
- Combat telemetry: batch JSON flushes via combat_logger.gd.
- Authoritative damage: networked_damage_manager.gd — clients request; server validates.
- Hitbox debug: hitbox_visualizer.gd +
SceneTree.debug_collisions_hint. - Combos / popups / FSM: combo_system.gd, damage_popup.gd, combat_state.gd.
MANDATORY for telemetry, networked hits, combos, and moved inline tutorials: elite-combat-patterns.md. Do NOT Load for first DamageData + HealthComponent pass.
Reference
Progressive disclosure: Skim Official Documentation only for the APIs you are implementing (Areas, layers/masks, Resources, signals, timers, animation hit windows). Open Related Skills when wiring adjacent systems—do not preload the whole lattice.
Official Documentation
- Using Area2D — Hitbox/hurtbox combat is Area overlap detection (
area_entered/ monitoring), not CharacterBody movement queries. - Physics introduction — Prefer collision layers/masks for hit filtering; groups are slower and do not replace physics masks for high-frequency combat.
- Area2D — 2D hit volumes:
monitoring/monitorable,area_entered, and layer/mask bits for team/faction filtering. - Area3D — 3D
HitboxComponent/ hurtbox volumes use the same Area overlap model with 3D layers and shapes. - CollisionShape2D — Enable/disable attack shapes with
set_deferred("disabled", …)so the physics server is not mutated mid-step; never non-uniform-scale the node. - PhysicsShapeQueryParameters3D — Nodeless AoE/explosions via
intersect_shapeonPhysicsDirectSpaceState3Dwithout spawning temporary Area nodes. - AnimationPlayer — Drive hitbox active windows from animation tracks (or method calls) so attacks are not permanently monitoring.
- Resources — Keep
DamageData/ combat stats as data (Resource/RefCounted), andduplicate()shared templates per instance so enemies do not share one health pool. - Using signals — Emit
health_changed/died/ damage events so HUD and VFX subscribe without coupling lifebars into the player script. - SceneTreeTimer — Hit-stop after
Engine.time_scale = 0must usecreate_timer(..., ignore_time_scale=true)or the thaw timer freezes with the world. - Tween — Interruptible hitstun/flash VFX: kill and recreate tweens on consecutive hits instead of stacking parallel flash animations.
- High-level multiplayer — Authoritative damage: clients request hits; the server validates and confirms via
@rpcbefore applyingtake_damage.
Related Skills
Prerequisites
- godot-2d-physics — Area layers/masks,
CollisionShape2Ddeferred disable, and space queries are the physics substrate under hitbox/hurtbox filtering. - godot-signal-architecture — Damage, health, and death signals need clear ownership so combat components stay decoupled from UI and AI listeners.
- godot-composition — Prefer
HealthComponent/HitboxComponentchildren over baking combat into a monolithic Character script. - godot-resource-data-patterns —
DamageData, elemental flags, and combat stats belong in Resource/RefCounteddata with safeduplicate()on spawn.
Complements
- godot-ability-system — Abilities resolve into this skill’s damage/targeting pipeline; keep ability metadata separate from
DamageData. - godot-rpg-stats — Armor, resistances, crit chance, and modifier stacks feed
take_damagebefore health is written. - godot-animation-player — Attack animations own hitbox enable windows, cancel frames, and recovery locks for combos.
- godot-state-machine-advanced — IDLE/ATTACKING/BLOCKING/STUNNED combat states belong in a character FSM that gates
can_act, not ad-hoc bool soup. - godot-input-handling — Combo buffers and attack actions should call into combat/combo systems from the action map rather than embedding hit logic in input callbacks.
Downstream / consumers
- godot-monte-carlo-balancer — After DamageData, i-frames, cooldowns, and crit curves are tunable, Monte Carlo sims prove DPS/TTK bands before shipping difficulty.
- godot-multiplayer-networking — Predicted hits, lag compensation, and authority checks build on the DamageData + server-validate RPC split.
- godot-genre-action-rpg — Action-RPG combat loops assemble hitboxes, abilities, stats, and progression genre glue on top of this skill.
Master
- godot-master — Library router and mirrored module entry; use when discovering peer skills or syncing shared script mirrors after Domain Skill edits.
Loading...
Select a file to preview
Analyzing security...
Checking scan reports and verification data.
Bill of Materials
Everything this skill can do — files, network, commands, and more.