Plan the idiomatic-Go refactor in TODO.md

Itemize the refactor from transliterated port to idiomatic Go: eight
stepped feature branches (descriptive constant renames, typed kind
enums, un-overloaded Object fields, per-subsystem method renames,
god-object extraction, effects dispatch tables, constructor/style
pass, docs refresh), slotted ahead of the existing playtest/lint/
release steps. Also add the styleguide-required .gitignore (a stray
built binary was sitting untracked in the root).
This commit is contained in:
2026-07-06 20:54:32 +02:00
parent 2bcc3894e2
commit 1133feb0ba
2 changed files with 82 additions and 15 deletions

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
*.log
*.out
*.test
/rogue

85
TODO.md
View File

@@ -2,13 +2,33 @@
pre-1.0 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 # Next Step
Playtest hardening pass: play several full games with the tcell binary Refactor step 1 (branch refactor/descriptive-constants): rename
and extend run_test.go to script a deeper multi-level playthrough constants to descriptive, less C-like names. Creature/object/room/place
(descend past level 5, use potions, scrolls, zapping, save/restore). flag bits (IsHuh→Confused, IsHalu→Hallucinating, CanHuh→CanConfuse,
Fix any panics, message mismatches, or divergences from the C behavior SeeMonst→SenseMonsters, ObjIsFound→WasFound, IsCanc→Cancelled, ...),
that this uncovers, and commit the fixes with regression tests. trap types (TMyst→TrapMystery), item subtype constants
(PLSD→PotionLSD, SIDRorS→ScrollIdentifyRingOrStick,
RAddHit→RingDexterity, WsHasteM→WandHasteMonster,
TwoSword→WeaponTwoHandedSword, ...), Max* count constants →
Num*Types, and the Level.NTraps field → TrapCount. Pure rename; no
behavior change; tests unchanged.
# Completed Steps # Completed Steps
@@ -33,15 +53,58 @@ that this uncovers, and commit the fixes with regression tests.
# Future Steps # Future Steps
1. Adopt the house Go linting standards: copy .golangci.yml from the 1. Refactor step 2: typed kind enums — PotionKind, ScrollKind,
RingKind, WandKind, WeaponKind, ArmorKind, TrapKind as iota enums
with fmt.Stringer; Object.Which and the ObjInfo tables move to the
typed kinds; the object category glyph bytes ('!', '?', ...) become
an ObjectKind with a Glyph() method so item category and map
character stop sharing one byte namespace.
2. Refactor step 3: un-overload Object fields — split Object.Arm into
ArmorClass/Charges/GoldValue; parse damage dice ("1x4/1x2") once
into a DiceSpec type at table definition instead of per swing;
save-format update with round-trip test migration.
3. Adopt the house Go linting standards: copy .golangci.yml from the
prompts repo and bring game/, term/, and cmd/ lint-clean (the port prompts repo and bring game/, term/, and cmd/ lint-clean (the port
is greenfield code, so no exemptions apply). is greenfield code, so no exemptions apply).
2. Verify the seed-compatibility claim against the C reference on 4. Refactor step 4: method renames, movement/world subsystem
master: same seed, same dungeon, same item tables, for several (doMove→moveHero, beTrapped→springTrap, rndmove→randomStep,
doRooms/doPassages/doMaze→digRooms/digPassages/digMaze,
chgStr→changeStrength, ...); remove the goto/label flows in doMove,
dispatch, and saveGame in favor of loops and helpers.
5. Refactor step 5: method renames, items/combat/UI subsystems
(invName→inventoryName, rollEm→rollAttacks, doPot→applyPotionFuse,
getItem→promptPackItem returning (obj, ok), getDir→promptDirection);
int status codes (attack returning -1) become named results. Two or
three commits, one subsystem each.
6. Refactor step 6: extract types from the god object — MessageLine
owns the msg/addmsg/endmsg machinery; pack/inventory operations move
onto *Player; monster/object list management and map queries
consolidate onto *Level; RogueGame keeps turn orchestration and
cross-system effects only.
7. Refactor step 7: effects dispatch — the giant quaff/readScroll/doZap
switches become per-kind handler tables of small named methods,
keeping effect order and RNG call sequence identical.
8. Refactor step 8: constructor and style pass per the house
styleguide — game.New(game.Params{...}) replacing NewGame(Config);
replace the gameEnd panic unwind with error-based turn results where
feasible; 77-column wrap sweep.
9. Docs refresh: update ARCHITECTURE.md Part 2 and README.md for the
post-refactor names; add the C name → Go name rename table.
10. Playtest hardening pass: play several full games with the tcell
binary and extend run_test.go to script a deeper multi-level
playthrough (descend past level 5, use potions, scrolls, zapping,
save/restore). Fix any panics, message mismatches, or divergences
from the C behavior that this uncovers, with regression tests.
11. Verify the seed-compatibility claim against the C reference on
c-master: same seed, same dungeon, same item tables, for several
seeds. seeds.
3. Broaden unit test coverage where playtesting finds thin spots 12. Broaden unit test coverage where playtesting finds thin spots
(rings, sticks, wizard commands). (rings, sticks, wizard commands).
4. Tag a release once a full game (Amulet retrieval and score entry) 13. Tag a release once a full game (Amulet retrieval and score entry)
completes without defects. completes without defects.
5. Note: this repo is exempt from the standard policy scaffold. Do not 14. 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.
15. Note: this repo is exempt from the standard policy scaffold. Do not
add Makefile, Dockerfile, or REPO_POLICIES.md. add Makefile, Dockerfile, or REPO_POLICIES.md.