Neo Angband 0.28.0
Pre-releaseWhat you can download
| Platform | File |
|---|---|
| Windows (installer) | Neo Angband Setup 0.28.0.exe |
| Windows (portable, one file) | Neo Angband-0.28.0-portable.exe |
| macOS | .dmg, or the .zip if you prefer to unpack it yourself |
| Linux | .AppImage (no install), .deb, or .tar.gz |
| Self-hosting | neo-angband-web-0.28.0.zip - static files, any web server |
The portable Windows build and the AppImage need no installer:
download, run, and the game keeps its saves in a folder beside itself.
These builds are not code-signed
There is no Apple Developer identity or Windows certificate behind this
project yet, so your OS blocks the first launch.
Windows is one click: SmartScreen says "Windows protected your PC",
choose More info then Run anyway.
macOS is not one click, and the dialog it shows you does not contain the
way through - it offers only Done and Move to Trash. Do this:
- Drag the app out of the
.dmg, then double-click it and press Done
on the refusal. This step is required: it is what makes the permission
below appear, and it expires about an hour later. - Open System Settings -> Privacy & Security and scroll to
Security, near the bottom. - Press Open Anyway on the line naming Neo Angband, authenticate, and
launch it again.
Or, the same decision in one command:
xattr -d com.apple.quarantine "/Applications/Neo Angband.app"
The old right-click -> Open trick does NOT work: Apple removed that
bypass in macOS 15 Sequoia.
On Apple Silicon take the arm64 build. The x64 one is for Intel Macs,
not a fallback - Apple is withdrawing Rosetta 2, so on a current Mac it is
likelier to refuse to launch than to run slowly.
If that trade is not one you want to make, build it yourself -
docs/INSTALL.md - or play in the browser, which needs no trust decision.
Your save
Saves survive an update. Every save-format change ships the conversion that
reads the version before it, and a save this build cannot open is left
untouched rather than replaced.
A mod-authoring release: a plugin now gets the SDK's authoring stack and the
game's own composed records live in ctx, and can apply a staged mod with a
proper reload instead of asking the player to press one - alongside a fix for
two windows open on the same character overwriting each other's saves, and a
Turbo speed tier for a mod's autoplayer.
Fixed
- Two windows open on the same character no longer overwrite each other's saves.
The character a window writes to is now that window's own, held for as long as
it is open, instead of being read from a setting every window on the origin
shared. Opening a character that is already being played somewhere else is
refused with an explanation rather than allowed and then silently lost, and a
window that ends up without the character - a duplicated tab, which resumes
without passing the character select - says so instead of playing on unsaved.
neo-angband-activestill records which character to offer at the next launch;
it no longer decides where a save goes.
Added
- A player-visible speed control for a mod's autoplayer: the mod's own Fixes &
tweaks screen (Mods -> the mod) now shows an Autoplayer speed row - Turbo,
Fast, Normal or Slow - beside the rule that hands it the keyboard in the
first place, once it holds the controller slot. Takes effect at once, no
reload. Fast, Normal and Slow match the debug agent seam's existing
?speed=fast|normal|slowtiers; Turbo (10ms) has no named equivalent there,
since the debug seam already reaches 10ms by passing a raw millisecond
value instead of a tier name. ctx.authoring: the mod SDK's authoring stack, handed to a plugin. The
whole public barrel, live, on the termsctx.coreis handed over: blueprints
measured from core's own records,peersFor,suggestFields,templateRecord,
draftRecord,checkRecordsandModProject. Always present and gated by no
capability, because these are pure functions over data the caller supplies. A
tool that helps somebody write a monster could reach none of it before: a plugin
resolves no bare specifier, so the published npm package was out of reach of the
game it describes.ctx.composedRecords: the records the running game was composed from.
Every content record as JSON, keyed by pack-file stem with no extension, which
is the shape the authoring functions accept. This is the unbound twin of
ctx.registries: a boundMonsterRacehas nobase, because the binder
resolved the name into a pointer, so a table of comparable records could not be
built from the registry. Mod-added records are in it on the same terms as
core's, each carrying its provenance, so a draft based on another mod's content
can name the dependency it just acquired. Absent during content composition,
for the reasonctx.registriesis.ctx.reloadGame: a mod can apply what it just staged. The game's own
mod-change sequence, behind eithermod:installormod:session- whichever
capability the mod already holds - because content composes at load and
staging plus reload are one act: a mod that cannot follow a stage with a
reload leaves the player holding something the running process will never
load. What the host does that a mod cannot do for itself is the sequence -
every plugin'suninstall()runs, the autoplayer hands the keyboard back, the
live character is written down, and the session comes back on that character
instead of on the title screen. It is not a permission to reload: a plugin
runs in the page and reacheslocationwith no grant at all, and a mod
calling that directly loses the player's progress since the last save.- An install outcome now carries the game's own wording.
ctx.installMod(bytes)answers withlineson both arms: the lines the Mods
screen itself prints for that same install, including one row per unmet
requirement and the author's advice under them. A mod built inside the game
therefore fails a standards check in the same words as one somebody downloaded,
rather than in a second vocabulary a player cannot look up.problemis
unchanged and is still one whole sentence. - A second API-surface ratchet, over the SDK.
packages/mod-sdk/mod-sdk-api-surface.jsonrecords its 94 runtime exports and
mod-authoring-surface.test.tsfails in both directions against it. Handing a
namespace to a plugin puts every name in it beyond the compiler's reach, which
is why core has had this since 2026-08-02;node tools/api-surface.mjsnow
checks and updates both baselines in one run.
Changed
- The download screen's size line now shows the exact byte count, comma-grouped,
instead of rounding to KB or MB - "162,343,507 Bytes" rather than "155 MB".
The screen already reads as a terminal (the ASCII progress bar); an unrounded
count fits that and visibly climbs while the download runs, where a
one-decimal MB figure barely moves.
Found something that does not match Angband 4.2.6? Open an issue or come and say so in the Discord.