Combat Systems Design
Learning Objectives: By the end of this lesson, you will be able to:
- Design balanced and engaging combat mechanics
- Create damage formulas that produce meaningful player choices
- Implement combat design patterns like rock-paper-scissors and risk-reward
- Balance action economy for turn-based and real-time combat
- Analyze and improve existing combat systems
1. Welcome and Introduction (5 minutes)
Icebreaker Activity
Think of the last combat encounter you found truly satisfying in a game. What made it memorable? Was it the challenge? The spectacle? The strategy? The feeling of power? Now think of a combat system you found boring or frustrating. What was different?
Combat is where many games succeed or fail, yet it’s often designed by intuition rather than intentional systems thinking.
Lesson Overview
- Duration: 120-150 minutes
- Prerequisites: Lessons 1-3 (MDA, Core Loops, Feedback)
- Materials Needed: Spreadsheet software, calculator, access to games for analysis
2. Learning Objectives and Session Outline (5 minutes)
What We’ll Cover Today:
- Combat Fundamentals - What makes combat engaging
- Action Economy - Managing what players can do
- Damage Systems - Formulas and calculations
- Combat Patterns - Rock-paper-scissors, risk-reward, positioning
- Balance Techniques - Testing and iterating combat numbers
- Case Studies - Learning from successful combat systems
Success Criteria:
By the end of this session, you should be able to design and balance a basic combat system with damage formulas, meaningful choices, and clear counterplay.
3. Foundation Knowledge (15-20 minutes)
Core Concepts
What Makes Combat Engaging?
Combat systems succeed when they create:
- Agency: Players feel their choices matter
- Tension: Stakes feel real, outcomes uncertain
- Mastery: Skill improvement is visible and rewarded
- Variety: Different approaches remain viable
- Feedback: Actions feel impactful and satisfying
Real-World Analogy: Good combat is like chess, not coin flipping. Every move should matter, create new possibilities, and require thought. But unlike chess, it should also feel exciting.
Why This Matters:
- Combat is often 60-80% of gameplay time
- Bad combat drives players away regardless of other qualities
- Great combat creates moments players remember and share
Types of Combat Systems
| Type | Examples | Key Characteristics |
|---|---|---|
| Real-time Action | Dark Souls, Devil May Cry | Timing, reflexes, positioning |
| Turn-based | Final Fantasy, XCOM | Strategy, planning, resource management |
| Real-time Strategy | StarCraft, Total War | Macro/micro management, economy |
| Card-based | Hearthstone, Slay the Spire | Deck building, hand management |
| Hybrid | Active Time Battle, Baldur’s Gate 3 | Elements of multiple types |
Key Terminology
- Action Economy: What actions players can take per turn/time period
- DPS (Damage Per Second): Damage output over time
- TTK (Time To Kill): How long to defeat a target
- Burst vs Sustained: High damage now vs consistent damage over time
- Counterplay: Options opponents have to respond to strategies
- Tech: Unintended but skillful use of mechanics
4. Detailed Explanation and Examples (25-30 minutes)
Action Economy
Action economy governs what players can do and when. It’s the foundation of tactical combat.
Turn-Based Action Economy
In XCOM, each soldier has 2 actions:
- Move + Move = Maximum distance
- Move + Shoot = Medium distance, one attack
- Shoot + (nothing) = Stay still, guaranteed shot
- Special Ability = Often uses both actions
This creates choices:
- Do I maximize damage (shoot) or positioning (move)?
- Do I play safe or aggressive?
- Do I use my special now or save it?
Design Principles:
- Actions should compete with each other
- No single action should always be optimal
- Context should change which action is best
- Some actions should be commitments (using both action points)
Real-Time Action Economy
In Dark Souls, stamina governs actions:
- Attack: Costs stamina
- Dodge: Costs stamina
- Block: Drains stamina on hit
- Sprint: Costs stamina
- Stamina regenerates when not acting
This creates choices:
- Can I afford to attack, or do I need stamina to dodge?
- Do I block this attack or dodge it?
- Do I finish the combo or save stamina for escape?
Design Principles:
- Resource should recover (or combat stalls)
- Different actions should have different costs
- Running out should be dangerous but not instant death
- Aggressive and defensive options should compete
Damage Systems
Basic Damage Formula
The simplest formula:
Damage = Attack Power - Defense
Problems:
- Defense can reduce damage to 0 or negative
- Scaling is unpredictable
- Small stat changes have outsized effects
Percentage-Based Reduction
Damage = Attack Power × (100 / (100 + Defense))
Examples:
100 Attack vs 0 Defense = 100 × (100/100) = 100 damage
100 Attack vs 50 Defense = 100 × (100/150) = 66.7 damage
100 Attack vs 100 Defense = 100 × (100/200) = 50 damage
100 Attack vs 200 Defense = 100 × (100/300) = 33.3 damage
Benefits:
- Defense always reduces damage but never eliminates it
- Diminishing returns on stacking defense
- Predictable scaling
Multi-Factor Damage Formula
Real games use multiple factors:
Final Damage = Base Damage
× Attack Multiplier
× Type Multiplier
× Critical Multiplier
× (100 / (100 + Defense))
× Random Variance
Where:
- Base Damage: Weapon/skill base value
- Attack Multiplier: 1 + (Strength / 100) or similar
- Type Multiplier: 0.5, 1.0, or 2.0 for elemental matchups
- Critical Multiplier: 1.0 normally, 1.5-2.0 on crit
- Defense: As above
- Random Variance: 0.85-1.0 for slight randomness
Designing Damage Curves
Level Scaling Considerations:
Level 1 player vs Level 1 enemy:
100 Attack × (100/(100+50)) = 66.7 damage
Enemy has 200 HP = 3 hits to kill
Level 50 player vs Level 50 enemy:
500 Attack × (100/(100+250)) = 142.9 damage
Enemy has 1000 HP = 7 hits to kill
Problem: Higher levels = more hits needed!
Solution: Scale attack faster than defense, or keep ratios consistent
Combat Design Patterns
Rock-Paper-Scissors
Create counter relationships to prevent dominant strategies:
ARMOR
↗ ↘
beats loses to
↑ ↓
MAGIC ←───→ SPEED
loses to / beats
Implementation:
- Armored units: High defense, slow, weak to magic
- Magic units: Bypass armor, fragile, weak to fast attacks
- Fast units: Strike first, dodge, weak to armored units
Design Tips:
- Pure RPS is solved (just counter opponent)
- Add layers: positioning, resources, incomplete information
- Allow hybrid options that don’t perfectly counter anything
Risk-Reward Trade-offs
Every choice should have costs and benefits:
| Action | Reward | Risk |
|---|---|---|
| Heavy Attack | High damage | Long recovery, easy to punish |
| Light Attack | Fast, safe | Low damage |
| Counter | Massive damage on success | Vulnerable if mistimed |
| Defensive Play | Safe | Lose initiative, don’t deal damage |
| All-in Aggression | Win quickly | Lose badly if it fails |
Design Principle: Players should understand the trade-off before committing. No “gotchas.”
Positioning Systems
Add spatial dimensions to create tactical depth:
Flanking:
Front: Normal damage
Side: +25% damage
Rear: +50% damage
Cover:
No Cover: 100% hit chance
Half Cover: 75% hit chance
Full Cover: 50% hit chance
Height:
High Ground: +10% damage, +20% accuracy
Low Ground: -10% damage, -20% accuracy
Zone Control:
Melee Zone: Adjacent enemies can't pass without Opportunity Attack
Control Zone: Enemies in range have reduced accuracy
Common Misconceptions
-
Misconception: “More damage = more fun” Reality: TTK (time to kill) affects pacing. Instant death isn’t satisfying.
-
Misconception: “Randomness is always bad” Reality: Controlled randomness adds variety. Pure determinism is solvable.
-
Misconception: “Balance means everything is equal” Reality: Balance means everything is viable. Options can differ in power if they differ in situational value.
5. Live Coding Demonstration (20-25 minutes)
Example 1: Designing a Basic Combat System
Scenario: Create combat for a turn-based RPG with 3 character classes
Step 1: Define Classes
WARRIOR:
- High HP, High Defense, Medium Attack
- Role: Tank, sustained damage
MAGE:
- Low HP, Low Defense, High Attack
- Role: Burst damage, AoE
ROGUE:
- Medium HP, Low Defense, Medium Attack
- Role: Single target, critical hits
Step 2: Set Base Stats
class_stats = {
'warrior': {'hp': 150, 'attack': 20, 'defense': 30, 'speed': 10},
'mage': {'hp': 80, 'attack': 35, 'defense': 10, 'speed': 15},
'rogue': {'hp': 100, 'attack': 25, 'defense': 15, 'speed': 25}
}
Step 3: Design Damage Formula
def calculate_damage(attacker, defender, skill_power=1.0, crit=False):
base = attacker['attack'] * skill_power
# Critical hit (rogue specialty)
crit_mult = 2.0 if crit else 1.0
# Defense reduction
defense_mult = 100 / (100 + defender['defense'])
# Random variance
import random
variance = random.uniform(0.9, 1.1)
damage = base * crit_mult * defense_mult * variance
return int(damage)
# Test: Warrior vs Mage
warrior = class_stats['warrior']
mage = class_stats['mage']
damage = calculate_damage(warrior, mage)
print(f"Warrior hits Mage for {damage} damage")
# ~18 damage, Mage has 80 HP = ~4-5 hits to kill
damage = calculate_damage(mage, warrior)
print(f"Mage hits Warrior for {damage} damage")
# ~27 damage, Warrior has 150 HP = ~5-6 hits to kill
Step 4: Add Skills
skills = {
'warrior': {
'strike': {'power': 1.0, 'cost': 0},
'power_attack': {'power': 1.8, 'cost': 2, 'self_stun': True},
'defend': {'damage_reduction': 0.5, 'cost': 0}
},
'mage': {
'fireball': {'power': 1.0, 'cost': 1, 'aoe': True},
'pyroblast': {'power': 2.5, 'cost': 3, 'cast_time': 2},
'barrier': {'absorb': 30, 'cost': 2}
},
'rogue': {
'strike': {'power': 1.0, 'cost': 0},
'backstab': {'power': 1.5, 'cost': 1, 'crit_chance': 0.5},
'evade': {'dodge_chance': 0.8, 'cost': 1}
}
}
Example 2: Balancing Time To Kill
Problem: Mage dies too fast, Warrior is too tanky
Analysis:
# Current TTK calculations
def calculate_ttk(attacker, defender, skill_power=1.0):
damage_per_hit = calculate_damage(attacker, defender, skill_power)
return defender['hp'] / damage_per_hit
# TTK Matrix
classes = ['warrior', 'mage', 'rogue']
for attacker_name in classes:
for defender_name in classes:
attacker = class_stats[attacker_name]
defender = class_stats[defender_name]
ttk = calculate_ttk(attacker, defender)
print(f"{attacker_name} vs {defender_name}: {ttk:.1f} hits")
# Results:
# warrior vs warrior: 8.7 hits (too long)
# warrior vs mage: 4.1 hits (fast)
# warrior vs rogue: 5.5 hits (ok)
# mage vs warrior: 5.4 hits (good)
# mage vs mage: 2.3 hits (very fast)
# mage vs rogue: 3.1 hits (fast)
# rogue vs warrior: 6.7 hits (slow)
# rogue vs mage: 3.3 hits (ok)
# rogue vs rogue: 4.4 hits (ok)
Tuning:
# Adjust to target 4-6 hits average
# Increase Mage HP slightly
class_stats['mage']['hp'] = 100 # Was 80
# Reduce Warrior defense slightly
class_stats['warrior']['defense'] = 25 # Was 30
# Increase Rogue attack slightly
class_stats['rogue']['attack'] = 28 # Was 25
Example 3: Fighting Game Frame Data
Design a fighting game attack:
attack_data = {
'jab': {
'startup': 4, # Frames before hitbox active
'active': 2, # Frames hitbox is out
'recovery': 8, # Frames after before can act again
'damage': 20,
'hitstun': 12, # Frames opponent can't act after hit
'blockstun': 8, # Frames opponent can't act after block
'on_hit': +2, # Advantage frames when hitting
'on_block': -2, # Advantage frames when blocked
}
}
# Calculate frame advantage
total_frames = 4 + 2 + 8 # = 14 frames total
# If I hit on frame 5 (first active frame)
# Opponent is in hitstun for 12 frames
# I finish recovery at frame 14
# Opponent recovers at frame 5 + 12 = 17
# I have 17 - 14 = 3 frames advantage (close to on_hit of +2)
# This jab is:
# - Fast (4 frame startup, most moves are 6-10)
# - Safe on block (-2 means opponent can't punish easily)
# - Leads to pressure on hit (+2 means I act first)
6. Hands-On Practice (30-40 minutes)
Exercise 1: Damage Formula Design (10 minutes)
Objective: Create and test a damage formula
Instructions:
- Design a damage formula with Attack, Defense, and one additional factor
- Set up a spreadsheet to test various Attack vs Defense values
- Ensure damage is never 0 and scales reasonably
- Calculate TTK for 3 different power level matchups
Starter Template:
| Attacker Atk | Defender Def | Damage | Defender HP | Hits to Kill |
|--------------|--------------|--------|-------------|--------------|
| 10 | 5 | ??? | 100 | ??? |
| 50 | 25 | ??? | 300 | ??? |
| 100 | 50 | ??? | 600 | ??? |
Exercise 2: Class Balance (15 minutes)
Objective: Balance an asymmetric combat system
Scenario: You have 3 classes that should be balanced against each other:
- Tank: High HP/Defense, Low Damage
- DPS: Medium HP, High Damage
- Healer: Low HP, Medium Damage, Can restore HP
Requirements:
- Assign stats to each class (HP, Attack, Defense, Special)
- Calculate head-to-head TTK for each matchup
- Identify any problematic matchups (one-sided, too long, too short)
- Adjust stats to balance
- Consider: Should Tank always beat DPS? Should Healer have any winning matchups?
Exercise 3: Design a Combat Encounter (15 minutes)
Objective: Create an interesting combat scenario
Challenge: Design a boss fight that requires players to:
- Use different damage types at different phases
- Make positioning decisions
- Manage a resource (cooldowns, special meter, etc.)
Deliverables:
- Boss stat block (HP, Attack, Defense, Abilities)
- Phase transitions (what changes at 50% HP, 25% HP?)
- Player choices (what decisions do they make?)
- Win condition and fail state
- Estimated fight duration
7. Common Pitfalls and Troubleshooting (10 minutes)
Frequent Mistakes
-
Problem: One strategy dominates (spam best move) Cause: No rock-paper-scissors or insufficient counterplay Solution: Add counters, make dominant strategy risky
-
Problem: Fights take too long Cause: Defense scales faster than offense Solution: Reduce defense values or add armor-piercing options
-
Problem: Fights end too fast (one-shots) Cause: Attack far exceeds defense, no recovery options Solution: Increase HP, add defensive abilities, reduce burst
-
Problem: Combat feels random Cause: Too much RNG in damage/hit calculations Solution: Reduce variance, add ways to mitigate randomness
Debugging Tips
- Spreadsheet everything: Test formulas before implementing
- Watch playtests: Where do players die? Where do they feel frustrated?
- Track data: Win rates, average fight length, popular strategies
- A/B test: Try different values with different player groups
Warning Signs
| Symptom | Likely Problem | Check This |
|---|---|---|
| Players only use one move | Missing counterplay | Add punish window |
| Fights are coin flips | Too much RNG | Reduce variance |
| Glass cannon dominates | Defense is useless | Buff defensive options |
| Turtling dominates | Aggression is punished | Add chip damage, time limits |
8. Best Practices and Professional Tips (5 minutes)
Industry Standards
- TTK varies by genre: Shooters: 0.3-1s, RPGs: 5-30s, Fighting games: 10-30s
- Damage variance: Usually 0.8-1.2× base, rarely more
- Critical hits: 1.5-2× is standard, higher feels “broken”
- Elemental systems: Usually 2× advantage, 0.5× disadvantage
Advanced Techniques
Damage Buckets: Separate damage into types that reduce independently:
Total Damage = Physical Damage × (1 - Armor%)
+ Magic Damage × (1 - Magic Resist%)
+ True Damage × 1.0
Soft/Hard Caps: Prevent stat stacking from breaking balance:
If Crit Chance > 50%: Diminishing returns
If Armor > 75%: Hard cap, can't exceed
EHP (Effective HP): Calculate real survivability:
EHP = HP × (100 + Defense) / 100
Example:
1000 HP with 50 Defense = 1000 × 1.5 = 1500 EHP
800 HP with 100 Defense = 800 × 2.0 = 1600 EHP
(Second build is tankier despite less HP)
Next Steps in Your Learning Journey
- Study fighting game frame data in depth
- Analyze MOBA balance patches
- Read postmortems of combat system development
- Prototype and playtest your own combat system
9. Summary and Review (5 minutes)
Key Takeaways
- Action economy creates choices - what competes with what?
- Damage formulas need careful design - percentage reduction > flat reduction
- Rock-paper-scissors prevents dominance - but add depth beyond it
- TTK affects pacing - faster isn’t always better
- Test with spreadsheets before code - math catches problems early
Quick Review Questions
- What’s wrong with “Damage = Attack - Defense”?
- How does action economy create meaningful choices?
- Name two combat design patterns and their purposes.
- What is TTK and why does it matter?
For Instructors
Teaching Tips
- Use fighting game footage to demonstrate frame data concepts
- Have students play different combat-focused games and compare
- Work through damage formulas on whiteboard with class
- Discuss why certain combat systems “feel” good
Assessment Ideas
- Complete damage formula design with spreadsheet analysis
- Combat encounter design document
- Balance analysis of an existing game
- Comparison essay of two different combat systems
Adaptation Notes
- For beginners: Focus on basic formulas and rock-paper-scissors
- For advanced students: Discuss fighting game tech, competitive balance
- For programmers: Include implementation patterns, state machines for combat
- For narrative designers: Discuss how combat serves story moments