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
Helvecta
Party member
Posts: 167
Joined: Wed Sep 26, 2012 6:35 pm

Another Question About 0.9's RNG

Post by Helvecta »

I'm checking out some of the features for 0.9 and the RNG doesn't want to play nice. Running the following (the wiki's example and an assertion to check the outcome) always returns "9". Since this is the wiki's example, I figure it should be more... random.

Code: Select all

function love.load()
    rng = love.math.newRandomGenerator()
    rng:setSeed(os.time())
    randomNumber = rng:random(1,100)
    assert(nil, randomNumber)
end
Can someone lay the knowledge smackdown on me? Thanks.
"Bump." -CMFIend420
User avatar
slime
Solid Snayke
Posts: 3132
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Another Question About 0.9's RNG

Post by slime »

Does this give something more random?

Code: Select all

function love.load()
    rng = love.math.newRandomGenerator()
    rng:setSeed(os.time())
    rng:random()
    randomNumber = rng:random(1,100)
    assert(nil, randomNumber)
end
Or maybe this:

Code: Select all

function love.load()
    rng = love.math.newRandomGenerator()
    rng:setSeed(tonumber(tostring(os.time()):reverse()))
    randomNumber = rng:random(1,100)
    assert(nil, randomNumber)
end
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 »

What on Earth..

Your first example runs like clockwork in reverse, decrementing by one every time I run it (I set the RNG to output a number between 1 and 10 and run the file roughly once a second); the second one only gives numbers between 1 and 6 when set up the same way, and seems to increment by one each time I run it. I suppose that's since the seed is based on os.time(), and I'm starting the application roughly once every second, but the random number shouldn't be incrementing by one just because os.time() is incrementing by one.. right!?

Output, first example:

Code: Select all

8, 8, 7, 6, 5, 4, 3
Output, second example:

Code: Select all

1, 2, 3, 4, 5, 6, 1
"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 »

Unfortunately the algorithm used (xorshift) produces very similar initial results for similar seeds, they should diverge, though.
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 »

Oh, alright; I suppose needing an RNG within the first couple seconds of an app's execution does seem unlikely, so I can live with that.

But what about this function?

Code: Select all

function Random(min, max, isFractional)
	local gen = love.math.newRandomGenerator()
	gen:setSeed(os.time())
	local isFractional = isFractional or false
	local randomNumber
	if isFractional == true then
		randomNumber = gen:random(min * 100, max * 100) / 100		-- math random doesn't play nice with decimals..
	else
		randomNumber = gen:random(min, max)
	end
	assert(nil, randomNumber) -- some debug junk
	return randomNumber
end
the purpose of the function is to return a random number, but with support for decimals (maybe I'm wrong but playing with random suggests that it doesn't do decimals).

However, everytime I call the function,

Code: Select all

Random(- 5, 5, true)
the assertion returns -4.2, every time. Every time!


Something's funky here, but what? And why? :o:
Last edited by Helvecta on Fri Dec 20, 2013 3:23 pm, edited 3 times in total.
"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 »

Well, you're seeding too much, mostly.
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 thought that :setSeed was necessary when setting up the RNG but reading other stuff is agreeing with what you're advising. I guess by now you're figuring out that I'm not familiar with what makes an RNG less predictable. :crazy:

Okay, so I need to reseed less, but I have nowhere else to set the seed since the RNG it's effecting is local and called in the function, so I'll just get rid of that line (removed: gen:setSeed(os.time())). Doing this has little effect; the RNG just spits out -0.26 at this point.

So looking back at Slime's post, I decide I should try to emulate it and generate a random number before I generate a random number (added: gen:random()), making the RNG spit out 3.35. Setting the seed again (added: gen:setSeed(os.time())) makes the number change each time, but it follows a predictable time-based pattern, running backwards from 5 to -5 (code below)

Code: Select all

function Random(min, max, isFractional)
   local gen = love.math.newRandomGenerator()
   gen:setSeed(os.time())
   gen:random()
   local isFractional = isFractional or false
   local randomNumber
   if isFractional == true then
      randomNumber = gen:random(min * 100, max * 100) / 100      -- math random doesn't play nice with decimals..
   else
      randomNumber = gen:random(min, max)
   end
   assert(nil, randomNumber) -- some debug junk
   return randomNumber
end
Why does it refuse to be random? :brows:
"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 »

So why does that RandomNumberGenerator need to be created there? You can create it elsewhere, or use the global one (love.math.random), that means you don't have to seed for every result.
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 »

A function that returns or uses a pseudo-random number should not mess with the seed. You could do something like this:

Code: Select all

local gen = love.math.newRandomGenerator()
gen:setSeed(os.time())
gen:random()

function Random(min, max, isFractional)
   local randomNumber
   if isFractional then
      randomNumber = gen:random(min * 100, max * 100) / 100      -- math random doesn't play nice with decimals..
   else
      randomNumber = gen:random(min, max)
   end
   assert(nil, randomNumber) -- some debug junk
   return randomNumber
end
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:love.math.random
Oh, that's perfect, thanks for throwing that my way, I didn't know that existed.
That begs the question though: why does all this stuff about RandomGenerators even exist if the same can be done with love.math.random? Is it because of the control over the generator's seed? I guess so that you could replicate seemingly random numbers if you needed to?
Robin wrote:A function that returns or uses a pseudo-random number should not mess with the seed.
I'll keep that in mind, thanks! I tested out the example you posted in LOVE though and it still seems to generate a number "like clockwork". Maybe it's because of the way I'm testing it, but I don't think that should matter.
I recorded a video of it, too, to show you what I'm doing.


Figuring out what differentiates this from love.math.random - and figuring out how to actually make RandomGenerator work - would help me a ton, so any info clearing this up would be appreciated. ^^
"Bump." -CMFIend420
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 212 guests