Live Demo • Installation • Usage • Docs • Algorithms • Contributing
A JavaScript procedural generator for Mazes, Terrains, and Biomes. Designed for game developers and professional hobbyists, Labyrinthos.js offers a very simple-to-use API for crafting complex, customizable landscapes.
- Procedural Generation - Create vast, diverse maps and mazes algorithmically
- 2D and 3D Map Generation - Supports both 2D Tile Maps and 3D Voxel Map generation
- Submap Embedding - Seamlessly integrate smaller maps into larger maps
- TileMap Queries - Easily query subsections of a
TileMap
for applying custom transforms - TileSet Support - Flexible
TileSet
mapping for assigning metadata toTileMap
ids - Biomes - Create realastic Biomes with weighted distribution and Perlin Noise
- Parametric L-Systems - Create generational enviroments using L-Systems with parameters
- Realiable Randomness - Leverages Mersenne Twister for advanced predictable randomness
- ASCII Masking - Built-in support for generating custom Roguelike game maps
- Export Functionality - Easily export maps in various formats, including Tiled
.tmj
JSON
CDN Release 1.1.0
Files | CDN | Size |
---|---|---|
labyrinthos.js | Link | 160kb |
labyrinthos.min.js | Link | 60kb |
NPM
npm install labyrinthos
You can explore all Maze and Terrain generators in the browser with our live demo.
If you click "Explore 2D" or "Explore 3D" in the demo, the TileMap will open in an instance of Mantra.js.
laby-editor.mp4
laby-3d-view.mp4
laby-2d-perlin.mp4
This demo can export generated maps to Tiled JSON format ( with default bundled TileSet
assets ).
Labyrinthos map data is internally represented by arrays of integers.
let map = new LABY.TileMap({
width: 3,
height: 3
});
map.fill(2)
The TileMap.data
array will contain an array that looks like this:
[2, 2, 2, 2, 2, 2, 2, 2, 2]
Each integer value in TileMap.data
array corresponds to a Tile.id
.
let map = new LABY.TileMap({
width: 3,
height: 3,
depth: 3
});
map.fill(3);
For 3D Voxel Maps, TileMap.data
is a nested array with first index representing depth
values.
[
[3, 3, 3, 3, 3, 3, 3, 3, 3],
[3, 3, 3, 3, 3, 3, 3, 3, 3],
[3, 3, 3, 3, 3, 3, 3, 3, 3]
]
From Yantra CDN Build
<script src="https://yantra.gg/labyrinthos.js"></script>
<script>
document.addEventListener('DOMContentLoaded', (event) => {
let map = new LABY.TileMap({
width: 32,
height: 32
});
map.fill(1); // fill entire map with 1
labyrinthos.mazes.RecursiveBacktrack(map, {});
console.log('RecursiveBacktrack', map);
// output maze with ASCII mask
console.log(map.mask());
});
</script>
Using labyrinthos npm
package
Each TileMap
has a TileMap.use()
method which can be used to embed maps inside each other. The following example creates (4) quadrants:
import labyrinthos from 'labyrinthos';
// Main map - 8x8 = 64 tiles
const mainMap = new labyrinthos.TileMap({ width: 8, height: 8 });
// Sub maps - 4x4 = 16 tiles each
const subMap1 = new labyrinthos.TileMap({ width: 4, height: 4 });
const subMap2 = new labyrinthos.TileMap({ width: 4, height: 4 });
const subMap3 = new labyrinthos.TileMap({ width: 4, height: 4 });
const subMap4 = new labyrinthos.TileMap({ width: 4, height: 4 });
// Fill each submap with distinct values
subMap1.fill(1);
subMap2.fill(2);
subMap3.fill(3);
subMap4.fill(4);
// Position submaps in each quadrant of the main map
mainMap.use(subMap1, 0, 0); // Top-left quadrant
mainMap.use(subMap2, 4, 0); // Top-right quadrant
mainMap.use(subMap3, 0, 4); // Bottom-left quadrant
mainMap.use(subMap4, 4, 4); // Bottom-right quadrant
console.log('mainMap', mainMap);
console.log(mainMap.mask());
You can find more examples at: ./examples
let myMap = new LABY.TileMap({
x: 0,
y: 0,
width: 32,
height: 32
})
This will generate a new TileMap
instance with default data. From here we can run either a Maze
or Terrain
algorithm on the myMap
object like:
LABY.mazes.RecursiveBacktrack(myMap);
// shows myMap data array
console.log(myMap.data);
// renders myMap with default ASCII chart
console.log(myMap.mask());
Queries subsections of the map and returns a new TileMap
instance.
see: ./examples/tilemap-query.js
;
Embed Maps / Nest Map / Use submaps. This is useful for creating larger composite maps and re-using maps.
see: ./examples/sub-maps.js
;
Apply custom mask to map data and view as ASCII text.
see: ./examples/roguelike-mask.js
The terrain generators will return a value from 0-1, this needs to be scaled to match a TileSet
whole integer index value.
For example, calling tileMap.scaleToTileRange(10)
, will scale all the values to a range of 0-9 using whole integers.
Exports the TileMap
to the Tiled data format.
- [✅] - Aldous-Broder Algorithm
- [✅] - Binary Tree Algorithm
- [✅] - Cellular Automata
- [✅] - Eller's Algorithm
- [✅] - Growing Tree Algorithm
- [✅] - Recursive Backtracking
- [✅] - Recursive Division
- [✅] - Spiral Backtracking
- [✅] - Thomas Hunter
- - Trémaux's Algorithm
- - Random Walk
- - Maze Growing Algorithm (Seeded Growth)
- - Voronoi Diagrams
- - Randomized Prim's Algorithm
- - Randomized Kruskal's Algorithm
- - Wilson's Algorithm
- - Hunt-and-Kill Algorithm
- - Sidewinder Algorithm
- - Fractal Recursive Maze
- [✅] - Perlin Noise
- [✅] - Fault Line Algorithm
- - Diamond-Square Algorithm
- - Simplex Noise
- - Voronoi Diagrams
- - Midpoint Displacement
- - Cellular Automata (for terrain erosion)
- - Hybrid Multi-fractal Terrain Generation
- - Particle Deposition
- - Value Noise
- [✅] - Circle
- [✅] - Square
- [✅] - Triangle
- - Hexagon
- [✅] - Basic
- [✅] - Parameteric Rules using custom
function(context)
- - Parameteric Rules with Sutra.js
npm test
If you have any issues using Labyrinthos.js or wish to improve the Labyrinthos.js please feel free to Open An Issue or Open A Pull Request.
Labyrinthos.js intends to support a wide variety or generators. Let's do this!
Discord Invite:: https://discord.gg/QgNAZhG9nF
Yantra Works 2023 AGPL