Four documented claims had gone false and were actively misdirecting agents working this repo; the independent reviewer on PR #9 repeated one of them verbatim. Each claim was re-verified against the tree before rewriting. MEMORY.md "Error handling" described C's exit() calls being unwound by a gameEnd panic recovered in Run. Refactor step 8 removed that: gameEnd appears nowhere in the sources, myExit (game/rip.go) restores the terminal via Terminal.Fini and calls os.Exit(0), and Run() has no return values and never returns. The section now states that model and its testing consequence -- a death exits the test binary, which is why tests drive command() directly and crash sweeps pin the hero with fortify() in game/run_test.go. MEMORY.md "Linting" said approved exceptions are recorded in a "Repo-specific exceptions" block in .golangci.yml. There is no such block: the config is byte-identical to canonical (sha256 021cc83f...46bcb) and the approvals live in in-code //nolint directives carrying their dates. Following the old text would have meant editing the canonical config. The same paragraph listed paralleltest as an approved disable when it was fixed instead -- no paralleltest token exists in the tree and all 32 tests call t.Parallel(). MEMORY.md "Debugging" and README.md both told the reader to run go test directly. Since PR #9 the test target carries -timeout 30s -race -cover, so a raw invocation silently drops the race detector while appearing to verify the change. Both now point at make test / make check. TODO.md asserted the host golangci-lint is "currently v2.12.2". It is v2.10.1 and the repo pins nothing, so the claim documented an accident of one machine. Only the false claim is removed; the pin question is tracked separately. Documentation only: no code, Makefile, or config change. Next Step is deliberately not rotated, per the precedent for out-of-band issue work.
238 lines
14 KiB
Markdown
238 lines
14 KiB
Markdown
# Workflow
|
|
|
|
- branch (from `main`)
|
|
- do the work in Next Step
|
|
- move Next Step to the top of Completed Steps
|
|
- move the top item of Future Steps into Next Step
|
|
- commit (`TODO.md` changes in the same commit as the work)
|
|
- merge to `main` if the branch is not protected, otherwise open a PR
|
|
- push
|
|
|
|
# Status
|
|
|
|
pre-1.0
|
|
|
|
The port on main is complete and faithful (function-by-function from Rogue 5.4.4
|
|
C; reference sources on c-master/modern-rogue). Current phase: refactor from a
|
|
transliterated port into idiomatic Go — one feature branch per step below,
|
|
descriptive naming, real types, house style per
|
|
~/dev/prompts/prompts/CODE_STYLEGUIDE_GO.md.
|
|
|
|
Refactor ground rules:
|
|
|
|
- Behavior must not change unless a step says so. The full test suite (scripted
|
|
sessions, generation invariants, C-compatible RNG goldens) gates every step;
|
|
80x24 seed-compatible gameplay stays intact.
|
|
- Renames keep the C lineage greppable: doc comments retain their "(file.c
|
|
func_name)" breadcrumbs, and the docs refresh step adds a C-name → Go-name
|
|
table to ARCHITECTURE.md.
|
|
|
|
# Next Step
|
|
|
|
Broaden unit test coverage where playtesting finds thin spots (rings, sticks,
|
|
wizard commands).
|
|
|
|
# Completed Steps
|
|
|
|
- 2026-08-09 Stale-docs correction (`docs-staleness`, closes #3): four claims in
|
|
`MEMORY.md`/`TODO.md`/`README.md` had gone false and were misdirecting agents
|
|
— the reviewer on PR #9 repeated one of them verbatim. Each was re-verified
|
|
against the tree before rewriting. (1) `MEMORY.md` described C's `exit()`
|
|
being unwound by a `gameEnd` panic recovered in `Run`; refactor step 8 deleted
|
|
that, `gameEnd` appears nowhere in the sources, and `myExit` (`game/rip.go`)
|
|
now calls `Terminal.Fini` then `os.Exit(0)` while `Run()` never returns — so
|
|
the section states the exit model and its testing consequence (a death exits
|
|
the test binary; hence `fortify()` in `game/run_test.go`). (2) `MEMORY.md`
|
|
said approved lint exceptions live in a "Repo-specific exceptions" block in
|
|
`.golangci.yml`; no such block exists and the config is byte-identical to
|
|
canonical (sha256 `021cc83f…46bcb`), the approvals having moved to in-code
|
|
`//nolint` directives carrying their dates — and `paralleltest` was listed as
|
|
an approved disable when it was in fact fixed (no `paralleltest` token in the
|
|
tree; 32 `t.Parallel()` calls against 32 tests). (3) `MEMORY.md` "Debugging"
|
|
and (4) `README.md` both told the reader to run `go test` directly, which
|
|
since PR #9 silently drops `-timeout 30s -race -cover`; both now point at
|
|
`make test`/`make check`. Also dropped the false "currently v2.12.2" host
|
|
linter claim from the 2026-08-07 entry (the host is v2.10.1 and nothing is
|
|
pinned; the pin question is tracked separately). Documentation only — no code,
|
|
`Makefile`, or config change; `Next Step` deliberately not rotated, since this
|
|
was out-of-band issue work.
|
|
|
|
- 2026-08-09 Policy-shaped `make test` (`make-test-policy-pattern`): the `test:`
|
|
target was a bare `go test $(GO_PKGS)` and now runs
|
|
`-timeout 30s -race -cover` with the mandated conditional verbose rerun (on
|
|
failure it reruns with `-v` and then `exit 1`, so a flaky pass on the second
|
|
attempt cannot rescue the build). `$(GO_PKGS)` is kept rather than hardcoding
|
|
`./...`. The substance was `-race`, not the Makefile edit: this is the first
|
|
time the suite has run under the race detector, and it is clean — no data
|
|
races across five consecutive uncached runs, including the tcell terminal
|
|
layer and the `os.Exit`-path playthrough tests. Wall clock 5.1s cold
|
|
(including the race build) and ~2.3s warm, against the 20s policy budget. The
|
|
failure path was exercised with a throwaway failing test to confirm the rerun
|
|
fires and `make` exits non-zero. Build tooling only; no game behavior change.
|
|
|
|
- 2026-08-07 Canonical linter config (`golangci-v2.12.2`): replaced
|
|
`.golangci.yml` with the shared canonical config (v2 schema; settings now live
|
|
under `linters.settings`, so the `lll`/`funlen`/`cyclop`/`dupl` thresholds
|
|
actually apply — the old top-level `linters-settings` block was silently
|
|
ignored). The four repo-specific disables (`mnd`, `exhaustive`,
|
|
`paralleltest`, `testpackage`) moved out of the config into targeted in-code
|
|
`//nolint` directives carrying the original approval dates, so the config
|
|
stays byte-identical to canonical. Real fixes: `t.Parallel()` in all 32 tests,
|
|
24 long lines wrapped or their comments tightened, control bytes in
|
|
`term/tcell.go` as character literals, and two `wsl_v5` defer cuddles. The
|
|
repo has no golangci-lint version pin to bump (no Dockerfile or CI;
|
|
`make lint` runs whatever `golangci-lint` is on the host).
|
|
|
|
- 2026-07-24 Seed compatibility — item tables (seed-compat): instrumented the C
|
|
reference on modern-rogue with a DUMP mode (testdata/c_seedcompat.patch) that
|
|
forces the RNG seed and prints the per-seed item appearance tables (potion
|
|
colors, scroll names, ring stones, wand/staff materials) before initscr, and
|
|
captured its output for four seeds as testdata/item_tables.golden.
|
|
TestSeedCompatItemTables regenerates the same tables from the Go port and they
|
|
match byte for byte — proving the LCG and its consumption order through the
|
|
whole init sequence agree with C. The remaining "same dungeon (map)" half
|
|
would need the harder headless-curses C dump (new_level draws to curses);
|
|
deferred — the item-table match already validates RNG-order faithfulness
|
|
through init, and the Go generation goldens guard determinism thereafter.
|
|
|
|
- 2026-07-23 Playtest hardening (playtest-hardening): added two death-safe
|
|
crash-sweep drives through the real turn loop, within the step-8 os.Exit
|
|
constraint (a fortify() helper pins HP/food/exp and clears the freeze/stuck
|
|
counters each turn so no death exits the test binary; fixed seeds keep them
|
|
deterministic). TestDeepPlaythrough uses quaff/read/zap through command
|
|
dispatch, then descends to depth 8 with a save/restore at depth 4;
|
|
TestTurnLoopCrashSweep mashes movement/search/rest for 200 turns on four
|
|
seeds. Neither surfaced a panic. The interactive "play several games at a real
|
|
tcell terminal" portion needs a human at an 80x24 terminal and is left to the
|
|
maintainer; the binary's non-interactive paths (`-s` scores) were
|
|
smoke-tested.
|
|
|
|
- 2026-07-23 Docs refresh (docs-refresh): rewrote ARCHITECTURE.md Part 2 (the
|
|
pre-implementation design sketch) to match the final code — current type/field
|
|
names (ObjectKind, DiceSpec, split o_arm, step-1 flag names, TrapCount, Level
|
|
list methods), the static tables now on the per-game gameData struct, the
|
|
daemon/effect handler tables, the MessageLine extraction, the Terminal
|
|
interface, the flat gob SaveState, and the New(Params) + os.Exit design. Added
|
|
§7.1, a C-name → Go-name rename table, and a README note on the make targets.
|
|
|
|
- 2026-07-23 Refactor step 8 (refactor/constructor-style): constructor and exit
|
|
pass. NewGame(Config) → New(Params) and Restore takes Params, so the package's
|
|
primary type gets the canonical New() constructor with a named-field Params
|
|
struct (styleguide 139/159). The gameEnd panic unwind is gone: one game run is
|
|
one process, so myExit restores the terminal (new Terminal.Fini) and calls
|
|
os.Exit(0), and Run() no longer returns; the four Run()-to-completion tests
|
|
were reworked/dropped since death (combat or starvation) now exits the process
|
|
(TestScoreRendersList and TestRunDownStairs preserve what is still drivable;
|
|
save/restore stays covered by TestSaveRestoreRoundTrip). The 77-column wrap
|
|
sweep was dropped per sneak (2026-07-23): line lengths left as-is (lll caps at
|
|
88 and passes).
|
|
|
|
- 2026-07-07 Refactor step 7 (refactor/effects-dispatch): effects dispatch
|
|
tables plus a full decomposition sweep — the quaff / readScroll / doZap
|
|
switches, the attack monster-power switch, the be_trapped switch, the daemon
|
|
d_func switch, and the command-key switch all became handler tables on
|
|
gameData (quaffHandlers, readHandlers, zapHandlers, hitHandlers, trapHandlers,
|
|
daemonHandlers, commandHandlers), one small named method per case. Every
|
|
remaining cyclop/gocognit/nestif hot spot was split into named helpers across
|
|
fight, misc (look), command, chase, move, passages, options, pack, things,
|
|
save, daemons, rooms, score, monsters, rings, rip, io, object, weapons,
|
|
wizard, and term/tcell, plus three test functions. Effect order and RNG call
|
|
sequence preserved throughout; the whole golangci-lint run is now 0 issues.
|
|
|
|
- 2026-07-07 Refactor step 6 (refactor/god-object-extraction): MessageLine (was
|
|
MsgLine) owns the msg/addmsg/endmsg machinery, wired to its screen/look/input
|
|
needs via attach(); RogueGame keeps one-line msg/addmsgf/endmsg shorthands so
|
|
call sites are unchanged. Player owns pack bookkeeping (nextPackChar,
|
|
removeFromPack — the state half of leave_pack; leavePack keeps only LastPick
|
|
tracking). Level owns object/monster list management and lookup (ObjectAt
|
|
replaces findObj; AddObject/RemoveObject/AddMonster/RemoveMonster replace
|
|
direct attachObj/detachObj/attachMon/detachMon on level lists).
|
|
Inventory/pickup UI flows stay on RogueGame deliberately: they are display and
|
|
turn orchestration, not state surgery.
|
|
|
|
- 2026-07-07 Refactor step 5 (refactor/item-combat-ui-renames, three commits,
|
|
one subsystem each): items — getItem→promptPackItem now returning (obj, ok),
|
|
invName→inventoryName, doPot→applyPotionFuse; combat — rollEm→rollAttacks,
|
|
attack/moveMonster/chaseStep return (removed bool) instead of C -1/0 int
|
|
codes; UI — getDir→promptDirection. C breadcrumbs kept; suite green.
|
|
|
|
- 2026-07-07 Refactor step 4 (refactor/movement-renames): movement/world renames
|
|
(doMove→moveHero, beTrapped→springTrap, rndmove→randomStep,
|
|
doRooms/doPassages/doMaze→digRooms/digPassages/digMaze, chgStr→changeStrength,
|
|
doRun→startRun, moveStuff→finishMove, turnref→turnRefresh,
|
|
moveMonst→moveMonster, doChase→chaseStep, setOldch→setOldChar, cansee→canSee,
|
|
roomin→roomIn, runto→runTo, conn→connectRooms, putpass→putPassage,
|
|
passnum→numberPassages, numpass→numberPassage, rndPos→randomPos,
|
|
rndRoom→randomRoom, treasRoom→treasureRoom, accntMaze→accountMaze); all
|
|
goto/label flows replaced with loops (moveHero retry loop + extracted
|
|
passageTurn, dispatch re-dispatch loop, chaseStep passage loop, saveGame
|
|
labeled prompt loop); C breadcrumbs kept in doc comments.
|
|
- 2026-07-07 Lint adoption finished (refactor/no-package-globals): all 37
|
|
package-level vars moved into `gameData` (built by `newGameData`, hung on
|
|
RogueGame as `g.data`, set in NewGame and Restore); ObjectKind
|
|
Glyph()/objectKindForGlyph became switches; the table-reading subtype
|
|
Stringers were removed; isMagic became a RogueGame method; goconst fixed with
|
|
named word constants (potionName, goldName, staffName, ripWall, ...);
|
|
testpackage and exhaustive disabled in .golangci.yml with sneak's approval
|
|
(2026-07-07); misspell's corruption of the "ther" scroll syllable reverted.
|
|
mnd disabled with sneak's approval (2026-07-07, follow-up commit). Remaining
|
|
red: cyclop (36), nestif (30), gocognit (23) stay until step 7 fixes them per
|
|
sneak's ruling.
|
|
- 2026-07-06 Lint adoption bulk (refactor/lint-adoption, 5ba9fe8): .golangci.yml
|
|
copied verbatim from the prompts repo (plus the sneak-approved paralleltest
|
|
exception, 2026-07-06); ~1,500 findings fixed (autofix formatting sweep,
|
|
errcheck/err113/noinlineerr error handling, forbidigo, funcorder, recvcheck
|
|
pointer receivers, goprintffuncname renames msg helpers to *f, revive doc
|
|
comments, gocritic switch rewrites, gosec real fixes plus justified nolints,
|
|
unparam signature tightening, C-faithful "missle" spellings restored after
|
|
misspell autofix changed game text).
|
|
- 2026-07-06 Module base path updated to git.eeqj.de/sneak/rgoue (go.mod, term/
|
|
and cmd/ imports, ARCHITECTURE.md, version string).
|
|
- 2026-07-06 Refactor step 3 (refactor/object-fields): Object.Arm split into
|
|
ArmorClass/Charges/GoldValue/Bonus (rings); Stats.Arm → ArmorClass; damage
|
|
strings parsed once into DiceSpec at table definition (ParseDice keeps C
|
|
roll_em parse semantics, incl. "%%%x0" and "000x0" edge cases,
|
|
regression-tested); save format 5.4.4-go3.
|
|
- 2026-07-06 Refactor step 2 (refactor/typed-kinds, b940cfc): ObjectKind
|
|
separates item category from map glyph (Object.Type byte → Kind ObjectKind
|
|
with Glyph()); PotionKind/ScrollKind/RingKind/
|
|
WandKind/WeaponKind/ArmorKind/TrapKind typed iota enums with Stringer; typed
|
|
accessors on Object; getItem/inventory/whatis filters take ObjectKind
|
|
(KindCallable/KindRingOrStick replace CALLABLE/R_OR_S); save format bumped to
|
|
5.4.4-go2. Suite green.
|
|
- 2026-07-06 Refactor step 1 (refactor/descriptive-constants): renamed all flag
|
|
bits, trap types, item subtype constants, and Max* counts to descriptive names
|
|
(IsHuh→Confused, SeeMonst→SenseMonsters, WsHasteM→WandHasteMonster,
|
|
MaxSticks→NumWandTypes, ...); Level.NTraps→TrapCount; C names kept as comment
|
|
breadcrumbs. Pure rename, suite green.
|
|
- 2026-07-06 Made the rgoue branch Go-only: removed C sources and the
|
|
autoconf/VS build system (they remain on master and modern-rogue), ported the
|
|
last wizard command (item-probability listing), rewrote README.md for the Go
|
|
port (c0b533e)
|
|
- 2026-07-06 Ported the command loop, save/restore, the tcell terminal layer,
|
|
and the playable binary at cmd/rogue (41fc104)
|
|
- 2026-07-06 Ported item effects: potions, scrolls, options, call_it (cdf9bf7)
|
|
- 2026-07-06 Ported combat, the chase driver, traps, zapping, death and scores
|
|
(3c5add8)
|
|
- 2026-07-06 Ported dungeon generation, base items, the pack, and monster
|
|
creation (a69ef7d)
|
|
- 2026-07-06 Ported the foundation: types, seed-compatible RNG, item tables,
|
|
daemon scheduler (7fa2048)
|
|
- 2026-07-06 Wrote ARCHITECTURE.md Parts 1 and 2: complete map of the C program
|
|
and the Go port design (91eeee0, 45dba95)
|
|
- Fork base: Davidslv/rogue C 5.4.4 with modernization fixes (C23 prototypes,
|
|
ncurses compat), preserved on master/modern-rogue
|
|
|
|
# Future Steps
|
|
|
|
1. Tag a release once a full game (Amulet retrieval and score entry) completes
|
|
without defects.
|
|
2. Full-terminal-size support (deferred by explicit decision 2026-07-06):
|
|
per-game dungeon dimensions instead of the 80x24 constants; open design
|
|
questions are resize policy, gameplay tuning at larger sizes, and a --classic
|
|
80x24 mode.
|
|
3. Note: this repo is exempt from the standard policy scaffold. A minimal dev
|
|
Makefile (fmt/fmt-check/lint/test/check targets) exists per sneak's
|
|
2026-07-07 request, but do not add a Dockerfile, CI config, or
|
|
REPO_POLICIES.md.
|