Submind YouTube summaries
Thumbnail for Automated Game Hacking: Adding Procedural Generation to a Classic RPG - EMF 2026

Automated Game Hacking: Adding Procedural Generation to a Classic RPG - EMF 2026

Watch on YouTube

Video summary

Nikki introduces the concept of automated game hacking, specifically focusing on adding procedural generation to classic role-playing games like Final Fantasy. She explains that while traditional ROM hacks are often passion projects created for specific goals like racing or speedrunning, automation allows for the creation of "randomizers" that generate unique gameplay experiences every time a player starts a new game. These tools level the playing field for high-level players by introducing unpredictability, such as randomizing encounters and item locations, which prevents runs from becoming repetitive rote memorization tasks. Nikki shares her inspiration drawn from existing projects like Final Fantasy 4 Free Enterprise, noting that while those games offer great open-world modifications, they are often closed-source with limited customization options for beginners, prompting her to build her own tool called HMS Jane for the Game Boy Advance version of Final Fantasy. To achieve this procedural generation, Nikki had to reverse engineer the game's internal data structures, which function similarly to tables in Dungeons and Dragons used to define encounters and treasure drops. She developed a custom programming language consisting of a disassembler and an assembler to translate the game's binary scripts into readable source code and back again. This allowed her to manipulate complex logic without breaking the game, such as learning magic spells before unlocking them or shuffling items while maintaining their rarity distribution through weighted randomization. A significant technical challenge involved handling non-linear script flows where certain events, like waking up a sleeping prince, depended on multiple conditions; she solved this by creating macros that could dynamically insert specific commands based on the current state of the game world. The final system incorporates advanced logic to ensure gameplay integrity, such as using a constraint solver called Clingo to prevent impossible scenarios like placing a key item in a locked chest or requiring a ship before reaching an island without one. Nikki demonstrates how the randomizer can alter NPC dialogue and plot progression while still respecting the core narrative structure, ensuring that players encounter new adventures rather than just broken mechanics. The project is open-source and available on GitHub, serving as both a functional tool for creating endless variations of classic RPGs and an educational resource for others interested in game hacking. Ultimately, her work highlights how automation can breathe new life into older titles by offering fresh challenges and discoveries while preserving the essential spirit of the original design.
Read the full video transcript
Hi everyone, welcome to the arcade workshop and um this is Nikki. Nikki's been hacking games since the '9s apparently. Um so I'm really excited to hear about this procedural generation of hacking of Final Fantasy. So over to Nikki. [applause] Hello. Um, uh, okay. Sorry. It'll take me a moment to get the the microphone thing. Okay, great. Um, yes. Welcome to automated game hacking. So, um, I'm Nikki, as they just said, and I'm going to talk to you about adding procedural generation to a classic RPG. Um, but first things first. So, I'm going to give some light spoilers to a game that is older in some parts of the world than others, but still older than 20 years. Um, if you haven't played these games, um, I definitely encourage you to play them in the first Final Fantasy, which I'm going to talk about the most. The light warriors go to space, so maybe that's appropriate. Um so um so yes we have automatic game hacking. So be before we talk about this let's take a step back. Um why would you want to hack games in the first place? Um and so one of the obvious things is a renewed sense of discovery. So, like if you play a game and you really enjoyed it, you know, being able to reexperience the world maybe in a different setting and that sort of thing could be could be fun. Um, new adventures, there's people that make that, you know, do like um full full conversion mods for, you know, like Fallout and and Skyrim and that sort of thing. And those are all game hacking. um for challenge. You might think, you know, Elder Ring is hard, sure, but what if the bosses were twice as hard being able to do that? Um and the other thing is like racing. So, you might want to you might want to create a special um version of the game that is designed for racing. And so, you might think, okay, well, this is cool. And there are some people who just make these ROM hacks as a one-off and they're like these amazing passion projects of love. Um, but after you do that, you might think, well, what if I could automate this? Um, and so if you automate this sort of game generation, you typically call it a randomizer. Um, and randomizers in particular are really popular for racing, for like speedrunning because like when you play, for example, Final Fantasy, um, if you're if you are a speedrunner at the at the highest levels, there's not really much that changes in your runs. It's basically you want to make sure that you menu exactly, you go, you take the exact steps that you want to to avoid random encounters and that sort of thing. And so, um, and so it makes it so that there's a very high ceiling on on getting into there. So, you not only have to know the game very very well, you also have to execute the game very very well. [clears throat] In a randomizer, the the um the world is is is random is random. So like you you have a lot of experience with the game and you don't necessarily know what's going to come next. So you're both kind of adjusting to the challenge on the fly, which takes makes it so that highle players are sort of on equal footing. So, I ended up making this game, this game randomizer called HMS Jane. Um, the title is in reference to the Queen of Cornelia, who is we I just figured that the name of the ship will be named after her. Um, and I, um, yeah, this was a lot of fun to make, and I just wanted to talk to you a little bit about that. And before I talk about how this works, I figured I would talk a little bit about the inspiration. So before I started my randomizer, I played a lot of this randomizer called Final Fantasy 4 Free Enterprise. [snorts] And it's essentially the Final Fantasy 4 is this really elegant story. It's very linear. Um, it's a really fun game to play, but um, Free Enterprise gives you the Enterprise, which is this airship that's on the thing, and it basically turns it into an open world adventure. And so, um, I really love this game and I wanted to help out. Um, so, as I said, it's got great core gameplay. the the developers of Final Fantasy really got into their own when they got to this this version. Um, it has a great community. I was telling you about how there's like racing that goes on. The community generally makes a special um designed seed they call them for racing each week. And so then newbies can come in and they can play the game and try it out. And then um sometimes during the week, people who have been in the community for a really long time, who are very very familiar with the game will also play play that seed and record it. And so then if you're new, you can go through and you can see how you did. And then you can watch a recording and see like, oh, when when this player did found this thing in this box, they thought, oh, well, I definitely want to check this thing. And I didn't think that because I was thinking more along the lines of the vanilla game. Um, and you know, fond memories like Ryia is probably one of my favorite Final Fantasy characters in all of the games. Um, there was only one tiny problem. It was closed source. I understood why it was closed source. the developers had a very strong vision of what the game was supposed to be, of how the randomizer was supposed to work. And um and this is great because like I know there's some other randomizers that give you that have a lot more options and which is also really nice once you're familiar with it, but as a beginner it sort of can put you off because you're not sure which knobs to turn for like a fun experience versus really challenging. So that's what led me to decide that since I couldn't contribute to this one, what I could do is I could take the Final Fantasy for the Game Boy Advance and I could build a randomizer around it, sort of inspired by the other randomizers that I played. Um, so in the Game Boy Advance version, you play as four adventurers. Um you can pick a number of from a number of classes and um when you start the game you arrive outside the first city of Cornelia each holding a dark crystal. Um so how do you make a randomizer? So, the first thing is that we've got these things in the ROM that are data tables, and they're essentially exactly the same as in Dungeons and Dragons, like the the Dungeon Masters book. [snorts] Um, so they have in there like um if you're in a swamp tile and you know, you roll a three, this is the encounter that you're going to get and this is how what monsters are in it. this is how many of them could be there and that sort of thing. And this is all exactly in the game. Um, and so if you know where these things are, you can just sort of mess around with the numbers. Um, shift around some of the encounters and you get you get a really interesting experience. Um, there's also all of the treasure in the treasure chests, all of the magic in the shops. Um, and that all weapons, armor in the in the shops and what you find. And so, um, and I was really lucky because other people had made hacks for the Game Boy Advance version and they had documented where all these tables were. So, it was just like, okay, well, let's get going. >> [snorts] >> So, um, once you know where the tables are, you can decide how you want to randomize it. So, one of the ways that you can randomize it is you can basically not randomize it. And you might think that's a bit odd, but um, randomizers, including mine, typically add quality of life features where there's like, you know, either um, like in my version, you can learn magic before you would normally be able to learn magic in the in the game. So like you can learn the spell even though you can't cast it. So that when you level up to be able to cast it, you can just immediately start using it. And that's not available in the vanilla game. And so you might want to have this available while you're playing the original game because you might just think, "Oh, these these are really nice." I mean, it it is from the8s, so some some quality of life features could be added. Um you could do shuffled. Um, shuffling is like shuffling a deck of cards. So, like no matter how many times you shuffle a deck of cards, you're only going to find like one queen of hearts, one ace of diamonds. Um, and the same thing goes here. So, you take all of the treasure in the game and you shuffle it around. You're not going to find two of the best swords in the game. Now, you're only going to find the one, but you might find it in a completely different place. Um, and then the final one is random. And even within random, there are a couple of different options here. We can just do completely random and which can be I mean honestly it can be pretty fun because if you get a good seed and then every treasure chest basically contains amazing items. Um but it it's also incredibly swingy, right? So one of the off so another way you do it is you do weighted random numbers and this is how I did it for HMSG. So essentially what I did for for my game is I put I weighted the different areas of the world. So, in the middle of the of the world is where you start and it has the lowest sort of value treasures and then there's the mid game and then towards the end game and then the final two dungeons have the highest chance of the best items. [snorts] And like it's important to note that this is only a chance. So, like you could get a really really powerful item right in the beginning or really really weak items towards the end. Um, I think one of the fun things is that in the next to the last dungeon in the original game, there's this treasure chest that you have to like go walking off the beaten path for and you open it up and it has in it the armor that is the very first cheapest armor that you can buy from the first town, which always seems really fun to me. [snorts] Um, and so, um, some randomizers just stop here. Like the Pokémon randomizers, I think, generally just do this. Um, which is great because like you can randomize which starters you have. You can randomize which moves they the Pokémon learn at what levels they learn them. You can then you can start going really extreme and be and change which Pokemon involve evolve into which other Pokemon or like which types are strong or weak against other types. So you sort of really have to adapt on the fly while you're playing. But like I said, I really really enjoyed Free Enterprise and I really liked that sort of openw world feeling and so I wanted to be able to randomize how the progression went. So this is the world of Final Fantasy 1 and when you start off you start in this middle town at the bottom on this peninsula and the king of Cornelia is there and he is like my my daughter has just been kidnapped. Please rescue her. And so then you you do this and you kick off this adventure that brings you around the world on so so many fetch quests and [laughter] you go around and you finally light all of the crystals and you come back and you enter the final dungeon and save the world. Oh, spoilers. But I told you. [laughter] Um, [snorts] so, um, these are the different things. These specifically are the different places and people that you meet on on the thing. And so, what I wanted to be able to do is I wanted to be able to take each of the things that these people gave you or each of the things that you find in these locations and move them to other places. Um, and these are this information is not in like a nice little table. This is in these scripts that are that are there. So scripts um basically run things like this where they have dialogue, they have the sprite movement, they can check um and set plot flags as you go along. Um, and you can and and they can initiate battles like here. Um, so in order to to do this, I need to be able to to update these scripts. The nice thing is that the scripts are pretty easy to understand. So um, there is an up code which is basically this is what the instruction does. Then there's a size and then the parameters. So even if I don't know what the instruction does, I know how big it is so I can get the next instruction. So if I know only a few of the instructions, I can still go through and sort of reverse engineer the whole thing. And so like this is the script that was just running um but all of the commands are unknown to us. So one of the things that I could do is I could and when I first tried this I just said okay well let me just go in and you know I know that like this is the com the instruction that will set a plot flag and this is the instruction that will give a key item and this is the instruction that checks for key items. Let me just leave everything alone except change these around. And so I tried it and it worked out pretty well, but then I got to the first script where it needed to be longer in the randomizer than in the original game. Um, and so I needed to figure out a way to deal with this in a better way. And so I thought about it for a bit and I thought, you know, what would be the most reasonable way to do it if I can't just do this search and replace? Well, let's make a programming language. Um, so we've got these. So, I decided to make this programming language and I decided to make it in two parts. Essentially, there's a disassembler and an assembler. And so, you can point it at one of the scripts in the ROM and it will spit out the the source code and then you can point the other thing to the source code and it will turn them back into the bytes for the ROM. So, the first instructions I I knew um were the really important ones that I needed, like the end of the script, um loading dialogue, because even though I remove most of the dialogue because of how it doesn't really make sense anymore, um there's still like you received this item or that sort of thing. Um, I there's the instructions for setting the plot flags, for checking the fly flags, and for giving and taking items. And then, like I said, um, I ended up discovering that there are some of these scripts that are really, really compact in the original game. And so, I needed to also find and understand how the flow control worked. And so there's like go to, there's um conditional jumps and that sort of thing. Um, a really fun one was that the treasure chests aren't aligned to the same grid that the that the um that the map tiles are. And so if you put a treasure chest in in the script, you have to move it by three pixels, which is why I ended up learning that instruction. Um, so yeah. So let's take a look at some of these scripts. So in the game, there's actually two sort of sets of scripts that run. One set of scripts runs when you enter a map and that sort of checks your where you are in the game and sets up the conversations for the NPCs and different like cutscenes and that sort of thing that will happen. So, like for this one, we've got the sleeping prince, and in the game, you are supposed to bring the joltic to the sleeping prince to wake him up. And when he wakes up, he gives you the mystic key. And so, we go, we the uh the script when you enter the map says, "Do you have the mystic key?" Because if you have the mystic key, then obviously you woke up the prince. He gave it to you. And so you not only have the mystic key so you can unlock the treasure ball, but you also should wake up the prince because the prince is obviously awake. If you don't have the mystic key, then the prince is asleep because he didn't give you the mystic key. Um then and then you can check, do you have the jolt tonic? Because if you're going to wake him up, then what you want to do is you want to change the script that's on the doctor there from him telling you like, "Oh, please can you we need to find something to to save our our our friends and turn it to the script that says, "Oh, thank you for bringing me the drill tonic. Here, let's wake up the prince." [snorts] Um, and so that yeah, this is how it works in the vanilla game. But then when you get to the randomizer, it ends up being a little bit more complicated because you still want to check if you have the mystic key because there's still the treasure vault that's locked. So if you have the mystic key, you need to unlock the treasure vault, but you might not have gotten the mystic key from the prince. So, you might have the mystic key, but the prince might still be asleep because it might be the sword, the Excalibur, the sleeping Excalibur. Um, and so, but you so then you you have to check is the treasure vault locked and then you say, "Oh, did do you have the reward from this location?" If you do, then the NVC is awake and he gave you the the thing. If not, then you can check just like in vanilla if you have the Joel tonic. If you have the drill tonic, then you set up the same script to wake up the friends. So this is what these scripts work look like. So, and I was saying that you know this sets up a script on the doctor to give the mystic key in the original version or like in this case it would be the Excalibur. So how does this script look? So this script looks very similar um except it's typically very linear. It's there's sometimes a few instructions that are like if the if the warriors of light are facing you know left or right or up or down then do these things typically to make it so that the so that they turn around and walk to a specific place but otherwise everything is basically linear. Um, and so when I made these things, I added these macros. So we have in here like give Lucam reward cuz like in this spot, this is where Luan would be in the vanilla game. Um, and so there's all of this these instructions around it. And then it has this thing in there. And what I do is I I have a table that I made that says, you know, like if Bahamut is Lukan or if if if the if the person giving you the reward is Bahamut, then these are the the things to do. So I need to set this specific plot flag. I need to give this specific key item. In this case, Bahamut doesn't give you a key item. And then if there are any other instructions that need to run because in this case there's a special instruction that basically promotes the warriors of light from like a fighter and a black bell to a um a paladin and a master. And so what I do is I take these and I turn them into the commands and then I just insert the commands in that macro and then boom, everything works. And um so yeah, this this ended up working out really well. Um I talked way too fast. Um, no. Um, um, yeah. So, the game work worked out really well. I, um, we played it with some people. We, it was streamed on Twitch a couple of times. Um, and it's open source. If you want to grab it, it's on GitHub. It's called HMS Jane if you just search for that. Um, but there are other there are many many other types of of randomizers. Um, there are randomizers, as I said, there's Final Fantasy 4, final the original Final Fantasy. There's one for the NES version of Final Fantasy. Um, and there's also randomizers for sort of modern games, more modern games like Elder Ring, Hollow Knight, and that sort of thing. I think there's a really good randomizer that's for Breath of the Wild, but I'm not entire I not entirely sure how to how to run it. [snorts] Um, but yeah, um, this QR code goes to the big list of video game randomizers. Um, and yeah, um, that's about it and I will take questions in the Q&A tent. >> [applause] >> And now and now I'll answer the first question. So when you're randomizing things, how do you make it make sure that like you don't like put the mystic key into the box that has the mystic key that you need to unlock? And the answer is that you use a constraint solver. And I have I have this there's there's this one file that has like these are the things that that this this lock requires these keys to unlock. So like you can't get to Provoka unless you have a ship and that sort of thing. And there's there's a a program called Clingo that just solves that and spits out a nice little JSON object that I use. [laughter] >> [applause]