We built the suite as one Vite and Phaser 3 app with a DOM hub, and gave every game the same shape: a pure, deterministic TypeScript engine with no DOM, and a Phaser scene that only renders the engine and turns input into engine calls.
Key design decisions
- Engines first, scenes second. The platformer, café, maze and note codec are plain TypeScript modules driven at a fixed 60 Hz step where it matters. That is why 54 unit tests can cover the rules directly, without a browser.
- A solver as level QA. The Hug Maze ships with a breadth-first solver over bear positions and pushable objects. Every one of the 15 levels is proven solvable, its par is the solver’s optimum, and during design we also re-solved each level with its featured mechanic removed to see whether the puzzle really depends on it.
- Physics-aware level checks. Snack Run’s tests derive reach limits from the real jump arc and prove that both bears can reach the goal and every snack in all 5 levels.
- Kind failure states. The café never ends badly: an expired order makes Dudu cry, and Bubu’s Cheer Up Strawberry restores 30% patience for everyone. The platformer’s Love Tether rewards staying together instead of punishing hard.
- Serverless sharing. A love note and its decorated room are compressed with deflate into a base64url URL hash. An optional secret word encrypts it with AES-GCM-256 and a PBKDF2 key, and decoding validates and clamps every field.
- Procedural, resolution-aware art. Both bears, the customers, food, furniture and tiles are Canvas 2D vector painters baked into texture atlases at the device pixel ratio, with the camera zoomed to match, so a 1600 × 900 logical scene is pixel-sharp on any display.
Architecture
src/core holds the art (bears and props), texture baking, synthesised audio and a single LocalStorage save with the shared Paw Coin wallet. src/games holds the four engines, src/scenes one Phaser scene per game on a shared base scene (fixed step, popups, particles), and src/ui the hub, top bar, HUD, modals and touch controls.