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