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
More info here


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


I prefer to use for random numbers


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

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


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

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

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)
	self.last_pos = random_x
	local pos_of_ball = go.get_position("/ball")
	pos.x = random_x
	factory.create(fac, pos)

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.


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 :frowning:

I gave different values to self.last_pos but same result :frowning:

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)

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 :slight_smile:

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:

    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.


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 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()

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.

2018-10-27%2002_20_38-exp 2018-10-27%2002_19_50-exp

And “better rng”

2018-10-27%2002_21_45-exp 2018-10-27%2002_21_32-exp