Library / SDK
munificent/hauberk avatar
munificent/hauberk

Hauberk: a Dart roguelike kept readable as a teaching codebase, and now a compatibility question

A web-based roguelike written in Dart.

2,172 stars215 forksDartNOASSERTION

At a glance

What is it?
An ASCII dungeon crawler built to be forked, whose README asks for contributions it cannot accept, and whose toolchain still points at a Dart web URL that has moved.
Who is it for?
Hauberk is worth reading as a reference implementation rather than as a dependency. It solves the parts of roguelike development that are genuinely fiddly, procedural dungeon generation, field of view, item generation and turn order, in Dart, with a folder layout that keeps each concern in its own file.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 24 days ago.
What is it written in?
Mainly Dart, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.

Editorial analysis

An ASCII roguelike, written to be forked rather than extended

The README is unusually direct about what the project is for. Hauberk is a roguelike, described as an ASCII-art based procedurally-generated dungeon crawl game, written in Dart and running in the browser. Then the Contributions section explains that the author is keeping it mostly read-only, because another open source project already has more activity than can be handled alongside writing a book and having a full-time job.

The invitation that follows is the actual purpose of the repository: the author would be delighted if the codebase served as a springboard for your own game, and you can fork it and make it your own thing in any way you choose. That is a different proposition from an open source project seeking contributors, and it changes what you should expect. Bug reports are welcome, pull requests probably will not be looked at, and nobody is going to add a feature you need.

The numbers support that reading. The repository has 2171 stars, 214 forks and 17 open issues, and 214 forks against 2171 stars is a high ratio, which is what you would expect from a codebase people clone in order to write their own game rather than an application people deploy. It was pushed on 2026-09-18 and is not archived, so the code is not rotting, but nothing about the repository suggests ongoing game development.

There is a homepage at munificent.github.io, served over plain HTTP rather than HTTPS, which is a small detail consistent with a project that is hosted but not actively operated.

Running it needs a Dart dev channel release

The Running section asks for the Dart SDK, and specifies which one: the latest dev channel release, rather than stable. Once Dart is installed and its `bin/` directory is on your PATH, there are three steps, clone the repository, run `make serve` from the root, and open localhost:8080 in a browser.

What that serve target does is one line. The Makefile calls it a trivial makefile to shorten some common commands, and the target runs Dart's build_runner in serve mode, which compiles Dart source to JavaScript on the fly and watches for changes. That is the whole local development story, and it is a pleasant one: no bundler configuration, no node_modules, one make target.

The SDK link is the part that has aged. It points at webdev.dartlang.org/tools/sdk, and the domain has since moved to dart.dev. The instruction to use a dev channel release is the other half of the problem, because dev channels are, by definition, the channel where things are expected to change without notice. A codebase pinned to an unreleased channel of the toolchain in the year it was written is a codebase whose build you should expect to have to adjust.

The project does have real structure beneath that make target: `lib/` for source, `test/` for tests, `web/` for web assets, `bin/` for scripts, `tool/` for tooling, `doc/` and `note/` for generated and hand-written material, and a `build.yaml`. There is also a `pubspec.lock`, so dependency versions were committed deliberately.

Hand-authored bitmap fonts committed as Photoshop files

The most unusual thing in the tree is not code. It is eight `.psd` files: `font.psd`, `font_6_8.psd`, `font_6_9.psd`, `font_8.psd`, `font_8_10.psd`, `font_9_12.psd`, `font_10_12.psd` and `font_12_12.psd`, plus a `palette.psd`.

The naming pattern is legible once you know it, and it explains the whole approach. Each filename encodes a cell size, so `font_6_8` means 6 pixels wide by 8 pixels tall, and there are eight of them covering a range of resolutions. An ASCII roguelike that renders with real bitmap glyphs at multiple terminal resolutions needs a hand-drawn font atlas per size, and an author who wanted the game to look right will open Photoshop and draw them by hand rather than find a TTF that matches. The presence of a separate `palette.psd` suggests the same for colour.

This is committed binary source, which is a choice with consequences. It means the visual identity of the game lives in files that no diff can review and that contribute to repository size. It also means anyone forking the game gets a consistent look for free, which is exactly what a springboard codebase should provide, and it is one of the reasons the author can say you can make it into your own thing: the assets are there and they are deliberately part of the gift.

`bin/update_docs.dart` is what the `docs` make target runs, and the `build` target depends on it, which means documentation generation is part of a release build.

The build target clones a branch and copies files into it

The Makefile is the whole build system, and the `build` target is worth reading in full because it does something no modern toolchain would. Its steps are: run the docs target, run `dart run build_runner build --output web:build --release`, remove a local `gh-pages` directory, clone the repository's own `gh-pages` branch into that directory as a single-branch clone, copy the built `build/` output into it, delete `packages`, `.build.manifest` and `.packages` from the clone, and stop.

So publishing this game is a `git clone` of a deployment branch followed by a file copy, with cleanup of build_runner artifacts at the end. It works, and it is legible to anyone who knows git, but it means the deployed site is a branch in the same repository as the source. There is no CI configuration in the tree doing this instead, so the person running the command is doing it from a machine with push access.

