ARCHITECTURE.md 17 KB

Combat System Architecture

Class Relationships

┌─────────────────────────────────────────────────────────────────┐
│                    MazeAgent (Agent.cs)                         │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │ + CurrentRoom: Room                                      │   │
│  │ + IsFinished: bool                                       │   │
│  │ + IsDead: bool                                           │   │
│  │ + CharacterSheet: CharacterSheet ◄──┐                   │   │
│  │ + PathHistory: List<Room>            │                   │   │
│  │ + HasVisited(roomId): bool           │                   │   │
│  └──────────────────────────────────────┼───────────────────┘   │
│                                         │                        │
└─────────────────────────────────────────┼────────────────────────┘
                                          │
                                          │ owns
                                          ▼
        ┌──────────────────────────────────────────────────────────┐
        │            CharacterSheet (CharacterSheet.cs)            │
        │  ┌─────────────────────────────────────────────────────┐ │
        │  │ - baseStats: CharacterStats                         │ │
        │  │ - equippedWeapon: Weapon◄──────┐                   │ │
        │  │ - equippedArmor: Armor◄────┐   │                   │ │
        │  │ - inventory: List<Item>     │   │                   │ │
        │  │ - tempBonuses: Dict         │   │                   │ │
        │  │                             │   │                   │ │
        │  │ + GetEffectiveAttack()      │   │                   │ │
        │  │ + GetEffectiveDefense()     │   │                   │ │
        │  │ + GetEffectiveSpeed()       │   │                   │ │
        │  │ + EquipWeapon()             │   │                   │ │
        │  │ + EquipArmor()              │   │                   │ │
        │  │ + AddToInventory()          │   │                   │ │
        │  │ + ApplyTemporaryBonus()     │   │                   │ │
        │  └─────────────────────────────────┼───────────────────┘ │
        │                                    │                      │
        └────────────────────────────────────┼──────────────────────┘
                                             │
                            ┌────────────────┴────────────────┐
                            │                                 │
                            ▼                                 ▼
        ┌──────────────────────────────┐  ┌──────────────────────────┐
        │     CharacterStats           │  │        Item (base)        │
        │  (CharacterStats.cs)         │  │   (Items/Item.cs)        │
        │  ┌────────────────────────┐  │  │  ┌────────────────────┐   │
        │  │ - maxHealth            │  │  │  │ - itemName         │   │
        │  │ - speed                │  │  │  │ - description      │   │
        │  │ - attack               │  │  │  │ - icon             │   │
        │  │ - defense              │  │  │  │ - rarity           │   │
        │  │ - magic                │  │  │  │                    │   │
        │  │ - currentHealth        │  │  │  │ + OnEquip()        │   │
        │  │                        │  │  │  │ + OnUnequip()      │   │
        │  │ + Clone()              │  │  │  │ + GetLabel()       │   │
        │  │ + TakeDamage()         │  │  │  └────────────────────┘   │
        │  │ + IsAlive              │  │  │           ▲                │
        │  └────────────────────────┘  │  │           │                │
        │                              │  │    ┌──────┴──────┐         │
        └──────────────────────────────┘  │    │             │         │
                                          │    ▼             ▼         │
                                          │ ┌────────┐  ┌────────┐    │
                                          │ │Weapon  │  │Armor   │    │
                                          │ │(Items/ │  │(Items/ │    │
                                          │ │Weapon) │  │Armor)  │    │
                                          │ └────────┘  └────────┘    │
                                          └──────────────────────────┘

┌──────────────────────────────────────────────────────────────────────┐
│                Room (Core/Room.cs)                                   │
│  + Encounter: MonsterEncounter ◄──┐                                 │
│  + Exits: List<Exit>              │                                 │
│  + Position: Vector2              │                                 │
│  + DepthFromStart: int            │                                 │
└──────────────────────────────────────────────────────────────────────┘
                                    │ has
                                    │
                                    ▼
        ┌──────────────────────────────────────────────────────┐
        │    MonsterEncounter (Monsters/MonsterEncounter.cs)  │
        │  ┌───────────────────────────────────────────────┐  │
        │  │ - monsters: List<MonsterInstance>             │  │
        │  │ - visibleMonsterCount: int (incomplete info)  │  │
        │  │                                               │  │
        │  │ + SpawnMonsters(templates, min, max)          │  │
        │  │ + GetPerceivedChallengeRating()               │  │
        │  │ + GetActualChallengeRating()                  │  │
        │  │ + HasLivingMonsters: bool                     │  │
        │  │ + AliveMonsterCount: int                      │  │
        │  └───────────────────────────────────────────────┘  │
        │           │                                          │
        │           │ contains                                 │
        │           ▼                                          │
        │  ┌──────────────────────────────────────────────┐   │
        │  │    MonsterInstance                          │   │
        │  │  ┌──────────────────────────────────────┐   │   │
        │  │  │ + Template: Monster                  │   │   │
        │  │  │ + CharacterSheet: CharacterSheet     │   │   │
        │  │  │ + IsDefeated: bool                   │   │   │
        │  │  └──────────────────────────────────────┘   │   │
        │  └──────────────────────────────────────────────┘   │
        │           │                                          │
        │           │ uses                                     │
        │           ▼                                          │
        │  ┌──────────────────────────────────────────────┐   │
        │  │       Monster (Monsters/Monster.cs)         │   │
        │  │    [ScriptableObject Template]              │   │
        │  │  ┌──────────────────────────────────────┐   │   │
        │  │  │ + monsterName: string                │   │   │
        │  │  │ + baseStats: CharacterStats          │   │   │
        │  │  │ + startingWeapon: Weapon (optional)  │   │   │
        │  │  │ + startingArmor: Armor (optional)    │   │   │
        │  │  │ + possibleLoot: Item[]               │   │   │
        │  │  │                                      │   │   │
        │  │  │ + CreateCharacterSheet()             │   │   │
        │  │  │ + GetRandomLoot()                    │   │   │
        │  │  └──────────────────────────────────────┘   │   │
        │  └──────────────────────────────────────────────┘   │
        │                                                      │
        └──────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────┐
