Pokemon Red — You Are the Trainer
You play Pokemon Red directly. One button press at a time. You see the screen, read the state, decide what to press, press it, see what happened, decide again. You are the player.
Setup (first time)
git clone https://github.com/drbarq/Pokemon-OpenClaw.git
cd Pokemon-OpenClaw
pip install pyboy pillow numpy fastapi uvicorn requests
# Place your legally obtained ROM at ./PokemonRed.gb
Start a Session
cd ~/Code/pokemon-openclaw && python scripts/emulator_server.py --save ready --port 3456
The Loop
Every turn is the same:
1. Look
# Get game state (position, HP, battle status, party)
curl -s http://localhost:3456/api/state
# Get screenshot
curl -s http://localhost:3456/api/screenshot -o /tmp/pokemon.png
Use the image tool to look at the screenshot. Always look before acting.
2. Think
Based on what you see:
- Where am I? Where do I need to go?
- Am I in a battle? What should I do?
- Is my HP low? Should I heal?
- Is there an NPC or item nearby?
If you need directions, ask the pathfinder:
curl -s "http://localhost:3456/api/route?destination=Viridian+City"
Returns a list of steps: ["right", "right", "up", "up", ...]
This is your GPS — follow it one step at a time, or ignore it if you see something better to do.
Check available destinations:
curl -s http://localhost:3456/api/destinations
3. Act — ONE button press
curl -s -X POST http://localhost:3456/api/press \
-H 'Content-Type: application/json' \
-d '{"button": "up", "reasoning": "Following route north to Viridian"}'
ONE button per press. The server enforces this — it rejects lists and has a 500ms cooldown.
Use "button" (singular). Valid: up, down, left, right, a, b, start, select
The response includes the game state after the press, so you immediately know what happened.
4. Repeat
Go back to step 1. Every turn you look, think, press one button.
Battles — THINK EVERY MOVE
Battles are where the real decisions happen. NEVER spam A. Every press is a choice.
When you see the battle menu (FIGHT / ITEM / PKMn / RUN), STOP and think:
FIGHT: Which move should I use? Check type matchups. Don't waste PP on weak moves.
- Navigate the move menu with
up/down, confirm witha - After selecting, press
athrough animations ONE AT A TIME, looking at the screen each time
ITEM: Do I need to heal? Use a Potion if HP is low. Throw a Poke Ball if this is a Pokemon worth catching.
- Press
downto highlight ITEM,ato open bag - Navigate to the item, press
ato use it
PKMn: Should I switch Pokemon? If the matchup is bad, switch.
RUN: Am I too weak for this fight? Running is smart, not cowardly. Better to run than whiteout.
CATCH: If you see a new Pokemon you don't have, TRY TO CATCH IT. Weaken it first (get HP low), then throw a Poke Ball.
Between EVERY button press in battle: Look at the screenshot. What's on screen right now?
- Is it the battle menu? → Make a strategic choice
- Is it move selection? → Pick the right move
- Is it text/animation? → Press
ato advance, then look again - Did the battle end? → Check state, continue exploring
NEVER do this: for i in $(seq 1 5); do curl press a; done — that's not playing, that's mashing.
Key Endpoints
| Endpoint | Method | Purpose |
|---|---|---|
/api/state |
GET | Position, party, badges, battle status |
/api/screenshot |
GET | PNG of current screen |
/api/press |
POST | Press ONE button, get state back |
/api/route |
GET | Ask pathfinder for directions to a destination |
/api/destinations |
GET | List all known destinations |
/api/maps |
GET | Which maps have pathfinding data |
/api/quest |
GET | Current quest objective |
/api/quest/complete |
POST | Mark step done + save lesson |
/api/command |
POST | Save/load/speed commands |
Strategy
- One move at a time. No multi-button sequences. No bash loops. Press ONE button, look at screen, think, press next.
- Battles are strategic. Choose moves based on type matchups. Use items. Catch new Pokemon. Run when outmatched.
- Use the pathfinder as GPS. Ask for route, follow one step at a time. Re-query after battles or detours.
- Catch Pokemon. If you see something new, try to catch it. Build a team.
- Manage HP. Below 30% → use a Potion or head to Pokecenter. Don't push your luck.
- Ignore text_active. That flag is broken (always true). Look at the screenshot instead.
- Save often.
{"command": "save", "name": "checkpoint_name"} - NEVER use bash loops for button presses. Each
curlto/api/pressmust be its own separate tool call, with a screenshot check before the next one.
Session Pattern
- Start emulator (if not running)
- Check quest + state
- Play turns: look → think → press one button → repeat
- Save state before exiting
- Report: location, level, quest progress, battles fought