# Lua math.random problem

Hi guys, the game that I working on is creating blocks with position of x in some range. But I realized that on the start of the game it always pick the same value like every time it picks 320. What is the problem or how can I fix it?

You have to use math.randomseed before math.random

4 Likes

Also should always discard first few random values as the first few will always be the same due to some C thing

math.random();math.random();math.random();math.random();

I prefer to use https://github.com/subsoap/defrng/blob/master/defrng/mt.lua for random numbers

4 Likes

Is that a lua or a defold thing, because that is really annoying.

If youâ€™re talking about needing to clear the first few bad RNG itâ€™s a Lua thing. Using MT avoids the issue.

1 Like

Itâ€™s not really a defold or a lua thing, it is a computer thing. You should read more about it, because itâ€™s really interesting*

*well i think itâ€™s quite interesting

7 Likes

Thanks for reference, I am currently using it. However there is another problem

``````function init(self)
self.last_pos = 100
create(self, "#diamond-factory")
end

function create(self, fac)
local pos = vmath.vector3()
pos.y = 480
local random_x = m.random(50, 590)
while self.last_pos >= random_x - 100 or self.last_pos <= random_x + 100 do
random_x = m.random(50, 590)
end
self.last_pos = random_x
local pos_of_ball = go.get_position("/ball")
pos.x = random_x
factory.create(fac, pos)
end
``````

I am using this script to pick values of long distance. If the position of the last one is between â€śprev_x - 100 and prev_x + 100â€ť then it should pick new value until it is OK. But the game crashes because of infinite loop. What is the problem ? Or how can I fix it? Any idea?

So, we start with `self.last_pos == 100`, so letâ€™s figure out what values of `random_x` get us out of the loop.

• `self.last_pos >= random_x - 100` is `false` when `random_x >= 201`
• `self.last_pos <= random_x + 100` is `false` when `random_x < 0`

Since `random_x` canâ€™t be less than `50`, it will never be less than `0`, so your `while` loop will never exit.

2 Likes

Why loop like that? Canâ€™t you pass in the correct min and max values to math.random()?

1 Like

There is a ball which is moving from left to right and right to left all the game time, so when the ball reaches a block, then the next block must be far away from ballâ€™s position on the reach point. I donâ€™t know if it is clear

I gave different values to self.last_pos but same result

Sorry for flood but I solved the problem, It was my mistakeâ€¦

``````	while random_x >= self.last_pos - 200 and random_x <= self.last_pos + 200 do
random_x = m.random(50, 590)
end
``````

This worked fine while self.last_pos is initially 320. Then the random_x value should be between 120 and 520. So thanks for ideas

1 Like

Since youâ€™re trying to ensure the delta (difference) between two objects is â€ślarge enoughâ€ť you should rewrite the conditional to make that clear, like:

``````repeat
random_x = math.random(50, 590)
until math.abs(self.last_pos - random_x) >= 200
``````

Thatâ€™s far easier to understand: keep generating a random number until the delta between the random and the `self.last_pos` is more than `200`.

3 Likes

I am going to remember that bit of code. it is handy!

@Pkeod thanks for the link! this module should really be included in Defold, the default math.random is very annoying due to this math.randomseed(os.clock()*100000000000) and even with that from my test the module from your link works a lot better out of box!

1 Like

What are you doing to that poor seed?

Use math.randomseed(socket.gettime()) and optionally throw away the first random value.

1 Like

@britzl maybe â€śmath.randomseed(socket.gettime())â€ť works fine when I need to pick a number from the big range, but for my example, I just tested it, when I have 3 elements array (table) and I need to pick 1 random element from this array 3 times - one after another (my case is I just instantiate 3 objects but the object can have 3 different sprites and in init() of the object I assign one of the spites randomly) - â€śmath.randomseed(socket.gettime())â€ť works really bad unfortunately, basically almost always picking the same value for all 3 object (calls). When I use math.randomseed(os.clock()*100000000000) - this works better but the linked library - works perfectly out of box without any additional linesâ€¦

I noticed that the default math.random works really bad when I need to pick a random element from some small array (small range of numbers math.random(1,3) for example) without this â€śos.clock()*100000000000â€ť madness , so basically analogue to https://docs.yoyogames.com/source/dadiospice/002_reference/maths/real%20valued%20functions/choose.html which works excellent in GMS 2â€¦

Ah, I see. Well, hmm, if you throw away the first one or two random numbers you start to get the kind of variation that is to be expected:

``````-- os.time() seems to work equally well
math.randomseed(socket.gettime()) math.random() math.random()
print(math.random(1,3))
``````

Not optimal. Perhaps we can deal with this better internally in the engineâ€¦

1 Like

exactly, it is a bit hacky, and given the number of questions on the forum about â€śRandom does not workâ€ť I believe this is the problem which must be addressed given the fact how often random functionality needed in game development.

Here are some illustrations of â€śbad rngâ€ť drawing 4 colors randomly on a canvas I made a few years ago. I think the method was pick a random x,y and pick a random one of the 4 colors based on the RNG methods. So after a few seconds the patterns would emerge.

And â€śbetter rngâ€ť

8 Likes