Replace Phaser 3 with Svelte 5 as the rendering and UI layer. The
framework-agnostic core (level parser, board model, progress store,
microban level data) moves from src/game/core → src/lib/core with zero
code changes. Scenes and the hand-rolled button factory are gone; in
their place:
- src/App.svelte root router (menu / levels / game)
- src/views/MenuView title + play + progress + hints
- src/views/LevelSelectView paginated 5x4 grid with native <button>s
- src/views/GameView owns BoardModel, handles input, HUD, win
- src/views/Board purely presentational DOM renderer
- src/views/AppButton shared themed wrapper for native <button>
- src/app.css Nord palette ported to CSS variables
GameView uses a non-reactive BoardModel ref and syncs plain snapshot
fields (player, boxes, moves, won) into $state after every mutation —
Board consumes only plain props, so Svelte reactivity stays predictable
and the core class stays framework-agnostic. GameView is keyed on
levelIndex in App, so changing level remounts with fresh state.
Native <button> everywhere kills the click-hitbox class of bugs.
Animations are now CSS transform transitions (110ms) instead of tweens.
Bundle shrinks from ~1.5 MB Phaser to ~65 kB JS / 23 kB gzipped — about
60x smaller. Removed: phaser, terser, src/game, log.js (analytics
ping), phasermsg vite plugin, manual Phaser chunks, terser config,
public/style.css. Scripts simplified to dev/build.
Docs updated: codebase summary, architecture, code standards,
changelog, roadmap, README.
Expand the level data from the first 100 Microban layouts to the complete
set, up through the two oversized finale mazes ("Take the long way home"
and "The Dungeon"). Responsive tile sizing already handles the large
grids — no rendering changes needed.
Update credit language in README, PDR, changelog, roadmap, codebase
summary, menu subtitle, and the data file header to reflect the full
set. Credit for David W. Skinner's layouts remains prominent; ownership
of the engine, UI, parser, and progression code stays explicit.
Verified all 155 layouts parse cleanly, have a player, matching box/goal
counts, and none start already solved.
Replace the 3 hand-crafted JSON levels with the full Microban set (100 solvable
puzzles by David W. Skinner) stored as XSB text and parsed at runtime. Rework
the game into kebab-case modules under a 200-LOC budget:
- core/level-parser: XSB parse with flood-fill interior detection
- core/board-model: pure move/undo/win logic, Phaser-free
- core/progress-store: localStorage persistence with graceful fallback
- core/theme: Nord palette, fonts, responsive tile sizer
- ui/button-factory: one rounded button impl with hover/press
- ui/board-renderer: animated tile/wall/goal/box/player drawing
- scenes: menu, paginated level select (5x4 grid, 5 pages), game
Add WASD movement, U/Z undo, R restart, Esc to menu, live move counter,
best-move tracking per level, win overlay with next/levels actions, and a
radial-gradient CSS backdrop.
Drop the dead Arcade Physics wiring, the broken manual shutdown/destroy code,
the unused main.js self-import, and the hardcoded 3-level registry state.
Add docs/ and refresh README.