GameMaker randomize() not working

MissingNo.

Member
Alright so after trying to create NPCs with random movement utilizing "random_range"
I noticed that the values did not change every time I restarted or relaunched the project.

So to see if "randomize()" truly wasn't working I made sure "randomize()" was in my room creation code and I made a object that was it's sole purpose was to generate a random value and draw it to the screen.
And the value I always get is 381.55. It doesn't matter if I restart or relaunch the test.

This is my room creation code:
Code:
randomize();
And this is my test object create event:
Code:
TestValue = (random_range(MinValue, MaxValue));
And this the test object draw event:
Code:
draw_self();
draw_text(x + 0, y + -30, string("Caption: ") + string(TestValue));
What the heck is going on? Reading the GMS2 Manual tells me calling "randomize()" once on room creation should force GMS2 to generate a new seed.

And just so everybody knows MinValue is set to 0 and MaxValue is set to 1000.
 
T

Timothy

Guest
Sounds weird, but room creation code is likely called after the create events. Move your call to randomize to the create event.
 

MissingNo.

Member
Sounds weird, but room creation code is likely called after the create events. Move your call to randomize to the create event.
I failed to mention this but I also tried using a controller object that calls "randomize()" in the game start event and I still get 381.55 each time with my random test object.
 
T

Timothy

Guest
I failed to mention this but I also tried using a controller object that calls "randomize()" in the game start event and I still get 381.55 each time with my random test object.
Lol, again, it sounds weird, but game start is likely called after create. Most reliable way is to create an init room that only does things like define globals, seed random, etc then goes to the next room (real first room)
 

MissingNo.

Member
Wait so you guy's are saying your supposed to use the create event with "randomize()"? I was always told to use Game Start with "randomize()" or the room creation code. And I was told to not put it in the creation event. Was it different in GMS 1.4?

Well it is in fact working now that I put it in the creation event. I could have sworn in the past you weren't supposed to do that. Thank you both for your help.
 
Last edited:

FrostyCat

Redemption Seeker
Wait so you guy's are saying your supposed to use the create event with "randomize()"? I was always told to use Game Start with "randomize()" or the room creation code. And I was told to not put it in the creation event. Was it different in GMS 1.4?

Well it is in fact working now that I put it in the creation event. I could have sworn in the past you weren't supposed to do that. Thank you both for your help.
The best practice with randomize() is to call it once at the beginning of the game, well before the creation of anything else that depends on randomization. It is typically done in a room dedicated to setup, placed first in the room sequence. Then you can use the Game Start event (of an object that has an instance in the setup room) or that setup room's Room Creation Code to run randomize(). Your problem is calling randomize() in a later room not dedicated to setup, and specifically after creating something dependent on it instead of before.
 

MissingNo.

Member
Nah, those are the last events to get run. I know, it doesn't make sense, but you get used to it, like going to work at 6 a.m. everyday.
Haha yeah but I Imagine there is some reason at engine level to do it that way. But I thought that in GMS 1.4 or GM8 that Game Start was before Create.
If that wasn't the case then either then my whole life has been a lie.
 
It makes some sense if you look at it from a basic game design perspective. Imagine you have a simple game, such as Pong. Instances are created, events are run, the game is technically set up and ready to go, and then the Game Start event kicks in and determines how the game will actually play. For example, the event could randomly set the base speed level of the balls to come, or what the score cap should be. It's an event that seems designed for beginners creating simple concepts, rather than it being an event anyone with experience would seriously use for major projects.
 

Evanski

Raccoon Lord
Forum Staff
Moderator
I thought randomize doesnt change because the game seed doesnt change, when the game is compiled into an .exe then randomize is diffrent everytine
 
Last edited:
I thought randomize doesnt change because the game seed doesnt change, when the game is compiled into an .exe then randomize is diffrent everytine
The sole function of randomize() is to change the game's seed. It would be extremely annoying if it didn't and you had to compile every single time you wanted to test a game featuring a lot of randomness.
 

TsukaYuriko

☄️
Forum Staff
Moderator
Haha yeah but I Imagine there is some reason at engine level to do it that way. But I thought that in GMS 1.4 or GM8 that Game Start was before Create.
If that wasn't the case then either then my whole life has been a lie.
At your service - I'm here to ruin your life. Engage the test results! :p

