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

doom-osm-godmode

v1.2.2

Published

DOOM OSM GODMODE — Turn any real-world place into a playable GZDoom WAD. Geocode → OSM → UDMF → PWAD. Zero dependencies.

Downloads

107

Readme


Give it a place name, a GeoJSON file, or a config — it geocodes through Nominatim, pulls polygon features from OpenStreetMap via Overpass, projects them into a connected room-and-corridor layout, and writes a PWAD in UDMF format ready for GZDoom.

Zero npm dependencies. Node 20+ only.

Quick Start

# run the bundled demo (offline, no network)
npm run demo

# build a real place
node src/cli.js build-place "Colosseum, Rome, Italy" --radius 450
node src/cli.js build-place "Eiffel Tower, Paris" --radius 450

# hand-crafted architecturally accurate building
node scripts/build-galway-cathedral.js

# search without building
node src/cli.js search "Eiffel Tower, Paris"

# build from a config file
node src/cli.js build-config examples/colosseum.json

Installation

git clone https://github.com/eoinjordan/doom-osm-godmode.git
cd doom-osm-godmode
npm test          # verify everything works
npm run demo      # generate a WAD from the bundled demo site

Or install globally from npm:

npx doom-osm-godmode build-place "Colosseum, Rome" --radius 450

No npm install needed — there are no dependencies.

Start the map on GZDOOM or Ultimate on Windows:

"C:\Games\GZDoom\gzdoom.exe" -iwad "C:\Program Files (x86)\Steam\steamapps\common\Ultimate Doom\base\doom2\DOOM2.WAD" -file "C:\Users\Eoin\git\doom-osm-wad\output\galway-cathedral-v3\MAP01.wad" +map MAP01

Screenshots

CLI Reference

doom-osm-godmode

Commands:
  search <query>                              Search Nominatim for a place
  build-place <query> [options]               Geocode + OSM fetch + WAD export
  build-config <config.json>                  Build from a JSON config file
  demo [--out output/demo-site]               Build the bundled demo WAD

Options for build-place:
  --radius <meters>     Override bounding box with a fixed radius (default: use Nominatim bbox)
  --map <MAPXX>         Map lump name (default: MAP01)
  --max-rooms <count>   Cap on rooms generated (default: 12)
  --title <name>        Override the map title
  --out <dir>           Output directory (default: output/<slugified-title>)

Programmatic API

const { buildFromPlace, buildFromConfig, buildDemo } = require('doom-osm-godmode');

// from a place name (hits Nominatim + Overpass)
const result = await buildFromPlace('Sydney Opera House', {
  radiusMeters: 500,
  mapName: 'MAP01',
  maxRooms: 10,
  outputDir: './output/sydney'
});

// from a config file (place query or offline GeoJSON)
const result = await buildFromConfig('examples/colosseum.json');

// bundled demo (no network)
const result = await buildDemo('./output/demo');

All functions return { outputDir, mapPath, featureCount, exportedFeatures }.

Output

Each build writes a folder containing:

| File | Description | |------|-------------| | site.json | Normalized feature set with projected metrics | | layout.json | Room/corridor grid layout used for WAD generation | | TEXTMAP.udmf | Human-readable UDMF map geometry | | MAPINFO.txt | GZDoom map metadata (sky, music, title) | | <MAPXX>.wad | Packaged PWAD — load this in GZDoom |

Config Format

Place query (network):

{
  "title": "Colosseum District",
  "mapName": "MAP01",
  "placeQuery": "Colosseum, Rome, Italy",
  "radiusMeters": 450,
  "maxRooms": 10,
  "outputDir": "../output/colosseum"
}

Offline GeoJSON:

{
  "title": "Demo Waterfront",
  "mapName": "MAP01",
  "inputGeoJson": "demo-site.geojson",
  "maxRooms": 8,
  "outputDir": "../output/demo-site"
}

Relative paths in configs resolve from the config file's directory.

Architecture

place query / GeoJSON
       │
       ▼
   geocode.js ──► Nominatim API
       │
       ▼
     osm.js ────► Overpass API (polygon features)
       │
       ▼
 feature-set.js   project to local coords, filter, sort
       │
       ▼
   layout.js      grid-based room placement + corridors + theming
       │
       ▼
    udmf.js       UDMF vertices, linedefs, sidedefs, sectors, things
       │
       ▼
    wad.js        binary PWAD packaging
       │
       ▼
  MAP01.wad       ready for GZDoom

Key Source Files

| File | Purpose | |------|---------| | src/cli.js | CLI entry point and command router | | src/workflow.js | Build pipeline orchestrator | | src/geocode.js | Nominatim geocoding | | src/osm.js | Overpass polygon fetching | | src/feature-set.js | Feature normalization and projection | | src/geo.js | Mercator projection, bbox, polygon math | | src/layout.js | Grid room placement, corridors, theming | | src/udmf.js | UDMF text map generation | | src/wad.js | PWAD binary packing | | src/lib/cli.js | Argument parser | | src/lib/fs.js | File I/O utilities |

Room Theming

Features are themed by kind:

| Kind | Floor | Ceiling | Light | Notes | |------|-------|---------|-------|-------| | building | stone | flat | 152 | Default indoor | | water | nukage | flat | 144 | Floor at -24 | | park | grass | sky | 176 | Outdoor feel | | road | light stone | flat | 160 | Corridors |

Testing

npm test          # smoke tests via node:test
npm run check     # syntax-check all source files
npm run validate  # structural WAD/UDMF validation (builds + verifies integrity)

Agent Playtest via doom-mcp

