Randomness in computing is a LIE! There are a handful of things that computers simply can not do, lying is one example and making random numbers is another. When a computer makes a “random” number, it just appears to be random, or at least random enough that you can’t tell.
On the Game Boy this is even more true. Most modern computers, consoles, etc., have some sort of built-in random functionality, but the Game Boy does not have any function for random within its hardware. Sorry if you are thinking, “but Pokémon has randomness..”, your childhood was a lie! However, as long as it looks random that “should” be good enough, right?
If the Game Boy has no random functionality, then what on earth is Random in the [Variable: Math Functions] script event?
As I mentioned, randomness in a game just needs to be close enough to feel like it’s actually random, but in GB Studio if you put the random function in the wrong place it’s not even going to be close. You might find your game “randomly” spitting out the same number every time and this happens because GB Studio’s random function is based on the Game Boy’s frame buffer.
The Problem with Frame Buffers
What is a frame buffer? The frame buffer is a portion of RAM that is used to store data for the current image that’s being displayed on screen (more or less). That data is then used to create a number when the random event is called. So what’s the problem? If that frame buffer is in that same state every time you ask for a random number, it will always spit out the exact same number!
So how do you fix this kind of problem? You introduce a second form of randomness. There’s one thing you have access to that is nearly impossible to predict: the player! If you put your random event on some kind of user input, the chances of 2 different players having the same frame in the same state when they select their input is very low.
Let’s try an example. I’ve created a very simple scene in GB Studio. There are two actors, and two variables. The actor on the left with the sage sprite will display Global Variable  by using a text box that has [$00$] in it. The actor on the right with the npc_002 sprite will display Global Variable . The difference between the two variables is at what point we call the [Variable: Math Functions] event with the Random parameter.
The first randomizer for variable , is called when the scene is initialized (or On Init). The second randomizer for variable  is called when the player interacts with the actor on the right.
Of course, you wouldn’t expect the first variable to change once this scene is loaded, but close the game and reload it from start. Notice something? The sage always states it’s the same variable, even though it’s supposed to pick a number randomly. This is because the place and time where the number is picked is always the same (when it loads) making it never pick a random number.
Hopefully this helps explain why your random event might not appear to be working correctly in some places and I hope that you now have a better idea on how to fix it. Happy coding!