C's command.c 317-338 has a `when '+'` arm in the main command switch, under #ifdef MASTER, that toggles wizard mode. The port had no '+' at all, so the key fell through dispatchKey's default to illcom and answered "illegal command '+'". The password half of that arm was dropped deliberately (wizard mode is ROGUE_WIZARD configuration) and is recorded in ARCHITECTURE.md section 9. The leave half was lost silently, and it is a different decision: it does not touch the password machinery. The substantive part of it is turn_see(TRUE) rather than the flag -- wizard sight draws every monster the hero cannot see, so without the re-hide there is no way back to normal visibility, and clearing the flag alone would leave the screen lying. New wizardToggleCommand, registered in commandHandlers between '^' and Escape, which is C's own switch order. Because C's arm sits in the main switch rather than the `if (wizard) switch (ch)` sub-switch that wizardCommand ports, it is reachable whether or not wizard is set, so the non-wizard case was a divergence too. It resolves the way the dropped passwd() forces: a password check that no longer exists can never succeed, so the else arm is what C did on a wrong answer -- the message "sorry", with no prompt, since nothing typed into one could change the outcome, and none of the noscore/turn_see(FALSE) bookkeeping of C's unreachable success branch. The choice is stated in the doc comment and in section 9. Two tests drive '+' through g.dispatch. The wizard one spawns a phantom (ISINVIS straight from the monster table, so seeMonst is false and it is on screen only because wizard sight put it there), asserts the precondition, then asserts the flag cleared, SenseMonsters cleared, the cell restored to the map char under the monster with standout off, the exact message text, and After false. Deleting the turnSee(true) call fails it on all three visibility assertions. The other pins "sorry". No RNG call is added: the turn_off arm of turn_see never reaches rnd. TestSeedCompatItemTables is green against the untouched golden.
Rogue: Exploring the Dungeons of Doom (Go port)
Rogue is the original dungeon-crawling adventure game that spawned an entire genre. This branch is a faithful Go port of Rogue 5.4.4: explore procedurally generated dungeons, fight monsters, collect treasure, and attempt to retrieve the Amulet of Yendor.
Original authors: Michael Toy, Ken Arnold, and Glenn Wichman (1980–1983, 1985, 1999).
The port is function-by-function faithful to the classic C sources — same
dungeon generation (seed-compatible RNG), same combat math, same item tables,
same messages. The C reference implementation lives on the master and
modern-rogue branches; ARCHITECTURE.md documents both the
original program structure and the design of this port.
Building and running
Requires Go 1.25 or later and a terminal at least 80x24.
go build ./cmd/rogue
./rogue
# Restore a saved game
./rogue ~/rogue.save
# View high scores
./rogue -s
# Test the death screen (demo mode)
./rogue -d
In-game commands
Press ? in game for the full list.
- arrows or h/j/k/l/y/u/b/n — move (shift to run, ctrl to run until adjacent)
.rest,ssearch for hidden doors and trapsiinventory,,pick up,ddropqquaff potion,rread scroll,eeat foodwwield weapon,Wwear armor,P/Rput on / remove ringtthrow,zzap a wand,f/Ffight>/<take the stairsSsave,Qquit
Environment
# Game options, as in the original
export ROGUEOPTS="name=YourName,terse,jump,fruit=mango"
# Wizard (debug) mode, with a reproducible dungeon
ROGUE_WIZARD=1 SEED=12345 ./rogue
The scoreboard is kept in ~/.rogue.scores. Save files are Go gob snapshots
and, as in the original, are deleted when restored.
Code layout
game/ the game engine: one Go file per original C file,
function-by-function (see ARCHITECTURE.md for the mapping)
term/ tcell-backed terminal, replacing curses
cmd/rogue/ the executable
The engine package is fully headless-testable: make test runs scripted command
sequences, dungeon-generation golden checks, and an RNG compatibility test
against the original C generator.
For development, the Makefile wraps the toolchain: make fmt (gofmt +
prettier), make lint (golangci-lint), make test (the suite, under the race
detector with coverage and a timeout), and make check (all three). Use the
targets rather than invoking go test directly — they carry the flags the
project relies on.
License
BSD-style; see LICENSE.TXT.
Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman. All rights reserved.