A browser game that mashes a merge puzzle together with bowling. You look straight down a lane like you're standing at the foul line of a bowling alley. Random pucks appear at your end; bowl them down the lane, and when two pucks with the same number collide they merge into the next one up. Merge all the way to the top tier to clear it for a big bonus.
- Aim with your mouse or finger — a dotted guide shows the launch path.
- Tap / click the lane to bowl the current puck.
- Matching pucks that touch merge into the next tier (1 → 2 → 3 → …).
- Merging two of the top tier clears them in a burst for +750.
- The pile builds toward you. If a settled puck crosses the red foul line, the lane jams and the game ends.
The Next puck is previewed in the top-right; your best score is saved locally.
Requires Node.js 18+.
git clone https://github.com/mitchallen/game-merge-101.git
cd game-merge-101
make install # or: npm install
make dev # or: npm run devmake dev starts the Vite dev server with hot reload and opens the game in your
browser (defaults to http://localhost:5173). That's it — no external assets or
services to configure.
- Rendering: Three.js — a perspective camera looking down the lane gives the real bowling-alley depth. All textures are generated procedurally (no external assets), so the build is fully self-contained.
- Physics: a small custom top-down 2D simulation (
src/physics.js) — circle bodies with friction, wall/back-wall bounces, mass-weighted collision impulses, and merge-on-contact. Keeping physics in-house makes the merge rules exact and avoids a heavyweight 3D physics dependency for what is really a flat-table game. - Build: Vite, driven by
make.
The pucks only ever slide on a flat table, so the simulation is genuinely 2D. A bespoke circle solver is a few hundred lines, runs anywhere, and lets the merge/clear logic live right inside the collision step — cleaner than reconciling merge events against a general 3D engine (cannon-es / Rapier). Three.js still does all the 3D rendering.
make install # install dependencies (three, vite)
make dev # start the dev server with hot reload (opens the browser)
make build # production build -> dist/
make preview # serve the production build
make clean # remove dist/
make distclean # remove dist/ and node_modules/game-merge-101/
├── Makefile # build/run targets
├── index.html # HUD, overlays, styles
├── vite.config.js
└── src/
├── config.js # tier palette, alley geometry, physics tuning
├── physics.js # renderer-agnostic top-down puck simulation
└── main.js # Three.js scene, rendering, input, game loop
Tuning knobs (tier colors/sizes, lane dimensions, launch speed, friction,
scoring) all live in src/config.js.
