godot-combat-system

Installation
SKILL.md

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 entitiesset_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.

Installs
296
GitHub Stars
586
First Seen
Feb 10, 2026
godot-combat-system — thedivergentai/gd-agentic-skills