COMBAT_REFERENCE.md 12 KB

Combat System Reference

Quick lookup for all classes, methods, and stat calculations.

Core Classes at a Glance

Class Purpose Location
CharacterStats Base stat container (health, speed, attack, defense, magic) Combat/CharacterStats.cs
CharacterSheet Equipment + bonuses management Combat/CharacterSheet.cs
Item Base equipment class Combat/Items/Item.cs
Weapon Attack-boosting equipment Combat/Items/Weapon.cs
Armor Defense-boosting equipment Combat/Items/Armor.cs
Monster ScriptableObject monster template Combat/Monsters/Monster.cs
MonsterEncounter Room encounter state Combat/Monsters/MonsterEncounter.cs
CombatResolver Combat resolution (skeleton) Combat/CombatResolver.cs
RoomEncounterConfig Encounter spawn config Combat/RoomEncounterConfig.cs
MazeAgent Updated with CharacterSheet Agent/MazeAgent.cs
AutonomousAgentBrain Updated with peek & retreat Agent/AutonomousAgentBrain.cs

CharacterStats API

// Properties
float MaxHealth { get; }              // Total durability
float CurrentHealth { get; set; }     // Current (0 = dead)
float Speed { get; }                  // Initiative and movement
float Attack { get; }                 // Damage output
float Defense { get; }                // Damage reduction
float Magic { get; }                  // Spell power

// Methods
CharacterStats Clone()                // Create a copy
void RestoreHealth()                  // Reset to max
void TakeDamage(float damage)        // Reduce health
float CalculateDamageReduction(float incomingDamage) // Returns reduced damage
bool IsAlive { get; }                 // health > 0

CharacterSheet API

// Properties
CharacterStats Stats { get; }                    // Base stats
Weapon EquippedWeapon { get; }                   // Current weapon
Armor EquippedArmor { get; }                     // Current armor
IReadOnlyList<Item> Inventory { get; }           // Items in inventory

// Effective stat getters (include all bonuses)
float GetEffectiveAttack()                       // Base + equipment + buffs
float GetEffectiveDefense()
float GetEffectiveSpeed()
float GetEffectiveMagic()
float GetEffectiveMaxHealth()                    // For armor bonuses

// Equipment management
bool EquipWeapon(Weapon weapon)                  // Returns false if can't equip
bool EquipArmor(Armor armor)
void AddToInventory(Item item)

// Bonus management
void ApplyTemporaryBonus(string key, float bonus, string statType = "attack")
void ApplyTemporaryBonus(string key, float attackBonus = 0, float defenseBonus = 0, float magicBonus = 0, float speedBonus = 0, float healthBonus = 0)
void RemoveTemporaryBonus(string key)

// Combat
void ResetForNewFight()                         // Reset bonuses, keep equipment

Weapon/Armor API

// Weapon specific
class Weapon : Item
{
    float AttackBonus { get; }
    float MagicBonus { get; }
    float DefenseBonus { get; }          // Parry bonus
    float SpeedBonus { get; }            // Can be negative
}

// Armor specific
class Armor : Item
{
    float DefenseBonus { get; }
    float HealthBonus { get; }           // Extra max health
    float SpeedPenalty { get; }          // Heavy armor slows you
    float MagicResistance { get; }
}

// Base Item class
abstract class Item
{
    string ItemName { get; }
    string Description { get; }
    Sprite Icon { get; }
    int Rarity { get; }                  // 1-5

    virtual bool OnEquip(CharacterSheet character)  // Returns false = can't equip
    virtual void OnUnequip(CharacterSheet character)
    virtual string GetLabel()                       // For UI display
}

Monster API

// ScriptableObject template
class Monster : ScriptableObject
{
    string MonsterName { get; }
    Color Color { get; }                        // For visualization
    CharacterStats BaseStats { get; }
    Weapon StartingWeapon { get; }
    Armor StartingArmor { get; }
    Item[] PossibleLoot { get; }

