nesformer is a free, open-source project by Drew Breunig (MIT licence): https://github.com/dbreunig/nesformer.
It takes a stock Qwen3.5 AI model and, instead of training it, uses a compiler to calculate every weight. The NES's 6502 processor, its 2 KB of memory and a game cartridge's program end up inside the model. When you play, the model predicts the console's execution log one token at a time. A small host program draws the picture, reads the controller and keeps time.
It builds on Qwenputer by Divyansh Agrawal (https://github.com/divagr18/qwenputer), which did the same for CHIP-8 and RISC-V.
What you need
- Python 3.11 or newer (I used 3.12)
- About 1 GB of free disk space for the weights. No GPU is needed: it runs on one CPU core.
- Patience. My laptop drew about one frame every 3.4 seconds.
Download the code and the weights
git clone --depth 1 https://github.com/dbreunig/nesformer.git
cd nesformer
unzip -o nesformer-weights.zip # 3.3 MB zip -> weights/model.safetensors (933 MB)
shasum -a 256 -c weights/SHA256SUMS # should print: weights/model.safetensors: OKInstall
python3 -m venv .venv
source .venv/bin/activate
pip install numpy scipy numba pillow
python -m nesformer info # describes the checkpoint: Qwen3_5ForCausalLM, 7 circuit layersPlay a game on the weights
This is the run from the video: Full Game by Doug Fraker (a free MIT homebrew game that ships in roms/). It presses
Start, holds Right and jumps every half second.
python -m nesformer run roms/full_game.nes --frames 460 --show \
--buttons "start@40-45,right@90-460,a@110-125+170-186+202-218+234-250+266-282+298-314+330-346+362-378+394-410+426-442+458-474"--showdraws every frame in your terminal as the model generates it. It needs 24-bit colour: iTerm2 or Windows Terminal.- When it finishes, you get
full_game.gifin the folder. Add--png frames/to save every frame as an image. - 460 frames is 7.7 seconds of game time. On my MacBook (CPU only) that took 26 minutes: 3,322,934 tokens at about 2,100 tokens a second, and every frame matched a normal 6502 CPU's run exactly.
Want it quicker? Use --frames 120 for a 2-second test run.
Try the other things
python -m nesformer trace roms/full_game.nes --tokens 40 # print the model's raw token stream
python -m nesformer check roms/thwaite.nes # run the weights next to a normal 6502 CPU, stop at any differenceroms/thwaite.nes is Thwaite by Damian Yerrick, a missile-defence homebrew game (GPL-3.0).
Controller cheat sheet
--buttons takes button@start-end frame ranges, at 60 frames a second:
start@60-65presses Startright@200-600holds Righta@250-265+300-315presses A twiceright+b@200-600holds Right and B together
Good to know
- It's slow on purpose: a real NES needs about 700,000 tokens a second. The author measured 150-290x slower than the real console.
- Only NROM cartridges (mapper 0) work, so no bank-switching games yet.
- There's no sound, because the audio chip isn't in the model.
- You supply your own ROMs. Only use games you own or free homebrew games like the two that come with it.
Credit: nesformer by Drew Breunig (MIT); Qwenputer by Divyansh Agrawal (MIT); Full Game by Doug Fraker (MIT). This guide isn't affiliated with any of them, with Nintendo or with Alibaba's Qwen team.