Automated Game Hacking: Adding Procedural Generation to a Classic RPG - EMF 2026
Watch on YouTubeVideo 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]