August 9, 2026 · Updated September 15, 2026

Teaching agents to play Paper Mario

I was playing Paper Mario and wondering how much of it we could get running at 60 FPS. The game has decompiled source available, so it seemed worth trying, even if some animations had to stay at their original rate. I was already giving coding agents difficult programming problems, and I wanted to see how far we could get with this one.

The agent would need to play the modified game to check its work, which seemed straightforward enough. The opening of Paper Mario mostly asks you to create a save file, get through some dialogue, and walk into a castle, so I expected the difficult questions to be about timing, rendering, and what we had broken.

I ended up coaching it through file select.

Getting to the door

This was early in 2026, with GPT-5.3-Codex. It could write useful software around the emulator and talk about Paper Mario, but actually operating the game was a different matter.

I told it to look up walkthroughs and use whatever information would help. A walkthrough would tell it to go through the door with a star on it, and there was a giant door with a giant star right there in the screenshot. To me, someone who has played games my whole life, the game was practically pointing at the destination. The agent still struggled to connect what it had read with where it needed to go.

I could watch the problem developing on screen. It would run a script that pressed A repeatedly while seeing only occasional screenshots. I was watching the actions happen; it was trying to reconstruct them afterward. It couldn't reliably tell whether a button press had worked, whether it was still in dialogue, or whether it had moved closer to its goal.

Savestates should have helped. I told it to use them, and then it lost track of which state held useful progress and what it was safe to reload. Even basic navigation became a long exercise in explaining things I normally do without thinking. I needed it to go up the stairs.

By then I was using agents for much more than programming. Given ways to find information and check their answers, they were useful for research, everyday questions, and thinking through problems. I had become used to finding another thing they could help with, so I hadn't expected walking through a door in Paper Mario to be where that stopped.

It could explain what I needed to do in the game, but I couldn't get it to actually do it. GPT-5.4 got farther, but I kept running into the same problems with navigation and checking whether an action had worked. GPT-5.5 was the first model where I started seeing a way through.

The renderer I wanted

I eventually put the 60 FPS work aside because I couldn't get the agents to make enough progress. I still wanted hi-res textures and better scaling in ParaLLEl, so I turned my attention there.

I liked playing with ParaLLEl and wanted to keep its rendering behavior and Vulkan path, but I also wanted the community texture packs I used with GLideN64. Switching renderers to get one feature meant giving up something else I liked, so my goal was fairly specific: make a fork that could handle the hi-res textures and scaling while preserving the rest of the emulator's behavior.

MasterKillua and other pack authors had already spent years redrawing Paper Mario's textures at high resolution, by hand. I wanted to make that work usable in the renderer I preferred.

Title screen: textures and scaling: Original · normal scaling

The original textures, with the usual protection that keeps these 2D surfaces at native resolution.

The same saved title screen at 1440×1080. The first four settings use the June 10 build; the fifth shows the later fixes together. Getting the pack to load was only part of the work. Use the buttons to compare; open the image for full resolution.

To check the renderer changes, I needed the agents to reach more of the game. A title screen that looked right wasn't enough when every new room could reveal a rendering problem we hadn't seen. To feel confident in the changes, I wanted coverage across a whole playthrough, and eventually across other games. Building up a library of useful savestates takes time, and someone still has to inspect what renders. I wanted agents to help with both parts.

When I play a game, I want to enjoy it. I don't want every room to become an assignment to capture debug data. If the agents could reach a known location and inspect it after each change, I wouldn't have to keep making those trips myself. That was why I kept trying to get them to play.

Making the project workable

The codebase was dense, the relevant tests were missing, and the agents had trouble finding their way through it. I started adding N64 documentation and asking them to build tests, separate responsibilities, and refactor while preserving existing behavior.

GPT-5.3-Codex did useful work here, and parts of those refactors and tests survived into the version I use today. Getting the replacement textures to render correctly was still a struggle.

From March through May, the renderer work went through two serious attempts. The plans sounded plausible, and parts of the feature would work, but then another change would break something else or the agent would spend days chasing the wrong difference between two images.

In the first attempt, we compared our output with GLideN64, where the texture packs already worked. The renderers didn't draw everything the same way, though, and the agents confused some of those differences with texture problems. An agent trying to match the images could work on the shape or placement of something instead of fixing which texture was being loaded. I kept directing it back toward the texture pipeline while watching it pursue the wrong target.

In the next attempt, we converted texture packs ahead of time into our own PHRB format and served them through a common runtime. We kept that approach, but the tests could still report a texture hit while the picture was wrong. Finding a replacement didn't tell us whether it made it through the rest of the pipeline and appeared correctly on screen. It might look wrong or fail to show up at all. We needed to inspect the final image.

Mt. Rugged: a fix could become a regression: March attempt

The damage number has a recognizable star around it. This part already worked in the first attempt.

Recreated from the same saved battle at 1440×1080. March uses the legacy texture pack; May and the later build use the same converted pack. The March comparison therefore includes a pack-format and content difference. Use the buttons to compare; open the image for full resolution.

I spent a lot of time with the emulator on screen, watching the agents work. Getting comparable screenshots was itself a struggle. They could load the wrong state, misread a visual difference, or fix one artifact while introducing another. Asking them to play farther into the game to find more evidence usually got us stuck on gameplay again.

By the time I put the renderer work on hold, I knew the pattern. I could keep the agents busy, but I wasn't getting a renderer I wanted to play with.

