1
\$\begingroup\$

I have three objects. All of them in the create event contain an action each (execute a piece of code):

obj_r01 => r01=0;

obj_r02 => r02=0;

obj_r03 => r03=0;

Image (to clarify what I have tried to explain):

enter image description here

So far so good, but I have one more object that modifies the variables of these other three: obj_control

The obj_control contains two events: create and draw.

enter image description here

crete event (obj_control):

obj_r01.r01=irandom(9);
obj_r02.r02=irandom(9);
obj_r03.r03=irandom(9);

draw event (obj_control):

This event contains three actions, precisely three "execute a piece of code":

enter image description here

piece one:

draw_text(x,y,obj_r01.r01); => applies to obj_r01

piece two:

draw_text(x,y,obj_r02.r02); => applies to obj_r02

piece three:

draw_text(x,y,obj_r03.r03); => applies to obj_r03

The objects are arranged as follows in the room:

enter image description here

In execution this is what happens:

enter image description here

The value of r01 is randomized, but that of r02 and r03 is not. I also tried to modify the obj_control creation event code to:

randomize();
obj_r01.r01=irandom(9);
randomize();
obj_r02.r02=irandom(9);
randomize();
obj_r03.r03=irandom(9);

However the result does not change. With this I could only suspect that the irandom () function can only create a storable random value, would it solve such a problem?


EDIT 1:

I tried putting randomize() only at the beginning of the code as suggested to me by @Philipp and @DH.:

randomize();
obj_r01.r01=irandom(9);
obj_r02.r02=irandom(9);
obj_r03.r03=irandom(9);

But there was no change in the result.

I also did a test to be sure if the value was not even being randomized or if the values ​​of r02 and r03 were being randomized to 0 and for that I modified their values ​​in the creation of each object:

In obj_r02:

r02=10

In obj_r03:

r03=100

The result:

enter image description here

The first value (not surprisingly) was randomized, but the second and third values ​​were not. Thus it is clear that the randomization is not being made or that the draw event is occurring before the radomization of r02 and r03.

\$\endgroup\$
  • 5
    \$\begingroup\$ Generally reseeding your randomizer using randomize() before each call will increase correlation between outputs, rather than decrease it. That's because you've tethered them all to be only one shuffle step away from whatever data source is used to drive randomize (generally the system clock). PRNGs are typically optimized to give good decorrelation in depth (sequential results from the same seed) not in breadth (initial results from adjacent seeds - hash functions are better optimized for this use). What happens if you randomize only before the first roll? \$\endgroup\$ – DMGregory Mar 30 '17 at 22:31
2
\$\begingroup\$

The random number generator used by GameMaker is not a true random number generator. It is a pseudorandom number generator (or short: PRNG). A PRNG will return a sequence of numbers which look randomly, but are actually a deterministic sequence. The sequence of numbers a PRNG generates depends on its initial state, the so-called seed value. When you initialize a PRNG with the same seed, it will generate the same sequence.

That means that when you want each run of a game to be an unique experience, you need to use a different seed value for the PRNG for each run. As a developer you usually don't care where that value comes from, just that it isn't the same you already used. Game Maker's randomize function has the purpose to re-seed the random number generator with a new seed which is unlikely to be the same as the last time the game was run. I don't know what that function does exactly "under the hood" to achieve that, but it likely calculates the seed value from various entropy sources, like the current time, user input, etc. When you call randomize multiple times, those entropy sources might not have changed, so you re-initialize it again with the same seed. That means the PRNG will return the same sequence.

That means you generally should call randomize() exactly once: when the game starts. Then just call irandom(n) when you need a random number and it should return a different random number each time (or the same number... with a chance of one in n). So your game initialization function would look like this:

randomize();
obj_r01.r01=irandom(9);
obj_r02.r02=irandom(9);
obj_r03.r03=irandom(9);
\$\endgroup\$
  • \$\begingroup\$ So, what should I do to generate three random values ​​so that the three objects display three random values? \$\endgroup\$ – Boneco Sinforoso Mar 31 '17 at 23:57
  • \$\begingroup\$ Call randomize in the initialization function of your game, and just call obj_r01.r01=irandom(9); obj_r02.r02=irandom(9); obj_r03.r03=irandom(9); where you need them \$\endgroup\$ – derstander Apr 1 '17 at 4:32
  • \$\begingroup\$ @BonecoSinforoso answer updated. \$\endgroup\$ – Philipp Apr 1 '17 at 10:32
  • \$\begingroup\$ I did not get the expected result \$\endgroup\$ – Boneco Sinforoso Apr 1 '17 at 18:25
  • \$\begingroup\$ @BonecoSinforoso What results did you expect and what results did you get instead? \$\endgroup\$ – Philipp Apr 1 '17 at 18:31
2
\$\begingroup\$

A complement to @DMGregory comment is the real use of randomize().

It's supposed to set the seed, and there is no need to do it more than once as already noted, but also, as said here

Please note, that when using the random number functions in GameMaker: Studio the initial seed is always the same, as this makes tracing errors and debugging far easier. Should you wish to test with true random, you should call this function at the start of your game.

So, not calling will wield the same results over the runs. The best case is to just call once, at the start of the game, and never call it again to make it "truly" random.

\$\endgroup\$
  • \$\begingroup\$ So, what should I do to generate three random values ​​so that the three objects display three random values? I have already excluded two of the three randomize() \$\endgroup\$ – Boneco Sinforoso Apr 1 '17 at 0:02
  • \$\begingroup\$ @BonecoSinforoso At the create event of an object, run randomize(). Then, on the objects that need to call irandom(), just use it. Nothing more needed to setup. \$\endgroup\$ – DH. Apr 1 '17 at 3:36
  • \$\begingroup\$ I did not get the expected result \$\endgroup\$ – Boneco Sinforoso Apr 1 '17 at 18:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.