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:
- Disable MazeRenderer: Uncheck or remove the MazeRenderer component
- Add ChunkedMazeRenderer: Attach this to your Grid GameObject
- 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:
- Create Mesh GameObject: Empty GameObject with MeshRenderer/MeshFilter
- Attach MeshMazeRenderer: Configure materials and settings
- Material Setup:
- Create materials for floor and walls
- Assign to Floor Material and Wall Material fields
- 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:
- Setup ChunkedMazeRenderer as above
- Add MazeFogOfWar component to manage exploration
- AI Entities: Use
MazeAIEntity for pathfinding with limited vision
- Vision Range: Set how far entities can see (explores new areas)
Asynchronous Generation
For large mazes that take time to generate:
- Add AsyncMazeGenerator to your MazeController GameObject
- Configure UI (optional):
- Assign progress bar and text for generation feedback
- 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
// 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
- Create a new empty GameObject named "MazeManager"
- Attach the MazeController script to it
- 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)
- Create a Grid GameObject if you don't have one
- Create two child Tilemaps:
- "CombinedTilemap" (walls and floors together)
- "DecorationTilemap"
- Attach MazeRenderer to the Grid
- Assign the tilemaps in the inspector
- 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
MazeController controller = GetComponent<MazeController>();
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<Vector2Int> starts = maze.StartPoints;
List<Vector2Int> exits = maze.ExitPoints;
Use Pathfinding for AI
var pathfinder = new MazePathfinder(mazeData);
List<Vector2Int> path = pathfinder.FindPath(start, goal);
// Find reachable areas
HashSet<Vector2Int> reachable = pathfinder.FindReachableTiles(position, maxDistance);
Check Terrain Costs
MazeTile tile = maze.GetTile(x, y);
float movementCost = tile.GetMovementCost();
Create AI Characters
When you create AI characters:
- Use
MazePathfinder to find paths
- Check
IsWalkable before moving
- Use
GetMovementCost() to calculate movement time
- 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
- Create a
Character class that uses MazePathfinder
- Implement monster spawning system
- Create UI for maze parameters
- Add procedural tileset
- Implement save/load system for generated mazes
- Add dynamic lighting
- Create AI behavior system using the room types