Random integer in range from stream (time)

Hello !

I have a question about random integer from stream.
In all my project I am using a random integer in range from stream to get random integer, and the stream is made from time (using the milliseconds). I haven’t any problem before, it was working well.

But today, I was adding a function to my AI that is supposed to get a random integer and play a hit montage depending on this integer.
I have 4 hit montages, so I decide to get a random int between 0 and 3 and depending to this integer I get the hit montage from a data table.

Here is the function (I delete a part of the function and replace it by a print to be sure if it is working or not) :

After some test it appears that I always get number 1 and 2, never 0 and 3. I have done A LOT of test, more than hundred, maybe 200 ? And it is always 1 or 2.
So, it seems that my way to get number is not good… It is a bad news for because I did this to get number in all my project for a lot of things…

So, I did another test, I link to a keyboard key the previous code (not the function, just the code) and decide to test to see which number I could have. And surprise ! It works.

Why is it not working in my previous function, but working in an event like input action ? It is really strange. Is there a reason ? I have done more test, the fact that is it a function and an event is not the cause.

By the way, is this a bad idea to get random number as I am doing ? I now there is a lot of way to do it, but I thought this way was easy… Please tell me if it is a bad thing what I am doing. :slight_smile:

Thank you a lot for your help and your time !

All the best,

Thomas

EDIT : another strange fact, I changed the value that was from 0 to 3, by 0 to 4 and then I manage to get random value from 0 to 3. But in the documentation, integer in range is supposed to get integer >= min and <= max, so the number 3 was supposed to be INCLUDE in the stream. Also, in my test with the input key, I was able to have number 3 without asking for number between 0 and 4.

2 Likes

The make random stream creates a stream object. That stream object then generates the random numbers. So you should call the make steam once in your Begin Play to create the stream then pass that stream to to the random integer in range function.

4 Likes

Thank you for your answer !
Is it obligatory ? I mean, is this the reason why it will not work ? Because when I do the test with the keyboard, I don’t to this and I have no problem.
It is not that I don’t want to change my code, it is just that I have done this in absolutely all my blueprint, so I would like to understand and be sure of what is the problem :slight_smile:

1 Like

Its not obligatory - but its a better use of resources (the create stream is expensive) and if you don’t then there is the risk that because the stream will always generate the same number given the same seed and with your code you are only ever using the first number in the stream then if it takes the same time between calls you get the same random number.

2 Likes

Ok, thank you for the explanation. I will change this :slight_smile:
May I ask you another question ? If I decide to set stream at the beginning play, how often should I reset the stream / recreate the stream ?

Do you think it is a better idea to have the same stream in all my project (setting it at the beginning of the game and access it from everywhere), or a stream for each BP that will have to get random number ?

Thank you again for your time !

1 Like

I would tend to give each actor its own stream - that keeps things clean. A global stream is an option but I try to avoid global things so I can to make my blueprints more reusable. Once a stream is created it is best not to reset it just let it run.

3 Likes

Ok, I understand :slight_smile: Thank you very much for your help and your time. I will try your solution tomorrow on my AI to see if all is working better now. I will also watch more tutorials about stream, because it seems I hadn’t understood everything about it :joy:

Nevermind, thank you very much for your help and your time, I will set this question as “solved” tomorrow after the end of my tests :slight_smile:

2 Likes

As said above, making a new stream every time is sub-optimal.
That being said – why do you seem to get only certain values?
One reason might be that the “current millisecond” time is actually correlated – there’s a certain frame time (and it’s very stable with vsync,) so it may be that using that as seed causes the “random” to initialize a certain way.
You might actually get better results if you do something like “divide the get millisecond output by 17” before you initialize the stream.

2 Likes

The problem with the random stream implementation is that is guarantees a random distribution if you pull numbers from the same stream, but it has very low starting entropy (i.e. is not very random) for seeds with similar bits. So similar seeds create similar numbers. Since you are using milliseconds as seed, there is not enough variation in the input bits to generate random numbers for every new stream objects.

As others have said, create the stream once and then pull random numbers from it instead.

4 Likes

Thank you a lot everybody for your help and your time. I understand better the stream now, and I will use them correctly :grinning:

Have a nice day !

2 Likes