│   AutonomousAgentBrain (Agent/AutonomousAgentBrain.cs)              │
│  ┌──────────────────────────────────────────────────────────────┐   │
│  │ - _controller: MazeAgentController                           │   │
│  │ - _retreatThreshold: float                                   │   │
│  │                                                              │   │
│  │ + ChooseExit(agent, room): Exit                             │   │
│  │ + PeekThroughExit(exit, agent): float [CR]                  │   │
│  │ + ShouldTakeExit(exit, agent): bool                         │   │
│  │ + FilterByThreat(exits, agent): List<Exit>                  │   │
│  │                                                              │   │
│  │ PEEK MECHANIC:                                              │   │
│  │ 1. Before choosing an exit, peek into adjacent rooms        │   │
│  │ 2. Get perceived challenge rating (incomplete info)         │   │
│  │ 3. Compare to retreat threshold                             │   │
│  │ 4. Avoid dangerous exits if safer options exist             │   │
│  └──────────────────────────────────────────────────────────────┘   │
└──────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────┐
│   CombatResolver (CombatResolver.cs) [SKELETON - EXPAND ME]         │
│  ┌──────────────────────────────────────────────────────────────┐   │
│  │ + ResolveCombat(agent, encounter): CombatOutcome            │   │
│  │                                                              │   │
│  │ - BuildTurnOrder(agent, encounter): List<Turn>              │   │
│  │ - ExecuteAgentTurn(agent, encounter)                        │   │
│  │ - ExecuteMonsterTurn(monster, agent, encounter)             │   │
│  │ - AttackMonster(agent, encounter, targetIdx)                │   │
│  │ - AttackAgent(monster, agent)                               │   │
│  │ - AwardLoot(monster, agent)                                 │   │
│  │                                                              │   │
│  │ TODO: Full implementation with:                             │   │
│  │ - Turn order calculation                                    │   │
│  │ - Multiple damage types                                     │   │
│  │ - Special abilities                                         │   │
│  │ - Status effects                                            │   │
│  │ - AI decision making                                        │   │
│  └──────────────────────────────────────────────────────────────┘   │
└──────────────────────────────────────────────────────────────────────┘

Data Flow

1. Agent Encounters a Room with Monsters

Agent.EnterRoom(room)
  └─> room.Encounter exists?
      └─> Yes: Trigger combat
          └─> CombatResolver.ResolveCombat(agent, encounter)
              ├─> BuildTurnOrder()
              ├─> Loop: ExecuteAgentTurn() / ExecuteMonsterTurn()
              ├─> Return: Victory / Defeat / Fleeing
              └─> Apply outcome (agent dies / loot awarded / etc.)
      └─> No: Continue normally

2. Agent Makes Decision (Peek & Retreat)

AutonomousAgentBrain.ChooseExit()
  └─> For each exit:
      ├─> PeekThroughExit()
      │   └─> room.Encounter.GetPerceivedChallengeRating()
      └─> ShouldTakeExit()
          ├─> If CR < retreatThreshold: take it
          └─> Else: maybe retreat (randomness)
  └─> FilterByThreat() removes dangerous exits
  └─> Return safest valid exit

3. Item Equipping Flow

CharacterSheet.EquipWeapon(weapon)
  ├─> Weapon.OnUnequip() old weapon (if any)
  │   └─> RemoveTemporaryBonus()
  ├─> Weapon.OnEquip(this)
  │   └─> ApplyTemporaryBonus("weapon_attack", bonus)
  └─> GetEffectiveAttack() now includes bonus

Stat Calculation Example

Agent with:
  - Base Attack: 10
  - Equipped Weapon: +5 Attack bonus
  - Temporary Buff: +3 Attack

GetEffectiveAttack() = 10 + 5 + 3 = 18

Defense reduction calculation:

Monster attacks for 20 base damage
Agent defense: 5
Defense reduction: min(10% × 5, 90%) = 50%
Actual damage taken: 20 × (1 - 0.5) = 10

Missing Pieces (You'll Implement)

  1. Combat UI — Show health bars, stats, action buttons
  2. Ability System — Special attacks, spells, items with effects
  3. Status Effects — Poison, stun, buff/debuff system
  4. Item Pickup — Drop loot when monsters die
  5. Inventory UI — Manage equipment, consumables
  6. Audio/VFX — Combat feedback (hit sounds, damage numbers)
  7. AI — Monster targeting, ability selection
  8. Difficulty Scaling — Scale encounters by depth or agent power

See CombatResolver.cs for where to add these.