Claude-skill-registry dnd-simple-combat

Manage D&D 5e combat encounters with turn-based mechanics, attack rolls, and HP tracking. This skill should be used when the user requests to start a combat encounter, fight a monster, enter the training arena, or engage in battle with their D&D character.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/dnd-simple-combat" ~/.claude/skills/majiayu000-claude-skill-registry-dnd-simple-combat && rm -rf "$T"
manifest: skills/data/dnd-simple-combat/SKILL.md
source content

D&D Simple Combat System

Overview

Orchestrate D&D 5th Edition combat encounters in a training arena setting. Handle equipment assignment, monster selection, initiative rolls, turn-based combat with attack and damage rolls, and post-combat healing. Combat follows 5e rules for attack resolution (d20 + bonus vs AC) and supports multiple end conditions (victory, defeat, flee, surrender).

Available Scripts

Access five Python scripts in the

scripts/
directory:

  1. roll_dice.py - Dice rolling (copied from Tutorial 1)
  2. character.py - Character management (copied from Tutorial 2)
  3. bestiary.py - Monster database management
  4. equipment.py - Equipment and AC calculation
  5. combat.py - Combat mechanics and turn resolution

Combat Workflow

Follow this workflow when conducting a training arena combat encounter:

Step 1: Seed Bestiary (First Time Only)

On first use, seed the bestiary database with initial monsters:

python3 ~/.claude/skills/dnd-simple-combat/scripts/bestiary.py seed

This adds Goblin and Skeleton (CR 1/4) to the bestiary.

Step 2: Check Character Equipment

Before combat, verify the character has equipment:

python3 ~/.claude/skills/dnd-simple-combat/scripts/equipment.py show CHARACTER_NAME

If no equipment found, equip starting gear based on their class:

python3 ~/.claude/skills/dnd-simple-combat/scripts/equipment.py equip CHARACTER_NAME CLASS_NAME

Starting equipment by class:

  • Fighter: Chain mail (AC 16), longsword (1d8+STR), shield (+2 AC)
  • Wizard: No armor (AC 10+DEX), quarterstaff (1d6+STR)
  • Rogue: Leather armor (AC 11+DEX), shortsword (1d6+DEX)
  • Cleric: Chain mail (AC 16), mace (1d6+STR), shield (+2 AC)

Step 3: Start Combat

Initialize the combat encounter:

python3 ~/.claude/skills/dnd-simple-combat/scripts/combat.py start CHARACTER_NAME MAX_CR

MAX_CR calculation: Use

character_level / 4
as a guideline. Level 1 character = CR 0.25.

This command outputs JSON containing:

  • Character stats (HP, AC, weapon, DEX modifier)
  • Selected monster stats (HP, AC, attack, abilities)
  • Initiative rolls for both combatants
  • Who goes first ("character" or "monster")

Parse this JSON and display the combat start state to the user in narrative form:

You enter the training arena and face a Goblin!

Initiative:
  - You rolled 14 (total: 16)
  - Goblin rolled 11 (total: 13)

You go first!

Combat State:
  - CHARACTER_NAME: 11/11 HP, AC 18
  - Goblin: 7/7 HP, AC 15

Step 4: Combat Loop

Execute turns in initiative order. Continue until an end condition is met.

Character's Turn

