I Analyzed 28k+ Randomized ALttP ROMs So You Don't Have To

pawptart1 pts0 comments

I Analyzed 28k+ Randomized ALttP ROMs So You Don't Have To

Software engineer professionally interested in cycling, hiking, baseball, and video game development on the side. Most of my projects attempt to integrate one or more of these.

site

github

email

linkedin

rss

I Analyzed 28k+ Randomized ALttP ROMs So You Don't Have To

/> ty porter

/> home

10 July 2026

In my previous post Reverse Engineering A Link to the Past Randomizer I discussed developing Mudora, a Go tool to analyze randomized A Link to the Past ROMs even when they’re encrypted. This post is a follow up to that work, where I wanted to use my new tool to analyze a corpus of randomized games to see if there were any latent features that could speed up optimal play in ALttPR.

While item placements are randomized in ALttPR, they still have to obey heuristics that allow for the game to be completable. The question I hope to answer using Mudora is: “Do those heuristics bias certain items to be placed in specific locations, and by checking those locations first, can we speed up the average completion time of an ALttPR game?”

I may have gone a little overboard…

Generating the ROMs

The good news is, getting randomized ROMs is pretty easy. You can, of course, do this via the website (https://alttpr.com) for one-off ROMs, but I needed a lot of data. Luckily the randomizer is open-source, so after downloading it and installing PHP and some dependencies, I could generate games. I used the default settings:

From there it’s a simple loop over the CLI to generate a ton of ROMs. I kicked off 5 threads running this loop, but it filled up 50GB of my hard drive with ROMs, so I decided to stop early. I ended up with 28,193 randomized Zelda 3 ROMs, which took a handful of hours. I didn’t time it directly, something like ~4 hours spent generating ROMs sounds about right.

for i in {1..10000}; do<br>php artisan alttp:randomize alttp.sfc outputs \<br>--goal=ganon \<br>--state=open \<br>--weapons=randomized \<br>--glitches=none \<br>--crystals_ganon=7 \<br>--crystals_tower=7 \<br>--item_placement=advanced \<br>--dungeon_items=standard \<br>--accessibility=items \<br>--hints=on \<br>--item_pool=normal \<br>--item_functionality=normal<br>done

Creating the Dataset

Now the fun begins. I needed to turn this into a usable dataset. I kicked off a thread pool with 5 more workers that handled kicking out to a compiled Mudora binary subprocess which would read the item data. This got parsed into an intermediate JSON representation just for temporary checkpointing purposes, since I lost the data once during processing. Mudora can churn through ROMs pretty quickly, but this part took about 10 minutes to process.

From there, I had pandas suck in the JSON. One of my initial tries saw that Mudora failed to process some of the games (some games had all locations “UNKNOWN”), so I culled those rows. When I repeated the process it didn’t happen again, so there might be some latent bug in Mudora I need to dig into later. Either way, the data was clean.

You can find the full dataset on Kaggle: https://www.kaggle.com/datasets/typorter/a-link-to-the-past-randomizer-item-locations.

Analyzing the Data

I did all the analysis in a Jupyter notebook you can find here (which also includes the dataset creation script if you want to repeat it).

The goal of my analysis is pretty simple:

Calculate the probability of an item appearing in each location in the game.

Generate a heatmap so we can visualize any trends – this is perfect because hotspots for items that grant progression are really important and might indicate that you should go out of your way to check them if you’re looking for a specific item.

First Pass

As expected the first pass is a bit of garbage. The signal to noise ratio is incredibly low. There’s a couple of items that have 100% or at least near 100% probability, like finding a small key in the entrance to Swamp Palace or keys in Castle Tower. On the other hand it’s completely impossible to find maps, keys, compasses, crystals, or pendants in the overworld (at least in this mode).

If you look at the far right you can see some special locations called Waterfall Bottle and Pyramid Bottle – these aren’t really items, but instead faerie (fairy) fountains where you can throw an empty bottle to have them filled. They’re listed on the spoiler log on https://alttpr.com, so Mudora faithfully recreates it without them being real items. You don’t actually receive a guaranteed bottle at that location.

Overall, this gives us big vertical and horizontal blanks and completely drowns out the signal.

Heatmap after the first pass. (Click to view full size.)

Filtering Dungeon Items

Next step is to cull out dungeon items like keys, compasses, and maps, as well as dungeon rewards. While we’re at it we’ll also filter out some special locations like the dungeon rewards and the bottle fill locations, as well as locations where you can only get a key.

Heatmap after dungeon item/location filtering. (Click to view full...

roms randomized items locations mudora item

Related Articles