Project timeline · Feb – Jul 2026 688 commits across five repos · 9 model releases · 8 key events
The Paper Mario project against the model release calendar, February – July 2026 Timeline from Feb 1 to Jul 5, 2026, on a piecewise scale: February through May compressed, June expanded about 4 times. Lanes top to bottom: 5 project eras (bront era, Attempt A, Attempt B, The Fable build, The playthrough); 8 key events; daily commits on a square-root scale peaking at 74 on Mar 5; and 9 model releases, OpenAI above the line, Anthropic below. A full-height band marks “Fable 5 suspended · export-control directive” from Jun 12 to Jul 1; the build's last commits and most of the playthrough sit inside it. Fable 5 suspended · export-control directive · Jun 12 – Jul 1 FABLE 5 SUSPENDED EXPORT-CONTROL DIRECTIVE · JUN 12 – JUL 1 The one-Friday prequel · Feb 27 · 16 commits: 14 to agent-tools + 2 to papermario-dx. The first attempt at agent play. The one-Friday prequel Attempt A ends · Mar 14 · Renderer work later discarded; the refactors and tests survive. Attempt A ends Build starts 04:34 UTC · Jun 10 · Fable 5, one day after its launch. ~20 active hours over 4 days. Build starts 04:34 UTC Last build commits · Jun 13 · 00:15 UTC · hours into the Fable suspension. Last build commits rsync to metapod · Jun 14 · 21.6 GB, agent-to-agent handoff. Codex takes over. rsync to metapod Goomba King falls · Jun 17 · 20:25 UTC, after a near game-over at 2 HP. Goomba King falls “END OF CHAPTER!” · Jun 21 · 04:38 UTC · Chapter 1 complete in hi-res. “END OF CHAPTER!” Chapter 2 title card · Jun 24 · 04:45 UTC · the goal frame. Last gameplay in the corpus. Chapter 2 title card

February 2026

  • FEB 5 GPT-5.3-Codex OpenAI release
  • FEB 5 Opus 4.6 Anthropic release
  • FEB 22 bront era GPT-5.3-Codex · Feb 22 – Feb 28
  • FEB 27 The one-Friday prequel 16 commits: 14 to agent-tools + 2 to papermario-dx. The first attempt at agent play.

March 2026

  • MAR 4 Attempt A bront · Mar 4 – Mar 15
  • MAR 5 Peak output: 74 commits in a day
  • MAR 5 GPT-5.4 OpenAI release
  • MAR 14 Attempt A ends Renderer work later discarded; the refactors and tests survive.
  • MAR 21 Attempt B bront · Mar 21 – May 2

April 2026

  • APR 16 Codex computer use OpenAI release
  • APR 16 Opus 4.7 Anthropic release
  • APR 23 GPT-5.5 OpenAI release

May 2026

  • MAY 28 Opus 4.8 Anthropic release

June 2026

  • JUN 9 Fable 5 Anthropic release
  • JUN 10 The Fable build mander · claude-fable-5 · Jun 10 – Jun 14
  • JUN 10 Build starts 04:34 UTC Fable 5, one day after its launch. ~20 active hours over 4 days.
  • JUN 12 Fable 5 suspended export-control directive · through Jul 1
  • JUN 13 Last build commits 00:15 UTC · hours into the Fable suspension.
  • JUN 14 The playthrough metapod · GPT-5.5 · Jun 14 – Jun 28
  • JUN 14 rsync to metapod 21.6 GB, agent-to-agent handoff. Codex takes over.
  • JUN 17 Goomba King falls 20:25 UTC, after a near game-over at 2 HP.
  • JUN 21 “END OF CHAPTER!” 04:38 UTC · Chapter 1 complete in hi-res.
  • JUN 24 Chapter 2 title card 04:45 UTC · the goal frame. Last gameplay in the corpus.

July 2026

  • JUL 1 Fable 5 restored Anthropic release

Commits ran daily through each era, peaking at 74/day (Mar 5); 688 total.

scroll timeline →

When Fable arrived

I remember following the rumors before Fable 5 arrived, wondering whether this would finally be enough of a jump to make another attempt worthwhile. After spending so much time watching the earlier models struggle, I wanted to be ready if something came along that could get this project working.

I cleaned up the project so the next model would start with a manageable codebase, clear requirements, and a record of what had already failed.

The difference was visible within hours of trying it. Problems that had survived months of work began to resolve. Scaling worked. The hi-res textures looked like the textures they were supposed to be. After watching so many partial fixes, it felt almost like a one-shot result, even though the following days still involved testing, corrections, and my feedback.

June 10 Later build Paper Mario forest battle, broken strips through the canopy and sky versus continuous artwork in the later build · June 10 Paper Mario forest battle, broken strips through the canopy and sky versus continuous artwork in the later build · Later build
The same saved battle, with the same texture pack and scaling settings. The canopy and sky lose their broken strips, and the sprites and damage star become recognizable. These 1440×1080 recreations show the accumulated improvements, not a claim that one change fixed the whole renderer.

Fable also investigated the problems differently. When a screenshot wasn't enough to explain an artifact, it wrote probes to find out more. It separated baseline rendering problems from hi-res, scaling, and tooling problems, and used other agents to review findings and challenge diagnoses.

One useful example was a vertical seam between strips of a scrolling backdrop. I had hoped getting the hi-res textures working might also resolve the scaling artifacts. It didn't. We had to separate the two problems: the seam could appear with no texture pack loaded, when those backdrop textures were allowed to scale up. Keeping them at native resolution avoided the gap but limited their detail. The investigation traced the gap to how the renderer assigned pixel coverage at an upscaled edge. Fixing that coverage let us keep the detail without the seam.

