Skip to main content

license pipelines coverage

nwn-dg

Neverwinter Nights (nwn) dungeon generator: cli & api.

nwn-dg lays out rooms and corridors on a grid, carves them into a connected maze, then maps every cell onto a real NWN tileset. The result can be written as a playable area file, as a preview image, or as json for a running server to consume through SetTileJson().

Work in progress: in alpha/beta stage. Please refer to file POC.md for more information.

Installation

You can install the latest version from PyPI package repository.

pipx install nwn-dg

Building the pycairo dependency requires the cairo development headers. On Debian, install them with apt-get install libcairo2-dev beforehand.

Writing binary .are files additionally requires nwn_gff, from the neverwinter.nim tools. It is only needed for --output-are. On Debian 12 (Bookworm) and later, it is packaged as neverwinter.nim in the unofficial nwn.ovh repository:

source /etc/os-release
sudo wget https://debian.nwn.ovh/sources.list.d/${VERSION_CODENAME}.sources -O /etc/apt/sources.list.d/nwn-ovh.sources
sudo wget https://debian.nwn.ovh/nwn-ovh-archive.gpg -O /usr/share/keyrings/nwn-ovh-archive.gpg
sudo apt-get update
sudo apt-get install -y neverwinter.nim

Usage

Command line interface

Generate a dungeon and write a preview image:

nwn-dg --output-tileset tdc01 mydungeon

A more complete run, writing the area, the tile json and the random seed:

nwn-dg --seed mydungeon.seed --output-seed \
       --output-png --output-are --output-tile-json \
       --output-tileset tdc01 \
       --png-axes-ids --png-axes-base 0 --png-tileset-idx \
       mydungeon

The positional argument is a base filepath; each output appends its own extension to it.

Map size, room count and corridor shape are set through the --map-* options; --map-door-entrance and --map-door-exits place the stairs, taking N, E, S, W or X for random, one letter per door. Run nwn-dg --help for the full list and current defaults.

Options documented as "may cause generation failure" constrain the generator enough that no valid dungeon may exist for a given seed. nwn-dg exits with an error rather than returning a broken map; retry with another seed or different options.

In order to test generated outputs, it's possible to create the are file, and to copy it to the module folder in your toolset profile hierarchy. When area is closed and re-opened it should have the proper new layout.

Api

The generator is also exposed over https, so a live module can request a fresh dungeon through NWNX_HTTPClient instead of shipping pre-generated files.

Start the server:

nwn-dg-api --port 8080

Serving over tls, which is what a module reaching an https:// url expects:

nwn-dg-api --port 8080 \
           --ssl-certfile ./ssl/localhost.crt \
           --ssl-keyfile ./ssl/localhost.key

A self-signed certificate is enough when the api and the game server sit on the same host:

mkdir -p ./ssl
openssl req -new -x509 -days 365 -noenc \
        -out ./ssl/localhost.crt -keyout ./ssl/localhost.key

From a checkout, the launcher is ./bin/nwn-dg-api. Run nwn-dg-api --help for the full list of options.

Docker

The api also ships as a container image, which saves installing the cairo headers:

Registry Image
GitLab registry.gitlab.com/cappysan/apps/nwn-dg:latest
Docker Hub nwnovh/nwndg:latest

The server listens on port 8000 inside the container; publish it on whatever the game server can reach:

docker run -d -p 8001:8000 nwnovh/nwndg:latest
docker run -d -p 8001:8000 registry.gitlab.com/cappysan/apps/nwn-dg:latest

Endpoint

POST /dungeon/tilejson generates a dungeon and returns the same document as --output-tile-json, as the response body.

  • The request body must be sent as application/json; the schema in openapi.yml declares no other content type and anything else is rejected.
  • Keys are the cli long options without their leading --, so --map-width 21 becomes "map-width": 21.
  • An empty object generates a dungeon with every default.
  • File-writing output-* flags are ignored, since the endpoint returns the document rather than writing it; output-tileset is honoured and selects the tileset as it does on the command line.
