A procedurally generated map and scenario generator for Descent: Journeys in the Dark, featuring a unique technical approach: all map rendering is done using Pandas DataFrames and Matplotlib, with tile placement and rotations handled entirely through matrix mathematics.
This project uses an unconventional rendering system that treats map generation like photo editing software or game rendering engines:
- Multi-layered architecture: Each visual layer (base tiles, walls, doors, monsters, treasures) is a separate Pandas DataFrame
- Matrix-based transformations: All tile rotations and placements are computed using linear algebra operations on NumPy arrays
- DataFrame rendering: Matplotlib visualizes the composed layers, with each DataFrame representing different map elements
- Procedural generation: Random tile selection, placement, and connection using graph-based algorithms
This approach demonstrates how traditional data science tools (Pandas, NumPy) can be creatively repurposed for game development and computational geometry tasks.
- Randomly generates multi-area dungeon layouts with connected tiles
- Automatic tile placement using matrix rotations (0°, 90°, 180°, 270°)
- Smart door placement and area transitions
- Randomized terrain obstacles and line-of-sight calculations
The generator supports revealing areas incrementally as players explore:
quest = DescentScenario()
quest.create_quest()
# Show only the first area
quest.show(1)
# Reveal the second area
quest.show(2)
# Reveal the third area
quest.show(3)
# Show the complete map
quest.show()Example: Progressive Map Reveal
Starting with just the first area visible, new sections of the dungeon are revealed as the party progresses:
Note: Run ScenarioBuilder.ipynb to generate example images
- Monster selection: Randomized enemy groups with balanced difficulty
- Treasure distribution: Procedurally placed chests, potions, and relics
- AI behaviors: Monster-specific combat tactics and movement patterns
- Boss encounters: Automatically generated climactic battles
- Save and load generated scenarios
- Export map configurations
- Reproducible quests using seed values
AI_Overlord/
├── descent_ai.py # Core classes: DescentScenario, Monsters, Treasures, etc.
├── ScenarioBuilder.ipynb # Interactive scenario generation demo
├── OverlordAIBuilder.ipynb # Monster AI behavior testing
├── rules.md # Game rules and monster abilities
├── data/ # CSV files for tiles, monsters, terrain
│ ├── tile_import.csv
│ ├── monster_import.csv
│ ├── obstacle_import.csv
│ └── colour_import.csv
└── saved_maps/ # Saved scenario files
pip install -r requirements.txtfrom descent_ai import *
# Generate a new quest
quest = DescentScenario()
quest.create_quest()
# Display the full map
quest.show()
# Save for later
quest.save()Open ScenarioBuilder.ipynb to see the progressive reveal system in action and experiment with different generation parameters.
Each map element is stored as a separate Pandas DataFrame layer:
- Layer 0: Base tile coordinates and IDs
- Layer 1: Wall positions and orientations
- Layer 2: Door placements
- Layer 3: Monster spawn points
- Layer 4: Treasure and obstacle locations
Tile rotations use 2D rotation matrices:
R(θ) = | cos(θ) -sin(θ) |
| sin(θ) cos(θ) |
Applied to tile edge coordinates to compute valid connection points at 90° increments.
- Select random tile from available pool
- Compute all valid rotation orientations using matrix math
- Calculate connection points to existing map structure
- Place tile and update available connection edges
- Repeat until area is complete
See rules.md for complete monster AI behaviors, combat mechanics, and special abilities.
Personal project for Descent: Journeys in the Dark enthusiasts. All game content belongs to Fantasy Flight Games.