Look closer at the separate vertical-seam fix
pre-fix core fixed Zoomed crop at the backdrop strip junction, the pre-fix core showing a one-pixel vertical seam versus the fixed build with the seam healed · pre-fix core Zoomed crop at the backdrop strip junction, the pre-fix core showing a one-pixel vertical seam versus the fixed build with the seam healed · fixed
A retained close-up of the backdrop junction before and after the edge-coverage fix, with no texture pack loaded and 4× scaling. This vertical gap was a separate issue from the title screen's horizontal breaks.

I still needed to watch the screen and push back on some of its conclusions. In one investigation, it decided that the texture pack contained gaps, but I had seen those textures render correctly in the reference renderer. Pointing that out sent it back to our code.

In another, it concluded that a pack texture was corrupt and prepared to remove it. I pushed back because I thought we might be hiding another bug, and the problem turned out to be in our renderer. The pack entry stayed.

GLideN64 · reference parallel-ish · mid-build Paper Mario sewer scene, GLideN64 reference versus the mid-build parallel-ish frame with black-box sprite corruption · GLideN64 · reference Paper Mario sewer scene, GLideN64 reference versus the mid-build parallel-ish frame with black-box sprite corruption · parallel-ish · mid-build
The same sewer scene in both renderers, June 12: sprites trapped in boxes, a dark blob covering the wall. The agent had concluded the pack was at fault and queued the entry for removal. GLideN64 is the visual reference; the captures are not an exact frame match.
parallel-ish · June 12 parallel-ish · July 2 Paper Mario sewer scene, the June 12 build with sprite-box corruption versus the July 2 build with those boxes removed · parallel-ish · June 12 Paper Mario sewer scene, the June 12 build with sprite-box corruption versus the July 2 build with those boxes removed · parallel-ish · July 2
The boxes and dark blob are gone in the July 2 capture. That was a useful fix, but it only resolved part of the scene's rendering problems. None of the 94 reviewed frames showed that box corruption; this was a check for that specific artifact, not proof that every texture, tint, or scaling issue was fixed.

We used code review throughout this work, but agents could read the code carefully and still give a confident, incorrect explanation for what was wrong on screen. We needed to test those explanations against what the renderer actually produced.

The agents reviewed frames too. Paired screenshots, independent reviewers, and deliberately challenging their conclusions became part of the process. That gave us more ways to catch mistakes, but my own observation could still overturn a diagnosis that looked settled.

The refactors, tests, documentation, and texture format from the preceding months all contributed, but I had reached the limit of what I could get the earlier models to do. I know how to program, and I know games and the N64, but I didn't know this area of renderer development. I was still learning how to work with agents, too.

Someone with more expertise might have been able to steer those models through it. I couldn't. With Fable, I could finally get the textures and scaling working well enough to use, even without knowing how to solve those renderer problems myself.

A computer for the playthrough

Once the renderer looked promising, I wanted evidence from farther into the game. I was hoping Codex computer use would help GPT-5.5 get there, and at the time it was only available on macOS. I bought a dedicated Mac mini so I could try it and give the agent a machine of its own.

The move between machines produced one of my favorite small scenes in the project. I pointed the agents at each other, and the agent on the Linux machine copied the project and wrote a briefing for the one on the Mac. There were platform problems to work through, but the receiving agent kept investigating and fixing them until it got the game running.

With a screenshot tool and a virtual controller, it could already see the game and send inputs. Trying Codex computer use didn't help as much as I had hoped, because it still struggled to tell what its inputs had done.

The dedicated machine did let me leave the task running, come back to see how it was doing, and steer it over time without needing that computer for something else. That gave us room for an extremely long playthrough, with the controls and my guidance developing as we went.

Giving the agent control of time

I had been telling the agents about tool-assisted speedruns, or TAS: exact inputs, counted frames, and savestates. Watching the agent overshoot or lose track of an action made me keep asking it to slow down. Advance a few frames, take a screenshot, and check what happened.

What helped was turning that advice into code it could use. I had been thinking about Claude Code's Dynamic Workflows, where Claude writes an orchestration script that can coordinate many agents in parallel or through successive stages, with conditions determining what happens next. If Claude had been trained to work this way, I wondered whether I could give it a similar structure for gameplay. The idea was to put the sequence in code: send an input, advance a known number of frames, inspect the result, and decide what to do next.

We developed a TypeScript TAS runtime with frame-counted inputs, neutral frames, save and load points, screenshots, and monitoring. That let the game wait while the agent thought, and a sequence could include checks and recovery points instead of being one long burst of button presses.

the tas runtime · a dynamic workflow in gameplay costume metapod · excerpts verbatim from the transcripts

01 where it came from · jun 17

auro

“Look into Claude dynamic workflows, tell me what you think”

the codex agent

“What you want is not exactly ‘Claude dynamic workflows for TAS’ as shipped. It is a dynamic workflow-shaped TAS runtime: agents write bounded scripts, but the script talks to a deterministic emulator API, not raw UI, raw shell, or free-form agent turns.”

same thread

“The big rule: only one driver owns emulator state. Dynamic workflows can still use subagents, but they should do read-only work: route theory, source lookup in papermario, reviewing failed traces, proposing next search spaces.”

OpenAI's agent read Anthropic's workflow docs and adopted the shape. The same session scaffolded the TypeScript runtime that evening; 57 review subagents in 25 waves hardened it overnight; the first live run drove the game at 01:40 on June 19.

