# 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 │ │ - 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