# Maze Generation System - Setup & Usage Guide ## Overview This is a comprehensive maze generation system for Unity 2D designed with AI pathfinding in mind. It generates large, procedural mazes with multiple rooms, hallways, terrain types, and various special room types (safe rooms, boss rooms, rest rooms, etc.). ## Core Components ### 1. **MazeTile.cs** Represents a single 1x1 unit square in the maze. **Tile Types:** - `Wall` - Impassable barriers - `Floor` - Basic walkable surface - `Terrain` - Special terrain with movement penalties **Terrain Types:** - `Normal` - Movement cost: 1.0x - `Swamp` - Movement cost: 2.0x (slower) - `Lava` - Movement cost: 3.0x (dangerous) - `Ice` - Movement cost: 0.5x (risky/slippery) - `Stone` - Movement cost: 1.5x ### 2. **MazeRoom.cs** Represents rectangular rooms in the maze. **Room Types:** - `Normal` - Standard rooms - `Safe` - No monsters - `Rest` - Resting/healing areas - `Restroom` - Special purpose - `Boss` - Boss encounter rooms - `End` - Exit rooms ### 3. **MazeData.cs** Core data structure holding: - 2D tile grid - List of all rooms - Start and exit points - Helper methods for querying and manipulating the maze ### 4. **MazeConfig.cs** Configuration scriptable object for generation parameters: - Maze dimensions (100x100 to 10000x10000) - Room count and sizes - Start/exit point counts - Hallway widths - Special room distribution - Random seed ## Handling Very Large Mazes (1000x1000+) For mazes larger than 500x500, the traditional tilemap rendering will cause Unity to crash due to memory limitations. Here are several approaches to handle huge mazes: ### Option 1: Chunked Tilemap Rendering Use `ChunkedMazeRenderer` instead of `MazeRenderer` for large mazes: 1. **Disable MazeRenderer**: Uncheck or remove the MazeRenderer component 2. **Add ChunkedMazeRenderer**: Attach this to your Grid GameObject 3. **Configure Settings**: - `Chunk Size`: 32-64 (smaller chunks = more responsive but more objects) - `Render Distance`: 2-3 chunks around camera - Assign tile assets as with regular MazeRenderer **Pros**: Familiar tilemap workflow, good performance **Cons**: Still limited by total tile count, not suitable for 1000x1000+ ### Option 2: 3D Mesh Rendering For maximum performance with huge mazes, use `MeshMazeRenderer`: 1. **Create Mesh GameObject**: Empty GameObject with MeshRenderer/MeshFilter 2. **Attach MeshMazeRenderer**: Configure materials and settings 3. **Material Setup**: - Create materials for floor and walls - Assign to Floor Material and Wall Material fields 4. **Settings**: - `Wall Height`: 2.0 (makes walls visible in 3D) - `Tile Size`: 1.0 - `Chunk Size`: 32-64 for large mazes - `Render Distance`: 2-3 **Pros**: Handles millions of tiles, 3D visualization, best performance **Cons**: No tilemap RuleTiles, different workflow ### Option 3: Fog of War + Chunked Rendering Combine chunked rendering with fog of war for exploration-based games: 1. **Setup ChunkedMazeRenderer** as above 2. **Add MazeFogOfWar** component to manage exploration 3. **AI Entities**: Use `MazeAIEntity` for pathfinding with limited vision 4. **Vision Range**: Set how far entities can see (explores new areas) ### Asynchronous Generation For large mazes that take time to generate: 1. **Add AsyncMazeGenerator** to your MazeController GameObject 2. **Configure UI** (optional): - Assign progress bar and text for generation feedback 3. **Call GenerateMazeAsync()** instead of regular generation ### Performance Tips - **Disable Debug Visualization**: Uncheck "Visualize Debug" in MazeController for large mazes - **Chunk Size**: Balance between 32-64. Smaller = more responsive camera movement - **Render Distance**: Keep low (2-3) to limit active chunks - **Mesh Rendering**: Preferred for 1000x1000+ mazes - **Background Generation**: Use AsyncMazeGenerator to prevent UI freezing ### AI Pathfinding in Large Mazes The `MazeAIEntity` component provides: - **Fog of War Navigation**: Only paths through explored areas - **Vision-Based Exploration**: Automatically explores as it moves - **Dynamic Pathfinding**: Updates path as new areas are discovered - **Start/Exit Targeting**: Automatically finds and paths to exits ### Configuration for 1000x1000 Mazes ```csharp // MazeConfig settings for huge mazes Width: 1000 Height: 1000 TargetRoomCount: 100-200 (fewer rooms for performance) MinRoomWidth: 5 MaxRoomWidth: 15 (smaller rooms generate faster) MinRoomHeight: 5 MaxRoomHeight: 15 MinStartPoints: 1 MaxStartPoints: 5 MinExits: 1 MaxExits: 5 ``` ### Memory Considerations - **Tilemap Rendering**: ~1MB per 100x100 tiles - **Mesh Rendering**: ~100KB per 100x100 tiles - **Chunked Approach**: Only active chunks use memory - **Fog of War**: Stores explored tiles (grows over time) For a 1000x1000 maze: - Full tilemap: ~10GB (will crash) - Mesh rendering: ~100MB (manageable) - Chunked + fog of war: ~10-50MB active ## Setup Instructions ### Step 1: Create the Game Objects 1. Create a new empty GameObject named "MazeManager" 2. Attach the **MazeController** script to it 3. In the Inspector, expand the MazeConfig section and adjust parameters ### Step 2: Configure MazeConfig Edit these key parameters: ``` Width: 100-500 (start small for testing) Height: 100-500 TargetRoomCount: 20-50 MinRoomWidth: 5 MaxRoomWidth: 25 MinRoomHeight: 5 MaxRoomHeight: 25 MinStartPoints: 1 MaxStartPoints: 3 MinExits: 1 MaxExits: 5 MaxHallwayWidth: 3 ``` ### Step 3: Create Tilemaps (Optional - for visualization) 1. Create a Grid GameObject if you don't have one 2. Create two child Tilemaps: - "CombinedTilemap" (walls and floors together) - "DecorationTilemap" 3. Attach **MazeRenderer** to the Grid 4. Assign the tilemaps in the inspector 5. Assign tile sprites for each terrain type > Use `CombinedTilemap` for both wall and floor tiles so `RuleTile` neighbor matching works correctly. ### Step 4: Generate and Test - Tick "Generate On Start" on MazeController - Press Play - Check Console for generation logs - Call `mazeController.GenerateMaze()` to regenerate ## Usage Examples ### Access the Maze in Your Code ```csharp MazeController controller = GetComponent(); MazeData maze = controller.GetCurrentMaze(); // Get tiles MazeTile tile = maze.GetTile(x, y); bool isWalkable = maze.IsWalkable(x, y); // Get rooms MazeRoom room = maze.GetRoomAtTile(x, y); // Get start/exit points List starts = maze.StartPoints; List exits = maze.ExitPoints; ``` ### Use Pathfinding for AI ```csharp var pathfinder = new MazePathfinder(mazeData); List path = pathfinder.FindPath(start, goal); // Find reachable areas HashSet reachable = pathfinder.FindReachableTiles(position, maxDistance); ``` ### Check Terrain Costs ```csharp MazeTile tile = maze.GetTile(x, y); float movementCost = tile.GetMovementCost(); ``` ### Create AI Characters When you create AI characters: 1. Use `MazePathfinder` to find paths 2. Check `IsWalkable` before moving 3. Use `GetMovementCost()` to calculate movement time 4. Use room type information for behavior changes ## Future Extensibility ### Monster Areas Currently configured but not implemented: - Create MonsterArea class to define regions with specific monster types - Assign monsters to rooms based on difficulty level ### Boss Encounters Boss rooms are marked - you can: - Spawn boss enemies inside them - Create special rules for boss encounters - Lock exits until boss is defeated ### Dynamic Obstacles Can add: - Movable obstacles - Destructible walls - Locked doors - Environmental hazards ### Performance Optimization For very large mazes (5000x5000+): - Use chunked rendering instead of full tilemap - Implement LOD system for distant areas - Cache pathfinding results - Use spatial hashing for quick lookups ## Configuration Presets ### Small Exploration Maze ``` Width: 100, Height: 100 TargetRoomCount: 10 Exits: 1-2 StartPoints: 1 ``` ### Medium Dungeon ``` Width: 300, Height: 300 TargetRoomCount: 30 Exits: 2-4 StartPoints: 1-2 ``` ### Large World ``` Width: 1000, Height: 1000 TargetRoomCount: 100 Exits: 5-10 StartPoints: 3-5 ``` ## Troubleshooting ### Maze not generating? - Check console for errors - Ensure MazeConfig is valid (ValidateConfig() called automatically) - Check if Random Seed is causing issues - try enabling "Use Random Seed" ### Performance issues? - Reduce maze size - Reduce room count - Disable MazeRenderer for very large mazes - Use chunked rendering instead ### Rooms not connected? - The algorithm guarantees connectivity via MST + extra connections - Check the console log for "Connectivity check" message - If rooms seem isolated, increase hallway width or room count ### Pathfinding too slow? - Reduce maze size - Cache frequently used paths - Consider pre-computing navigation meshes - Use simpler pathfinding for less critical AI ## Next Steps 1. Create a `Character` class that uses `MazePathfinder` 2. Implement monster spawning system 3. Create UI for maze parameters 4. Add procedural tileset 5. Implement save/load system for generated mazes 6. Add dynamic lighting 7. Create AI behavior system using the room types