    // Methods
    CharacterSheet CreateCharacterSheet()       // Create instance with fresh stats
    Item GetRandomLoot()                        // Random drop (can be null)
}

MonsterEncounter API

// Holds all monsters in one room
class MonsterEncounter
{
    class MonsterInstance
    {
        Monster Template { get; }
        CharacterSheet CharacterSheet { get; }
        bool IsDefeated { get; }                // health == 0
    }

    // Properties
    IReadOnlyList<MonsterInstance> Monsters { get; }
    int AliveMonsterCount { get; }
    int VisibleMonsterCount { get; }            // Incomplete info
    bool HasLivingMonsters { get; }

    // Methods
    void SpawnMonsters(Monster[] templates, int minCount, int maxCount)
    void DefeateMonster(int index)
    float GetPerceivedChallengeRating(CharacterSheet agentStats)  // What agent sees
    float GetActualChallengeRating(CharacterSheet agentStats)     // Real difficulty
    void ResetEncounter()                       // For retries
}

MazeAgent Combat API (Updated)

// New properties
CharacterSheet CharacterSheet { get; }          // Agent's stats + equipment
bool IsDead { get => !CharacterSheet.Stats.IsAlive; }

// New method
void Die()                                      // Called when defeated

// New event
event Action Died                               // Fired when agent dies

// Constructor now accepts CharacterSheet
MazeAgent(string name, Room startRoom, CharacterSheet characterSheet = null)

AutonomousAgentBrain Combat API (Updated)

// Updated Initialize signature
void Initialize(
    MazeAgentController controller,
    MazeGenerator generator,
    float initialDelay,
    float decisionInterval,
    float exploreChance,
    float retreatThreshold,                     // NEW: threat threshold (default 1.5)
    Func<bool> isLevelEnded
)

// Peek mechanic (public)
float PeekThroughExit(Exit exit, MazeAgent agent)  // Returns challenge rating

// Private retreat helpers
bool ShouldTakeExit(Exit exit, MazeAgent agent)
List<Exit> FilterByThreat(List<Exit> exits, MazeAgent agent)

Room API (Updated)

class Room
{
    // New property
    MonsterEncounter Encounter { get; set; }    // null if no encounter
    
    // Rest of API unchanged
}

CombatResolver API (Skeleton - Expand Me!)

// Main entry point
enum CombatOutcome { AgentVictory, AgentDefeated, Fleeing }

static CombatOutcome ResolveCombat(MazeAgent agent, MonsterEncounter encounter)

// TODO: Implement these private methods
static List<(bool IsAgent, int MonsterIndex)> BuildTurnOrder(...)
static void ExecuteAgentTurn(MazeAgent agent, MonsterEncounter encounter)
static void ExecuteMonsterTurn(int monsterIndex, MazeAgent agent, MonsterEncounter encounter)
static void AttackMonster(MazeAgent agent, MonsterEncounter encounter, int targetIndex)
static void AttackAgent(MonsterEncounter.MonsterInstance attacker, MazeAgent target)
static void AwardLoot(MonsterEncounter.MonsterInstance monster, MazeAgent agent)

Stat Calculation Examples

Effective Attack with Equipment

Base Attack: 10
Weapon Bonus: +5
Buff Bonus: +3
─────────────────
Effective Attack: 18

Damage with Defense

Attacker's effective attack: 15
Defender's defense: 5
Defense reduction: min(defense × 10%, 90%) = 50%
Damage taken: 15 × (1 - 0.5) = 7.5 health

Challenge Rating

Monster attack: 8, Monster health: 20
Monster threat: 8 + (20 × 0.1) = 10

Agent attack: 12, Agent defense: 4
Agent power: 12 + 4 = 16

Perceived CR: 10 / 16 = 0.625
(Below 1.5 threshold = manageable threat)

Common Usage Patterns

Create a Character Sheet

var stats = new CharacterStats();
var sheet = new CharacterSheet(stats);
sheet.EquipWeapon(mySword);
sheet.EquipArmor(myArmor);