Task: Output the name of the Create, Room Start and Game Start events as well as instance creation code and room creation code when they fire.

GMS 2.x, runtime 2.2.2.326:
Create
Instance creation code
Game Start
Room creation code
Room Start
GM:S 1.x, 1.4.9999:
Create
Instance creation code
Game Start
Room creation code
Room Start
GM 8.1.141:
Instance creation code
Create

Game Start
Room creation code
Room Start
Conclusion: Don't rely on the event order. Unlike hoping for the event order to play along nicely, @FrostyCat's proposed solution is foolproof under all circumstances.

I thought randomize doesnt change because the game seed doesnt change, when the game is compiled into an .exe then randomize is diffrent everytine
Unless you run randomize, the seed will be the same every time you run the game. Whether the game is compiled or not makes no difference either way - you either randomize it or it's always the same under any circumstances.

Wait so you guy's are saying your supposed to use the create event with "randomize()"? I was always told to use Game Start with "randomize()" or the room creation code. And I was told to not put it in the creation event. Was it different in GMS 1.4?

Well it is in fact working now that I put it in the creation event. I could have sworn in the past you weren't supposed to do that. Thank you both for your help.
The phrase "at game start" (which is a carbon copy from the manual) which I like to use when randomize is the context doesn't necessarily mean "in the Game Start event". It means "once, and only once during the game's run time, typically at the start and not at any time in between start and end". Allow me to elaborate.

Putting it in the Create event is technically wrong, but may be producing results of the same nature as what you expect. Given that you're expecting anything but predictable results, it's easy to mistake non-identical results as properly randomized.
That still makes it wrong, though, and it's the kind of wrong that will go unnoticed until it bites you in the back.

If you run randomize multiple times, the seed will be set to a new value multiple times. The frame of the PRNG (read: the "position" in the list of pseudo-random numbers that will be generated with the given seed) will also be reset.

