counterpunch.asm$DF60 · city.bin

Counterpunch

A PPO agent that learns NES Punch-Out!! from raw pixels. After about 10 million steps it knocks out Glass Joe in roughly 16 seconds of game time and is starting to land punches on Von Kaiser.

coverA frame from the project's stable-retro environment: Little Mac lands a punch on a reeling Glass Joe at 1:09 of round 1, under a random policy
A frame from the project's stable-retro environment: Little Mac lands a punch on a reeling Glass Joe at 1:09 of round 1, under a random policy
README.mdcounterpunch/index.mdx

A reinforcement learning agent for Punch-Out!! on the NES. stable-retro runs the emulator and stable-baselines3 trains a PPO agent with a CNN policy on 8 stacked 84×84 grayscale frames. The only other input is the reward, which is read out of RAM.

How it works

  • Nine actions. NOOP, dodge left/right, block, body blows, head punches and the star uppercut, each mapped to a button combo.
  • Reward from RAM. Health deltas, knockdowns, punches landed, stars earned and used, and a KO bonus. The RAM addresses were found and verified by hand, and the repo includes a written memory map and an HTML ROM map.
  • Curriculum. Training is mostly Glass Joe, with a 33% chance of starting against Von Kaiser. The Von Kaiser save state is generated by letting a trained model beat Glass Joe, then capturing the moment the next fight starts.
  • Eight frames, not four. Punch-Out!! is a game of tells, and four frames at a 4-frame skip only covers about 267 ms. Doubling the stack lets the agent see a whole wind-up before it commits.

Results so far

The first agent that worked (run 8) wins against Glass Joe about 95% of the time from 2M steps on. The current run is training against both opponents.

The research logs are worth reading for the failures. One run collapsed because of a reward term. Damage was double-counted when health reset after a knockdown. And the longest bug took days and came down to the NES ignoring a START press that only lasted one frame.

Running it

You need Python 3.10+, your own Punch-Out!! ROM, and preferably a CUDA GPU.

pip install -r requirements.txt
python3 scripts/make_state.py --match 1
python3 train.py
python3 evaluate.py --model models/<run>/best/best_model.zip --record

Training records milestone videos at 1%, 25%, 50%, 75% and 100% of the run.