Infinite map tree problem

Newest version

My game uses a chunk system, when it unloads and loads a chunk, if a tree has been cut down on the chunk and then that chunk is unloaded, once its loaded again the tree will be regrown in the place it was cut down

CODE:

extends TileMap

@export var noise = FastNoiseLite.new()
@export var biome_noise = FastNoiseLite.new()
@export var chunk_size : int = 16
@export var player : NodePath
@export var tileset : TileSet
@export var width : int = 10
@export var height : int = 10
@export var shallow_water_Threshold : float = 0.1
@export var water_threshold : float = 0.3
@export var sand_threshold : float = 0.4
@export var grass_threshold : float = 0.6
@export var otherTile : int = 2
@export var grass_tiles : Array = [Vector2i(0, 0), Vector2i(1, 0), Vector2i(2, 0), Vector2i(3, 0)]
@export var high_tiles : Array = [Vector2i(27,0), Vector2i(28,0)]
@export var chunk_delay : int = 0.1
@export var tree : PackedScene
@export var tree_threshold : float = 0.3
@export var tree_chance : float = 0.3
var rng = RandomNumberGenerator.new()
var chunk_pool =
var chunk_trees = {}
var chunks = {}

func _ready():
rng.randomize()
randomize_noise()

func randomize_noise():
noise.seed = rng.randi()
biome_noise.seed = rng.randi()

func generate_chunk(chunk_coords : Vector2i):
if chunk_coords in chunks:
return
var chunk = TileMap.new()
chunk.tile_set = tileset
chunks[chunk_coords] = chunk
add_child(chunk)
chunk.position = chunk_coords * chunk_size * chunk.tile_set.tile_size
chunk_trees[chunk_coords] =

rng.seed = chunk_coords.x * 100000 + chunk_coords.y

for x in range(chunk_size):
for y in range(chunk_size):
var world_x = chunk_coords.x * chunk_size + x
var world_y = chunk_coords.y * chunk_size + y
var noise_value = noise.get_noise_2d(world_x,world_y)
var coords = Vector2i(x,y)
var atlas_coords = map_noise_to_tile_atlast(noise_value)
chunk.set_cell(0, coords, 0, atlas_coords)

  	if noise_value > tree_threshold and rng.randf() < tree_chance:
  		var tree_instance = Create_tree(chunk, coords)
  		if chunk_coords not in chunk_trees:
  			chunk_trees[chunk_coords] = [x]
  		chunk_trees[chunk_coords].append(tree_instance)

func Create_tree(chunk : TileMap, coords : Vector2i):
var tile_pos = chunk.position + Vector2(coords.x, coords.y) * Vector2(tileset.tile_size.x, tileset.tile_size.y)
var tree_instance = tree.instantiate() # Instantiate the tree node
tree_instance.position = tile_pos # Set position of the tree node to the tile position
add_child(tree_instance) # Add the tree

var tree_key = ā€œ%s_%sā€ % [coords.x, coords.y]

return tree_instance

func remove_chunk(chunk_coords: Vector2i):
if chunk_coords in chunks:
# Remove all trees in this chunk
if chunk_coords in chunk_trees:
for tree in chunk_trees[chunk_coords]:
if tree != null:
tree.queue_free()
chunk_trees.erase(chunk_coords)

  # Remove the chunk itself
  chunks[chunk_coords].queue_free()
  chunks.erase(chunk_coords)

func map_noise_to_tile_atlast(value):
var seed = int(value * 1000)

if value < water_threshold:
return Vector2i(29,0)
elif value < shallow_water_Threshold:
return Vector2i(30,0)
elif value < sand_threshold:
return Vector2i(12,0)
elif value < grass_threshold:
var random_index = seed % grass_tiles.size()
return grass_tiles[random_index]
else:
var random_index = seed % high_tiles.size()
return high_tiles[random_index]

func update_chunks():
var player_node = get_node(player)
var player_pos = player_node.position
var tile_size = tileset.tile_size
var player_chunk_coords = Vector2i(floor(player_pos.x / (chunk_size * tile_size.x)), floor(player_pos.y / (chunk_size * tile_size.y)))
var radius = 3 # Number of chunks to keep around the player

Generate new chunks around the player

for x in range(player_chunk_coords.x - radius, player_chunk_coords.x + radius + 1):
for y in range(player_chunk_coords.y - radius, player_chunk_coords.y + radius + 1):
generate_chunk(Vector2i(x, y))

Remove chunks that are too far from the player

var chunks_to_remove =
for chunk_coords in chunks.keys():
if abs(chunk_coords.x - player_chunk_coords.x) > radius or abs(chunk_coords.y - player_chunk_coords.y) > radius:
chunks_to_remove.append(chunk_coords)
for chunk_coords in chunks_to_remove:
remove_chunk(chunk_coords)

func _process(delta):
update_chunks()

Neat, although hard to read without the indenting.