The cleanup steps are the interesting detail. Deleting `gh-pages/packages`, `.build.manifest` and `.packages` after copying implies those artifacts are generated inside the build output and are not wanted on a public page. Someone thought about what ends up served, which is more than most hand-rolled deploy scripts manage.

One small inconsistency: the `.PHONY` declaration lists only `docs` and `serve`, while `build` is a real target with a file of the same name nowhere in the tree. So `make build` works, but the file-based staleness check that phony targets exist to bypass is not declared for it.

The license lives in a file called COPYRIGHT

The README states that the project uses a very permissive MIT license and points the reader at a link labelled MIT license, which resolves to a file at the repository root named `COPYRIGHT`. The file is indeed there, among the shortest entries in the tree, so the link is not broken.

The naming is unusual enough to be worth flagging, because it interacts badly with tooling. GitHub's license detection looks for conventional filenames, and the repository metadata here reports the license as NOASSERTION rather than MIT. That means the license field on the GitHub page is empty, and any automated scan of your dependencies will flag this repository as having an unknown license.

The MIT text inside `COPYRIGHT` is what governs, and MIT is permissive in exactly the way the README promises: use it, copy it, modify it, ship it commercially, with attribution. The author is unusually relaxed about the rest, saying explicitly that you can do pretty much whatever you want with it.

The final lines of the README are a lesson in setting expectations early. Bug reports are welcome, pull requests probably will not be looked at because of the author's available time, and the thanks for understanding closes the section. It is a good pattern. A maintainer with one popular teaching project and a day job can say this once, clearly, and then people stop filing pull requests they expected replies to.

What a procedural dungeon generator actually has to solve

The value of the codebase for a reader is the shape of the problem, which is more interesting than the game. A roguelike needs at least four things working together, and Hauberk has a directory for each.

Procedural generation is the part everyone thinks about. A dungeon generator has to produce something that is not a rectangle and not random noise, which means room placement, corridor connection between rooms, and a guarantee that the result is fully traversable. Most of the engineering in that area is about the guarantee rather than the aesthetics.

Field of view is the part that surprises people. Because the display is ASCII characters in a grid, lighting a room with a torch radius is a matter of computing a shadowcasting algorithm per tile, and the character chosen for each cell has to encode both visibility and terrain. A wall you can see through is different from a wall you can see past, and the map symbols handle both.

Then there is turn order, which is a small scheduling problem with large consequences. If the player moves and a monster attacks in the same tick, the player takes damage from a monster whose move you never saw. If the game processes actors sorted by speed, a fast monster gets two moves and the display updates twice. Getting this right is what makes a turn-based game feel fair rather than arbitrary.

Items and effects come last: generation tables with rarity weights, effects that modify stats, and an inventory that has to survive save and load. The README's screenshots show a dungeon rendered with a bordered frame and colored glyphs, which is the payoff for the bitmap fonts described earlier.

Editorial conclusion

Hauberk is worth reading as a reference implementation rather than as a dependency. It solves the parts of roguelike development that are genuinely fiddly, procedural dungeon generation, field of view, item generation and turn order, in Dart, with a folder layout that keeps each concern in its own file. What it is not is a maintained game: the README asks you not to send pull requests, there are no releases to install, and the build depends on a Dart dev channel release and a build_runner workflow that predates the current Dart web story. The license file the README points you at is named COPYRIGHT rather than LICENSE, and GitHub reports no license for the repository, so check that file yourself before borrowing code. Clone it, run `make serve`, and read `lib/`.

Frequently asked questions

What language is Hauberk written in and where does it run?

Dart, compiled to JavaScript, and it runs in a browser. The local development setup is the Dart SDK plus build_runner in serve mode, started with make serve, after which the game is at localhost:8080. A production build runs build_runner in build mode with a release flag.

Can I contribute to Hauberk?

The README asks you not to. The author says the project is mostly read-only because another open source project already exceeds the time available, and welcomes bug reports while expecting not to have time for many pull requests. The stated intent is that you fork it and use the codebase as a starting point for your own game instead.

What license does Hauberk use?

MIT, as the README states, with the text stored in a file named COPYRIGHT at the repository root rather than a conventionally named LICENSE file. Because of the filename, GitHub detects no license for the repository and reports it as NOASSERTION, so the copyright file is the authoritative source and automated license scanners will flag the dependency as unknown.

What does Hauberk do for dungeon generation and rendering?

It generates dungeons procedurally and renders them as ASCII art with hand-drawn bitmap fonts, which the repository stores as eight Photoshop files named for their cell dimensions, from 6 by 8 up to 12 by 12, plus a palette file. The committed font assets are why a fork keeps a consistent look without redrawing anything.

Official sources

  1. Issues
  2. munificent/hauberk on GitHub
  3. Project website
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/munificent-hauberk.svg)](https://hysenlabs.com/projects/munificent-hauberk)