npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

random-dungeon-generator-ts

v1.0.0

Published

A Telengard-style random dungeon generator for TypeScript/JavaScript projects.

Readme

Random Dungeon Generator

A Telengard-style random dungeon generator for TypeScript/JavaScript projects. Generates repeatable, room-and-hallway dungeons using a seeded PRNG.

Features

  • Generates dungeons with rooms and hallways
  • Seeded for repeatable results
  • TypeScript and JavaScript compatible
  • Easily integrated into games or map tools

Installation

npm install random-dungeon-generator

Repeatability & Seeding

This generator uses a seeded pseudo-random number generator (PRNG). If you provide the same seed and parameters, you will always get the same dungeon layout. This is useful for:

  • Sharing dungeon layouts with others
  • Debugging and testing
  • Saving and reloading specific dungeons

Example:

import { DungeonGenerator } from 'random-dungeon-generator';

const generator = new DungeonGenerator();
const result1 = generator.generate(30, 20, 12345);
const result2 = generator.generate(30, 20, 12345);

console.log(result1.map);
console.log(result2.map);
// result1.map and result2.map will be identical
import { DungeonGenerator } from 'random-dungeon-generator';

const generator = new DungeonGenerator();
const result = generator.generate(30, 20, 12345);
console.log(result.map);

API

DungeonGenerator

generate(width: number, height: number, seed?: number | null, roomAttempts?: number, minRoomSize?: number, maxRoomSize?: number): DungeonResult

  • width (number): Number of columns in the dungeon (horizontal size)
  • height (number): Number of rows in the dungeon (vertical size)
  • seed (number, optional): Integer seed for repeatability (same seed = same dungeon)
  • roomAttempts (number, optional): How many times to try placing a room (default: 30)
  • minRoomSize (number, optional): Minimum width/height of a room (default: 3)
  • maxRoomSize (number, optional): Maximum width/height of a room (default: 7)
  • Returns: DungeonResult object containing the map, seed, and rooms

Example

import { DungeonGenerator } from 'random-dungeon-generator';

const generator = new DungeonGenerator();
const result = generator.generate(30, 20, 12345);
console.log(result.map);

exportDungeonToJson(width, height, seed?)

  • Utility function to generate a dungeon and export it as a JSON string.
  • Parameters are the same as generate above.
  • Returns: JSON string representing the dungeon result.

Types

  • Tile: 'wall' | 'floor'
  • RoomType: 'start' | 'end' | 'safe' | 'none'
  • Room:
    • x, y: Top-left coordinates
    • w, h: Width and height
    • roomNumber: Unique room number (starts at 1)
    • roomType: RoomType enum value
    • numberFromStart: Number of rooms to traverse from start
  • DungeonResult:
    • map: 2D array of Tile values
    • seed: The seed used for generation
    • rooms: Array of Room objects

Example

See test_dungeon.ts for a full example that prints a dungeon to the console.

Why use this package?

  • TypeScript-first: Full type support and documentation for modern JS/TS projects.
  • Repeatable dungeons: Seeded PRNG ensures the same parameters always generate the same map.
  • Simple API: Minimal, easy-to-use interface for quick integration.
  • Room and hallway style: Classic Telengard-style layouts, great for roguelikes and retro games.
  • Framework agnostic: Use in Node.js, browser, or with game engines like Phaser or PixiJS.

Usage Example & Sample Output

Here’s a demo script that prints a dungeon to the console, marking the start room (S), end room (E), room numbers, hallways (H), and unreachable spaces:

import { DungeonGenerator, RoomType } from 'random-dungeon-generator';

const generator = new DungeonGenerator();
const result = generator.generate(30, 20, 12345);
const map = result.map;
const rooms = result.rooms;

// Build a lookup for room positions and types
const roomLookup = new Map();
const roomNumberLookup = new Map();
for (const room of rooms) {
  for (let ry = room.y; ry < room.y + room.h; ry++) {
    for (let rx = room.x; rx < room.x + room.w; rx++) {
      roomLookup.set(`${ry},${rx}`, room.roomType);
      roomNumberLookup.set(`${ry},${rx}`, room.roomNumber);
    }
  }
}

// BFS to find reachable floor tiles from the start room
let startRoom = rooms.find(r => r.roomType === RoomType.Start);
const reachable = new Set<string>();
if (startRoom) {
  const queue: [number, number][] = [];
  const visited = new Set<string>();
  for (let ry = startRoom.y; ry < startRoom.y + startRoom.h; ry++) {
    for (let rx = startRoom.x; rx < startRoom.x + startRoom.w; rx++) {
      queue.push([ry, rx]);
      visited.add(`${ry},${rx}`);
    }
  }
  while (queue.length > 0) {
    const next = queue.shift();
    if (!next) continue;
    const [y, x] = next;
    reachable.add(`${y},${x}`);
    for (const [dy, dx] of [[0,1],[1,0],[0,-1],[-1,0]] as [number, number][]) {
      const ny = y + dy, nx = x + dx;
      if (ny >= 0 && ny < map.length && nx >= 0 && nx < map[0].length) {
        if (map[ny][nx] === 'floor' && !visited.has(`${ny},${nx}`)) {
          queue.push([ny, nx]);
          visited.add(`${ny},${nx}`);
        }
      }
    }
  }
}
function roomNumChar(num: number | undefined) {
  if (num == null) return '?';
  if (num >= 1 && num <= 9) return String(num);
  if (num >= 10 && num <= 35) return String.fromCharCode(55 + num); // 10->A, 11->B, ...
  if (num >= 36 && num <= 61) return String.fromCharCode(61 + num); // 36->a, 37->b, ...
  return '*';
}
const out = map.map((row, y) => row.map((t, x) => {
  const key = `${y},${x}`;
  if (!reachable.has(key)) return ' ';
  const type = roomLookup.get(key);
  const num = roomNumberLookup.get(key);
  if (type === RoomType.Start) return 'S';
  if (type === RoomType.End) return 'E';
  if (type === undefined) return 'H'; // Hallway
  if (typeof num === 'number') return roomNumChar(num);
  return ' ';
}).join('')).join('\n');
console.log(out);

Sample Output:

##############################
#   1HHH2HHH3HHH4HHH5HHH6HHH #
#   H   H   H   H   H   H   #
#   7HHH8HHH9HHHAHHHBHHHCHHH #
#   H   H   H   H   H   H   #
#   DHHHEHHHFHHHGHHHHHHIHHH #
#   H   H   H   H   H   H   #
#   JHHHKHHHLHHHMHHHNHHHOHHH #
#   H   H   H   H   H   H   #
#   PHHHQHHHRHHHSHHHTHHHUHHH #
#   H   H   H   H   H   H   #
#   VHHHWHHHXHHHYHHHZHHH1HHH #
#   H   H   H   H   H   H   #
#   2HHH3HHH4HHH5HHH6HHH7HHH #
#   H   H   H   H   H   H   #
#   8HHH9HHHAHHHBHHHCHHHDHHH #
#   H   H   H   H   H   H   #
#   EHHHFHHHGHHHHHHIHHHJHHH #
#   H   H   H   H   H   H   #
#   KHHHLHHHMHHHNHHHOHHHPHHH #
##############################

See test_dungeon.ts for a full working example.

License

MIT