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.
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.
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 2026688 commits across five repos · 9 model releases · 8 key events
February 2026
FEB 5GPT-5.3-CodexOpenAI release
FEB 5Opus 4.6Anthropic release
FEB 22bront eraGPT-5.3-Codex · Feb 22 – Feb 28
FEB 27The one-Friday prequel16 commits: 14 to agent-tools + 2 to papermario-dx. The first attempt at agent play.
March 2026
MAR 4Attempt Abront · Mar 4 – Mar 15
MAR 5Peak output: 74 commits in a day
MAR 5GPT-5.4OpenAI release
MAR 14Attempt A endsRenderer work later discarded; the refactors and tests survive.
MAR 21Attempt Bbront · Mar 21 – May 2
April 2026
APR 16Codex computer useOpenAI release
APR 16Opus 4.7Anthropic release
APR 23GPT-5.5OpenAI release
May 2026
MAY 28Opus 4.8Anthropic release
June 2026
JUN 9Fable 5Anthropic release
JUN 10The Fable buildmander · claude-fable-5 · Jun 10 – Jun 14
JUN 10Build starts 04:34 UTCFable 5, one day after its launch. ~20 active hours over 4 days.
JUN 12Fable 5 suspendedexport-control directive · through Jul 1
JUN 13Last build commits00:15 UTC · hours into the Fable suspension.
JUN 14The playthroughmetapod · GPT-5.5 · Jun 14 – Jun 28
JUN 14rsync to metapod21.6 GB, agent-to-agent handoff. Codex takes over.
JUN 17Goomba King falls20: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 24Chapter 2 title card04:45 UTC · the goal frame. Last gameplay in the corpus.
July 2026
JUL 1Fable 5 restoredAnthropic release
Commits ran daily through each era, peaking at 74/day (Mar 5); 688 total.
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 10Later 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 corefixed
‹ ›
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 · referenceparallel-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 12parallel-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 costumemetapod · 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
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".
inputspress the controllerholdpressneutralstepwaitFrames
checkpointsplaces you can return tosaveloadstateRing
observabilitylook at the screen, read the memorystatusshotnoteobservereadMemory
searchtry several futuressweepbranch
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
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.
f 000
A · press 6f → wait · 30f → stick ← · hold 42f → release → settle · 30f
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 progressjun 15 – 24, 2026 · utc
hammer jr. troopa #1 goomba king koopa bros end of chapter jr. troopa #2
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 1930 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
· 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
· narrates intent
Before moving blindly through `nok_14`, I’m reading its bridge setup and `nok_15` entry/heart block positions.
· reads the frame
view screenshot
· 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
· RAM probe
RAM probe
· decomp lookup
decomp lookup
· narrates intent
The source confirms `nok_14` has a blue switch at `(100, 0, -185)` that controls the bridge, so this is a map-
· narrates intent
I’m also spinning up two narrow explorers in the background: one for the `nok_14` switch/bridge interaction de
· subagent spawned
spawn subagent
· subagent spawned
spawn subagent
· narrates intent
Computer Use is still timing out on RetroArch, so I’m treating it as a secondary signal for now. The durable l
· reads the frame
view screenshot
· narrates intent
The live screenshot shows Mario and Kooper on the west-side bridge/ledge with the coin cluster ahead. I’m keep
· scripted sweep
branch sweep ×2
· narrates intent
Short probes are behaving cleanly: cardinal east advances along the upper ledge, while north-east/south-east m
· 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
· scripted sweep
branch sweep ×2
· narrates intent
The `nok_15` route scout came back with the next hard facts: heart block at `(-50, 60, -825)` is jump-activate
· narrates intent
Straight east from the entry reaches the coin cluster around `x=-655` and then stalls/falls in longer holds, s
· decomp lookup
decomp lookup
· narrates intent
The stall at `(-655, 75, -35)` is explained by source: that exact area triggers a hidden Koopa Troopa ambush.
· savestate · load
load slot 5
· controller input
0x0 120f
· screenshot
screenshot
· RAM probe
RAM probe
· narrates intent
At the ambush trigger, memory shows `encounterState=3` and `inputDisabledCount=1`; that’s not a wall, it’s the
· reads the frame
view screenshot
· narrates intent
That screenshot confirms the hidden Koopa jump-out at the coin cluster. I’m going to try avoiding the trigger
· scripted sweep
branch sweep ×5
· narrates intent
The switch scout confirms three activation options: stomp, hammer, or Kooper shell, with Kooper shell explicit
· narrates intent
The avoid route is promising: `SE90 + E180` drops to lower ground around `(-318, 0, 36)` without starting the
· savestate · load
load slot 5
· savestate · save
save slot 6
· controller input
0x0 90f · 0x0 180f · 0x0 30f
· screenshot
screenshot
· RAM probe
RAM probe
· 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
· reads the frame
view screenshot
· narrates intent
Visually, the lower branch lands directly beside the Spiked Goomba. That is a good controlled test case: I’ll
· RAM probe
RAM probe
· decomp lookup
decomp lookup
· narrates intent
I’m checking the existing battle probe before entering combat so I can track HP/FP and enemy HP instead of rel
· RAM probe
RAM probe
· narrates intent
The current route state has `7/15 HP` and `2/5 FP`, so I’m avoiding optional fights where reasonable. The near
· scripted sweep
branch sweep ×6
· narrates intent
The lower branch is inside the Spiked Goomba’s practical patrol/detection zone: even foreground detours are st
· narrates intent
No clean bypass turned up, so I’m switching to a controlled combat solution. Because it’s a Spiked Goomba, jum
· savestate · load
load slot 6
· controller input
0x2 18f · 0x0 90f
· screenshot
screenshot
· RAM probe
RAM probe
· narrates intent
The expected `0x2` hammer press did not start the field hammer action from this state, so I’m verifying the Re
· reads the frame
view screenshot
· narrates intent
One screenshot came back black even though memory says we’re still in field control. I’m not trusting that ima
· screenshot
screenshot
· RAM probe
RAM probe
· reads the frame
view screenshot
· narrates intent
The black screenshots look like a stale video buffer after loading a state while paused, not a memory/game fai
· controller input
0x0 3f
· screenshot
screenshot
· RAM probe
RAM probe
· narrates intent
Three neutral frames did not restore the adapter screenshot, so the live render path needs more attention. I’l
· reads the frame
view screenshot
· 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
· reads the frame
view screenshot
· narrates intent
The OS-level screenshot found the actual blocker: macOS is showing a RetroArch “access files in Documents fold
· narrates intent
Computer Use is still timing out on RetroArch even with the permission dialog visible, so I’m going through ma
· narrates intent
The accessibility click command is waiting longer than expected, which usually means the dialog is not exposed
· narrates intent
The dialog is not exposed as a normal RetroArch accessibility window. I’m checking whether a coordinate-click
· narrates intent
No coordinate helper is installed and PyObjC is not available, so I’m using the Computer Use coordinate click
· narrates intent
Computer Use refuses coordinate clicks because its RetroArch state call timed out. I’m going to identify the p
· narrates intent
There are two RetroArch installs registered, and Computer Use may have been targeting the wrong bundle. I’m re
· narrates intent
Targeting the exact MVK141 app works for Computer Use now, but the RetroArch content area is still black. The
· narrates intent
The attempted permission click is no longer relevant; the window is just black now. I’m going to load the earl
· savestate · load
load slot 5
· controller input
0x0 30f
· screenshot
screenshot
· RAM probe
RAM probe
· narrates intent
Loading the earlier protected slot did not restore video, so this is session-wide after the macOS permission i
· reads the frame
view screenshot
· narrates intent
The OS screenshot shows the dialog is still up and the game render is fine behind it. The Computer Use coordin
· narrates intent
Permission is cleared and the live RetroArch view is usable again. I’m back to the slot 6 combat branch; the e
· savestate · load
load slot 6
· controller input
0x0 3f
· screenshot
screenshot
· RAM probe
RAM probe
· narrates intent
Slot 6 reloaded cleanly and the control flags are normal again. I’m going to use hammer on the Spiked Goomba f
· reads the frame
view screenshot
· controller input
0x2 6f · 0x0 45f
· screenshot
screenshot
· RAM probe
RAM probe
· narrates intent
Hammer input is confirmed: `mask 0x2` entered field hammer action (`action=18`). It just whiffed from this dis
· reads the frame
view screenshot
· narrates intent
The hammer did connect visually; the battle state just had not fully transitioned at the first probe. I’m step
· controller input
0x0 60f
· screenshot
screenshot
· RAM probe
RAM probe
· narrates intent
We’re in battle. The first-strike transition landed us in a three-enemy fight with three 2-HP enemies and Mari
· reads the frame
view screenshot
· 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
· savestate · save
save slot 7
· RAM probe
RAM probe
· narrates intent
Slot 7 now marks the battle menu before choosing an attack. I’m going to test menu movement from that slot and
· scripted sweep
branch sweep ×2
· narrates intent
Four-frame menu nudges did not change the probe fields. I’m increasing the held duration and taking screenshot
· savestate · load
load slot 7
· controller input
0x0 30f · 0x0 10f
· screenshot
screenshot
· RAM probe
RAM probe
· reads the frame
view screenshot
· narrates intent
Long analog-down successfully selects Hammer. I’m confirming Hammer now; if target selection opens, I’ll keep
· controller input
0x1 6f · 0x0 30f
· screenshot
screenshot
· RAM probe
RAM probe
· narrates intent
Hammer confirm opened target selection, with the default target still at full 2 HP. I’m accepting the default
· controller input
0x1 6f · 0x0 20f
· screenshot
screenshot
· RAM probe
RAM probe
· narrates intent
Mario is in the Hammer action command (`SMASH`). I’m using the known hammer pattern: hold left during the wind
· decomp lookup
decomp lookup
· narrates intent
The source confirms Hammer needs stick-left held before the active phase, then neutral release in the input wi
· RAM probe
RAM probe
· decomp lookup
decomp lookup
· decomp lookup
decomp lookup
· narrates intent
`actionCommandMode=1` is learned mode, so the timing path is active. I’m holding left now and sampling the act
· RAM probe
RAM probe
· narrates intent
The Hammer command duration is 47 frames with standard difficulty. I’m holding left through the appear/start f
· controller input
0x0 5f
· RAM probe
RAM probe
· narrates intent
The command just entered active state at `timer=1` after the menu animation. I’m continuing the left hold in 5
· controller input
0x0 5f
· RAM probe
RAM probe
· narrates intent
Timer is advancing at roughly half the adapter frame count in this scene, so I’m staying in memory-guided chun
· controller input
0x0 5f
· RAM probe
RAM probe
· narrates intent
Hammer is at `timer=38`, exactly the computed ready point for difficulty 3 (`47 - 8 - 1`). I’m releasing to ne
· controller input
0x0 3f
· screenshot
screenshot
· RAM probe
RAM probe
· narrates intent
The release was one probe too early: the compact probe still showed `prog=2` at `timer=38`, and source only ac
· scripted sweep
branch sweep ×1
· 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
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.