Commit Graph

85 Commits

Author SHA1 Message Date
00d3f97c9b fix(game): suppress endings while the tutorial is active
A command during the walkthrough (e.g. use front_door -> fled) no longer ends
the game mid-tutorial; a pending ending fires once the tutorial finishes or is
skipped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 22:09:06 +02:00
236ed0a180 refactor: consistent isActive() guard on tutorial onCommand; tidy App imports 2026-06-01 21:59:07 +02:00
c315d3f4b7 feat: wire TutorialGuide into the game loop; show on New Game only
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 21:53:27 +02:00
e27a12e4fe fix(game): null-safe moved() + idempotent begin(); cover multi-step + go_to_room hint
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 21:49:47 +02:00
af319508f6 feat(game): TutorialGuide interactive walkthrough engine
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>
2026-06-01 21:42:30 +02:00
dbfdf86810 test(tutorial): cover malformed tutorial.yaml -> WorldLoadException 2026-06-01 21:40:06 +02:00
91f79b1537 feat(tutorial): Tutorial model + TutorialLoader + tutorial.yaml content
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 21:25:48 +02:00
d20f3fd7d6 fix(command): combined unknown-target message; cover both go-to summary forms
- 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>
2026-06-01 20:23:41 +02:00
97e2809719 feat(command): go to <room> auto-walk (BFS path, animated map, summary)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 20:13:25 +02:00
f1b9695c5e feat(game): Pathfinder BFS over visited rooms (locks + light aware)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 20:08:11 +02:00
62b7663e34 feat(io): travelStep hook for animated auto-walk (console no-op, Swing override)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 20:04:17 +02:00
3711ef5a67 test(loader): assert exact item set incl. demo items (restore completeness check) 2026-06-01 17:44:32 +02:00
4ab5ad9d42 feat(loader): load combinations.yaml; demo matches+torch -> lit_torch
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 17:38:17 +02:00
8257eb0c02 docs(command): update UseCommand javadoc for the combination form 2026-06-01 17:32:58 +02:00
9152aded4b feat(command): route use X on Y to the combination engine
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 17:31:07 +02:00
6eabebff00 fix(combinations): guard null response; reject self-combination at load
- 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>
2026-06-01 17:28:32 +02:00
ae7f9d6b05 feat(game): Combinations engine for use X on Y
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 17:22:16 +02:00
2747659800 test(loader): cover unknown consume id rejection 2026-06-01 17:19:41 +02:00
100b54c4d1 feat(loader): CombinationDto + CombinationFactory with id validation 2026-06-01 17:17:25 +02:00
c91bc3afea feat(model): World.combinations field + backward-compatible constructors 2026-06-01 17:13:05 +02:00
022973dc75 style(test): drop unused import in CombinationTest 2026-06-01 17:11:37 +02:00
cf592edc57 feat(model): Combination recipe record + order-independent key 2026-06-01 17:08:14 +02:00
b41ac80194 feat(io): themed full-window menu overlay in the GUI
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>
2026-06-01 16:21:46 +02:00
182a6911a0 fix: EOF ends game loop (ConsoleIO returns null on EOF); settings.json excluded from save slots
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 15:39:08 +02:00
98b1561ef2 feat(io): SwingIO.choose renders the menu as buttons 2026-06-01 15:27:15 +02:00
361fd0939c refactor(app): drop dead newSession param, unused import, restore main javadoc
- Remove unused `saves` parameter from `newSession(GameIO, SaveService)`
  → signature is now `newSession(GameIO)`, call site updated accordingly
- Remove unused `import thb.jeanluc.adventure.menu.MenuAction` (switch
  uses unqualified constants; import was dead, compile confirmed clean)
- Restore `/** Standard JVM entry point. @param args ignored */` Javadoc
  on `main` and restore full log message "Fatal error during game startup"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 15:25:01 +02:00
4604952f63 feat(app): main-menu shell loop wiring; gitignore saves/
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>
2026-06-01 15:17:46 +02:00
084b39e501 feat(game): autosave on quest completion 2026-06-01 15:12:18 +02:00
0f05680170 feat(command): save + menu commands (QuitCommand removal deferred to Task 11) 2026-06-01 15:10:10 +02:00
e4238e4553 test(menu): cover pickSlot selection and Back sentinel
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 15:03:18 +02:00
687e88e20a feat(menu): MainMenu, SettingsMenu, MenuAction (frontend-agnostic) 2026-06-01 14:58:41 +02:00
d847928587 test(settings): cover corrupt settings file falls back to defaults
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 14:56:14 +02:00
206fc758a5 feat(settings): Settings + SettingsStore; runtime-togglable ConsoleIO 2026-06-01 14:52:28 +02:00
ed41418434 test(save): cover version mismatch + slug; clean up tmp on move failure
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>
2026-06-01 14:50:10 +02:00
6a68d7e2f5 feat(save): SaveService disk persistence (atomic write, list, load) 2026-06-01 14:44:32 +02:00
3c7c9d2ad4 fix(save): restore visited set before setting current room; strengthen null-tolerance test
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>
2026-06-01 14:42:15 +02:00
3be1036142 feat(save): SaveCodec capture/apply over a fresh world; tolerate null collections
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 14:34:48 +02:00
c92c143058 feat(save): SaveData/SaveSlotInfo/SaveException model 2026-06-01 14:29:55 +02:00
310ee65285 feat(io): GameIO.choose numbered-menu primitive (console default) 2026-06-01 14:26:43 +02:00
c392f80ed0 feat: restore hooks for flags, quest progress, switch state 2026-06-01 14:21:56 +02:00
58352087c4 test(game): strengthen legacy-constructor delegation assertions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 14:19:54 +02:00
18336ecc44 feat(game): GameSession bundles savable state; turn + autosave hook 2026-06-01 14:15:44 +02:00
4ed1fa1010 feat(content): dark dungeon needs the lit lamp
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 23:08:42 +02:00
569cef20fe feat: darkness gating for go/look/take/examine + HUD light
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 23:07:36 +02:00
c3d80f86d7 feat: Room.dark + Item.light flags and Light helper
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 23:04:42 +02:00
b23f706521 feat(content): victory & flee endings; front-door flee switch
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 22:50:46 +02:00
2238aa6ff5 feat(game): EndingEngine + per-turn end check with summary
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 22:49:00 +02:00
3ec540e41b feat: Ending model + endings.yaml loading (ordered, optional)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 22:47:38 +02:00
1b22c996e1 feat(content): demo quest 'restore_power'; document quests command
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 22:34:57 +02:00
e3fb0c9fa6 feat(io): GUI quest-box under the map
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 22:33:57 +02:00