Question about weighted random spawning of objects

Godot Version

4.2.1

Question

Hi, I am making a vertical jumper platform game similar to say doodle jump, I have several platforms I want to spawn, currently it spawns 50 per “level” it works well I put all of the platforms in an array and randomize it however often the same platform spawns 2 or 3 times in a row and some are “death” platforms which makes it unplayable I am hoping with weighted randomness I could have better results as I havent found a suitable way that I am able to make sure two of the same dont spawn in a row (lack of skill on my part)

I am trying to use something like this as a weighted random selection in the create platforms function which is then passed to the level generation function however I get that nonexistant function instantiate in base float which i know is because i am trying to instantiate the rand var result incorrectly so I am hoping someone has an idea of where I am going wrong

> func create_platforms(location :Vector2):
> 	#var platforms = platform_array[platforms].instantiate()
> 	var rand = randf_range( 0, 1415)
> 	var platforms = rand.instantitate()
> 	if rand <= weight1:
> 		platforms = platform_scene
> 	elif rand > weight1 && rand < weight3:
> 		platforms = platform_scene_2
> 	elif rand > weight2 && rand < weight4:
> 		platforms = platform_scene_3
> 	elif rand > weight3 && rand < weight5:
> 		platforms = platform_scene_4
> 	elif rand > weight4 && rand < weight6:
> 		platforms = platform_scene_5
> 	elif rand > weight5:
> 		platforms = platform_scene_6
> 		
> 	platforms.global_position = location
> 	platform_parent.add_child(platforms)
> 	return platforms


thank you

Hello,

  • “randf_range” returns a random float between the first number and the second one (which are 0 and 1415 respectively in your code).

  • instantiate() is used to add a scene (let’s say for example a tree.tscn which contains the tree and the leaves) to another scene (that would be called level_1.tscn for example)

You are trying to instantiate a number, this is not how it works.
Let me try something and I’ll get back to you (I hope)

Hi, thanks for the reply
The weights range from 0-1415 which is why I did that. What I want is it to pick a number between those and instantiate the appropriate scene (in this case one of the platforms depending on which number or pulls) right now with the code I had before this it does 50 random platforms from the array of platforms per level which is great but a lot of times it will do two or three of the same in a row which if they are bad ones it makes it unplayable

So maybe I need to switch back to platforms.instantiate since rand should return an associated platform

this doesnt look right, and it’s a typo

One thing you could create an unsigned byte array at the start of the game or level, each byte value equals an index in an array of references to the different platform scenes. When you create that byte array you just put as many of each index (representing each platform scene) as the weight indicates, into that array. So if you had 3 platforms and the weights were 3, 2 and 4 respectively, the array of bytes would be [0,0,0,1,1,2,2,2,2], so then the random choice would pick between those 9 choices. Then you wouldn’t have to do those ifs and elifs each time.

With 4.3 you have RandomNumberGenerator — Godot Engine (latest) documentation in English

This is what I originally did, I had the standard original platform in the array like 5 times and the others 1 or 2 times it works good except that it still spawns like 2-3 of the same “death” platforms in a row very often causing the game to be unplayable figured the weights might work better

Thanks I have read over this a few times, just didn’t see anything to fix the problem. The random isn’t really the issue it’s the spawning of too many of the same one in a row which is why I figured doing proper weights might help

That’s not random though? You’re asking for something that’s not random, that’s a different question, multiple results of the same value are still random, in fact most people think non-random sequences are more random than real randomness because of this misconception

Heads heads heads is just as likely as heads tails heads

even weighted is still rng, just weighted
if you want to make it playable then you might actually want to limit how many of the “death” platform can spawn, and probably add a rule that for the first to tenth there wont be “death” platform
it’s back to how you need to generate the platforms

1 Like

I agree but weeks of searching I haven’t found a suitable way to do it so figured if I could get the weighted rng to work more effectively that may at least help

I’d suggest using some kind of queue to pick from, or alter the weights based on recent spawns, maybe a “credit” or “charge” for each type that’s recharged slowly to balance

Not sure what you are trying to do will get less repetition like that as it’s still truly random, what you could try is do something like how kerning works for fonts, where each letter has a value for how far away the next letter will be, based on the letter that will come after. So with that idea you could make an array of arrays, where if you could weight what comes after each of the previous platforms, so if 0 is the death platform, that array of indices wouldn’t include 0 at all if you don’t want 2 to happen in a row.

1 Like

You can define a list of probabilities based on what was last spawned

Real randomness usually has a lot of repetition. To make a sequence feel random without actually being random, you could do what some Tetris implementations do, where they make a “bag” of one each of all the possible tetris shapes, shuffle the bag, and draw one out for each piece spawn. Then, when the bag is empty, make a new bag and shuffle it. If the new bag starts with the same item as the last item of the previous bag, shuffle the new bag again until it starts with something else.

This algorithm delivers lots of variety, zero consecutive repeats, and feels more random to players than actual randomness. It also ensures that all the different item types will show up regularly, and in equal amounts, even if the game run is fairly short. Players generally consider this type of setup more “fair” than actual randomness.

1 Like