Download

Random isn't random?

I’m trying to have my map randomly laid out at the start of the game. I have Event Begin Play set the visibility of an object at the beginning of a round depending on a random int from 0 to 3. It works fine in the editor, but when I launch my game from the exe, it’s the same every time.

Has anyone else had this issue? I’m assuming its because the random seed is poorly selected, but I’m wondering if there’s some way for me to solve this simply in blueprint?

Are you using Random Integer in Range or Random Integer in Range from Stream?

Random Integer in Range

So what you need to do is do a random times the current time and date (down to milliseconds) to seed the random function and then it will work 100 times better.

I don’t understand why they’d have a random function that doesn’t return something remotely random. I shouldn’t have to seed it. A non-programmer using the tool would be out of luck (though idk, maybe Random Streams work differently). Is there anyway to seed this from blueprint though? I’m not at my computer at the moment, but I don’t recall seeing a seed option.

The random function is a public function.

To seed all you have to do is do random function and * the current time and date (down to milliseconds). IE: Random * TimeDate

Just call that once and it will be seeded.

See:

https://www.google.com/search?q=what+is+a+seed+for+random&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a&channel=sb

I don’t understand how that seeds it. Random Int doesn’t seed. It just returns a number. Multiplying that number by another number only effects the local variable. Also, you can’t even access the current time and date from blueprint as far as I can tell. I understand that I would want to use the date/time to seed the RNG, but that’s not what’s going on here. I’m trying to use Random in blueprint.

Is there a reason your aren’t using “Random Integer in Range from Stream”? You can seed a stream using the milliseconds from the current date and time. Without using your own stream variable the numbers are probably generated using a global stream that could be seeded in any arbitrary (and not-guaranteed-to-be-consistent) way. If you want to guarantee it changes every time, then it’s safest to create your own stream variable and seed it manually. Then you can also save seeds and re-create randomly generated maps for debugging purposes or as a feature of your game.

Okay, I’ll give that a try, thanks. I didn’t understand what Streams were for at the time I posted, and I’m just confused a bit then as to what’s the point of Random Integer if it’s seed is something so predictable.

The “random” numbers you can generate with a computer aren’t random at all - a computer is not capable to generate real random numbers at all. All you get are so called pseudo random numbers, as they are deterministic. That’s the reason you always get the same result with your inital setup.

As suggested here seeding the random function with the current time should work for your cause.

To extend a bit on this, there are many cases where you want random to be deterministic.

When working with large sets of generated data and debugging, you will be happy that random returnes the same set of numbers in the same order.

When generting things in general it also allows you to build up deeper layers while extending a system without changing the previous ones.

There is a specific Node to set the seed.
Seting a fixed seed value will also result in a repeating set of numbers each play trough, but it allows you to controll the system or even return to an existing random generation that you liked.

Using time allows a bigger feeling of randomnes, since it will supply a seed that is unique to the exact moment when it’s executed, and the user would need to set his clock back and make sure that the setting of the seed is triggered in the same milisecond as the previous time.

I understand random seeding, and how random isn’t true random (if such a thing could really exist). I also don’t mind UE4 pushing me to do the seeding myself in order to better support reproduceability. It just wasn’t clear. I just thought that if they have a default random node (sans streams) it should have a decent seed. If I’m getting random behavior in the editor but not in the packaged game, then I think it’s clearly not a good default seed, leading to the confusion we had here.

Sorry boss - this is standard behavior in pretty much every random number generator out there. Look at the STL, Google “random number generator”, etc. I’m sure the guys at Epic thought that following the decades-old standard was less confusing for programmers than making us try to figure out how to force it not to seed randomly.

I get the impression you think I want them to break away from whatever standard you’ve just described. I think you’re misreading into my issue here. There’s a function that appears to work one way in the editor but then doesn’t work the same way in the packaged game. Is the editor not intended to be a WYSIWYG tool for at least gameplay? That is not clear to someone new to game development or even just ue4.

Ah, now I understand your confusion.

Question - if you leave the editor and restart it do you get the same result as when launching the game stand-alone? I’m thinking that the editor is a layer over the stand-alone executable, so that launching the game isn’t actually restarting the executable and you get the next value in the sequence. This would cause the RNG to appear to be doing what you want in the editor but not in the stand-alone game.

The Random Int was selected for Event Begin Play in the Game Mode. I’d have to build tests that probably just use a construction script to actually see if I can replicate the ‘predictable’ random in editor. I’m probably not going to worry about it for now as I have bigger fish to fry.

I do not get the same sequence in the editor when I restart. However I do get it in a packaged game.

If you are using C++, you can use a FRandomStream and seed it with the current UnixTimestamp in seconds like so:


int64 DateInSeconds = FDateTime::Now().ToUnixTimestamp();
FRandomStream SRand = FRandomStream();
SRand.Initialize(DateInSeconds);

Now, instead of using FMath::FRand() you should use SRand.FRand(). I tested with a packaged build and it works. I get a different sequence every time.

If you are using Blueprints you can seed your random stream using Rama’s custom blueprint functions for getting the time.
https://forums.unrealengine.com/showthread.php?3851-(39)-Rama-s-Extra-Blueprint-Nodes-for-You-as-a-Plugin-No-C-Required!