02 the shape of one experiment · branch and reload

save · slot 8 · protected start koopa-village-segment-start hold right · 30f hold down · 30f hold up · 30f hold down-right · 45f shot · right_30f shot · down_30f shot · up_30f shot · downRight_45f reload ×4

A real script from June 19, four movement hypotheses from one protected savestate, a screenshot per branch, and a reload after every attempt. The script carries its own epistemics in a metadata field: "trust":"candidate only; every branch reloads protected start".

tas_route_ops · run-id paper-mario-koopa-fortress-calibrate-20260619 · mode scouting

03 the api a script may touch

inputs press the controller hold press neutral step waitFrames
checkpoints places you can return to save load stateRing
observability look at the screen, read the memory status shot note observe readMemory
search try several futures sweep branch

Scripts are TypeScript with normal control flow, but every emulator touch goes through this narrow object. Buttons are semantic, pm64.button.hammer() and pm64.stick.left(), and the script model bans raw button masks from permanent routes outright.

04 one battle turn, as frames · the hammer

A · 6f neutral · 30f hold left · 42f windup release settle · 30f A stick ← 0 6 36 78 81 111 frames

The A-press cadence, 6 frames down and 30 neutral, is verbatim from the adapter log; the windup, release, and settle counts are the hammer macro's declared defaults. The release is not timed by eye. In the agent's words: “hold left, watch stateTimer and actionProgress, then release”.

05 what a turn gets back · the evidence bundle

artifacts/tas-runs/paper-mario-ch1-trd01-kooper-hold-left-3f-slice-20260619-a/
├ manifest.json          mode, host, git commit, script sha256, rom hash
├ summary.json · summary.md   the report the next turn reads first
├ script/input.ts        the exact script that ran, copied into the bundle
├ traces/                every command and observation, in order
│  ├ commands.jsonl · observations.jsonl · timeline.tsv
│  └ notes.jsonl:        the route itself, one op per line
│     {"label":"route-segment:op","data":{... "op":{"kind":"hold","input":"left","frames":3}}}
│     {"label":"route-segment:op","data":{... "op":{"kind":"shot","label":"hold-left-t018","settleAfterLoadFrames":0}}}
├ captures/              one screenshot per shot(), with metadata sidecars
└ states/
   ├ scratch/            overwriteable checkpoints
   └ promoted/           checkpoints that earned durability

Every run leaves this folder behind or it didn't happen. This one wears the real run id of the June 19 hold-left timing slice, whose console signed off mid-swing, act=SMASH:11/23. The folder reads top to bottom: what ran, what happened, what it saw, what survived. The design goal from the origin thread, delivered: “one agent turn can launch a meaningful mini-playthrough experiment, then get back a compact report with screenshots, state hashes, macro trace, and failure labels”.

The controller replay shows the inputs from the script as button presses and stick movements, making it easier to follow what the code is asking the game to do.

Flat illustration of an N64 controller with the stick and A button lifted out f 000
The hammer turn replayed at the run's real 30 frames per second, the sequence written out under the pad. The stick cap and A button are cutouts from the art, so the parts physically move, and the counter ticks the same frame numbers as the piano roll. The timing is read straight from the adapter log; any logged input stream renders the same way.

The agent also had the decompiled game source and memory reads, which let it research a room's logic and inspect the state that controlled it. That was useful when a screenshot showed where Mario was without explaining why a door wouldn't open.

At that point, I felt we had given it every useful advantage we could think of. It could inspect the game's logic and state, control exactly when inputs happened, and go back to try again. I wanted to see how far it could get with all of that available.

Even with better controls, I still had to coach it through decisions like what to do after winning a difficult battle. I wanted it to go back, heal, and save so it could preserve that progress. Given a goal like finishing Chapter 1, it would keep throwing itself forward when a small retreat would have left it in a much better position.

My role became watching, describing what I saw, and helping it break the task into pieces it could manage. As the controls improved, it could work for longer stretches between those conversations.

The nine-day run

The playthrough reached from the game's opening to the Chapter 2 title screen over nine calendar days, including breaks and work on the tools. That distinction matters when reading the progress chart: a long flat stretch means there was no new recorded milestone. It doesn't tell us whether the agent was struggling or the run had paused.

