Skip to content

Tetris, played by a local model

Four Qwen models play a complete Tetris game through POST /v1/systemone. Code knows the rules: it lists every legal move, simulates the outcome and presses the keys. The model makes every choice, with one output token per two pieces.

Play in the browser →   Full test report · Source and recordings

ResultMeasured
Games that reached 10 line clears58 / 60
Qwen3.8-27B per decision, compact prompt0.73 s median
Lines per game, Qwen3.8-27B38.2 · random picks 14.3 · reference 37.8
Best score after 100 pieces15,262 · quality, compact, seed 202

Watch each model play

Seed 101, from the first piece to the tenth line clear. Waiting time is the measured round trip of each call.

fast · Qwen3.5-0.8Bvision · goal after 56 pieces · 0.14 s per call
balanced · Qwen3.5-4Bvision · goal after 30 pieces · 0.51 s per call
quality · Qwen3.6-35B-A3Bvision · goal after 32 pieces · 0.92 s per call
max · Qwen3.8-27Bcompact · goal after 32 pieces · 0.66 s per call

Results after 100 pieces

ProfileLines · visionLines · compactCall · visionCall · compactAgreement
fast · Qwen3.5-0.8B26.617.40.15 s0.03 s42%
balanced · Qwen3.5-4B35.833.00.65 s0.12 s73%
quality · Qwen3.6-35B-A3B38.238.20.91 s0.14 s84%
max · Qwen3.8-27B38.438.24.08 s0.73 s85%

Five seeds per cell, 100 pieces per game. Agreement compares the vision-prompt decisions with a reference evaluator that never moves a piece. All 60 games →

Without a model

On the same pruned plans, a random pick tops out in 90 of 100 games and clears 14.3 lines. Always taking the first plan clears 16.0. The code narrows the choice; the model makes it.

How one decision works

  1. Enumerate. Code lists every placement of the falling piece and of the next one: usually 300–600 two-piece plans.
  2. Prune without weights. A plan is dropped only when another matches or beats it on every measured fact. About three remain.
  3. Ask once. One Choice question lists the plans with their facts: rows cleared, new holes, height. The vision prompt adds a lettered image of each outcome.
  4. Read one token. The answer is a full distribution over the plans; code presses the keys of the chosen one.

The compact prompt sends the rules as the state, which never changes, and only the pieces and short plan facts as the question. The API keeps the state cached, so each call reads about 75–100 new tokens. That is what brings a dense 27B model under a second.

The image sent with one real decision: three lettered outcome tiles

Run it yourself

bash
uv run openjev serve                                  # balanced profile on :8000
uv run python examples/tetris/serve.py                # browser game on http://127.0.0.1:8765
uv run python examples/tetris/play.py bench --seeds 101,202,303,404,505 --modes vision,compact

Measured on an Apple M3 Max with llama.cpp on Metal. Five seeds per configuration is a small sample; timings depend on the machine and its load.

Open models. Local inference. Measured claims.