Sign in to your XDA account

Pokémon Emerald is a fantastic game, and I'm sure many are hit with a wave of nostalgia thinking about the older Pokémon games in general. These days, those older Pokémon games have an incredibly interesting modding scene, with plenty of fan-made modifications extending their lifespan decades later. However, that modding scene has also made it possible to store a file inside Pokémon Emerald. A file up to 10.8 KB in size, to be precise... and I tried it out.
As a primer, when you open a file on your computer, such as a text document, image, or even this web page, you're looking at a set of data structures that your computer knows how to interpret to represent the data that you expect. In the case of a web page, you can easily see what I mean by looking at the page source. You can see the HTML that your browser knows how to interpret and display to you, in the same way that your computer knows how to read the data inside a JPG to interpret it and display an image.
Abstracting that concept means that, really, anything can act as a file container, so long as there's a structured way that the data can be saved and then retrieved in the future. So, storing data in Pokémon Emerald is possible... and it's all thanks to mon-fs, where your data will be encoded as Pokémon. It's painful, it's slow, but it's a really neat way to explain how data is stored and how practically anything can be used to store data.

Related
I used North Korea's leaked Linux distribution, and it still has secrets a decade later
Red Star OS 3 is a weird (and old) operating system, but it has some pretty interesting tech inside.
Pokémon have a lot of data associated with them
A whole 68 bits of data per Pokémon
Look at the above images, taken from my encoding of a file into my Emerald save. The Pokémon itself, its nickname, gender, OT (Original Trainer), ribbons, ball used to catch it, and experience are all values that can be influenced by the player, and that's exactly how mon-fs works. It comes in two modes: "Full" mode and "Lite" mode.
- Lite: A file up to 3.2 KB can be stored in the game, though every Pokémon can be caught and named without any external tools.
- Full: A file up to 10.8 KB can be stored in the game, but it will require a save editor to work.
The difference between these two modes is due to the data that's easily accessible to the user. For example, there are 386 Pokémon in Emerald, which would allow for 8 bits of data. However, only 202 are obtainable, and accounting for Pokémon that can only be caught once, or obtained through eggs, drops this number further. Once all of those Pokémon are removed from the equation, and then convenience is factored in, this is brought down to four separate Pokémon, allowing for two bits of storage. These four Pokémon are:
- Poochyena
- Whismur
- Taillow
- Nincada
All four of these Pokémon can be caught on Route 116, and all of them have an appearance chance of 20% or above. They also all have an even chance of being male or female once encountered, which offers an additional bit of data on top of the two bits offered by these four Pokémon.
This approach may mean that you can't store as much data, but it does mean that it's significantly easier for a real person to go and catch these Pokémon, naming them in the right way and giving them the right items to represent true data. As for the name, this offers 60 bits of data, and uses every English character and most symbols. Spaces are excluded to make it easier to enter names by hand, as well. Finally, held items offer 5 bits of data, as 32 items can be purchased cheaply in-game and given to a Pokémon to hold.
All of this leaves us with the following data points:
- Species: 2 bits
- Name: 60 bits
- Gender: 1 bit
- Item Held: 5 bits
This offers 68 bits per Pokémon, and with 419 slots available (the last slot will need to be used for padding), we end up with 28488 usable bits, equivalent to 3.561 KB.
Encoding a file into several Pokémon
Painstakingly doing it by hand

There's a web utility to go along with mon-fs that will take a file and show you the Pokémon you need, items to give them, and the name to give them. You can save a "pc.json" file that outlines what these should be, and this can be reuploaded to the same website to get an output file back. As you can see above, it gives me the following requirements:
- Poochyena: Male, no held item, named "baaaaaaaaa"
- Nincada: Male, holding X Accuracy, named "aaaaaaaaaa"
- Poochyena: Male, holding Full Heal, named "aaaaaaaaaa"
- Nincada: Female, holding Awakening, named "g6n?Gizsvr"
- Whismur: Male, no held item, named "pRh/vBaCaa"
- Poochyena: Male, holding Revive, named "aaaaaaiwg6"
- Whismur: Female, no held item, named "qBcxefviaa"
Now, assuming I catch all of these Pokémon, what happens then? How can someone take the information, give it to someone else, and have them decode it? They can either use the mon-fs tool that you feed screenshots, use OCR, and spit out a pc.json file back... or the other user can load up your save file, manually enter the details on the site, and decode it there and then.

No matter what, though, you'll have a painstaking reconstruction of the file with either method. Not to mention the fact that going out and catching the Pokémon will take a while too, so it's not exactly a practical way to transfer files to people.
There are several limitations in place here to make it easier for a "regular" person to do this in-game with the tools available to them, though the "Full" mode ups the ante considerably. In this mode, storage increases to 211 bits per Pokémon, or roughly 11.05 KB. The documentation on the GitHub repository does not state why it's the case, but "Full" mode on the mon-fs website states that files under 10.8 KB are guaranteed to work. This may relate to padding values again, though I'm unsure.
It's not really useful, but it's very interesting

I tried to play with a locally built mon-fs to insert Pokémon and read them back out of the game save locally, and while injection worked, reading them back did not. The program failed to read the data stream from the save file, and I also could not get the tool for reading screenshots with OCR and converting them that way to work either. However, manual entry on the mon-fs website works, and someone truly dedicated to transferring files via Pokémon could do so manually.
While this particular project is certainly not practical for most people, it's still an interesting one regardless. Any game that allows any kind of user-controlled data can technically be used in this way, and we've seen similar techniques allow for arbitrary code execution in many games before, including Pokémon Diamond and Pearl. Of course, these are significantly more complex than just creating a recognized structure out of userdata and interpreting it from outside the bounds of the game.

This entire project is crazy, cool, and it can teach you a lot about data structures and how anything can be part of a data structure if you can control the order and some parameters of the items being used to build each "block" of data. To leave you with another example that would be easier to visualize, one could do this in a game like Minecraft. There are 16 wool colors in Minecraft, and you could map 0-F to those colors, which log_2 of 16 means that we would get 4 bits of storage per single block. With just 100 blocks, you could represent 0.05 KB of data; it's not exactly a lot, but it's a similar concept to storing data in Pokémon Emerald. A white block could represent 0000, light gray 0001, and so on.
If you're interested in trying this out, check out the mon-fs GitHub repository and have a look at the mon-fs website. Both will guide you through setting this up yourself and configuring it, and may give you some ideas of the other weird places you could store data, hiding in plain sight.