Search Unity

How to create random numbers in hierachy?

Discussion in 'Scripting' started by TheGaul, Dec 2, 2019.

  1. TheGaul

    TheGaul

    Joined:
    Apr 15, 2019
    Posts:
    199
    Say I create 10 galaxys.

    Then at a later time I want to create 100 random stars in one of these galaxys.

    So in other words I want each of these galaxys to have it's own unique random seed.

    But... I want the seed to be the same every time you play the game.. so it can't be based on things like the current time.

    The problem I find is that if you create random seeds with a random number generator then this makes things less random. So what is the correct way to do this?
     
  2. Karrzun

    Karrzun

    Joined:
    Oct 26, 2017
    Posts:
    129
    When writing the GenerateStars() method, couldn't you just pass a seed parameter instead of generating one during runtime? Maybe even make an overload to have an alternative version with seed?


    public void GenerateStars ()
    {
    // generate a random seed first
    // generate stars the way you want to
    }

    public void GenerateStars (int seed)
    {
    // generate stars the way you want to
    }



    // Edit: On a second thought, I think an overload is more appropriate than an optional parameter
     
  3. TheGaul

    TheGaul

    Joined:
    Apr 15, 2019
    Posts:
    199
    Yes, but how would I calculate a seed for each galaxy? And then I would need a seed for each star to generate unique planeteray systems and so on.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    There is no correct way. All you need is something that is sufficiently random that the player feels they've never seen each galaxy before. Part of this is from your seed choice, but also part of this comes from how much random information you put into each galaxy.

    The seed is the easy part. You can just use an ever-incremented number, or else use the current milliseconds since some known arbitrary date, such as what the Unix epoch time uses.

    The second part is the hard part: procedurally generating something interesting and consistent, regardless of what random numbers come up.
     
  5. TheGaul

    TheGaul

    Joined:
    Apr 15, 2019
    Posts:
    199
    Hmm... Yes, I guess I could just use an incremental seed for each galaxy. I'm not sure how random that would turn out though...
     
  6. TheGaul

    TheGaul

    Joined:
    Apr 15, 2019
    Posts:
    199
    I have an idea. Tell me if this is good.
    So I give the seeds of the galaxys:
    1 2 3 4 5 6 7 8 9

    Then to get the seeds of the stars in galaxy 8, I multiply the seed by 100 and then add a number so the seeds for the stars are:

    801 802 803 804 805 806... 899

    And so on.

    Hopefully if I use these seeds for the random name generator this would give me unique names for all the stars. But I'm not sure if consecutive seeds would cause any problems.

    I could probably add a constant, c, onto every seed to give different universes.
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    You are waaaaaaaay over-thinking this. Just use the in-built Unity seed mechanism, pick a number and move forward. As I said, the seed part is trivial; it's the usage of the random values that will ultimately determine the character and quality of your universes.
     
  8. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    I'm rather unclear on the structure of your game vis-a-vis how it affects your random number requirements. When do you need to generate new seeds, when do you need to make sure you're using the same seeds as before? If you literally just want one set of seeds for your game that will never change and will be the same for every player every time they play for all of time, then you can just get some high-quality random numbers (e.g. from random.org) and write them directly into your game's source code.

    Do you need the ability to regenerate individual galaxies by themselves without simulating the whole universe? If you only generate the entire universe as a unit, then you can do it all with a single seed and a single random generator, just make sure you generate everything in the same order every time. The only reason you'd need separate seeds for each galaxy is if you want to be able to regenerate just a single galaxy (e.g. when the player visits it) without needing to generate all the other galaxies at the same time.


    If your requirements are stringent enough that you can't use an "original" random number generator to generate your other seeds, then this is going to be even worse. The key thing is that all the numbers are mathematically derived from the other numbers. Basically, this IS a random number generator that you are using to generate your other seeds--it's just a very very low-quality random number generator.

    If you need something better, you want a high-entropy "true random" source, not a mathematical equation.
     
  9. TheGaul

    TheGaul

    Joined:
    Apr 15, 2019
    Posts:
    199
    It's not overthinking. Because I might not be necessarily creating the stars of the galaxys in the same order. Only when they are being visited. So if I don't think about it carefully, it will be different each time.
     
  10. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,493
    It depend on what you do, but your SEED don't have to be random, the seed HASH has to be, so it okay to use ordered number as seed, because well ... they are different which mean they will produce different number, as such you can use the coordinate as input seed.

    So the problem become what should be random and what should be persistent.
    1. the world is static, it's always the same across game session and player. You have a hardcoded initial seed.
    2. the world is different at each session, but persistent once generated (ie coming back to a same place should yield same result). Generate the global session seed at initialization of the world and store it for that session. Sharing that seed will create the same world (see minecraft).

    One problem with procedural generation is the concept of "deep echo", you go to a different galaxy a different planet, but stumble on a twin city identical to another place. That happen when the hierarchical seed are not correlated, if you generate a planet with seed 500 and it has a city with seed 384, well another planet can roll that same number, so you must keep the hierarchical "path" inside the seed by prefixing the seed of the parent to the children seed, such as city 500384 is distinct from city 085384, seed should be "coordinate", here it's the "tree path adress" to that city elements.

    If all your adress" seed are simple enumeration, they are guarantee to be distinct, now the problem is the quality of your random function, ie your random hash that will map your ordered address into shuffled data, so that the ordered quality disappear. Your hash must have 2 quality:
    1. your hash must not have collision, so given the working range of your generation, you can't have the same seed map back to the same number, the hash is said to be perfect, but even perfect hash can fail if you have more element than the range of the function.
    2. your hash should be statistically random enough, to know more about it read that: http://blog.runevision.com/2015/01/primer-on-repeatable-random-numbers.html

    I had these problems in a demo I made, in practice I did wing it by simply using the position (guarantee to be unique through spatial hash partition) and then using as a seed the position such as x+y*10+z*100 to break with offset the blitz3D poor successive seed randomness (see link above). In general strictly statistically random generation is not that important in game, as long it's visually pleasing enough and the pattern not visible at the scale you operate..
     
    TheGaul likes this.
  11. TheGaul

    TheGaul

    Joined:
    Apr 15, 2019
    Posts:
    199
    Yes, I think I pretty much came to the same conclusion. I'm sure I will end up with collisions somewhere. But this idea seems good enough for my purposes