Generated WADs can be playtested by an AI agent using doom-mcp — a Rust MCP server that embeds the real DOOM engine.

Quick setup

The repo includes a .mcp.json that configures doom-mcp to load your demo WAD:

# 1. Build a WAD first
npm run demo

# 2. Playtest it (automated agent navigation sequence)
npm run playtest -- output/demo-site/MAP01.wad

# 3. Or playtest a real-place WAD
node src/cli.js build-place "Colosseum" --radius 450
npm run playtest -- output/colosseum/MAP01.wad --skill 1 --ticks 300

What the playtest validates

The automated playtest spawns doom-mcp, loads the WAD, and runs through a navigation sequence:

  • Game starts — doom engine accepts the WAD
  • Player spawns — HP > 0 at spawn point
  • Player can move — position changes across multiple actions
  • Player survives — doesn't die during baby-difficulty walkthrough

Using doom-mcp interactively

For interactive agent playtesting (e.g., in Claude Code or Cursor):

{
  "mcpServers": {
    "doom": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "doom-mcp"],
      "env": {
        "DOOM_WAD_PATH": "/path/to/your/MAP01.wad"
      }
    }
  }
}

Then tell the agent: "Play this DOOM level and tell me if it's fun"

CI integration

The playtest.yml workflow runs structural validation on every tag push and can be triggered manually for any place:

Actions → Playtest → Run workflow → Enter place name → Go

Playing the WAD

# GZDoom (adjust path to your install)
gzdoom -file output/colosseum/MAP01.wad

The WAD is a PWAD — it layers on top of any IWAD (DOOM2.WAD, FREEDOOM2.WAD, etc.).

Hand-Crafted Buildings

The OSM pipeline creates grid-based rooms. For architecturally accurate buildings (cathedrals, temples, etc.), use a hand-crafted script:

# Build the Galway Cathedral demo (cross-shaped plan, green copper dome, grand nave)
node scripts/build-galway-cathedral.js

# Launch in GZDoom
gzdoom -iwad DOOM2.WAD -file output/galway-cathedral-v3/MAP01.wad +map MAP01

The cathedral builder demonstrates the UDMFBuilder class with polygon-based sector creation, grand interior aisle, raised chancel, self-validation, and exterior forecourt. Use it as a template for new hand-crafted maps.

Example maps included:

| Map | Type | Script / Command | |-----|------|------------------| | Galway Cathedral | Hand-crafted | node scripts/build-galway-cathedral.js | | Colosseum, Rome | OSM / live | node src/cli.js build-place "Colosseum, Rome, Italy" --radius 450 | | Eiffel Tower, Paris | OSM / live | node src/cli.js build-place "Eiffel Tower, Paris" --radius 450 | | Demo Waterfront | Offline GeoJSON | npm run demo |

Validate any WAD

# Structural UDMF diagnostic (checks for duplicate linedefs, etc.)
node scripts/diagnose-udmf.js output/galway-cathedral-v3/TEXTMAP.udmf

# Agent playtest via doom-mcp
npm run playtest -- output/galway-cathedral-v3/MAP01.wad

UDMF Geometry Rules

Common issues found when generating DOOM maps from real-world data:

| Issue | Symptom | Fix | |-------|---------|-----| | Duplicate linedefs (same vertex pair) | Flickering/transparent walls | Use a single polygon for complex shapes; deduplicate in addInnerSector | | Collinear overlapping linedefs | See-through walls, BSP errors | Never let two linedefs share the same 2D line segment | | Inner sector outside parent bounds | Rendering void, hall-of-mirrors | Ensure all inner sector vertices are strictly inside the outer polygon | | Separate rooms at same crossing | Duplicate shared edges | Use ONE polygon for the union shape (e.g., a cross), not overlapping rectangles | | Underground areas sharing x,y with upper | DOOM 2.5D sector conflict | Place underground areas at different x,y coords; connect via teleporter | | Invisible walls on two-sided linedefs | Side walls transparent where floor heights match | Set wrapmidtex = true + blocking = true + texturemiddle on the two-sided linedef | | Floating mid-textures on promoted linedefs | Choppy half-height walls | Clear texturemiddle when promoting one-sided to two-sided; use upper/lower instead | | Zero-height pillar sectors (floor = ceiling) | Player stuck, node builder errors | Use Thing-based pillars (type 30) instead of sector-based pillars |

Repeatable pattern for future OSM meshes

  1. Run node src/cli.js build-place ... for the grid-room WAD
  2. Run node scripts/diagnose-udmf.js output/<name>/TEXTMAP.udmf to check geometry
  3. Run npm run playtest -- output/<name>/MAP01.wad for engine validation
  4. If the grid rooms are too abstract, create a hand-crafted script (see scripts/build-galway-cathedral.js)
  5. Always run self-validation before writing the WAD

Notes

  • Network commands use public OSM infrastructure (Nominatim, Overpass). Keep requests reasonable.
  • Only polygon features become rooms. Roads and linear features are not yet carved into sectors.
  • The layout is a blockout interpretation — connected rooms reflecting real feature hierarchy, not pixel-perfect street geometry.

Roadmap

  • exact polygon-to-sector carving (replace grid rooms with real building outlines)
  • road and canal line buffering into traversable sectors
  • Doom encounter placement (monsters, ammo, weapons)
  • texture themes per location style
  • multi-map episode generation
  • freeform agent-described layouts (no OSM needed)
  • automatic duplicate linedef detection in the OSM pipeline

Contributing

PRs welcome. Run npm test and npm run check before submitting.

License

MIT — see LICENSE