Astray
Astray is a lua based maze, room and dungeon generation library for dungeon crawlers and rougelike video games
Astray is a robust Lua library for procedural generation of mazes, rooms, and dungeons. It provides a flexible system for creating diverse layouts suitable for dungeon crawlers, roguelikes, and other games requiring procedural map generation. The project is written primarily in Lua, distributed under the zlib License license, first published in 2014. Key topics include: crawlers, dungeon, dungeon-crawler, love2d, lua.
Astray
Astray is a robust Lua library for procedural generation of mazes, rooms, and dungeons. It provides a flexible system for creating diverse layouts suitable for dungeon crawlers, roguelikes, and other games requiring procedural map generation.
<p align="center"> <a href="https://raw.githubusercontent.com/SiENcE/astray/master/sample.png"> <img border="0" src="https://raw.githubusercontent.com/SiENcE/astray/master/sample.png"> </a> </p>Features
- Procedural maze generation using modified depth-first search
- Customizable room placement and connection
- Configurable parameters for dungeon characteristics:
- Corridor density and sparseness
- Room size and quantity
- Dead end frequency
- Direction change probability
- ASCII map output with customizable tiles
- Support for different cell types (corridors, rooms, doors)
Installation
- Copy the Astray folder to your project:
bashgit clone https://github.com/SiENcE/astray.git
- Include the library in your Lua code:
lualocal astray = require('astray')
Quick Start
lualocal astray = require('astray') -- Initialize generator with desired parameters -- Note: Astray generates uneven-sized maps (e.g., 39x39 from 40x40 input) local height, width = 40, 40 local generator = astray.Astray:new( width/2-1, -- Map width height/2-1, -- Map height 30, -- Change direction modifier (1-30) 70, -- Sparseness modifier (25-70) 50, -- Dead end removal modifier (50-99) astray.RoomGenerator:new( -- Room generator configuration 4, -- Number of rooms 2, 4, -- Min/Max room width 2, 4 -- Min/Max room height ) ) -- Generate dungeon local dungeon = generator:Generate() -- Convert to ASCII tiles local tiles = generator:CellToTiles(dungeon) -- Print the dungeon for y = 0, #tiles[1] do local line = '' for x = 0, #tiles do line = line .. tiles[x][y] end print(line) end
Configuration
Astray Constructor Parameters
luaAstray:new(width, height, changeDirectionMod, sparsenessMod, deadEndRemovalMod, roomGenerator, seed)
| Parameter | Range | Description |
|---|---|---|
| width | > 0 | Width of the dungeon in even numbers (map will be uneven) |
| height | > 0 | Height of the dungeon in even numbers (map will be uneven) |
| changeDirectionMod | 1-30 | Higher values create more winding corridors |
| sparsenessMod | 25-70 | Higher values create sparser layouts (fewer corridors, larger wall regions) |
| deadEndRemovalMod | 50-99 | Higher values remove more dead ends |
| roomGenerator | — | A RoomGenerator instance (see below) |
| seed | optional | Pass a number for a reproducible dungeon; omit for a random one each run |
Room Generator Parameters
luaRoomGenerator:new(rooms, minWidth, maxWidth, minHeight, maxHeight)
| Parameter | Description |
|---|---|
| rooms | Number of rooms to generate |
| minWidth | Minimum room width |
| maxWidth | Maximum room width |
| minHeight | Minimum room height |
| maxHeight | Maximum room height |
Customizing Tiles
You can customize the appearance of generated dungeons by providing a tile mapping:
lualocal symbols = { Wall = '#', Empty = ' ', DoorN = '-', -- north/south doors sit in horizontal walls DoorS = '-', DoorE = '|', -- east/west doors sit in vertical walls DoorW = '|' } local tiles = generator:CellToTiles(dungeon, symbols)
Map Size
A maze is a grid of cells separated by walls, so CellToTiles produces a grid
of cells * 2 + 1 tiles per axis — always an odd number. With
cells = size/2 - 1, the natural output lands one tile short of an even target
(e.g. 40 → 39).
To get an exact size, pass the desired width and height to CellToTiles. It
pads the grid with wall tiles up to that size, keeping the maze sealed:
lualocal width, height = 40, 40 local generator = astray.Astray:new(width/2-1, height/2-1, 30, 70, 50, astray.RoomGenerator:new(4, 2, 4, 2, 4)) -- Pad the natural 39x39 grid up to an exact 40x40 local tiles = generator:CellToTiles(dungeon, symbols, width, height)
Targets smaller than the natural size are ignored — cropping would expose cell
interiors and leave the maze unsealed. Omit the target arguments to keep the
natural odd size.
Example Output
Map size= 39 39
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓ ▓▓▓-▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓ | ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓-▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓ | | ▓ ▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓ ▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓ ▓ ▓
▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓
▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓
▓ ▓-▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓
▓ | ▓▓▓▓▓ ▓▓▓ ▓ ▓
▓ ▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓ ▓▓▓
▓ ▓ ▓▓▓▓▓▓▓▓▓ ▓ ▓
▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓
▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓
▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓
▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓
▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓
▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓
▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓
▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓
▓ ▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓ ▓
▓ ▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓ ▓
▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓-▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓ ▓▓▓
▓▓▓▓▓▓▓▓▓ | | ▓▓▓ ▓▓▓▓▓ ▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓ ▓▓▓ ▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓-▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
License
Distributed under the zlib/libpng License. See LICENSE for more information.
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Acknowledgments
This work is based on various dungeon generation techniques and algorithms:
- Dirkkok's Random Dungeon Generation
- Myth-Weavers Dungeon Generator
- Thomas Bowker's Dungeon Generation
Support
For issues, questions, or contributions, please visit the GitHub repository.
Author
Florian Fischer
Contributors
Showing top 1 contributor by commit count.
