- Add ./mvnw wrapper (script-only) so the project builds/runs without a
system Maven install.
- Add maven-shade-plugin producing a self-contained release/HauntedManor.jar
(merges audio SPI services; no dependency-reduced-pom).
- Document running via ./mvnw and via the jar directly in the README.
- Ignore docs/superpowers/ (planning specs kept locally, untracked).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
App.run ended its menu loop on Quit and just returned. The console exits then,
but in the GUI run() is on a daemon worker while the Swing JFrame stays
displayable on the EDT, keeping the JVM alive — and the dismissed menu overlay
just revealed the running game underneath ("back into the game"). EXIT_ON_CLOSE
only fires for the native window X, not a programmatic quit.
Add a GameIO.shutdown() teardown hook (default no-op) and call it after the menu
loop ends. SwingIO overrides it to stop music, dispose the window, and exit the
JVM, mirroring EXIT_ON_CLOSE; console keeps the no-op. Extract an injectable
App.run overload and add AppQuitTest asserting the Quit path invokes shutdown().
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Give the map/quests sidebar more room: raise the width fraction (0.28 -> 0.34)
and minimum (180 -> 220), and remove the SIDE_MAX upper clamp so the panel
keeps scaling with the window instead of stopping at 460px.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Install the downloaded Cascadia Mono Nerd Font as src/main/resources/fonts/
game.ttf — the exact name SwingIO.loadFont() looks up on the classpath
(/fonts/game.ttf), so the GUI now uses a real monospaced Nerd Font (icon
glyphs included) instead of falling back to the logical monospaced font.
Include the font's SIL Open Font License as required for redistribution.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Switch OggMusicBackend from streaming an external, git-ignored music/ folder
(relative to the run directory) to streaming bundled classpath resources under
/music/, so the four manor tracks ship inside the JAR and play out of the box —
consistent with how fonts are bundled. The play loop reopens the resource each
iteration via a BufferedInputStream (the vorbisspi SPI needs mark/reset to read
the OGG header). Missing tracks still fall back to silence.
Add the four converted OGG Vorbis tracks (manor-theme/cellar-drone/musicbox/
lament) under src/main/resources/music/, un-ignore that path, and re-anchor the
gitignore so only the top-level MP3 source folder stays ignored. Update
docs/music.md for the bundled approach and conversion recipes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the 5-room demo with a condensed 14-room manor on one spine
(restore power -> escape) that stacks all five mechanics, plus an optional
spirit thread feeding 3 prioritized endings (no hard-fail). Pure YAML on the
existing engines: 14 rooms across 3 levels, ~16 items, 5 combinations, the
old_man hint NPC, restore_power + lay_to_rest quests, and 3 endings.
Consolidate to one world: remove the toy "Test Manor" test fixture so the
loader tests exercise the real shipped world. Adapt WorldLoaderTest and
TutorialLoaderTest to form-invariants of the real world, and add
WorldSolvableTest, which walks the critical path (light/lock gating +
Combinations.tryUse + flags) to guarantee power_on, ghost_banished, and a
victory ending are reachable — an unsolvable world now fails the build.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Guard colorMode and glyphMode against null in the Settings compact
constructor (alongside the existing musicLevel guard), so a hand-edited
settings.json with a missing field no longer NPEs in SettingsMenu.
Remove the unused MusicLevel import from SettingsMenu. Assert that the
defaulted musicLevel survives a round-trip in SettingsStoreTest.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
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>
- 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>
- 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>
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>