feat!: rewrite on Svelte 5, drop Phaser

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.
This commit is contained in:
tiennm99 committed 2026-04-12 00:50:46 +07:00
1 parent 94fee81e6b
commit 8a3d4b4a9d
33 files changed
+1280 -818

No files matched your search

@@ -0,0 +1,43 @@
# Svelte Migration
**Date:** 2026-04-12
**Status:** In progress
## Goal
Replace Phaser 3 with Svelte 5 as the rendering/UI layer. Keep framework-agnostic modules untouched. Ship a smaller, more structured, natively-clickable version of the same game.
## Stays
- `core/level-parser.js`, `core/board-model.js`, `core/progress-store.js` → moved to `src/lib/core/`
- `data/microban-levels.js` → moved to `src/lib/data/`
- All 155 levels
- Nord palette (ported to CSS variables)
- Vite as build tool, GitHub Pages deploy
## Goes
- `phaser` dependency, `terser` devDependency, `log.js` analytics ping
- `src/game/` (main, scenes, ui)
- Vite `manualChunks: { phaser }`, `phasermsg` plugin, terser options
- `npm run dev/build` scripts' `node log.js … &` prefix
## Comes in
- `svelte` + `@sveltejs/vite-plugin-svelte` devDependencies
- `src/App.svelte` — view router
- `src/main.js` — mount point
- `src/app.css` — theme + resets
- `src/views/MenuView.svelte`
- `src/views/LevelSelectView.svelte`
- `src/views/GameView.svelte`
- `src/views/Board.svelte`
- `src/views/AppButton.svelte`
## Steps
1. Update `package.json` deps and scripts.
2. `npm install`.
3. Port core/data modules to `src/lib/`.
4. Write Svelte components + entry.
5. Update `vite/config.*.mjs` (svelte plugin; drop Phaser-specific bits).
6. Update `index.html`.
7. Delete old `src/game/`, `log.js`.
8. Verify prod build.
9. Update docs (codebase summary, architecture, changelog, roadmap).
10. Single atomic commit.