Skip to main content
combat-basics is a skill from the Summer skill library: a guide your AI agent reads when the task matches, so it builds the good version on the first try. Damage: hitbox and hurtbox Areas, a reusable Health component, damage signals, knockback, projectiles.

When your agent uses it

  • Adding attacks, health and damage, or enemies that can be hit and hit back
  • Adding projectiles or bullets — homing, piercing, area-of-effect, or pooling hundreds of them
  • Wiring death and respawn, or debugging hits that never land or friendly fire

Install

summer setup installs every skill for your agent. To add only this one:
Swap claude-code for your agent, such as codex or cursor. See Skills for every option.

The skill

The standard combat pattern is hitbox + hurtbox + health, wired by signals. Build it component-first: the same three pieces work for player, enemies, and destructibles.

The layer model (set this up first)

Attacks are Area2D/Area3D, not solid bodies. A hitbox (the attack) detects a hurtbox (the thing that can be hurt) via collision layers/masks: Rule: every combat Area masks only the OPPOSING side. This is why the player’s sword never damages the player. An Area reports area_entered only for areas on a layer in its OWN mask, so the hurtbox below (which listens) must mask the opposing hitbox layer; a hurtbox with an empty mask never registers a hit. Name the layers once so you are not counting bits by hand — summer_project_setting(key="layer_names/2d_physics/layer_4", value="PlayerHit") (use layer_names/3d_physics/... for 3D), one call per layer.

Health component (reuse everywhere)

Attach to any damageable node. It owns HP and fires signals; UI and death logic just listen.

Hurtbox -> Health

The hurtbox is an Area on the body; when a hitbox overlaps it, read the hitbox’s damage and route it to the Health node.

Hitbox

Enable the hitbox only during the active frames of a swing (toggle monitoring/monitorable or the CollisionShape’s disabled), driven by an AnimationPlayer track. An always-on melee hitbox hits on touch, which feels wrong.

Death, knockback, feedback

  • On died: queue_free(), spawn a death VFX, drop loot, add_kill() on your game manager. For the player, switch to a GAME_OVER state instead of freeing.
  • Knockback: push the victim velocity = (victim.global_position - attacker.global_position).normalized() * force, decay it each frame.
  • Every hit needs feedback or it reads as broken: a flash (modulate to white for 0.05s), a damage number (floating Label), a small screen shake, a hitstop (Engine.time_scale = 0.05 for one frame). Silent damage feels like a no-op.

Projectiles (short version)

An Area2D/3D that moves forward and calls take_damage on what it hits, then frees itself.
Homing, piercing, AoE, and pooling many bullets are in this skill’s references/projectiles-and-aoe.md — read it only when you need one of those.

Traps

  • Hitbox on the wrong layer/mask = no hits or friendly fire. Verify the layer table above before debugging the scripts.
  • Two Areas with neither monitoring nor monitorable never report overlap.
  • Freeing a node mid-signal can error - defer with queue_free() (safe), not free().
  • Damaging in _process instead of on overlap = continuous per-frame damage.

Applying it in Summer Engine

  • Scripts (health.gd, hurtbox.gd, hitbox.gd, projectile.gd) are files: create with summer_write_file(path=..., content=..., create_only=true), change with summer_replace_text. Check each with summer_get_script_errors.
  • Nodes (the Area, its CollisionShape, the Health child) are scene mutations: summer_add_node / summer_set_prop with scenePath, or one summer_batch with AddNode / SetProp ops so the scene saves once. Set collision_layer and collision_mask as integers (bit values), not layer names.
  • Prove a hit with a RunVerification probe (see playtesting-a-feature): spawn or find one enemy, press the attack action, report() the enemy’s Health.current before and after. A static scene check cannot show that a hit registered.

From a shell

No Summer MCP tools in this session? Run each one as a command; when summer --version is missing or below 4.0, use npx -y summer-engine@latest in place of summer. Fields are flags in kebab-case (--scene-path res://main.tscn) or one --input '<json>', and summer ops describe <op> prints the exact input. The summer-cli skill has the rest.

Files in this skill

  • make-game: Orchestrate ‘make me a game’: brainstorm, plan, scaffold, mechanics, art, audio, polish, verify, ship.
  • character-movement: Player controllers for 2D and 3D, plus the standard third-person controller for Summer humanoids.
  • game-feel: Add juice: hit-flash, trauma camera shake and audio ducking, one hit fires all three.
  • auto-fire-targeting: Fix auto-fire targeting (survivors, ARPG, tower defense) with pending damage to stop overkill.
  • design-npc: Design enemy, NPC, boss or companion behavior: perception, state machine, telegraphs, script stub.

Source: library/skills/combat-basics/SKILL.md, rendered from summer-engine@4.3.0 on npm.