Page 1 of 2

Same randomness between instances of the same class

Posted: Thu Feb 22, 2018 5:12 pm
by scissors61
Hi 2d lovers.
I want to move randomly two identical objects with math.random. the randomness is set by they deciding between 8 possible moves, so I set math.random(1,8) the problem is that for both of this instances the random decisions are the same, so they move the same. I think if I can create a local random or a different random seed for each I could solve the problem, but I haven't found a way to do so. Sorry that I am not presenting any code example,I am very limited right now (writing from a tablet in a starbucks), but I think it's easy to understand the problem also.

Re: Same randomness between instances of the same class

Posted: Thu Feb 22, 2018 5:33 pm
by raidho36
Just don't touch your seed value. Then every time you call random, it'll be different.

PRNGs always produce identical series of numbers given identical seed. Series are fairly long and impossible to memorize so they appear random, and in-game with different number of times this function is called per frame, specific random values will go into different fields, further increasing appearance of randomness. But it will always be the same if you start with the same seed. Hence you can input random map generator seed to get identical map, and you seed it to something unpredictable (like current system time at the start of the game) when you need random outcome.

Computers don't have real random number generators, because by design they double as powerful electric noise generators, which is detrimental to the function of the device. Unix systems have a software device that accumulates entropy from all sources available to it and uses it to generate highly random numbers by feeding bits of entropy into normal PRNG function. But that's still not truly random. You gonna need something like tesla coil to produce noise from which you can pick out truly random values.

Re: Same randomness between instances of the same class

Posted: Thu Feb 22, 2018 7:51 pm
by zorg
scissors61 wrote: Thu Feb 22, 2018 5:12 pmI think if I can create a local random or a different random seed for each I could solve the problem, but I haven't found a way to do so.
Well then, let me help you: love.math.newRandomGenerator
That creates a new, self contained PRNG object, which you can seed, and query, and they don't cross-interact with each other, nor with the global prng state (neither löve's nor lua's, of course)

Re: Same randomness between instances of the same class

Posted: Wed Feb 28, 2018 8:43 pm
by scissors61
raidho36 wrote: Thu Feb 22, 2018 5:33 pm You gonna need something like tesla coil to produce noise from which you can pick out truly random values.
Great, just more steps to attain my goals. But not seeding made the two instances generate the same number, and the same pattern of numbers every time I start the love application. Maybe I misunderstood what you suggested.

zorg. It works, but it seems that adnzzzzZ Timer library cancels the randomness when I tween with it. I made an example with extracts of the code that I am using.

Re: Same randomness between instances of the same class

Posted: Wed Feb 28, 2018 8:59 pm
by zorg
From looking at your code,
1. self.speed is never modified so it always stays at 150
2. the self.timer.every function's second argument, which is an anonymous function, the self.timer:tween function's first value is a constant 3

I'm feeling like one of those would need to be changed for what you might want to accomplish, although i'd be lying if i understood what you want to do completely.

Re: Same randomness between instances of the same class

Posted: Wed Feb 28, 2018 10:47 pm
by scissors61
What I'm trying to do with the anonymous function you mentioned is to randomly change the direction of the object. But when I create more than two objects with Timer's tween the randomness between them is the same.

In other words
self.direction = self.randomness:random(1, 8) is being the same between the objects, and I want them to be different to have several of them as enemies.

The constant 3 is how long it takes to tween the values. Speed is the max number where the tween can reach. Direction changes that, the direction of x and y. It's a physics object and the tweened x and y go as a parameter of body:setLinearVelocity(x, y)

Re: Same randomness between instances of the same class

Posted: Wed Feb 28, 2018 11:18 pm
by pgimeno
You're initializing both generators with the same seed. os.time() typically has 1 second resolution, and even if not, the seed accepted by RandomGenerator:setSeed is an integer, so it will probably be floored. Unless you call the seeding functions with at least 1 second difference, you will most likely see the same values.

Don't have separate generators. Have the same generator for everything. If you need to store it in the instance, initialize it once and copy it to every instance.


Sorry, I didn't look at the code properly. I take that back.

The problem is that you're not creating two different objects, you're creating just one. I made a quick fix like this:

Code: Select all

function RandomEntity:new(seed)
     self = {}
     ...
I'd still suggest you to follow the advice in my second paragraph above (even if I've stricken it through).

Re: Same randomness between instances of the same class

Posted: Thu Mar 01, 2018 7:58 am
by zorg
pgimeno wrote: Wed Feb 28, 2018 11:18 pm Don't have separate generators. Have the same generator for everything. If you need to store it in the instance, initialize it once and copy it to every instance.

I'd still suggest you to follow the advice in my second paragraph above (even if I've stricken it through).
If he doesn't care about determinism, then that can work as well; the usefulness for one PRNG per instance is that the output of them are wholly reproducible, since the objects themselves are the only things that ever call their respective functions and nothing else outside said instances would call them.

Re: Same randomness between instances of the same class

Posted: Fri Mar 02, 2018 10:38 pm
by scissors61
pgimeno wrote: Wed Feb 28, 2018 11:18 pm
The problem is that you're not creating two different objects, you're creating just one. I made a quick fix like this:

Code: Select all

function RandomEntity:new(seed)
     self = {}
     ...

Your solution fixes the problem of the example but in my code still doesn't work because I'm using a personalized mix of OOP/ECS, but I'm trying to understand why.
My ignorance of how Lua works behind the scenes doesn't let me understand why it works now. Does the colon syntax makes a global self and when creating a local one new a different object is created?
Thanks.

Re: Same randomness between instances of the same class

Posted: Fri Mar 02, 2018 10:57 pm
by zorg
The problem is the following:

Code: Select all

local RandomEntity = {}
function RandomEntity:new(seed)
	self.timer = Timer()
--early end because this is enough to demonstrate the issue
end
The colon syntax implicitly adds a first parameter called self to the function definition in question, and when you call such a function, if that happens with the colon syntax as well, (iirc) the last table that contains the function itself will be passed into it as "self";

In your case, your original code did this:

Code: Select all

function love.load()
	random = RandomEntity:new(3)
	random2 = RandomEntity:new(58)
Now, apart from the fact that not even löve's constructors are called by the colon syntax (constructors create instances, not work on them, with the exception of copy constructors; although all this is of course implementation dependent; this isn't c++), you're basically passing in the RandomEntity table as self, in both instances.

pgimeno's fix creates separate instance tables each time, which is assumed in a constructor function; although this also has the secondary effect of now masking the "wrong" behaviour of you calling such a function with the colon syntax in the first case.