Let's examine this simple piece of code:
Code:
repeat(4)
{
    randomize();
    show_debug_message(irandom(100));
}
Result: (manually formatted for easier readability because I didn't want to over-complicate the code with proper output formatting)
89 66 68 11
(The 11 will be important in a moment.)

This will randomize the seed every time before generating a number. The results of these are not replicable - at least not fully, since what you are really getting here is the following:
[S1F1] [S2F1] [S3F1] [S4F1]
(S: seed, F: frame)

Using the following code after the first one, you can replicate the last generated number, and only the last one. It will be the first number to be output, as the seed you are copying is the one that was used to generate the last one.
Code:
var rnd = random_get_seed();
random_set_seed(rnd);

repeat(4)
{
    show_debug_message(irandom(100));
}
Result:
11 62 27 32
Which is actually:
[S4F1] [S4F2] [S4F3] [S4F4]
You can verify that this is the case by using the first piece of code and generating three further numbers after its execution:
Code:
repeat(4)
{
    randomize();
    show_debug_message(irandom(100));
}

repeat(3)
{
    show_debug_message(irandom(100));
}
18 19 26 8 78 38 15
Which is actually:
[S1F1] [S2F1] [S3F1] [S4F1] [S4F2] [S4F3] [S4F4]
Ignore the first three numbers, as they are not a part of the sequence of seed 4. The last four generated numbers will be equal to the sequence generated by re-setting the seed to the current seed - remember that this will also reset the frame, so you're starting at S4F1.

You can then replicate the last generated numbers like before:
Code:
var rnd = random_get_seed();
random_set_seed(rnd);

repeat(4)
{
    show_debug_message(irandom(100));
}
Result:
8 78 38 15
Which is actually:
[S4F1] [S4F2] [S4F3] [S4F4]


Therefore, the results become fully replicable if you only set the seed once, generate four numbers, re-set the seed to itself and generate four numbers again:
Code:
randomize();

repeat(4)
{
   show_debug_message(irandom(100));
}

var rnd = random_get_seed();
random_set_seed(rnd);

repeat(4)
{
   show_debug_message(irandom(100));
}
Result:
20 78 76 63
20 78 76 63
 

MissingNo.

Member
At your service - I'm here to ruin your life. Engage the test results! :p
Ain't that something... Well that does it, my life is a lie, everything is a lie, there is no truth, god is dead, nothing is real, it's all a simulation.:p

Anyways very exhaustive post I thank you for going out of your way to write all of that.
But yeah as said before it should only be run once per game launch, preferably in a boot room.
 
Last edited:

TheouAegis

Member
randomize() returns the produced seed as well, so it's really a combination of random_set_seed() and random_get_seed(), plus whatever subroutine determines what the seed will be.

global.room_seed = randomize();

Code:
var cat = randomize();
for(var i=0; i<1024; i++) {
if !(i & 7) random_set_seed(cat);
show_debug_message(irandom(100));
}
The above should randomly generate a set of 8 numbers and repeat them over and over in the console window (of course populating an array would be faster, but this is just a demo).
 

Joe Ellis

Member
It makes some sense if you look at it from a basic game design perspective. Imagine you have a simple game, such as Pong. Instances are created, events are run, the game is technically set up and ready to go, and then the Game Start event kicks in and determines how the game will actually play. For example, the event could randomly set the base speed level of the balls to come, or what the score cap should be. It's an event that seems designed for beginners creating simple concepts, rather than it being an event anyone with experience would seriously use for major projects.
This is really good, insightful, and (I think) how the events run in gm, when I read this I thought "Fu****... yeah thats exactly how it works"
but the thing is, I want the room start to initialize everything, THEN the instances are created and run events, it might be my personal preference, but this way seems better, and its the way I've made it work in "Warp3D"
That aside, I don't really see the problem with the randomize function, if it's not providing random results on startup it will the next step or step after, etc
 
I

immortalx

Guest
Sometimes it's the naming scheme in gamemaker that is the source of confusion. I remember when i first had to use instance_create_layer. Well, when you read the manual entry it makes sense, but who does read it at first :rolleyes: At first glance I thought it had something to do with layer creation. Instance_create_AT_layer would seem more understandable. And I still can't fathom room_speed. I can't stop visualizing a room traveling on rails...
 

Joe Ellis

Member
Sometimes it's the naming scheme in gamemaker that is the source of confusion. I remember when i first had to use instance_create_layer. Well, when you read the manual entry it makes sense, but who does read it at first :rolleyes: At first glance I thought it had something to do with layer creation. Instance_create_AT_layer would seem more understandable. And I still can't fathom room_speed. I can't stop visualizing a room traveling on rails...
I dunno why room speed still exists, you either want it at 30 or 60, anything else doesn't actually work with monitors, unless the monitor is 50hz, then 50 would be ideal, or 75 hz,,, but i dont really know about any monitors than use 75hz, I remember my old monitor did, but it was either a ctr or a very early flat screen, either way, I think the standard for games is 60, even 75hz monitors display the games at 60 far as I know. Everything should run at 60 if you ask me, then if you want the game to be at 30, there should be a setting in gm to put it to that, rather than any number from 1 to 99 or whatever the max is
 

rIKmAN

Member
Sometimes it's the naming scheme in gamemaker that is the source of confusion. I remember when i first had to use instance_create_layer. Well, when you read the manual entry it makes sense, but who does read it at first :rolleyes: At first glance I thought it had something to do with layer creation. Instance_create_AT_layer would seem more understandable. And I still can't fathom room_speed. I can't stop visualizing a room traveling on rails...
Use macros to change them if is an issue for you.
Add them to a script and then just add that script to every project to have them available.

My most used one was "log" instead of "show_debug_message" because 99.9% the time the function name was way longer than the data I wanted to print. Now I use a script which can take multiple values to print but the macro worked just as well for single values.
Code:
#macro log show_debug_message
#macro game_fps room_speed
#macro instance_create_at_layer instance_create_layer
#macro instance_create_at_depth instance_create_depth
You could macro every GML function to your preferred function names if you really wanted to.
 
I

immortalx

Guest
Yep, I do use/abuse macros and have a multi-value "print" script, as well as other helper scripts. It was as a beginner that some naming convensions seemed odd at first!
 
Top