No description
- TypeScript 51.1%
- HTML 48.3%
- CSS 0.5%
- Shell 0.1%
|
|
||
|---|---|---|
| design | ||
| docs | ||
| e2e | ||
| public | ||
| src | ||
| test-results | ||
| .gitignore | ||
| capacitor.config.ts | ||
| CLAUDE.md | ||
| deploy.sh | ||
| index.html | ||
| package-lock.json | ||
| package.json | ||
| playwright.config.ts | ||
| README.md | ||
| tsconfig.json | ||
| vite.config.ts | ||
PegPop
A mobile puzzle game built with a hybrid DOM + Phaser 3 architecture. Jump pegs to pop, fuse and trigger power-ups across handcrafted levels.
Tech Stack
- TypeScript + Vite — build tooling
- Phaser 3 — canvas-based game board rendering
- Tailwind CSS — shell UI styling ("Sugar Rush Gloss" theme)
- Vitest + happy-dom — unit and integration tests
- Playwright — end-to-end tests
- Capacitor — mobile packaging
Getting Started
npm install
npm run dev
Then open the URL printed by Vite.
Scripts
npm run dev # Vite dev server
npm run build # TypeScript compile + Vite build
npm test # Vitest watch mode
npm run test:ci # Vitest single run
npm run test:e2e # Playwright E2E tests
Run a single test file or pattern:
npx vitest run src/game/systems/Board.test.ts
npx vitest run -t "shuffle"
Architecture
PegPop uses a hybrid DOM + Phaser 3 architecture:
- Shell UI (
src/ui/) — menus, shop, overlays as vanilla DOM + Tailwind, managed by a hash-based router (src/router.ts). Each screen implementsRoute { mount, unmount }. - Game Board (
src/game/scenes/BoardScene.ts) — the only Phaser Canvas scene, mounted when navigating to#game/{levelId}and destroyed on exit. - Event Bus (
src/events.ts) — typed discriminated unionGameEventbridges Shell ↔ Phaser (GAME_WIN,GAME_DEFEAT,SCORE_UPDATE, …).
Game Systems
Pure TypeScript with no Phaser dependency, in src/game/systems/:
- Board — grid data structure (Map-based), cell operations and
shuffle() - MoveSystem — validates jumps, detects deadlock, determines power-ups from chain length (2→bomb, 3→ray, 4+→prism)
- FusionSystem — executes jumps: different color pops, same color fuses (tier upgrade), cristal+cristal both disappear
- ScoreSystem — points per action with chain multiplier (×1.5 per jump after first), star thresholds
- ObjectiveSystem — tracks score, clear, color elimination and crystal fusion goals
Services (src/services/)
- GameState — level completion, rank calculation, world unlocks
- SaveManager —
localStoragepersistence (key:pegpop_save) - CurrencyManager — gems, lives (max 5, 20 min regen), power-up inventory
- AudioManager + SfxSynth — Web Audio API synthesized sounds (no audio files)
- LevelManager — fetches
public/levels/level-{NNN}.json, caches in memory
Levels
Levels are JSON files in public/levels/level-{NNN}.json. Each defines board: Cell[], objectives, maxMoves and starThresholds.
Testing
- Unit tests co-located with source (
*.test.ts) — all game systems and services are covered - Integration tests in
src/game/integration.test.ts— full gameplay scenarios using pure TS systems - E2E tests in
e2e/navigation.spec.ts— Playwright navigation and UI
Phaser rendering, FX and audio are not unit tested (visual/audio only).
Design
"Sugar Rush Gloss" — warm rose palette, 3D glossy buttons, tonal separation over borders. Theme defined in src/style.css via @theme. Full reference in design/v3/sugar_rush_gloss/DESIGN.md.