Turn a hand-drawn sketch into a playable platformer level in seconds.
๐ฎ Live demo โ hopit.us
Sketch a level on grid paper, snap a photo, and HopIt converts it into a fully playable browser game โ complete with AI solvability analysis and an adaptive Hard Mode that remixes the level based on exactly where you died.
- Sketch โ Play โ Upload a photo of any hand-drawn grid and play it instantly
- Live Editor โ Paint and erase tiles directly on the canvas
- K2 Think Analysis โ Streaming AI reasoning verifies if your level is beatable and flags design issues
- Hard Mode โ Claude remixes your level with walkers, saws, crumble tiles, and flyers targeted at your death spots
- Physics Tuner โ Adjust gravity, jump strength, speed, and friction in real time
- Auto Mode โ Built-in decision-tree AI plays the level for you
| Draw this | Tile |
|---|---|
| Filled / shaded rectangle | Platform |
| Triangle โณ | Spike (instant death) |
| Circle โ | Player spawn |
| Star โ | Goal (finish) |
- Node.js 18+
- Gemini API key โ Get one free at Google AI Studio (image โ level conversion)
- Anthropic API key โ console.anthropic.com (Hard Mode remixing)
- K2 Think API key โ api.k2think.ai (optional โ solvability analysis panel)
git clone https://github.com/merkusvictory/platformer-level-builder.git
cd platformer-level-builder
# Install backend dependencies
cd backend && npm install
# Install frontend dependencies
cd ../frontend && npm install# From the repo root
cp backend/.env.example backend/.env
cp frontend/.env.example frontend/.envEdit backend/.env:
# Required โ converts uploaded images to level grids
GEMINI_API_KEY=your_gemini_key_here
# Required โ powers Hard Mode level remixing (Claude Haiku)
ANTHROPIC_API_KEY=your_anthropic_key_here
# Optional โ enables the K2 Think solvability analysis panel
K2_API_KEY=your_k2_key_here
K2_API_BASE_URL=https://api.k2think.ai/v1
# Leave as-is for local dev; set to your Vercel URL in production
FRONTEND_URL=http://localhost:5173
# Port (default 3000)
PORT=3000Edit frontend/.env:
# Leave empty for local dev โ Vite proxy forwards /api to localhost:3000
# Set to your Render backend URL for production
VITE_API_URL=Open two terminals:
# Terminal 1 โ backend (port 3000)
cd backend
node server.js
# Terminal 2 โ frontend (port 5173)
cd frontend
npm run devThe Vite dev server automatically proxies /upload, /verify, and /api to the backend โ no CORS issues, no extra config.
platformer-level-builder/
โโโ backend/
โ โโโ server.js # Express API โ /upload /verify /api/levels/hard-mode
โ โโโ .env.example # All environment variables with descriptions
โ โโโ render.yaml # Render deployment config
โ โโโ src/
โ โโโ geminiPipeline.js # Gemini Vision โ level JSON
โ โโโ levelConverter.js # Pipeline orchestration
โ โโโ verificationEngine.js # BFS reachability + K2 Think streaming
โ โโโ hardModeEngine.js # Deterministic hard mode fallback
โ โโโ agents/
โ โ โโโ hardModeAgent.js # Claude Haiku hard-mode remixer
โ โโโ config.js # Grid dimensions (50ร35)
โโโ frontend/
โโโ vite.config.js # Dev proxy โ localhost:3000
โโโ .env.example # Frontend environment variables
โโโ vercel.json # SPA rewrite rule for Vercel
โโโ src/
โโโ pages/
โ โโโ Upload.jsx # Upload, camera capture, demo picker
โ โโโ Processing.jsx # Upload progress
โ โโโ Play.jsx # Game engine โ canvas, physics, AI, editor
โโโ data/demoLevels.js # 5 built-in demo levels
โโโ components/ # Aurora, SplitText, StarBorder UI primitives
| Method | Path | Description |
|---|---|---|
POST |
/upload |
Multipart image โ SSE stream โ level JSON |
POST |
/verify |
SSE stream โ BFS + K2 Think solvability verdict |
POST |
/api/levels/hard-mode |
Claude hard-mode remix (deterministic fallback) |
GET |
/health |
Health check |
| Value | Tile |
|---|---|
0 / "" |
Empty |
"T" / 1 |
Platform |
"S" |
Spike |
"C" |
Coin |
"G" |
Goal |
"P" |
Player spawn |
"W" |
Walker enemy |
"F" |
Flyer enemy |
"Z" |
Saw blade |
"B" |
Crumble platform |
"J" |
Spring |
| Input | Action |
|---|---|
| Arrow keys / WASD | Move |
| Space / Up / W | Jump |
| R | Respawn |
Edit mode (click โ EDIT): click or drag to paint tiles, right-click to erase, Ctrl+Z to undo.
| Setting | Value |
|---|---|
| Root directory | frontend |
| Build command | npm run build |
| Output directory | dist |
VITE_API_URL |
Your Render backend URL |
| Setting | Value |
|---|---|
| Root directory | backend |
| Build command | npm install |
| Start command | node server.js |
| Env vars | Same as backend/.env.example |
Deploy order: Render first โ copy URL โ set
VITE_API_URLin Vercel โ deploy Vercel โ copy URL โ setFRONTEND_URLin Render โ redeploy Render.
| Layer | Stack |
|---|---|
| Frontend | React 19, Vite, Tailwind CSS 4, Framer Motion, HTML5 Canvas |
| Backend | Node.js, Express 5, Multer, Sharp |
| Vision AI | Gemini 2.5 Flash โ image to level grid |
| Hard Mode AI | Claude Haiku (Anthropic) โ adaptive level remixing |
| Solvability AI | K2 Think V2 (MBZUAI) โ streaming BFS reasoning |