SuperAPI AI Directory

godot-combat-system

Coding & development

View repository

Updated 10-15 18:28

About this skill

NEVER Do

  • NEVER use direct damage references (target.health -= 10) — Bypass armor, resistances, and i-frames. Always DamageData + 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_flags bitfields. String "physical" violates this skill’s own contract.
  • NEVER use try/catch to validate targets — GDScript has no exceptions. Use has_method(&"take_damage") / is checks.
  • NEVER hardcode hitstun with OS.delay_msec() — Blocks the OS thread. Use tweens / Engine.time_scale + ignore_time_scale timers.
  • 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 / RefCounted containers; 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)

  1. damage_data.gd — typed DamageData Resource with enum / flags for damage types (no String elements).
  2. health_component.gd — take_damage + i-frame gate + health_changed / died signals.
  3. hitbox_hurtbox.gd / hitbox_component.gd — Area hit delivery into hurtboxes.
  4. 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_shape on PhysicsDirectSpaceState3D without 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), and duplicate() 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 = 0 must use create_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 @rpc before applying take_damage.

Related Skills

Prerequisites

  • godot-2d-physics — Area layers/masks, CollisionShape2D deferred 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 / HitboxComponent children over baking combat into a monolithic Character script.
  • godot-resource-data-patterns — DamageData, elemental flags, and combat stats belong in Resource/RefCounted data with safe duplicate() 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_damage before 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.