GitPedia

Astray

Astray is a lua based maze, room and dungeon generation library for dungeon crawlers and rougelike video games

From SiENcE·Updated June 22, 2026·View on GitHub·

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

License: Zlib

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

  1. Copy the Astray folder to your project:
bash
git clone https://github.com/SiENcE/astray.git
  1. Include the library in your Lua code:
lua
local astray = require('astray')

Quick Start

lua
local 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

lua
Astray:new(width, height, changeDirectionMod, sparsenessMod, deadEndRemovalMod, roomGenerator, seed)
ParameterRangeDescription
width> 0Width of the dungeon in even numbers (map will be uneven)
height> 0Height of the dungeon in even numbers (map will be uneven)
changeDirectionMod1-30Higher values create more winding corridors
sparsenessMod25-70Higher values create sparser layouts (fewer corridors, larger wall regions)
deadEndRemovalMod50-99Higher values remove more dead ends
roomGeneratorA RoomGenerator instance (see below)
seedoptionalPass a number for a reproducible dungeon; omit for a random one each run

Room Generator Parameters

lua
RoomGenerator:new(rooms, minWidth, maxWidth, minHeight, maxHeight)
ParameterDescription
roomsNumber of rooms to generate
minWidthMinimum room width
maxWidthMaximum room width
minHeightMinimum room height
maxHeightMaximum room height

Customizing Tiles

You can customize the appearance of generated dungeons by providing a tile mapping:

lua
local 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. 4039).

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:

lua
local 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

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Acknowledgments

This work is based on various dungeon generation techniques and algorithms:

Support

For issues, questions, or contributions, please visit the GitHub repository.

Author

Florian Fischer

Contributors

Showing top 1 contributor by commit count.

View all contributors on GitHub →

This article is auto-generated from SiENcE/astray via the GitHub API.Last fetched: 6/29/2026