The Ledger

August 21, 2026

Neo Angband v0.23.0

Current state of the project at version 0.23.0 - the release where the port gives something back. Nothing about the game’s rules changed. What changed is that a mod can ask what the game is made of, that the Borg finally uses it, and that the game stopped deciding what a mod’s monster looks like - a rule 0.22.0 had added and 4.2.6 has no opinion about, handed to the tile set where it belongs.

Added

  • A plugin can now ask the game what it is made of: ctx.registries. Every race, object kind, feature, trap, store and projection the session actually runs on, bound, at its real index. Until now a plugin could see ctx.state - the monsters standing on the current level - which is enough to draw a frame and not enough to answer a question about a thing by index: what a creature you are merely remembering can do, what an item you have never picked up is worth, which kinds share a tval. It is the whole registry set rather than a curated slice, for the reason ctx.core is the whole namespace. A mod’s own content is in it on the same terms as core’s, because binding happens after every enabled mod composes and mods append, so nothing in a lookup tells a modded race from a core one. That is what lets a consumer treat modded and vanilla content identically without trying to.

    • The first consumer is the Borg, which had shipped since its port with its danger evaluator fed zeroes: makeCoreResolvers existed, was documented, and had no caller, because the race registry was not reachable from a plugin. It is now, so the Borg fears real monsters, including ones a mod added.
  • A tileset mod can supply tiles for content the pack has never heard of: registry:tiles. A plugin registers one filler, which runs after every pref layer - the pack’s own and each mod’s - and writes through a door that only ever fills what nothing assigned. So it cannot repaint the tile set even by mistake, and two mods filling different blanks cannot fight over one. The loose-pack engine also hands a filler a derive(donor, hue), which allocates a slot drawing an existing asset with its hue rotated; the tilesheet engine answers null, because its tiles are cells of a fixed atlas with no spare cell for a variant, and a filler copies the donor instead.

Removed

  • The game no longer decides what a mod’s monster looks like (fillTilesFromKin). 0.22.0 gave an added creature the tile of a race sharing its base, and an added item the tile of a kind sharing its tval. It is gone one release later, on the rule that has not moved since the port started: the port adds nothing to 4.2.6. Angband 4.2.6 has no concept of a record a mod added, so it has no opinion about what one should look like, and “the lowest-index relative’s picture” is a judgement rather than ported behaviour. It was also a judgement about art the game does not own - a tile set drawn in 2003 has no picture for content added twenty years later, and a relative’s picture there is a confident lie where a letter was the honest answer.

    Nothing is lost for a player who wants the behaviour, and it got better on the way out: neo-linoleum 0.15.0 carries exactly that rule, restricted to its own packs, and gives the added creature a recoloured tile of its own rather than a pixel-identical copy of its cousin’s. It is one switch in that mod’s options, on by default. Under Angband’s own tile sheets an added creature is a letter again, which is what it was before 0.22.0 and what a fixed atlas can honestly offer.

    For mod authors: ship tiles with your content, and if you do not, say so in your description and point players at a tile mod that fills blanks. Tutorials 2 and 3 now say that where the tile question comes up, and neither treats neo-linoleum as a dependency - a content mod is complete in ASCII with no tile set at all. The removal and its replacement are recorded in docs/modding/MOD_COMPATIBILITY.md under “Removals taken knowingly”, which is the fourth entry of exactly this shape and the first whose subject had shipped.

Downloads