How to make the cloned scenes not overlap

A common approach in procedurally generated games is to find local maximas or peaks in your noise data. Currently you are using randf_range many times, but using a FastNoiseLite allows you to sample noise.

Here’s a slide deck on finding peaks in 1d and 2d datasets.

The idea is given a noise texture, like the one below; we sample any point on it, is that point brighter than it’s neighbors? If so, we place a tree.

In Godot I’ve plotted coins on top of local maximas, they are fairly uniformly distributed. Though I can’t control exactly how many are spawned, editing the noise’s frequency can create a dense forest, or sparse plains. Similarly the trees will be at least SAMPLE_STEP pixels away from each other.

This was generated using a very naive approach that should be optimized for much larger scenes, but even with your 5000 square range it’s quick enough for one generation.

@export var noise: Noise

const SAMPLE_STEP = 12.0
const MIN_SIZE = 0
const MAX_SIZE = 5000

func _ready() -> void:
	for y in range(MIN_SIZE, MAX_SIZE, SAMPLE_STEP):
		for x in range(MIN_SIZE, MAX_SIZE, SAMPLE_STEP):
			var sample: float = noise.get_noise_2d(x, y)
			if sample < 0.01: # skip low-value samples, set higher for clumping trees
				continue

			var neighbor_top: float = noise.get_noise_2d(x, y - SAMPLE_STEP)
			var neighbor_bot: float = noise.get_noise_2d(x, y + SAMPLE_STEP)
			var neighbor_left: float = noise.get_noise_2d(x - SAMPLE_STEP, y)
			var neighbor_right: float = noise.get_noise_2d(x + SAMPLE_STEP, y)
			if sample > neighbor_top and\
				sample > neighbor_bot and\
				sample > neighbor_left and\
				sample > neighbor_right:
				make_coin(Vector2(x,y))