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>