Jev2048 ๐ฎ
September 17, 2026 ยท View on GitHub
TypeSafe's Jev plays 2048 โ many games in parallel, live in your browser.
Jev2048 is a small AI laboratory: instead of generating text, Jev (a TypeSafe System One decision model) picks the next 2048 move via a single choice decision per turn. The web app runs as many games in parallel as you like, tracks the best score (MAX) live, and lets you experiment with the state format Jev receives โ instructions, board encoding, features and choice criteria are all editable in the browser with a live JSON preview.

Full-quality video: demo.mp4.
Features
- Parallel runs โ start N games at once, every game plays itself via Jev, the best board is highlighted and the live MAX score (score, game #, max tile) is always visible
- State Format Editor โ change what Jev sees without touching code:
- free-text instructions
- board encoding: exponents (
0=empty,1=2,2=4, โฆ), raw values, or text grid - toggleable features (empty cells, max-tile corner, monotonicity, smoothness, mergeable pairs), legend, last move
- dynamic criteria (each move described by its outcome: merged points + empty cells) vs. static direction labels
- collapsible JSON preview of the exact request payload, flat row-by-row board rendering
- Leaderboard โ persistent high scores (
data/leaderboard.json), save the best run, one-click reset - Self-built 2048 engine โ no game library: slides, merges, spawns, scoring, game-over detection (
backend/game2048.py, covered by tests) - Resilient โ if the Jev API rate-limits or is unreachable, a local heuristic fallback keeps every game running (flagged in the response)
How it works
Browser (React + shadcn) โโโถ FastAPI โโโถ POST api.typesafe.ai/v1/systemone
parallel games Jev moves model "jev-latest", one `choice` question
โ per move: up | down | left | right
โโโ board + score โโโโโโโโโโโโโ choice + probabilities + confidence
Per move the backend sends the current board as state (format configurable in the UI, see above) plus a single choice question with only the valid moves as options โ so Jev can never pick an illegal direction. Score, moves and win detection stay server-side in the hand-written engine.
Quickstart
You need Python 3.10+ and Node 20+.
# 1. Backend
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
# 2. API key (.env is git-ignored โ never commit it)
echo 'JEV_API_KEY=your_key_here' > .env
# alternative variable name: TYPESAFE_API_KEY
# 3. Frontend (only needed after UI changes)
cd frontend && npm install && npm run build && cd ..
# 4. Run
python3 -m uvicorn backend.main:app --port 8000
# โ http://localhost:8000
API
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/health | Status + whether a Jev key is configured |
| POST | /api/game/new | New game ({"seed": 1} optional) |
| GET | /api/game/{id} | Game state |
| POST | /api/game/{id}/jev-move | Ask Jev for the best move and apply it |
| GET / PUT / DELETE | /api/format | Read / update / reset the state format |
| GET | /api/format/preview | Example request payload for a fixed demo board |
| GET / POST / DELETE | /api/leaderboard | High scores: read / save / reset |
Project structure
โโโ backend/
โ โโโ game2048.py # 2048 engine + board features (exponents, monotonicity, โฆ)
โ โโโ jev.py # Jev API client, format config, request builder, fallback
โ โโโ store.py # game sessions + JSON leaderboard
โ โโโ main.py # FastAPI app + static frontend
โ โโโ test_game2048.py
โโโ frontend/src/
โ โโโ components/ # ParallelRun, Leaderboard, FormatEditor, GameBoard, JsonTree
โ โโโ components/ui # shadcn components (Button, Card, Table, โฆ)
โโโ data/ # runtime state (git-ignored): leaderboard.json, format.json
โโโ demo.mp4 # demo video (shown above)
Tests
python3 -m pytest backend/test_game2048.py -q