Brainstormed design for backlog #6/#7: shell loop above the game loop,
GameIO.choose() primitive (console default + Swing buttons), GameSession
bundling savable state, JSON SaveData delta over the YAML world, single
active slot, autosave (quest-complete + quit + every 10 turns), and minimal
runtime-togglable settings (color/glyph mode).
Co-Authored-By: Claude Opus 4.8 (1M context) <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>
Room.dark + Item.light flags, a Light helper (isLit/carryingLight), and command
gating: can't enter a dark room without a lit light source; look/take/examine
obscured in the dark; HUD light field wired. Entry-gate prevents soft-locks.
Demo: dark dungeon needs the lit lamp. Fuel/timed light out of scope.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Priority-ordered, condition-driven endings (endings.yaml) checked each turn
after the quest tick; the first match prints an ending banner + run summary
(turns, quests X/Y, rank) and ends the game. EndingEngine mirrors the quest
engine; World gains 5/6/7-arg back-compat constructors. Two reachable demo
endings: victory (manor_secured) and flee (front door -> fled). Completes the
quest system (#3). 120 tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Priority-ordered condition-driven endings + an end-of-game summary (turns,
quests X/Y, rank). EndingEngine mirrors the quest engine; Game ends the loop
when an ending fires. endings.yaml optional; World gains 5/6/7-arg back-compat
constructors. Two reachable demo endings (victory, flee) with no new mechanics.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Condition-driven multi-stage quests on the foundation: Quest/QuestStage data,
QuestLog + QuestEngine (per-turn auto-advance with ✓/★ announcements and
cascade), START_QUEST effect, QuestView pushed/rendered like the map. Console
'quests' command and a GUI quest-box under the map. Demo quest restore_power
auto-advances as you restore power and earn the key. 116 tests green.
Win-condition/endings (3.3) deferred.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Condition-driven multi-stage quests on top of the foundation: Quest/QuestStage
data, QuestLog + QuestEngine (per-turn auto-advance with announcements),
START_QUEST effect, QuestView display via a console 'quests' command and a GUI
quest-box under the map. quests.yaml optional; World gains a 5-arg back-compat
constructor. Win/endings deferred to 3.3.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
One typed condition/effect vocabulary (GameState + Conditions + Effects)
wired into five integration points: condition-locked exits, state-dependent
room descriptions, conditional NPC dialogue, reactions with requires/effects,
and switch effects. All new YAML fields optional (backward compatible). Demo:
a generator switch sets power_on, which unlocks and lights the cellar and
changes the old man's dialogue. 107 tests green. Light/dark, item-combination,
quest objects and endings deferred.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Body text/HUD font now derives from a window-relative auto-scale (starting
at uiScale, growing as the window grows) and is re-applied on resize, so the
text tracks the window like the map does. Ctrl +/- zoom still multiplies on
top of both. Removes the resize hiccup where only the map reacted.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
MapPanel now scales the map to fit the side panel (min over width/height),
with the Ctrl +/- zoom as a multiplier on top, so it no longer overflows
and scrolls at normal zoom. The map re-fits whenever the window/side panel
is resized; side panel grows a little more (28%, max 460px) before capping.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
MapPanel had fixed pixel sizes and an 11pt font, so it ignored uiScale and
the Ctrl +/- zoom. It now multiplies all dimensions, strokes and the label
font by a scale set from uiScale x zoom in SwingIO.applyFonts().
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fog-of-war map from the directional exit graph: MapLayout (BFS) builds a
frontend-agnostic MapView; SwingIO draws it (Graphics2D MapPanel, replacing
the exits text), ConsoleIO mirrors it as ASCII via the `map` command.
Visited tracking on Player; per-turn map push from Game. 90 tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
AsciiMap sizes room boxes to the longest visible name (capped) so names
like 'Dark Hallway' are no longer truncated; connector centering follows.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Game now derives the MapView from the world each turn; GameTest gains a
real World (the per-turn map push needs it).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fog-of-war map from the directional exit graph. MapLayout (BFS) produces a
frontend-agnostic MapView; SwingIO draws it (Graphics2D MapPanel, replaces
exits text), ConsoleIO mirrors it as ASCII via the map command. Visited
tracking on Player. Item/NPC markers and locked-door styling deferred.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>