A skippable interactive walkthrough shown on New Game: a TutorialGuide layered
onto the real game loop makes the player perform the core commands
(look→examine→take→inventory→use→go→go to) in the starting room, with verb-/
alias-aware completion (movement steps require an actual room change), gentle
hints on wrong-but-valid input, and closing tips for the rest. Data-driven
(tutorial.yaml + standalone TutorialLoader); 'skip' ends it; loaded games never
show it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Alias-aware, stateful engine with verb/minArgs matching, go_direction/go_to_room
room-change detection, skip, and closing-tips on completion. 7 tests, all green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
BFS auto-walk over visited rooms (respecting locked exits + darkness), routed
through GoCommand (go to <room> vs go <direction>). Console: silent traversal +
a start/middle/destination summary line. GUI: the minimap animates the player
moving room-by-room via a new GameIO.travelStep hook (SwingIO override, ~300ms;
console no-op). New stateless Pathfinder BFS in the game package. Trie
autocomplete deferred.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- UX: unknown-target message now reads "don't know any direction or place
called '...'" so direction typos (e.g. 'go nroth') make sense
- clarity: resolveVisited uses equalsIgnoreCase for id/name matching;
add null-world guard comment pointing to CommandTestSupport
- Javadoc: note that 'to' filler word is stripped, making go-to forms equivalent
- tests: assert 'through the Hallway' in 3-node route; update unknown message
assertion; add adjacentWalkUsesShortSummary covering the n==2 short-form path
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Data-driven combination recipes (combinations.yaml: requires/consume/produce/
effects/response/failText), operands resolved from inventory or current room,
order-independent canonical pair key. UseCommand routes 2+ args to a new
Combinations engine; no parser change (on/with/to already fillers). Loader
validates ids + rejects self-combination/duplicate pairs at load. Demo:
matches + torch -> lit_torch (a working light source).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Combinations.tryUse: only write response when non-null and non-blank,
preventing NPE/IllegalArgument for effects-only recipes.
- CombinationFactory.fromDto: throw WorldLoadException when a == b,
since item singletons make a self-combination impossible at runtime.
- Tests: +effectsOnlyRecipeAppliesEffectsWithoutProduceOrResponse
(CombinationsTest 7→8), +rejectsSelfCombination
(CombinationFactoryTest 4→5).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the plain Swing JDialog menu with a glass-pane overlay that fills
the whole window: dark background matching the game palette, bundled font,
lavender heading, flat hover-highlighted buttons, Escape = last option. The
overlay hides the game chrome (HUD/map/quest panels) while in the menu and
rebuilds at the current frameScale*zoom on window resize, so it scales
correctly from startup.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a main-menu shell above the game loop (New Game / Load / Settings /
Quit) via a new GameIO.choose primitive (console numbered menu + Swing
buttons), JSON save/load as a delta over the YAML world (single active
slot; manual save, autosave on quest-completion + every 10 turns, and
quit-to-menu), and minimal runtime-togglable settings (colour + glyph).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace App.run with a main-menu shell (New Game / Load / Settings /
Quit) above the game loop, wire SaveCommand + MenuCommand into the
registry with an autosave callback, and remove the now-unused
QuitCommand. Migrate GameTest from QuitCommand to MenuCommand.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add loadRejectsIncompatibleVersion test asserting SaveException on schema
version 999, assert derived slug in listReturnsSlotMetadata, and harden
save() to delete the orphaned .tmp file when the non-atomic fallback move
also fails before re-throwing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reorder apply() so visitedRoomIds is restored before setCurrentRoom() is
called, ensuring the current room is never accidentally stripped from the
visited set by the subsequent clear(). Also adds a post-condition assertion
to applyToleratesMissingCollections that proves null roomItemIds leaves
room item tables empty after apply.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Room.dark + Item.light flags and a Light helper (isLit/carryingLight). Model B
gating: you can't enter a dark room without a lit light source; look/take/examine
are obscured in the dark; the HUD light field is wired. Entry-gate prevents
soft-locks. Demo: the dark dungeon needs the lit lamp to reach the generator.
127 tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>