- Add UI_SETTINGS_KEY to config.ts for separate localStorage entry
- Add uiOpacity field (default 0.8, range 0.4–1.0, 10 % steps) to UIScene
- loadUISettings / saveUISettings persist opacity independently of game save
- Replace all hardcoded panel BG alphas with this.uiOpacity:
build menu, villager panel, context menu, ESC menu, confirm dialog,
nisse info panel
- Debug panel (F3) background synced via updateDebugPanelBackground()
- Replace Settings toast with real Settings overlay:
title, opacity − / value / + buttons, Close button
- ESC key priority stack now includes settingsVisible
- repositionUI closes settings panel on window resize
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removes uiMenuOpen/uiMenuClose calls from openNisseInfoPanel() and
closeNisseInfoPanel() — the info panel is an observational overlay and
should not interrupt the game loop. Closes#15.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Clicking a Nisse opens a top-left panel showing name, AI status,
energy bar, active job, job priority buttons, and a live work log
(last 10 of 20 runtime-only entries). Closes via ESC, ✕, or clicking
another Nisse. Dynamic parts (status/energy/job/log) refresh each
frame without rebuilding the full group.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ESC key follows priority stack: confirm dialog → context menu →
build menu → villager panel → ESC menu → open ESC menu.
Menu items: Save Game, Load Game, Settings (placeholder), New Game
(with confirmation dialog).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
F3 toggles a debug overlay with:
- FPS
- Mouse world/tile coordinates
- Tile type under cursor
- Resources, buildings, crops on hovered tile
- Nisse count broken down by AI state (idle/walking/working/sleeping)
- Active jobs by type (chop/mine/farm)
- Pathfinding visualization: cyan lines + destination highlight
drawn in world space via DebugSystem
Added DebugSystem to GameScene. VillagerSystem exposes
getActivePaths() for the path visualization. JSDoc added to all
previously undocumented methods in VillagerSystem, WorldSystem,
GameScene, and UIScene.
Replaces plain cam.setZoom() with zoom-to-mouse: after each zoom step
the scroll is corrected by (mouseOffset from center) * (1/zBefore - 1/zAfter),
keeping the world point under the cursor fixed. Also fixes getCenterWorld()
which previously divided by zoom incorrectly. Added JSDoc to all methods.
Implements scroll correction after cam.setZoom() so the world point
under the mouse stays fixed. Formula accounts for Phaser's
center-based zoom: scrollX += (mouseX - cw/2) * (1/zBefore - 1/zAfter).
Tab switches between the two test scenes in both directions.
Also fixes centerWorld formula in ZoomTestScene overlay and logs.
Text overlay now uses a dedicated HUD camera (zoom=1, fixed scroll)
so it's never scaled by the world zoom. World objects and HUD objects
are separated via camera ignore lists. Added red screen-center
crosshair to HUD layer as a precise alignment reference.
Vite dev server gets a /api/log middleware (POST appends to
game-test.log, DELETE clears it). ZoomTestScene writes a zoom event
with before/after state on every scroll, plus a full snapshot every
2 seconds. Log entries are newline-delimited JSON.
Separate test environment at /test.html (own Vite entry, own Phaser
instance). ZoomTestScene renders a 50×50 tile grid with crosshair
markers and a live HUD overlay showing zoom, scroll, viewport in px
and tiles, mouse world/screen/tile coords, and renderer info.
Zoom uses plain cam.setZoom() — no mouse tracking — to observe
Phaser's default center-anchor behavior.
- Scroll wheel now zooms toward the mouse cursor instead of screen center
- Middle mouse button held: pan camera by dragging
- Both actions respect current zoom level