June playthrough · flat = no new recorded progress jun 15 – 24, 2026 · utc
hammer jr. troopa #1 goomba king koopa bros end of chapter jr. troopa #2
Playthrough progress: 22 story beats, June 15 – 24, 2026 Step chart of cumulative story beats over wall-clock time, climbing from 1 at Jun 15 · 16:10 to 22 at Jun 24 · 04:45 (UTC). Steep sections mark momentum; long flat shelves show no new recorded progress and can include stalls or breaks. Shaded bands mark the fortress routing interval on June 19–20 and Break between play sessions (gray diagonal hatch = break between play sessions). Dots mark each beat: green means played straight, hollow means assist or bypass, orange marks the route recovery. A thin strip just above the x-axis shows Codex log-event windows, including research and tooling, one solid bar per merged timestamp window (11 windows in view). Jun 19 · 18:52 → Jun 20 · 18:43, Key 1 to the trap · multiple rooms, battles, breaks and checkpoint recovery Fortress routing Break between play sessions · Jun 21 · 04:43 → Jun 23 · 15:36 Break between play sessions Codex log activity · Jun 15 · 12:20 → Jun 15 · 12:30 Codex log activity · Jun 15 · 13:10 → Jun 16 · 00:20 Codex log activity · Jun 16 · 01:00 → Jun 16 · 09:20 Codex log activity · Jun 16 · 14:10 → Jun 18 · 22:40 Codex log activity · Jun 19 · 01:10 → Jun 19 · 05:40 Codex log activity · Jun 19 · 08:50 → Jun 19 · 14:30 Codex log activity · Jun 19 · 16:40 → Jun 20 · 07:50 Codex log activity · Jun 20 · 13:20 → Jun 21 · 04:50 Codex log activity · Jun 22 · 14:20 → Jun 22 · 14:30 Codex log activity · Jun 23 · 15:30 → Jun 23 · 19:30 Codex log activity · Jun 23 · 20:00 → Jun 24 · 04:50 Jun 15 · 16:10 · Play starts Jun 15 · 17:32 · Bowser scripted loss Jun 15 · 18:15 · Goomba Village Jun 15 · 23:30 · Hammer acquired Jun 16 · 00:08 · Jr. Troopa #1 beaten Jun 16 · 08:23 · Goombario joins Jun 17 · 17:08 · Red & Blue Goomba Bros Jun 17 · 20:25 · Goomba King falls Jun 17 · 23:02 · Toad Town Jun 18 · 04:12 · Shooting Star Summit · Eldstar Jun 18 · 14:11 · Chapter 1 title card Jun 18 · 21:48 · Koopa Village Jun 19 · 05:33 · Kooper joins Jun 19 · 14:03 · Fortress entered (trd_00) Jun 19 · 18:52 · Key 1 Jun 20 · 18:43 · Trap block reached Jun 20 · 19:28 · Bombette joins ~Jun 21 · 03:30 · Bill Blaster bypassed Jun 21 · 04:29 · Koopa Bros / Fake Bowser Jun 21 · 04:38 · “END OF CHAPTER!” ~Jun 24 · 02:36 · Jr. Troopa #2 beaten Jun 24 · 04:45 · Chapter 2 title card
beat played straight assist · bypass route recovery Codex log activity play-session break

The strip under the chart shows when Codex produced log events, including research and work on the tools. It helps show the breaks in the run, but it isn't a measure of continuous gameplay or model thinking time.

The fortress became a long routing struggle. It reached the jail from the wrong side, worked through other rooms and battles, and eventually used research in the decompiled source to find the trap block that led into the cell. Getting there also meant recovering from an earlier checkpoint.

Getting through the second Jr. Troopa encounter took more than two hours, including work on button timing. The recorded win used ordinary battle inputs. Other parts of the run needed help: the Koopa Bros boss used a disclosed memory-write assist after timed action commands proved unreliable, and the Bill Blaster fight was abandoned and bypassed from a save.

When I say it reached Chapter 2, that includes my coaching, the tools we developed during the run, and the assisted obstacles. With that help, it was reaching places in the game that I had previously been unable to get it to reach.

At a smaller scale, the action timeline follows a half-hour stretch where a stall led to research into a hidden Koopa ambush. The game's source suggested what was happening, and a memory read helped confirm it.