Ask the user what they want to do:

  • Attack: Proceed with attack roll
  • Flee: Attempt to escape (DEX check or auto-succeed, designer's choice)
  • Surrender: End combat as defeat

To execute an attack:

python3 ~/.claude/skills/dnd-simple-combat/scripts/combat.py character-attack CHARACTER_NAME MONSTER_NAME MONSTER_AC MONSTER_HP

The command outputs JSON with:

  • Attack roll (natural d20)
  • Attack bonus and total
  • Whether it hit
  • Whether it was a critical hit
  • Damage dealt (if hit)
  • Monster's HP before and after

Parse and narrate the results:

You swing your longsword at the Goblin!
  Attack roll: 15 + 4 = 19 vs AC 15
  Hit! Damage: 6 slashing

The Goblin now has 1/7 HP remaining.

On critical hit (natural 20), emphasize it in the narrative:

CRITICAL HIT! You roll damage twice!
  Damage: 12 slashing

Monster's Turn

The monster always attacks (simple AI). Execute the monster's attack:

python3 ~/.claude/skills/dnd-simple-combat/scripts/combat.py monster-attack MONSTER_NAME MONSTER_ATTACK_BONUS MONSTER_DAMAGE CHARACTER_NAME CHARACTER_AC

The command outputs JSON with:

  • Attack roll results
  • Damage dealt (if hit)
  • Character's HP before and after

The character's HP is automatically updated in the database.

Parse and narrate:

The Goblin slashes at you with its scimitar!
  Attack roll: 12 + 4 = 16 vs AC 18
  Miss!

Or if it hits:

The Goblin slashes at you with its scimitar!
  Attack roll: 16 + 4 = 20 vs AC 18
  Hit! Damage: 5 slashing

You now have 6/11 HP remaining.

Check End Conditions

After each turn, check if combat should end:

  1. Monster HP ≤ 0: Victory
  2. Character HP ≤ 0: Defeat
  3. Character fled: Escaped
  4. Character surrendered: Defeat

If no end condition met, continue to next turn in initiative order.

Step 5: End Combat

When combat ends, call the end combat command:

python3 ~/.claude/skills/dnd-simple-combat/scripts/combat.py end CHARACTER_NAME OUTCOME

OUTCOME must be one of:

victory
,
defeat
,
fled

On victory or fled: Character is automatically healed to full HP.

On defeat: Character HP remains at 0 (or current value). No death saves in this tutorial - just narrative defeat.

Narrate the outcome:

Victory! The Goblin falls to the ground, defeated.
You have been fully healed and are ready for your next challenge.

Final HP: 11/11

Equipment Management Commands

Show Equipment

python3 ~/.claude/skills/dnd-simple-combat/scripts/equipment.py show CHARACTER_NAME

Calculate AC

python3 ~/.claude/skills/dnd-simple-combat/scripts/equipment.py ac CHARACTER_NAME

Outputs just the AC number.

Get Weapon Stats

python3 ~/.claude/skills/dnd-simple-combat/scripts/equipment.py weapon CHARACTER_NAME

Outputs JSON with weapon name, damage dice, attack bonus, and ability modifier.

Bestiary Management Commands

List All Monsters

python3 ~/.claude/skills/dnd-simple-combat/scripts/bestiary.py list

List Monsters by Max CR

python3 ~/.claude/skills/dnd-simple-combat/scripts/bestiary.py list --max-cr 0.5

Show Monster Details

python3 ~/.claude/skills/dnd-simple-combat/scripts/bestiary.py show MONSTER_NAME

Add New Monster

python3 ~/.claude/skills/dnd-simple-combat/scripts/bestiary.py add NAME CR 'JSON_STAT_BLOCK'

JSON stat block format:

{
    "ac": 15,
    "hp_dice": "2d6",
    "hp_avg": 7,
    "abilities": {
        "str": 8, "dex": 14, "con": 10,
        "int": 10, "wis": 8, "cha": 8
    },
    "attack": {
        "name": "Weapon Name",
        "bonus": 4,
        "damage_dice": "1d6+2",
        "damage_type": "slashing"
    }
}

Combat Rules Reference (5e)

Initiative

  • Roll d20 + DEX modifier
  • Higher total goes first
  • On tie, higher DEX goes first (or re-roll)

Attack Rolls

  • Roll d20 + proficiency bonus + ability modifier
  • Compare to target's AC
  • Meet or exceed AC = hit
  • Natural 20 = automatic critical hit (roll damage dice twice)
  • Natural 1 = automatic miss

Damage Rolls

  • Roll weapon damage dice + ability modifier
  • On critical hit, roll damage dice twice, then add modifier once
  • Subtract damage from target's current HP

Proficiency Bonus by Level

  • Levels 1-4: +2
  • Levels 5-8: +3
  • Levels 9-12: +4
  • Levels 13-16: +5
  • Levels 17-20: +6

AC Calculation

  • Unarmored: 10 + DEX modifier
  • Light armor (e.g., leather): Base AC + full DEX modifier
  • Heavy armor (e.g., chain mail): Base AC only (no DEX)
  • Shield: +2 AC bonus (stacks with armor)

Important Notes

  • Database location:
    ~/.claude/data/dnd-dm.db
  • Monster HP is rolled fresh each combat (using hp_dice)
  • Character HP is tracked persistently and updated in database
  • Character automatically heals to full after victory or fleeing
  • All combat scripts output JSON for easy parsing
  • Initiative ties default to character going first (or use DEX as tiebreaker)

Error Handling

Handle these common errors gracefully:

  • Character not found: Suggest using
    character.py list
    to see available characters
  • No equipment: Automatically equip starting gear for character's class
  • Bestiary empty: Run
    bestiary.py seed
    to add initial monsters
  • No monsters at CR: Suggest lowering max_cr or adding monsters with
    bestiary.py add

Radio Drama Narrative Style

Present combat as a radio drama - paint vivid pictures with words so the listener can see, hear, and feel the action. Act as a Dungeon Master bringing the scene to life.

Combat Opening (Step 3 - Start Combat)

Create atmosphere using the combat data:

Set the Scene:

  • Describe the training arena environment (torchlight, weapon racks, sand underfoot)
  • Build anticipation as the character enters
  • Reveal the monster dramatically based on its type and CR

Monster Introduction:

  • Use the monster's stats to inform description (high DEX = quick/agile, high STR = hulking/powerful)
  • Describe appearance, movement, demeanor
  • Create personality (Goblin = cunning/nasty, Skeleton = relentless/hollow, Zombie = shambling/groaning, Orc = fierce/aggressive)

Initiative Drama:

  • Describe the tense moment before combat begins
  • Use initiative rolls to narrate who strikes first and WHY (high roll = lightning reflexes, low roll = caught off guard)
  • Build tension: "Who will strike first?"

Example Opening:

⚔️  TRAINING ARENA ⚔️

The heavy wooden doors creak open, and Bob steps into the torch-lit arena.
Sand crunches beneath his boots. The air smells of sweat and steel.

From the shadows across the arena, a hunched figure emerges—a Goblin!
Its yellow eyes gleam with malicious intelligence as it draws a wicked
curved scimitar. The creature cackles, crouching low,ready to pounce.

The tension is palpable. Both warriors eye each other, muscles coiled...

Initiative:
- Bob rolled 15 + 1 (DEX) = 16
- Goblin rolled 20 + 2 (DEX) = 22

The Goblin EXPLODES into motion with startling speed! Bob barely has time
to raise his shield before the creature is upon him!

Combat State:
- Bob: 11/11 HP, AC 18 - Armored and ready
- Goblin: 11/11 HP, AC 15 - Fast and dangerous

During Combat (Step 4 - Combat Loop)

Attack Declarations: Describe the action BEFORE showing the dice roll:

  • Character positioning and movement
  • Weapon grip, stance, facial expression
  • Intent (desperate, calculated, furious)
  • Environmental details (dust kicked up, torchlight glinting on steel)

Attack Results - HITS:

  • Describe the impact viscerally (blade biting flesh, crunch of bone, spray of blood)
  • Monster/character reactions (howl of pain, grimace, stagger)
  • Use damage amount to inform severity (1-3 dmg = glancing, 4-7 = solid hit, 8+ = devastating)
  • Show HP changes dramatically ("The Goblin's knees buckle!" for low HP)

Attack Results - MISSES:

  • Never say just "miss" - describe WHY
    • Armor deflection: "The blade skitters off chain mail"
    • Dodge: "The Goblin twists aside at the last instant"
    • Parry: "Metal rings against metal as weapons clash"
    • Near-miss: "The sword whistles past, missing by inches"
  • Build tension with close calls

Critical Hits:

  • MAXIMUM DRAMA
  • Slow down time, describe the perfect opening
  • Epic impact description
  • Use dramatic formatting (⚡💥🔥)

HP Status Narration:

  • 75-100% HP: Fresh, confident, strong
  • 50-74% HP: Bloodied, breathing hard, determined
  • 25-49% HP: Wounded, desperate, fighting for survival
  • 1-24% HP: Barely standing, eyes wild, on death's door
  • 0 HP: Describe the fall, the final moment

Vary Your Language: Avoid repetition. Use synonyms and varied sentence structure:

  • Attack verbs: swing, slash, thrust, strike, lunge, cleave, drive, plunge
  • Movement: dodge, weave, duck, sidestep, roll, leap, pivot
  • Sounds: clang, ring, thud, crack, whistle, crunch, scrape
  • Sensory: flash of steel, spray of blood, cloud of dust, bitter tang of fear

Victory/Defeat (Step 5 - End Combat)

Victory:

  • Describe the killing blow in detail
  • Monster's final moment (collapse, dissolve, shatter based on type)
  • Character's reaction (relief, triumph, exhaustion)
  • Transition to healing with a moment of peace

Defeat:

  • Describe the character overwhelmed
  • Respectful narration of loss
  • Focus on the lesson learned

Example Victory:

Bob sees his opening—the Goblin overextends on a wild slash. He pivots,
bringing his longsword down in a brutal overhead chop!

🎲 Attack roll: 19 + 5 = 24 vs AC 15
💥 DEVASTATING HIT!

The blade cleaves through the Goblin's collarbone with a sickening CRUNCH.
The creature's eyes go wide, its scimitar clattering to the sand. It
crumples, twitching once, then still.

Silence falls over the arena. Bob lowers his sword, chest heaving. Victory.

🏆 The battle is won! Golden light washes over Bob as his wounds close.
He stands ready for whatever comes next.

Final Status: Bob 11/11 HP - Victorious and renewed!

Important Guidelines

  1. Always show dice rolls - Transparency builds trust
  2. Status updates after every action - Clear HP tracking
  3. Pacing - Short sentences for action, longer for atmosphere
  4. Emotion - Characters should feel fear, determination, relief
  5. Consistency - Match narrative tone to monster type (Goblin = scrappy, Skeleton = eerie, Zombie = relentless, Orc = brutal)
  6. Player agency - Make the player character feel heroic, skilled, and in control of their choices