Quick lookup for all classes, methods, and stat calculations.
| 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 |
// 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
// 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 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
}
// 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)
}
// 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
}
// 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)
// 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)
class Room
{
// New property
MonsterEncounter Encounter { get; set; } // null if no encounter
// Rest of API unchanged
}
// 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)
Base Attack: 10
Weapon Bonus: +5
Buff Bonus: +3
─────────────────
Effective Attack: 18
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
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)
var stats = new CharacterStats();
var sheet = new CharacterSheet(stats);
sheet.EquipWeapon(mySword);
sheet.EquipArmor(myArmor);
float atk = sheet.GetEffectiveAttack(); // Includes equipment
float def = sheet.GetEffectiveDefense();
float spd = sheet.GetEffectiveSpeed();
var encounter = new MonsterEncounter();
encounter.SpawnMonsters(monsterTemplates, minCount, maxCount);
room.Encounter = encounter;
float cr = encounter.GetPerceivedChallengeRating(agentStats);
if (cr > 1.5f) {
// Dangerous - retreat if possible
}
var agent = new MazeAgent("Agent_0", startRoom, characterSheet);
if (agent.IsDead) {
agent.Die(); // Mark as defeated
}
| 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 |
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
| 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 |
CharacterStatsCharacterSheetGetEffectiveStat() methodWeapon/Armor OnEquip() if applicablepublic class Accessory : Item
{
[SerializeField] private float _magicBonus;
public override bool OnEquip(CharacterSheet character)
{
character.ApplyTemporaryBonus("accessory_magic", _magicBonus, "magic");
return true;
}
}
Extend MonsterInstance to track:
List<StatusEffect> activeEffectsExtend character sheet with:
List<Ability> availableAbilitiesSee INTEGRATION_EXAMPLE.md for full implementation walkthrough!