Help with optymizing a tree , grass etc spawner

Godot Version

Godot 4.5.1

Question

Hello so i am creating a survival horror game and i tried to make an object spawner in my world , so i dont have to place every tree , stick , rock , grass etc . But i have a big problem with it , at a certain amount of sticks/trees or even grass the game just wont start , i figured it is a problem with the spawner and i tried looking at how to make it more optimized but i just cant figure it out.
I also tried to make a grass scene but as i said im not sure how to make it so it works , i tried using just an animatedSprite2d but it still wont work
the world code:

extends Node2D

class_name World
@onready var spawn = $environment
var positions: Array = []
var rect
var player
var tree_amount: int = 117
var rock_amount: int = 30
var bush_amount: int = 200
var berrybush_amount: int = 50
var bunny_amount: int = 5
var spawned_tree_positions:Array = []
var close: bool = false
var stick_amount: int = 70
var deer_amount: int = 3
func _ready():
	player = get_tree().get_first_node_in_group("Player")
	rect = $TileMapLayer.get_used_rect()
	for i in tree_amount:
		call_deferred("spawner", preload("res://World/tree.tscn"), 100)
	for i in rock_amount:
		call_deferred("spawner", preload("res://World/objects/rock.tscn"), 10)
	for i in bush_amount:
		call_deferred("spawner", preload("res://World/objects/bush.tscn"), 40)
	for i in berrybush_amount:
		call_deferred("spawner", preload("res://World/objects/berry_bush.tscn"), 40)
	for i  in bunny_amount:
		call_deferred("spawner", preload("res://animals/bunny.tscn"), 5)
	for i  in stick_amount:
		call_deferred("stick_spawner")
	for i in deer_amount:
		call_deferred("spawner", preload("res://animals/deer.tscn"), 50)
func spawner(spawnable_scene, min_dist):
	var x = randi_range(rect.position.x, rect.position.x + rect.size.x - 1)
	var y = randi_range(rect.position.y, rect.position.y + rect.size.y - 1)
	var world_pos = $TileMapLayer.map_to_local(Vector2i(x, y))
	var spawnable_instance = spawnable_scene.instantiate()
	spawnable_instance.global_position = world_pos
	var can_spawn := true

	for exist_pos in positions:
		if exist_pos.distance_to(world_pos) < min_dist:
			can_spawn = false
			break

	if can_spawn:
		spawn.add_child(spawnable_instance)
		positions.append(world_pos)
		if spawnable_instance.is_in_group("tree"):
			spawned_tree_positions.append(world_pos)

	else:
		call_deferred("spawner", spawnable_scene, min_dist)
		
	
func place_item(placed_item):
	var dir = get_global_mouse_position()
	var mousedistance = player.global_position.distance_to(dir)
	if mousedistance > 100:
		print("i can't place it that far!")
	else:
		var item_instance = placed_item.instantiate()
		item_instance.global_position = dir
		get_parent().add_child(item_instance)
func stick_spawner():
	var x = randi_range(rect.position.x, rect.position.x + rect.size.x - 1)
	var y = randi_range(rect.position.y, rect.position.y + rect.size.y - 1)
	var pos = $TileMapLayer.map_to_local(Vector2i(x, y))
	var stick_scene = load("res://World/objects/stick.tscn")
	var stick_instance = stick_scene.instantiate()
	stick_instance.global_position = pos
	var near_tree := false
	for tree_pos in spawned_tree_positions:
		if tree_pos.distance_to(pos) < 150:
			near_tree = true
			break

	if near_tree:
		spawn.add_child(stick_instance)
	else:
		call_deferred("stick_spawner")

the grass scene:

and the tree scene:

thanks in advance for any help!

nvm guys i got it , it was the else statement that reused the whole spawner function all over

2 Likes