39 lines
1.5 KiB
Markdown
39 lines
1.5 KiB
Markdown
---
|
|
title: "Nethack's Level Generation"
|
|
date: 2023-02-05T09:08:07-08:00
|
|
draft: true
|
|
---
|
|
|
|
I recently became interested in how Nethack generates levels. It has a distinctive feel that's uniquely Nethack, and
|
|
that can't be perfectly replicated with "room and corridor" algorithms that I've studied so far. Nethack's source code
|
|
is freely available on Github, though as I discovered while researching for this article, having it available doesn't
|
|
mean it's easy to understand.
|
|
|
|
I'm basing this entire series on the [Nethack 3.6][nh36] branch.
|
|
|
|
### Basics
|
|
|
|
It's written in C, using C89 style function declarations. You see a lot of functions defined like this, with the types
|
|
of arguments defined below the function declaration:
|
|
|
|
```c
|
|
int
|
|
a_function(a, b, c)
|
|
int a, b;
|
|
char c
|
|
{
|
|
// ...
|
|
}
|
|
```
|
|
|
|
The standard Dungeons of Doom map style is a hallmark of Nethack, Hack, and Rogue. Given this long lineage, the map
|
|
generator is (I suspect) one of the older parts of the codebase. A lot of the architectural decisions reflect a differen
|
|
time and place: it strives to be extremely memory and CPU efficient, reuses global in-memory structures rather than
|
|
declaring new ones, and generally makes due with less as often as possible. This includes variable names too.
|
|
|
|
Most of this happens in [`mklev.c`][mklevc_file].
|
|
|
|
Levels are always 80 columns by 21 rows in size.
|
|
|
|
[nh36]: https://github.com/NetHack/NetHack/tree/NetHack-3.6
|
|
[mklevc_file]: https://github.com/NetHack/NetHack/blob/NetHack-3.6/src/mklev.c
|