Another Question About 0.9's RNG
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
- 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
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.
Re: Another Question About 0.9's RNG
Aha! Gotcha. So for most purposes love.math.random will suffice.
Thanks for all the help, everyone. It's much appreciated!
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!Helvecta wrote:Maybe it's because of the way I'm testing it, but I don't think that should matter.
Thanks for all the help, everyone. It's much appreciated!
"Bump." -CMFIend420
- Hexenhammer
- Party member
- Posts: 175
- Joined: Sun Feb 17, 2013 8:19 am
Re: Another Question About 0.9's RNG
Try this:
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
..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.
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)
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)
- slime
- Solid Snayke
- Posts: 3170
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: Another Question About 0.9's RNG
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.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.
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.
Re: Another Question About 0.9's RNG
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.bartbes wrote:You could even do awesome things like forking and then choosing one of the forks.
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."Hexenhammer wrote:..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.Code: Select all
math.randomseed(os.time()) randomNumber = math.random(1,100)
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.
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?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.
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):
If the seed is an insertion point like I figure it is, why is it bad to change it wherever you want?Robin wrote:A function that returns or uses a pseudo-random number should not mess with the seed.
MY MIND IS IMPLODING.
- Attachments
-
- random.love
- (447 Bytes) Downloaded 104 times
"Bump." -CMFIend420
- 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
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:would you mind giving an example of what you mean by this?bartbes wrote:You could even do awesome things like forking and then choosing one of the forks.
The latter, see below.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?
Because you're resetting the position! It's like you're rewinding your movie, and complaining you always see the same scene.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?
Imagine the random numbers being a cycle like this:
Code: Select all
seed
|
\/
a -----> b
^ |
| |
| \/
d<------ c
- 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
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:
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.
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
Help us help you: attach a .love.
Re: Another Question About 0.9's RNG
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: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.
bartbes wrote:Because you're resetting the position! It's like you're rewinding your movie, and complaining you always see the same scene.
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!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.
"Bump." -CMFIend420
- 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
That's exactly what it's about.Helvecta wrote:is replicable randomness not possible this way?
Re: Another Question About 0.9's RNG
I guess the concept goes over my head; oh well
"Bump." -CMFIend420
Who is online
Users browsing this forum: No registered users and 5 guests