# 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 ```csharp // 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 ```csharp // Properties CharacterStats Stats { get; } // Base stats Weapon EquippedWeapon { get; } // Current weapon Armor EquippedArmor { get; } // Current armor IReadOnlyList 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 ```csharp // 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 ```csharp // 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 ```csharp // Holds all monsters in one room class MonsterEncounter { class MonsterInstance { Monster Template { get; } CharacterSheet CharacterSheet { get; } bool IsDefeated { get; } // health == 0 } // Properties IReadOnlyList 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) ```csharp // 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) ```csharp // Updated Initialize signature void Initialize( MazeAgentController controller, MazeGenerator generator, float initialDelay, float decisionInterval, float exploreChance, float retreatThreshold, // NEW: threat threshold (default 1.5) Func isLevelEnded ) // Peek mechanic (public) float PeekThroughExit(Exit exit, MazeAgent agent) // Returns challenge rating // Private retreat helpers bool ShouldTakeExit(Exit exit, MazeAgent agent) List FilterByThreat(List exits, MazeAgent agent) ``` --- ## Room API (Updated) ```csharp class Room { // New property MonsterEncounter Encounter { get; set; } // null if no encounter // Rest of API unchanged } ``` --- ## CombatResolver API (Skeleton - Expand Me!) ```csharp // 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 ```csharp var stats = new CharacterStats(); var sheet = new CharacterSheet(stats); sheet.EquipWeapon(mySword); sheet.EquipArmor(myArmor); ``` ### Check Effective Stats ```csharp float atk = sheet.GetEffectiveAttack(); // Includes equipment float def = sheet.GetEffectiveDefense(); float spd = sheet.GetEffectiveSpeed(); ``` ### Spawn Monsters in a Room ```csharp var encounter = new MonsterEncounter(); encounter.SpawnMonsters(monsterTemplates, minCount, maxCount); room.Encounter = encounter; ``` ### Evaluate Threat ```csharp float cr = encounter.GetPerceivedChallengeRating(agentStats); if (cr > 1.5f) { // Dangerous - retreat if possible } ``` ### Create Agent with Equipment ```csharp var agent = new MazeAgent("Agent_0", startRoom, characterSheet); ``` ### Check if Agent is Dead ```csharp 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 ```csharp 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 activeEffects` - Tick them down each turn - Apply temporary bonuses based on effect ### Add Combat Abilities Extend character sheet with: - `List availableAbilities` - Ability class with: cost, damage, target type, cooldown --- **See INTEGRATION_EXAMPLE.md for full implementation walkthrough!**