curl -k -X POST https://localhost:8080/dungeon/tilejson \
     -H 'Content-Type: application/json' \
     -d '{"output-tileset": "tdm01", "map-width": 21, "map-height": 9}'

Passing seed reproduces an exact dungeon, the same way --seed does on the command line:

curl -k -X POST https://localhost:8080/dungeon/tilejson \
     -H 'Content-Type: application/json' \
     -d '{"output-tileset": "tdm01", "seed": "mydungeon"}'

-k is only needed for a self-signed certificate. On the module side, see POC examples/nwn_dg.nss for the matching request and the SetTileJson() call it feeds.

Outputs

Flag Extension Contents
--output-png .png Map preview, with optional room ids, axes and tile indexes
--output-are-json .are.json The area as json, ready for nwn_gff
--output-are .are Binary area file, converted with nwn_gff
--output-tile-json .tile.json Input for SetTileJson(), see below
--output-tree .tree.png Graph of connected rooms
--output-seed .seed Random state, for reproducing the exact same dungeon

--output-png and --output-are-json are on by default; the rest are off. Every flag has a --no- counterpart.

Reproducibility

--seed accepts either a seed value or a path to a .seed file, whose content restores the full random state. Combined with --output-seed, any dungeon can be regenerated byte for byte. The state is also embedded, base64 encoded, in the seed key of the tile json, so an area artifact is self-describing.

Tile json

--output-tile-json writes what a module needs to build the area at runtime and then populate it:

  • tiles — tile id and orientation per index, for SetTileJson()
  • rooms — per room: neighbouring rooms, the cells it owns, and its sills
  • transitions — stairs up and down, with orientation, the room they open onto, whether they are the dungeon entrance, and the walking distance to every room
  • paths — the longest routes through the dungeon, as room ids
  • cells — deadends, useful for treasure and traps

See POC examples/nwn_dg.nss for a proof-of-concept module script consuming it.

Tilesets

Type Tileset
tdc01 Crypt
tdm01 Mines and Caverns
tds01 Sewers

See https://nwnlexicon.com/Tileset_resref.

Additional resources

License

This project is licensed under the MIT License - see the LICENSE file for details.

Locations

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nwn_dg-0.7.1.tar.gz (162.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nwn_dg-0.7.1-py3-none-any.whl (179.7 kB view details)

Uploaded Python 3

File details

Details for the file nwn_dg-0.7.1.tar.gz.

File metadata

  • Download URL: nwn_dg-0.7.1.tar.gz
  • Upload date:
  • Size: 162.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.11.16

File hashes

Hashes for nwn_dg-0.7.1.tar.gz
Algorithm Hash digest
SHA256 b68fa73032391d71cfe11c6d9c5c8b27300550498b87808ad499d61e50ac7b1a
MD5 800aaa84f51837d4b6aa252b2e5187b1
BLAKE2b-256 6c7994ab8c0a3d8a7d70520ac792fce7e942ef5909bad8bb8f211c697ba174ac

See more details on using hashes here.

File details

Details for the file nwn_dg-0.7.1-py3-none-any.whl.

File metadata

  • Download URL: nwn_dg-0.7.1-py3-none-any.whl
  • Upload date:
  • Size: 179.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.11.16

File hashes

Hashes for nwn_dg-0.7.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6106f524d3105dd0882603207611071c61dd09ced06fa4cee8aa4d5990164813
MD5 d1d391797fe489cef07bf9613a602441
BLAKE2b-256 c62750fbecf8a7359794e4e273fc5d4d92790e4ed54e24397733531c3f34ce9a

See more details on using hashes here.

Release history Release notifications | RSS feed

0.7.3

2 files

0.7.2

2 files

This release

0.7.1 This release

2 files

0.7.0

2 files

0.6.0

2 files

0.5.0

2 files

0.4.1

2 files

0.3.0

2 files

0.2.1

2 files

0.2.0

2 files

0.1.1

2 files

0.1.0

2 files

0.0.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page