AI_AGENT_ARCHITECTURE.md 12 KB

AI Agent System Architecture

System Flow Diagram

┌─────────────────────────────────────────────────────────────┐
│ MazeController                                              │
│  - Generates maze                                           │
│  - Manages renderers                                        │
│  - Triggers agent spawning                                  │
└────────────────┬────────────────────────────────────────────┘
                 │
                 │ spawns agents via
                 ↓
┌─────────────────────────────────────────────────────────────┐
│ AIAgentManager                                              │
│  - Spawns agents (initial + runtime)                        │
│  - Tracks active agents                                     │
│  - Manages configuration                                    │
│  - Provides statistics                                      │
└────────────────┬────────────────────────────────────────────┘
                 │
                 │ creates
                 ↓
┌─────────────────────────────────────────────────────────────┐
│ AIAgent (10+ instances)                                     │
│  - Navigates maze                                           │
│  - Makes pathfinding decisions                              │
│  - Moves toward goal                                        │
│  - Reports visited rooms                                    │
└────────────────┬────────────────────────────────────────────┘
                 │
                 │ uses
                 ↓
┌─────────────────────────────────────────────────────────────┐
│ AIRoomMemoryManager (Singleton)                             │
│  - Manages memories per character type                      │
└────────────────┬────────────────────────────────────────────┘
                 │
                 │ provides memory
                 ↓
┌─────────────────────────────────────────────────────────────┐
│ AIRoomMemory (per character type)                           │
│  - Tracks visited rooms                                     │
│  - Filters unvisited rooms                                  │
│  - Shared by all agents of same type                        │
└─────────────────────────────────────────────────────────────┘

Agent Decision Making Flow

┌──────────────┐
│ Agent Update │
└──────┬───────┘
       │
       ↓
┌─────────────────────────────────┐
│ Determine Current Room          │
│ (check position with GetRoomAtTile)
└──────┬──────────────────────────┘
       │
       ↓
┌─────────────────────────────────┐
│ Check if at Goal Exit Point     │
│ (maze.ExitPoints.Contains())    │
└──────┬──────────────────────────┘
       │
   YES │     NO
  ┌────┴──────────┐
  │               │
  ↓               ↓
┌──────────────────┐  ┌──────────────────────────────┐
│ Goal Reached     │  │ In Goal Room?                │
│ (Stop movement)  │  │ (GetRoomsByType End)        │
└──────────────────┘  └──────┬───────────────────────┘
                             │
                        YES  │    NO
                      ┌──────┴───────┐
                      │              │
                      ↓              ↓
                   ┌─────────────┐  ┌───────────────────┐
                   │ Path to     │  │ Choose Next Room  │
                   │ Exit in     │  │ (ChooseNextRoom)  │
                   │ Current Rm  │  └────────┬──────────┘
                   └─────────────┘           │
                                      ┌──────┴──────────┐
                                      │                 │
                                      ↓                 ↓
                                   ┌──────────────────┐
                                   │ Prefer Unvisited│
                                   │ (via RoomMemory) │
                                   └──────────────────┘
                                             │
                                             ↓
                                   ┌──────────────────┐
                                   │ Path to Room Exit│
                                   │ (A* within room) │
                                   └──────────────────┘
                                             │
                                             ↓
                                   ┌──────────────────┐
                                   │ FollowPath()     │
                                   │ Move at speed    │
                                   └──────────────────┘

Room Exploration Strategy

Agent starts in START room
    │
    ├─ Visit START room
    │   └─ Mark in RoomMemory as visited
    │
    ├─ Look for exits from START room
    │   └─ Find connected rooms via exits
    │
    ├─ Check RoomMemory: which are unvisited?
    │   └─ Unvisited rooms = HIGH PRIORITY
    │
    ├─ Path to exit of START room leading to unvisited room
    │
    ├─ Enter adjacent room
    │   └─ Mark in RoomMemory as visited
    │
    ├─ Repeat for new room...
    │
    └─ Eventually reach END room
        └─ Path to exit point
            └─ GOAL REACHED!

Character type memory shared between all agents:
- Agent A visited rooms: [1, 2, 3, 5]
- Agent B can see: "Rooms 1,2,3,5 visited" → knows to check rooms 4,6,7

Class Relationships

┌──────────────────────┐
│  AIRoomMemoryManager │
│  (Singleton)         │
└──────┬───────────────┘
       │ manages many
       ↓
┌──────────────────────────────────┐
│ AIRoomMemory                     │
│ (one per character type)         │
│                                  │
│ Properties:                      │
│  - characterType: string         │
│  - visitedRoomIds: HashSet<int>  │
│  - roomLastVisitTime: Dict<>     │
└──────────────────────────────────┘

┌──────────────────────┐
│   AIAgentManager     │
│  (one per game)      │
└──────┬───────────────┘
       │ spawns many
       ↓
┌──────────────────────────────────┐
│ AIAgent (MonoBehaviour)          │
│ (one per agent in scene)         │
│                                  │
│ Properties:                      │
│  - agentCharacterType: string    │
│  - agentId: int                  │
│  - currentRoom: Vector2Int       │
│  - roomMemory: AIRoomMemory      │
│                                  │
│ Methods:                         │
│  - Update() - main loop          │
│  - UpdateCurrentRoom()           │
│  - UpdatePathToGoal()            │
│  - FollowPath()                  │
└──────────────────────────────────┘
       │ references
       ↓
┌──────────────────────────────────┐
│ MazeData                         │
│ (one per maze)                   │
│                                  │
│ Provides:                        │
│  - GetRoomAtTile(x, y)          │
│  - IsWalkable(x, y)             │
│  - GetAdjacentWalkable(x, y)    │
│  - ExitPoints, StartPoints      │
└──────────────────────────────────┘

Data Flow for Room Memory

Agent 1 explores maze:
  Room 0 (start)  → Room 2 → Room 5
      │
      └─ Mark visited: {0, 2, 5}
         Store in: AIRoomMemory["Default"]

Agent 2 spawns later:
  Room 0 (start)  
      │
      ├─ Check memory: visited = {0, 2, 5}
      ├─ Available neighbors: {0, 1, 3}
      └─ Unvisited: {1, 3} → Choose 1 or 3
      
       → Room 1 → Room 3
           │
           └─ Mark visited: {0, 2, 5, 1, 3}
              Update: AIRoomMemory["Default"]

Agent 3 spawns even later:
  All agents see the same visited rooms list
  Coordinates exploration better
  Reaches goal faster with collective knowledge

Performance Characteristics

Agents (n=10, default):
  - Each agent pathfinds: every 0.5 seconds
  - A* search scope: within single room bounds
  - Memory per agent: ~1KB (pathfinding data)
  - Shared memory per type: ~100 bytes (room ID set)
  
Total overhead:
  - CPU: ~1-2ms per frame (10 agents)
  - Memory: ~10KB total
  
Scaling:
  100 agents: ~10ms, 100KB
  1000 agents: ~100ms, 1MB (not recommended)
  
Optimizations:
  - Shared room memory (not duplicated per agent)
  - A* limited to single room bounds (not full maze)
  - Configurable update interval
  - Path caching until room changes

This architecture ensures:

  1. Modularity - Each component has single responsibility
  2. Extensibility - Easy to add stats, combat, different AI types
  3. Efficiency - Limited scope pathfinding, shared memory
  4. Scalability - Can spawn many agents without huge overhead