nok_14 · the koopa ambush problem · jun 19 30 minutes · every event real
ambush found bypass scouted no bypass · fight hammer · SMASH
12:10 12:15 12:20 12:25 12:30 12:35 12:40
controller input ×15
scripted sweep ×6
savestate · save ×2
savestate · load ×6
screenshot ×13
reads the frame ×13
RAM probe ×22
decomp lookup ×6
subagent spawned ×2
narrates intent ×57
Every adapter call, probe, screenshot, and narration beat in the half hour where the agent found a hidden Koopa ambush in the game's own source, confirmed it with RAM reads, tried to route around it, and armed itself for the fight instead. Mined from the session transcript; each mark's tooltip carries the verbatim event, also available in the event list below.
Read the 142 events
  1. · narrates intent

    Slot 5 is now settled in `nok_14` at entry 0. Next map is `nok_15`, and `nok_15` has the heart block, so I’m r

  2. · narrates intent

    Before moving blindly through `nok_14`, I’m reading its bridge setup and `nok_15` entry/heart block positions.

  3. · reads the frame

    view screenshot

  4. · narrates intent

    I’ll keep pushing from the settled `nok_14` entry. First I’m going to re-anchor the live emulator state and in

  5. · RAM probe

    RAM probe

  6. · decomp lookup

    decomp lookup

  7. · narrates intent

    The source confirms `nok_14` has a blue switch at `(100, 0, -185)` that controls the bridge, so this is a map-

  8. · narrates intent

    I’m also spinning up two narrow explorers in the background: one for the `nok_14` switch/bridge interaction de

  9. · subagent spawned

    spawn subagent

  10. · subagent spawned

    spawn subagent

  11. · narrates intent

    Computer Use is still timing out on RetroArch, so I’m treating it as a secondary signal for now. The durable l

  12. · reads the frame

    view screenshot

  13. · narrates intent

    The live screenshot shows Mario and Kooper on the west-side bridge/ledge with the coin cluster ahead. I’m keep

  14. · scripted sweep

    branch sweep ×2

  15. · narrates intent

    Short probes are behaving cleanly: cardinal east advances along the upper ledge, while north-east/south-east m

  16. · narrates intent

    East is the useful first leg from `nok_14_ENTRY_0`; after 60 frames it reaches about `x=-719` at the same y-le

  17. · scripted sweep

    branch sweep ×2

  18. · narrates intent

    The `nok_15` route scout came back with the next hard facts: heart block at `(-50, 60, -825)` is jump-activate

  19. · narrates intent

    Straight east from the entry reaches the coin cluster around `x=-655` and then stalls/falls in longer holds, s

  20. · decomp lookup

    decomp lookup

  21. · narrates intent

    The stall at `(-655, 75, -35)` is explained by source: that exact area triggers a hidden Koopa Troopa ambush.

  22. · savestate · load

    load slot 5

  23. · controller input

    0x0 120f

  24. · screenshot

    screenshot

  25. · RAM probe

    RAM probe

  26. · narrates intent

    At the ambush trigger, memory shows `encounterState=3` and `inputDisabledCount=1`; that’s not a wall, it’s the

  27. · reads the frame

    view screenshot

  28. · narrates intent

    That screenshot confirms the hidden Koopa jump-out at the coin cluster. I’m going to try avoiding the trigger

  29. · scripted sweep

    branch sweep ×5

  30. · narrates intent

    The switch scout confirms three activation options: stomp, hammer, or Kooper shell, with Kooper shell explicit

  31. · narrates intent

    The avoid route is promising: `SE90 + E180` drops to lower ground around `(-318, 0, 36)` without starting the

  32. · savestate · load

    load slot 5

  33. · savestate · save

    save slot 6

  34. · controller input

    0x0 90f · 0x0 180f · 0x0 30f

  35. · screenshot

    screenshot

  36. · RAM probe

    RAM probe

  37. · narrates intent

    Slot 6 is now a lower-ground branch point at `(-318, 0, 36)`, clean control restored. I’ll keep slot 5 as `nok

  38. · reads the frame

    view screenshot

  39. · narrates intent

    Visually, the lower branch lands directly beside the Spiked Goomba. That is a good controlled test case: I’ll

  40. · RAM probe

    RAM probe

  41. · decomp lookup

    decomp lookup

  42. · narrates intent

    I’m checking the existing battle probe before entering combat so I can track HP/FP and enemy HP instead of rel

  43. · RAM probe

    RAM probe

  44. · narrates intent

    The current route state has `7/15 HP` and `2/5 FP`, so I’m avoiding optional fights where reasonable. The near

  45. · scripted sweep

    branch sweep ×6

  46. · narrates intent

    The lower branch is inside the Spiked Goomba’s practical patrol/detection zone: even foreground detours are st

  47. · narrates intent

    No clean bypass turned up, so I’m switching to a controlled combat solution. Because it’s a Spiked Goomba, jum

  48. · savestate · load

    load slot 6

  49. · controller input

    0x2 18f · 0x0 90f

  50. · screenshot

    screenshot

  51. · RAM probe

    RAM probe

  52. · narrates intent

    The expected `0x2` hammer press did not start the field hammer action from this state, so I’m verifying the Re

  53. · reads the frame

    view screenshot

  54. · narrates intent

    One screenshot came back black even though memory says we’re still in field control. I’m not trusting that ima

  55. · screenshot

    screenshot

  56. · RAM probe

    RAM probe

  57. · reads the frame

    view screenshot

  58. · narrates intent

    The black screenshots look like a stale video buffer after loading a state while paused, not a memory/game fai

  59. · controller input

    0x0 3f

  60. · screenshot

    screenshot

  61. · RAM probe

    RAM probe

  62. · narrates intent

    Three neutral frames did not restore the adapter screenshot, so the live render path needs more attention. I’l

  63. · reads the frame

    view screenshot

  64. · narrates intent

    I’m going to take an OS-level screenshot as a cross-check. If the RetroArch screenshot path is black but the w

  65. · reads the frame

    view screenshot

  66. · narrates intent

    The OS-level screenshot found the actual blocker: macOS is showing a RetroArch “access files in Documents fold

  67. · narrates intent

    Computer Use is still timing out on RetroArch even with the permission dialog visible, so I’m going through ma

  68. · narrates intent

    The accessibility click command is waiting longer than expected, which usually means the dialog is not exposed

  69. · narrates intent

    The dialog is not exposed as a normal RetroArch accessibility window. I’m checking whether a coordinate-click

  70. · narrates intent

    No coordinate helper is installed and PyObjC is not available, so I’m using the Computer Use coordinate click

  71. · narrates intent

    Computer Use refuses coordinate clicks because its RetroArch state call timed out. I’m going to identify the p

  72. · narrates intent

    There are two RetroArch installs registered, and Computer Use may have been targeting the wrong bundle. I’m re

  73. · narrates intent

    Targeting the exact MVK141 app works for Computer Use now, but the RetroArch content area is still black. The

  74. · narrates intent

    The attempted permission click is no longer relevant; the window is just black now. I’m going to load the earl

  75. · savestate · load

    load slot 5

  76. · controller input

    0x0 30f

  77. · screenshot

    screenshot

  78. · RAM probe

    RAM probe

  79. · narrates intent

    Loading the earlier protected slot did not restore video, so this is session-wide after the macOS permission i

  80. · reads the frame

    view screenshot

  81. · narrates intent

    The OS screenshot shows the dialog is still up and the game render is fine behind it. The Computer Use coordin

  82. · narrates intent

    Permission is cleared and the live RetroArch view is usable again. I’m back to the slot 6 combat branch; the e

  83. · savestate · load

    load slot 6

  84. · controller input

    0x0 3f

  85. · screenshot

    screenshot

  86. · RAM probe

    RAM probe

  87. · narrates intent

    Slot 6 reloaded cleanly and the control flags are normal again. I’m going to use hammer on the Spiked Goomba f

  88. · reads the frame

    view screenshot

  89. · controller input

    0x2 6f · 0x0 45f

  90. · screenshot

    screenshot

  91. · RAM probe

    RAM probe

  92. · narrates intent

    Hammer input is confirmed: `mask 0x2` entered field hammer action (`action=18`). It just whiffed from this dis

  93. · reads the frame

    view screenshot

  94. · narrates intent

    The hammer did connect visually; the battle state just had not fully transitioned at the first probe. I’m step

  95. · controller input

    0x0 60f

  96. · screenshot

    screenshot

  97. · RAM probe

    RAM probe

  98. · narrates intent

    We’re in battle. The first-strike transition landed us in a three-enemy fight with three 2-HP enemies and Mari

  99. · reads the frame

    view screenshot

  100. · narrates intent

    At Mario’s battle menu the cursor is on Jump, which is bad for spiked enemies. I’m saving this menu as slot 7

  101. · savestate · save

    save slot 7

  102. · RAM probe

    RAM probe

  103. · narrates intent

    Slot 7 now marks the battle menu before choosing an attack. I’m going to test menu movement from that slot and

  104. · scripted sweep

    branch sweep ×2

  105. · narrates intent

    Four-frame menu nudges did not change the probe fields. I’m increasing the held duration and taking screenshot

  106. · savestate · load

    load slot 7

  107. · controller input

    0x0 30f · 0x0 10f

  108. · screenshot

    screenshot

  109. · RAM probe

    RAM probe

  110. · reads the frame

    view screenshot

  111. · narrates intent

    Long analog-down successfully selects Hammer. I’m confirming Hammer now; if target selection opens, I’ll keep

  112. · controller input

    0x1 6f · 0x0 30f

  113. · screenshot

    screenshot

  114. · RAM probe

    RAM probe

  115. · narrates intent

    Hammer confirm opened target selection, with the default target still at full 2 HP. I’m accepting the default

  116. · controller input

    0x1 6f · 0x0 20f

  117. · screenshot

    screenshot

  118. · RAM probe

    RAM probe

  119. · narrates intent

    Mario is in the Hammer action command (`SMASH`). I’m using the known hammer pattern: hold left during the wind

  120. · decomp lookup

    decomp lookup

  121. · narrates intent

    The source confirms Hammer needs stick-left held before the active phase, then neutral release in the input wi

  122. · RAM probe

    RAM probe

  123. · decomp lookup

    decomp lookup

  124. · decomp lookup

    decomp lookup

  125. · narrates intent

    `actionCommandMode=1` is learned mode, so the timing path is active. I’m holding left now and sampling the act

  126. · RAM probe

    RAM probe

  127. · narrates intent

    The Hammer command duration is 47 frames with standard difficulty. I’m holding left through the appear/start f

  128. · controller input

    0x0 5f

  129. · RAM probe

    RAM probe

  130. · narrates intent

    The command just entered active state at `timer=1` after the menu animation. I’m continuing the left hold in 5

  131. · controller input

    0x0 5f

  132. · RAM probe

    RAM probe

  133. · narrates intent

    Timer is advancing at roughly half the adapter frame count in this scene, so I’m staying in memory-guided chun

  134. · controller input

    0x0 5f

  135. · RAM probe

    RAM probe

  136. · narrates intent

    Hammer is at `timer=38`, exactly the computed ready point for difficulty 3 (`47 - 8 - 1`). I’m releasing to ne

  137. · controller input

    0x0 3f

  138. · screenshot

    screenshot

  139. · RAM probe

    RAM probe

  140. · narrates intent

    The release was one probe too early: the compact probe still showed `prog=2` at `timer=38`, and source only ac

  141. · scripted sweep

    branch sweep ×1

  142. · narrates intent

    The retry is in progress. The action command stayed in `APPEAR` for several chunks, then entered `SMASH:11`; t

The June playthrough splits, with assistance flags

Playthrough splits · Paper Mario, Prologue → Chapter 2

All timestamps UTC. Milestones and the main break are reconstructed from the session's retained analysis. Splits show elapsed time between recorded beats, excluding the labeled break where marked. They are not measurements of active gameplay.

Prologue
Jun 15 · 16:10
Play starts
“Yup lets start playing!”
·
Jun 15 · 17:32
Bowser scripted loss
1h22m
Jun 15 · 18:15
Goomba Village
43m
Jun 15 · 23:30
Hammer acquired
5h15m
Jun 16 · 00:08
Jr. Troopa #1 beaten
38m
played straight
Jun 16 · 08:23
Goombario joins
8h15m
Jun 17 · 17:08
Red & Blue Goomba Bros
32h45m
Jun 17 · 20:25
Goomba King falls
Near game-over at 2 HP before the fight; healed by backtracking on the human's RPG advice.
3h17m
played straight
Jun 17 · 23:02
Toad Town
2h37m
Chapter 1
Jun 18 · 04:12
Shooting Star Summit · Eldstar
A 3-hour climb struggle.
5h10m
Jun 18 · 14:11
Chapter 1 title card
9h59m
Jun 18 · 21:48
Koopa Village
7h37m
Jun 19 · 05:33
Kooper joins
Fuzzy chase; partner verified via RAM (partner2_enabled=1).
7h45m
Jun 19 · 14:03
Fortress entered (trd_00)
8h30m
Jun 19 · 18:52
Key 1
4h49m
Jun 20 · 18:43
Trap block reached
Fortress routing involved multiple rooms, battles, breaks and a checkpoint recovery before the trap led into the jail cell. Elapsed time does not measure continuous work in one room.
23h51m
route recovery
Jun 20 · 19:28
Bombette joins
45m
~Jun 21 · 03:30
Bill Blaster bypassed
Fight abandoned after an hour; boss door taken from a pre-fight save. The researched flag assist was NOT used.
8h02m
bypassed
Jun 21 · 04:29
Koopa Bros / Fake Bowser
Cleared with a disclosed source-backed battle-state assist (gBattleState=26) after action-command unreliability.
59m
disclosed assist
Jun 21 · 04:38
“END OF CHAPTER!”
22:38 local, capture 260620-223807.
9m
· Break between play sessions ·
The Final Push
~Jun 24 · 02:36
Jr. Troopa #2 beaten
The retained transcript analysis records 2h17m from the ambush trigger to zero HP, including dialogue and work on input timing. Victory used ordinary battle inputs.
11h05m*
played straight
Jun 24 · 04:45
Chapter 2 title card
“Reached the goal. We are on the Chapter 2 title card in hi-res mode.”
2h09m
Total 8d 12h 35m wall clock, 58.9h between play sessions · * split excludes that break; remaining time includes research, tooling and other pauses

As I watched the playthrough, I was seeing very few graphical bugs, and I liked what was on screen. Earlier versions had been unusable for me, even when it was exciting that they rendered anything at all. Now, with some issues still there, this looked like the way I wanted to play Paper Mario.

We still needed broader coverage, but the run gave me much more confidence in the renderer, along with more locations to inspect and a set of controls we could use again.

From a playthrough to a benchmark

When I started writing about the project, I wanted to know how other models would handle the same task. The tools developed during GPT-5.5's run became the basis for all the subsequent evals and marathons.

Paper Mario Bench began with a smaller, fixed-budget route through the opening. That made repeated comparisons more affordable and put a stopping point on runs that could otherwise spend hours repeating unsuccessful actions. The site contains the results, the scoring rules, and the behavior analysis.

Running those comparisons also meant expanding the hardware beyond the dedicated Mac. I added more RAM and an Intel GPU to my Proxmox server so I could run more virtual machines with graphics support for the emulator.

A route that was a serious obstacle during development is now something many models can complete. In September, Astra finished all 15 opening attempts and Fable 5.1 finished 12 of 15. That gets them to the first Bowser battle, with Chapter 1 still ahead.

For models that now finish that route consistently, the longer marathons are more interesting. Both September marathons used medium effort and a six-hour budget. Fable 5.1 found the hammer, defeated the first Jr. Troopa, and left the playground. It kept working on combat and recovery after that, but recorded no later story milestone. Astra reached Koopa Bros. Fortress and lowered its first staircase. Neither completed Chapter 1, but the difference in how far they got gives us more to investigate than finishing the opening alone.

Fable 5.1 wasn't the strongest Claude marathon result. An earlier six-hour Opus 5 run at medium effort reached Toad Town, farther than Fable 5.1 managed here. Astra went farther still, reaching Koopa Bros. Fortress. These are individual runs under different harness versions, but they show why I want to test what newer models actually do rather than assume each release will improve on the last.

GPT-5.5's original run still reached farther because it had much more time, along with my coaching and the disclosed assists. Looking at Astra's results, I thought it had been on track to pass that endpoint if the run had continued, though that remains an impression rather than a result. Cost is why I keep the marathon budget to six hours. The later models also had the tools available from the start, while GPT-5.5 helped build them during its run.

What I found encouraging in the results was how far Astra had progressed with so little intervention. After all that time explaining how to get through file select, I was now considering how much more of a run like this I could afford.

A low token price doesn't make an attempt cheap if the model keeps spending without getting through the task. On difficult work, I care about whether it can finish as well as what it costs to try. Long runs also make cache-read pricing more consequential, so I want to compare progress with the cost of each attempt.

For the two September marathons, the recorded completed-token usage gives API-equivalent estimates of about $193 for Astra and $68.05 for Fable 5.1. Astra’s estimate prices all non-cached input as cache writes because Codex did not reliably report the split. Both estimates exclude unreported usage and are not subscription bills. The gap caught my attention, but Astra also got much farther, so this isn't a comparison of the price of doing the same work.

What I still want to build

parallel-ish is open source. I want to keep testing it, clean up the benchmark and its tools for an open-source release, and let the experiments evolve as we find more useful things to measure. How much I can run will depend on the cost and the work involved.

The Paper Mario Bench introduction goes into the directions I'm considering for the benchmark: limiting the tools and guidance, changing the challenge, and deciding what makes a fair budget for comparing models. Those questions will matter as more models finish the opening consistently.

I still want to return to the 60 FPS idea. More immediately, I want agents to reach a scene, check a change, and repeat that check without needing me to guide the whole trip. After reviewing Astra's results, I feel much closer to being able to build that loop.

I'm also exploring whether agents could help translate saves between the Super Nintendo and DS versions of Chrono Trigger. The differences between the games make it more complicated than copying a file, but an agent could help investigate them by playing through scenarios, inspecting memory and saves, and comparing what happens in each version. It would still take time, testing, and investment, but I can see a way to approach it now that doesn't depend on me manually playing through every comparison.

When I next sit down to play, I want to see the improvements and enjoy the game. The agents can help make sure it works before I get there.

~/agents-paper-mario · last sync 15 sep 2026
ESC