Check Effective Stats

float atk = sheet.GetEffectiveAttack();      // Includes equipment
float def = sheet.GetEffectiveDefense();
float spd = sheet.GetEffectiveSpeed();

Spawn Monsters in a Room

var encounter = new MonsterEncounter();
encounter.SpawnMonsters(monsterTemplates, minCount, maxCount);
room.Encounter = encounter;

Evaluate Threat

float cr = encounter.GetPerceivedChallengeRating(agentStats);
if (cr > 1.5f) {
    // Dangerous - retreat if possible
}

Create Agent with Equipment

var agent = new MazeAgent("Agent_0", startRoom, characterSheet);

Check if Agent is Dead

if (agent.IsDead) {
    agent.Die();  // Mark as defeated
}

Default Values

Setting Value Adjustable
Max Health 100 Per agent/monster
Speed 10 Per agent/monster
Attack 10 Per agent/monster
Defense 5 Per agent/monster
Magic 5 Per agent/monster
Retreat Threshold 1.5 Via brain Initialize
Encounter Chance 70% Via config
Min Monsters/Room 1 Via config
Max Monsters/Room 3 Via config
Monster Visibility 60-100% Per encounter (random)
Defense Reduction Cap 90% Hardcoded

Integration Checklist

  • Create Monster ScriptableObject (Assets/Resources/Monsters/)
  • Create Weapon ScriptableObject (Assets/Resources/Items/Weapons/)
  • Create Armor ScriptableObject (Assets/Resources/Items/Armor/)
  • Load resources in MazeSceneBuilder
  • Create agents with CharacterSheet
  • Pass retreatThreshold to AutonomousAgentBrain.Initialize()
  • Spawn encounters in rooms (MazeGenerator)
  • Implement combat resolution (CombatResolver.cs)
  • Trigger combat in MazeAgentController
  • Test agent peek & retreat logic
  • Test combat flow (victory/defeat)
  • Add UI for combat feedback

File Dependencies

MazeAgent.cs
  └─ CharacterSheet.cs
     ├─ CharacterStats.cs
     ├─ Weapon.cs
     │  └─ Item.cs
     └─ Armor.cs
        └─ Item.cs

AutonomousAgentBrain.cs
  └─ MonsterEncounter.cs
     └─ Monster.cs
        ├─ CharacterStats.cs
        └─ Weapon/Armor.cs

Room.cs
  └─ MonsterEncounter.cs

CombatResolver.cs
  └─ MazeAgent.cs
     └─ MonsterEncounter.cs

Common Mistakes & Fixes

Problem Cause Fix
"CharacterSheet not found" Missing using MazeGen; Add namespace
Agent doesn't have equipment Created with null CharacterSheet Pass sheet to constructor
Monsters don't spawn monsterPool is empty Load via Resources.LoadAll
Agents don't retreat retreatThreshold too high Lower it (e.g., 0.8)
Combat doesn't resolve CombatResolver not called Add trigger in MazeAgentController
Dead agents still moving Die() not called Call in combat victory/defeat

Want to Extend?

Add a New Stat

  1. Add field to CharacterStats
  2. Add bonus dict to CharacterSheet
  3. Add GetEffectiveStat() method
  4. Update Weapon/Armor OnEquip() if applicable

Add a New Item Type

public class Accessory : Item
{
    [SerializeField] private float _magicBonus;
    
    public override bool OnEquip(CharacterSheet character)
    {
        character.ApplyTemporaryBonus("accessory_magic", _magicBonus, "magic");
        return true;
    }
}

Add Status Effects

Extend MonsterInstance to track:

  • List<StatusEffect> activeEffects
  • Tick them down each turn
  • Apply temporary bonuses based on effect

Add Combat Abilities

Extend character sheet with:

  • List<Ability> availableAbilities
  • Ability class with: cost, damage, target type, cooldown

See INTEGRATION_EXAMPLE.md for full implementation walkthrough!