- Home /
Unity built-in seed?
I'm using Random.Range() without putting a seed. It means that I'm using the built-in seed. Can I know where this seed came from?
i am not sure but posible the seed is taken from clock/time so its different all the time, you need to know it for a specific case? if yes, isnt easier to just set up the seed manually?
Answer by troien · Jul 09, 2019 at 11:31 AM
As an answer to the question: "Can I know where the seed came from": No. You can't know for sure. This is handled in Unity's native code so we can't simply look it up in their reference github. It is probably set using something 'random' like the current time when you start the application. To quote the documentation:
The seed is normally set from some arbitrary value like the system clock before the random number functions are used. This prevents the same run of values from occurring each time a game is played and thus avoids predictable gameplay
The actual value used for initialization might also be platform dependant. As not every platform that Unity builds for might allow you to get the system clock for instance (not in the same way/precision at least).
Also, if you wish to set the seed yourself, you can use Random.InitState as mentioned by others already, it replaces Random.seed which is deprecated.
@troien , I see. Because my worry is that the seed is not good enough and might give the same result. I'm planning to use $$anonymous$$ersenne Twister on a C++ .dll to make a uniform distribution.
std::random_device seed;
std::mt19937 generator(seed());
std::uniform_int_distribution<int> distribution($$anonymous$$, max);
int number = distribution(generator);
Is it sensible to create your own PRNG? Or is using Unity's Random.Range() is already good enough and have unbias uniform distribution?
Well, Random.Range's distribution should be uniform, to quote the documentation:
The Random.Range distribution is uniform
Whether Random.Range is random enough depends on your usecase. A user won't be able to see a pattern and it will look random. So for most games it is random enough. But I personally wouldn't trust it for things like cryptography.
Also not sure whether I don't understand your wording or whether you don't understand this, so to clarify. The seed should have no influence over whether the numbers generated by the random number generator are Uniform or not. They should be Uniformly distributed anyway. The only thing that a random seed ensures is that you are less likely to get the same uniformly distributed range twice. If you are just worried about whether the seed is random or not, you can as mentioned set the seed yourself using Random.InitState before calling Random.Range for the first time. That way you don't have to write your own Random number generator.
Personaly I think that the seed is Random enough for games and such, but without the actual source code, nobody can give you a definitive answer. And the seed doesn't need to be randomly distributed at all for most usecases, as long as the chances of getting the exact same seed twice is very low and you have an equal chance to get each number. It doesn't matter if the seed increases linearly using a clock.
Also perhaps nice to know if you are thinking about writing your on, with their new dots approach, Unity released a new maths library which includes a random number generator. A few of the differences with the standard one in Unity:
There are no static methods, it is an instance you have to create.
You are forced to provide the seed yourself.
They host it on github, so you can read the source code.
If you want to take a look at it, You can open the package manager in Unity, filter on 'All packages' and then select $$anonymous$$athematics.
@troien Thank you for more information. I really appreciate it. :)
Since we can't see the actual source code, I think, It's safe enough to create my own RNG. For the seed, yes, one of my main concern is to avoid to get the exact same seed twice and to have unique seed for each of my machines.
I think, after reading some of your replies, It helps me to narrow down my concern about RNG of Unity. 1. How's the Quality of the Uniform Distribution of Random.Range()? 2. And how should I seed my RNG so that it has a unique seed for each machine?
Answer by revolute · Jul 09, 2019 at 09:09 AM
Random has a seed (or something like it after unity deprecated Random.seed for some reason). Check this page.
Unity had previously used the $$anonymous$$ersenne Twister. The "seed" property was highly misleading as it only represents the initial seed (well, that's what a seed is meant for) and not the current state of the PRNG. The mersenne twister has a huge state buffer. So when you want to store the current state, this wasn't possible at all.
Unity then switched to an Xorshift 128 variant. This PRNG has a state of 128 bits (4 integers). The seed is still just a single integer, however it can not be read out. Unity initializes the generator with the current date, time and maybe even tick count when it starts up. This initialization doesn't need to be an actual int seed. They could just initialize the actual internal state manually. Though when initializing the state manually you have to ensure that not all 4 ints are 0.
In general if you want to provide a seed, deter$$anonymous$$e the seed yourself and use Random.InitState. If you want to automatically generate a different seed each time your application start, just use int seed = (int)System.DateTime.Now.Ticks);
as seed and use it in InitState.
If you want to save the current state of the random number generator, just store the state somewhere. When you assign that state back the generator will just continue from this point on.
If you're looking for a simpler but consistent behaviour, you can also use my XorShift64 implementation. It's a bit simpler than the 128 bit version. Also the whole state fits into a single ulong value. Note that this is not a static class like Unity's Random class. You can create as many instances as you want. Each has it's own internal state. Though of course you have to store that instance somewhere.
@Bunny83 , It's good to know that Unity uses $$anonymous$$ersenne Twister before. Because I'm planning to create my own PRNG using $$anonymous$$ersenne Twister on a C++ .dll if I'm not able to know how unity seed there PRNG. So switching to Xorshift 128 variant is much better than $$anonymous$$ersenne Twister?
Your answer
Follow this Question
Related Questions
Random: When to set the seed ? 1 Answer
Questions about changes to UnityEngine.Random. Random.Seed deprecated 3 Answers
Best way to instantiate lots of objects 0 Answers
Simple Enemy Script Questions About Random.Range. 3 Answers
Random.Range HELP!!! 2 Answers