Another Question About 0.9's RNG

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Another Question About 0.9's RNG

Post by bartbes »

If determinism is important, using random number generator objects, you can have multiple pieces of codes working with their own seeds, and their own generators. You could even do awesome things like forking and then choosing one of the forks. In general though, there's occasions where it's useful to have one generator not affect the other (because they're different parts of the code, for example), and this API allows for that.
User avatar
Helvecta
Party member
Posts: 167
Joined: Wed Sep 26, 2012 6:35 pm

Re: Another Question About 0.9's RNG

Post by Helvecta »

Aha! Gotcha. So for most purposes love.math.random will suffice.
Helvecta wrote:Maybe it's because of the way I'm testing it, but I don't think that should matter.
I was wrong; it was the way I was testing it. Maybe forcing the program to assert a pseudo-random number immediately didn't give the generator proper time to engage. I figure this because actually setting up an app that displayed random numbers worked just fine!

Image


Thanks for all the help, everyone. It's much appreciated! :awesome:
"Bump." -CMFIend420
User avatar
Hexenhammer
Party member
Posts: 175
Joined: Sun Feb 17, 2013 8:19 am

Re: Another Question About 0.9's RNG

Post by Hexenhammer »

Try this:

Code: Select all

    rng = love.math.newRandomGenerator()
    rng:setSeed(tonumber(tostring(os.time()):reverse():sub(1,6)) )
    rng:random();rng:random();rng:random();
    randomNumber = rng:random(1,100)
 
There are two problems with your original code:

1. The seed value. os.time() is almost identical between calls, and unfortunately the most significant bits are identical . The strange vodoo done to the os.time() return value basically makes the bits which change more often the most significant ones.

2. As bartbes already explained, the first numbers returned are not very "random" (I know that is pedantically incorrect phrasing).

So there is your solution, massage the os.time() return value and throw the first few numbers away. But here comes the kicker...

.. you don't need to do any of that now that LÖVE uses LuaJIT. This

Code: Select all

    math.randomseed(os.time())
    randomNumber = math.random(1,100)
..will work just fine with LuaJIT's RNG. The new LÖVE RNG is pretty pointless now given that LuaJIT already addresses all common issues of the vanilla Lua one.
User avatar
slime
Solid Snayke
Posts: 3144
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Another Question About 0.9's RNG

Post by slime »

Hexenhammer wrote: .. you don't need to do any of that now that LÖVE uses LuaJIT.
[..]
The new LÖVE RNG is pretty pointless now given that LuaJIT already addresses all common issues of the vanilla Lua one.
LÖVE can use Lua 5.1 or Lua 5.2-compatibility or LuaJIT 2.0 or LuaJIT 2.1 - it's just distributed with LuaJIT 2.0 by default. If you make a LÖVE game and expect other people running their own copies of LÖVE to be able to run it with the results you expect, you might not want to rely on a particular implementation of the Lua math.random, especially since you don't need to.

Not only that, but you can have completely separate RNGs using different seeds at the same time with LÖVE's RandomGenerator objects, which is something LuaJIT doesn't provide at all without completely separate Lua states.

love.math.getRandomSeed and RNG:getSeed are useful as well.
User avatar
Helvecta
Party member
Posts: 167
Joined: Wed Sep 26, 2012 6:35 pm

Re: Another Question About 0.9's RNG

Post by Helvecta »

bartbes wrote:You could even do awesome things like forking and then choosing one of the forks.
Since this thread is still kicking, would you mind giving an example of what you mean by this? Or a resource that explains what this means in greater detail? I think Jasoco mentioned something that sounds similar, but I'd like to make sure I know what you mean.
Hexenhammer wrote:

Code: Select all

    math.randomseed(os.time())
    randomNumber = math.random(1,100)
..will work just fine with LuaJIT's RNG. The new LÖVE RNG is pretty pointless now given that LuaJIT already addresses all common issues of the vanilla Lua one.
I know Slime just replied about this but I thought it's worth pointing out that he also stated that "The love.math.random function exists partly because math.random's implementation is different on different operating systems. love.math.random will give the same results regardless of OS, given the same inputs (if the random seed/state is the same), but math.random will not."

Somebody else on the forums (I can't find what the exact response was) noted the implications of having RNGs that are dependent on OS by giving an example of generating a map on multiple OSs, and noting that - even though the same function is used to generate random data - the maps would end up different for people on different OSs because of math.random. Avoiding that seems to be the primary reason for making love.math.random.

This is coming from someone that barely knows how to use an RNG though, so take my rambling with a grain of salt.
Hexenhammer wrote:1. The seed value. os.time() is almost identical between calls, and unfortunately the most significant bits are identical . The strange vodoo done to the os.time() return value basically makes the bits which change more often the most significant ones.
So, hypothetically speaking, let's say I use a RNG to fetch 3 random numbers, with the following seeds: 1, 2, and 3. For the sake of the example, the returned numbers will be 3, 6, and 1. Then, I try to use the same RNG to fetch 3 random numbers again, with the seeds being 2, 3, and 4. Would I get completely different random numbers? Or would I get 6, 1, and a new random number?

I ask this because one of Plu's posts makes it seem like the seed is the insertion point in a list of numbers, from which a number in this list is returned based on the seed. If that's the case, I could see why it's important to make the seed as random as the numbers returned from said list, and almost explains why you want to reverse os.time.

Why do I say almost? Because now I'm confused about what Robin posted a while ago. In Robin's post, gen:setSeed(os.time()) is placed outside of any function, yet the numbers are still always different! Since os.time is defined at the beginning, shouldn't it be a static value at that point (whatever os.time is when :setSeed is called)? And even if os.time as the argument is somehow dynamic (seriously, if you guys say that os.time is a dynamic argument I'm going to dissolve into the floor), shouldn't the returned numbers be the same "random" number returned over and over until os.time changes (that is, until a second has passed)?

Robin even specifically stated that I shouldn't be setting the seed inside of the function (and testing it myself has confirmed it):
Robin wrote:A function that returns or uses a pseudo-random number should not mess with the seed.
If the seed is an insertion point like I figure it is, why is it bad to change it wherever you want?

MY MIND IS IMPLODING. :death:
Attachments
random.love
(447 Bytes) Downloaded 96 times
"Bump." -CMFIend420
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Another Question About 0.9's RNG

Post by bartbes »

Helvecta wrote:
bartbes wrote:You could even do awesome things like forking and then choosing one of the forks.
would you mind giving an example of what you mean by this?
If you have a game where moving through time is an important mechanic, it might be interesting to store the random seed at any point you can (or do) diverge, that way you can faithfully rewind and start again. You could also do some weird magic with statistics-based games where you calculate two options using two diverging branches of choices, and then with that result, you can pick either and they both would have been possible from the point you started calculating them. So basically, you can do some cool, weird shit with "replay" mechanics, while still keeping it deterministic.
Helvecta wrote: So, hypothetically speaking, let's say I use a RNG to fetch 3 random numbers, with the following seeds: 1, 2, and 3. For the sake of the example, the returned numbers will be 3, 6, and 1. Then, I try to use the same RNG to fetch 3 random numbers again, with the seeds being 2, 3, and 4. Would I get completely different random numbers? Or would I get 6, 1, and a new random number?
The latter, see below.
Helvecta wrote:it seem[s] like the seed is the insertion point in a list of numbers
[...]
Robin even specifically stated that I shouldn't be setting the seed inside of the function (and testing it myself has confirmed it):
[...]
If the seed is an insertion point like I figure it is, why is it bad to change it wherever you want?
Because you're resetting the position! It's like you're rewinding your movie, and complaining you always see the same scene.
Imagine the random numbers being a cycle like this:

Code: Select all

seed
|
\/
a -----> b
^        |
|        |
|        \/
d<------ c
This is a reasonable approximation of how it really works (except the cycle is so long, it's practically infinite). You ask for a number with the seed producing this cycle, and you get 'a', then you ask for one again, get 'b', then 'c', then 'd' and then 'a' again. What you're doing is you're getting 'a', then telling it to use the same seed (start at the same point), and then you get 'a' again.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Another Question About 0.9's RNG

Post by Robin »

An important detail I think you're missing, Helvecta, is that asking for a random number changes the seed (which is why you don't mess with the seed). The PRNG is written such that the next seed will produce an unpredictable number next.

A PRNG generally works like this:

Code: Select all

local hiddenSeed = 0

function seed(seednr)
    hiddenSeed = seednr
end

function getrandomnumber()
    local nr = makeNumberBasedOnSeed(hiddenSeed) -- depends on specific PRNG
    hiddenSeed = makeNewSeedBasedOnSeed(hiddenSeed) -- depends on specific PRNG
    return nr
end
With a good PRNG, the function makeNewSeedBasedOnSeed makes sure that the sequence of seeds produced (and thus of the numbers produced) is unpredictable. But if you keep seeding, you never let it finish the sequence, like bartbes showed in his ASCII diagram.
Help us help you: attach a .love.
User avatar
Helvecta
Party member
Posts: 167
Joined: Wed Sep 26, 2012 6:35 pm

Re: Another Question About 0.9's RNG

Post by Helvecta »

bartbes wrote:it might be interesting to store the random seed at any point you can (or do) diverge, that way you can faithfully rewind and start again.
So, like if your character were to die, you could reload from the beginning and use that seed to regenerate the world as it was when you saved (assuming that the world was originally generated using the same seed)? Or is replicable randomness not possible this way?
bartbes wrote:Because you're resetting the position! It's like you're rewinding your movie, and complaining you always see the same scene.
Robin wrote:An important detail I think you're missing, Helvecta, is that asking for a random number changes the seed (which is why you don't mess with the seed). The PRNG is written such that the next seed will produce an unpredictable number next.
OH. So it's not my responsibility to change the seed; LOVE chooses a random one for me. I think realizing this brings everything full circle, many thanks! :nyu:
"Bump." -CMFIend420
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Another Question About 0.9's RNG

Post by bartbes »

Helvecta wrote:is replicable randomness not possible this way?
That's exactly what it's about.
User avatar
Helvecta
Party member
Posts: 167
Joined: Wed Sep 26, 2012 6:35 pm

Re: Another Question About 0.9's RNG

Post by Helvecta »

I guess the concept goes over my head; oh well :oops:
"Bump." -CMFIend420
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Imnotaplayer and 0 guests