package module
Version: v0.0.0-...-04124d7 Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Apr 18, 2020 License: MIT Imports: 4 Imported by: 0





What is dngn?

dngn is a golang library specifically created to help make generating random maps easier.

Why is it called that?

Because it's short, simple, and to the point. Also, vwls r vrrtd.

Why did you create dngn?

Because I needed to do random map generation for a game and didn't seem to find a library around anywhere.

And so, here we are.

How do I install it?

Just go get it and import it in your game application.

go get github.com/SolarLune/dngn

Or import and use it directly in your code with a go.mod file in your project directory, and it will go ahead and automatically download it and use it for your project. See the Go wiki.

How do I use it?

dngn is based around Rooms and Selections. A Room contains a rune array, representing the Room's data. You can either manipulate the data array manually, or use Selections to grab a selection of cells in the Room to alter.

To start off with using dngn, you can just create a Room, and then use one of the included Generate functions to generate the data:

import "github.com/SolarLune/dngn"

var GameMap *dngn.Room

func Init() {

    // This line creates a new Room. The size is 10x10.
    GameMap = dngn.NewRoom(10, 10)

    // This will select the cells the map has, and then fill the selection with "x"s.

    // Selections are structs, so we can store Selections in variables to store the "view" of the data.
    selection := GameMap.Select()

    // This will run a drunk-walk generation algorithm on the Room. It starts at a random point
    // in the Room, and walks around the Room, placing the value specified (0, in this case)
    // until the room is the percentage provided (0.5, or 50%, in this case) filled.
    GameMap.GenerateDrunkWalk(' ', 0.5)

    // This function will degrade the map slightly, making cells with a ' ' in them randomly turn into a cell with a 'x',
    // depending on how heavily the cell is surrounded by 'x's.
    GameMap.Select().ByRune(' ').Degrade('x')

    // Room.DataToString() will present the data in a nice, easy-to-understand visual format, useful when debugging.

    // Now we're done! We can use the Room.


Selections can also be powerful, as they allow you to easily select cells to manipulate. You can also chain Selection filtering functions together. As an example, say you wanted to randomly change a small percentage of floor tiles (' ') into trap tiles ('z'). You could easily do this with Selections, like so:

    GameMap.Select().ByValue(' ').ByPercentage(0.1).Fill('z')

And that's about it! There are also some nice additional features to make it easier to handle working with and altering Rooms.

Wait... How do I actually LOOK at it?


So dngn just does map generation - it doesn't handle visualization / rendering of the map. For that, you can use another framework, like pixel, Ebiten, raylib-goplus, or go-sdl2.

Soooo that's about it. If you want to see more info or examples, feel free to examine the main.go and world#.go tests to see how a couple of quick example tests are set up.

You can check out the GoDoc link here, as well.

You can also run the example by simply running the example from the project's root directory:

$ go run ./example/


For the actual package, there are no external dependencies. dngn just uses the built-in "fmt" and "math" packages.

For the tests, dngn requires Ebiten to create the window, handle input, and draw the shapes.



Package dngn is a simple random map generation library primarily made to be used for 2D games. It features a simple API, and a couple of different means to generate maps. The easiest way to kick things off when using dngn is to simply create a Room to represent your overall game map, which can then be manipulated or have a Generate function run on it to actually generate the content on the map.



This section is empty.


This section is empty.


This section is empty.


type Room

type Room struct {
	Width, Height int
	Data          [][]rune

	CustomSeed bool
	// contains filtered or unexported fields

Room represents a dungeon map. Width and Height are the width and height of the Room in the layout. This determines the size of the overall Data structure backing the Room layout. Data is the core underlying data structure representing the dungeon. It's a 2D array of runes. Seed is the seed of the Room to use when doing random generation using the Generate* functions below. CustomSeed indicates whether the Seed was customized - if not, then it will default to using the time of the system to have random generation each time you use Generate* functions.

func NewRoom

func NewRoom(width, height int) *Room

NewRoom returns a new Room with the specified width and height.

func NewRoomFromRuneArrays

func NewRoomFromRuneArrays(arrays [][]rune) *Room

NewRoomFromRuneArrays creates a new Room with the data contained in the provided rune arrays.

func NewRoomFromStringArray

func NewRoomFromStringArray(array []string) *Room

NewRoomFromStringArray creates a new Room with the data contained in the provided string array.

func (*Room) Area

func (room *Room) Area() int

Area returns the overall size of the Room by multiplying the width by the height.

func (*Room) Center

func (room *Room) Center() (int, int)

Center returns the center position of the Room.

func (*Room) ClearSeed

func (room *Room) ClearSeed()

ClearSeed clears a custom seed set for random generation. When using a clear seed, random generation functions will use the system's Unix time.

func (*Room) CopyFrom

func (room *Room) CopyFrom(other *Room, x, y int)

CopyFrom copies the data from the other Room into this Room's data. x and y are the position of the other Room's data in the destination (calling) Room.

func (*Room) DataToString

func (room *Room) DataToString() string

DataToString returns the underlying data of the overall Room layout in an easily understood visual format. 0's turn into blank spaces when using DataToString, and the column is shown at the left of the map.

func (*Room) DrawLine

func (room *Room) DrawLine(x, y, x2, y2 int, fillRune rune, thickness int, stagger bool)

DrawLine is used to draw a line from x, y, to x2, y2, placing the rune specified by fillRune in the cells between those points (including) in those points themselves, as well. thickness controls how thick the line is. If stagger is on, then the line will stagger it's vertical movement, allowing a 1-thickness line to actually be pass-able if an object was only able to move in cardinal directions and the line had a diagonal slope.

func (*Room) GenerateBSP

func (room *Room) GenerateBSP(wallValue, doorValue rune, numSplits int)

GenerateBSP generates a map using BSP (binary space partitioning) generation, drawing lines of wallValue runes horizontally and vertically across, partitioning the room into pieces. It also will place single cells of doorValue on the walls, creating doorways. Link: http://www.roguebasin.com/index.php?title=Basic_BSP_Dungeon_generation BUG: GenerateBSP doesn't handle pre-existing doorValues well (i.e. if 0's already exist on the map and you try to use a doorValue of 0 to indicate not to place doors, it bugs out; either it might place a wall where a doorway exists, or it won't place anything at all because everywhere could be a door). A workaround is to use another value that you turn into 0's later.

func (*Room) GenerateDrunkWalk

func (room *Room) GenerateDrunkWalk(fillRune rune, percentageFilled float32)

GenerateDrunkWalk generates a map in the bounds of the Room specified using drunk walking. It will pick a random point in the Room and begin walking around at random, placing fillRune in the Room, until at least percentageFilled (0.0 - 1.0) of the Room is filled. Note that it only counts values placed in the cell, not instances where it moves over a cell that already has the value being placed. Link: http://www.roguebasin.com/index.php?title=Random_Walk_Cave_Generation

func (*Room) GenerateRandomRooms

func (room *Room) GenerateRandomRooms(fillRune rune, roomCount, roomMinWidth, roomMinHeight, roomMaxWidth, roomMaxHeight int, connectRooms bool) [][]int

GenerateRandomRooms generates a map using random room creation. fillRune is the rune to fill the rooms generated with. roomCount is how many rooms to place, roomMinWidth and Height are how small they can be, minimum, while roomMaxWidth and Height are how large they can be. connectRooms determines if the algorithm should also attempt to connect the rooms using pathways between each room. The function returns the positions of each room created.

func (*Room) Get

func (room *Room) Get(x, y int) rune

Get returns the rune in the specified position in the Room's Data array. A convenience function stand-in for "value := room.Data[y][x]".

func (*Room) MinimumSize

func (room *Room) MinimumSize() int

MinimumSize returns the minimum distance (width or height) for the Room.

func (*Room) Resize

func (room *Room) Resize(width, height int) *Room

Resize resizes the room to be of the width and height provided. Note that resizing to a smaller Room is destructive (and so, data will be lost if resizing to a smaller Room).

func (*Room) Rotate

func (room *Room) Rotate()

Rotate rotates the entire room 90 degrees clockwise.

func (*Room) Select

func (room *Room) Select() Selection

Select generates a Selection containing all of the cells of the Room.

func (*Room) SelectContiguous

func (room *Room) SelectContiguous(x, y int) Selection

SelectContiguous generates a Selection containing all contiguous (connected) cells featuring the same value as the cell in the position provided.

func (*Room) Set

func (room *Room) Set(x, y int, char rune)

Set sets the rune provided in the Room's Data. A convenience function stand-in for "room.Data[y][x] = value".

func (*Room) SetSeed

func (room *Room) SetSeed(seed int64)

SetSeed sets a custom seed for random generation.

type Selection

type Selection struct {
	Room  *Room
	Cells [][]int

A Selection represents a selection of cell positions in the Room's data array, and can be filtered down and manipulated using the functions on the Selection struct.

func (Selection) AddSelection

func (selection Selection) AddSelection(other Selection) Selection

AddSelection adds the cells in the other Selection to the current one if they're not already in it.

func (Selection) By

func (selection Selection) By(filterFunc func(x, y int) bool) Selection

By simply takes a function that takes the X and Y values of each cell position contained in the Selection, and returns a boolean to indicate whether to include that cell in the Selection or not. This allows you to easily make custom filtering functions to filter down the cells in a Selection.

func (Selection) ByArea

func (selection Selection) ByArea(x, y, w, h int) Selection

ByArea filters down a selection by only selecting the cells that have X and Y values between X, Y, and X+W and Y+H. It crops the selection, basically.

func (Selection) ByNeighbor

func (selection Selection) ByNeighbor(neighborValue rune, minNeighborCount int, diagonals bool) Selection

ByNeighbor selects the cells that are surrounded at least by minNeighborCount neighbors with a value of neighborValue. If diagonals is true, then diagonals are also checked.

func (Selection) ByPercentage

func (selection Selection) ByPercentage(percentage float32) Selection

ByPercentage selects the provided percentage of the cells curently in the Selection.

func (Selection) ByRune

func (selection Selection) ByRune(value rune) Selection

ByRune filters the Selection down to the cells that have the character (rune) provided.

func (*Selection) Contains

func (selection *Selection) Contains(x, y int) bool

Contains returns a boolean indicating if the specified cell is in the list of cells contained in the selection.

func (Selection) Degrade

func (selection Selection) Degrade(char rune) Selection

Degrade applies a formula that randomly sets the cells in the selection to the provided char rune if their neighbors have that same rune value. The more neighbors that have the rune value, the more likely the selected cell will be set to it as well.

func (Selection) Expand

func (selection Selection) Expand(distance int, diagonal bool) Selection

Expand expands the selection outwards by the distance value provided. Diagonal indicates if the expansion should happen diagonally as well, or just on the cardinal 4 directions.

func (Selection) Fill

func (selection Selection) Fill(char rune) Selection

Fill fills the cells in the Selection with the rune provided.

func (Selection) Invert

func (selection Selection) Invert() Selection

Invert inverts the selection (selects all non-selected cells from the Selection's source Room).

func (Selection) RemoveSelection

func (selection Selection) RemoveSelection(other Selection) Selection

RemoveSelection removes the cells in the other Selection from the current one if they are already in it.

func (Selection) Shrink

func (selection Selection) Shrink(diagonal bool) Selection

Shrink shrinks the selection by one.

Source Files


Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
t or T : Toggle theme light dark auto
y or Y : Canonical URL