Tilemap layer seems to be deleting and re-adding itself(?)

Godot Version

Godot v4.2.2

Question

calling the method clearSelectIndicator() would vomit out a bug “setTile(): Index p_layer=2 is out of bounds ((int)layers.size() = 1).”

get_layers_count() would alternate from returning 1 and returning 3 every frame (there’s supposed to be 3 layers).

idk how layers are getting deleted and/or added on its own

extends TileMap

var mapSize = 8
var tileDic = {}
var selectSize = 1
var selectedCoords : Array[Vector2i] = []
var mouseMapPos = Vector2(0, 0)
const tileData = {
	"grass_1" :{
		"name" : "grass_1",
		"placable" : true,
		"atlasPos" :  [0, Vector2i(4, 2)],
		"size" : Vector2i(1, 1)
	},
	"grass_2" :{
		"name" : "grass_2",
		"placable" : true,
		"atlasPos" :  [0, Vector2i(3, 2)],
		"size" : Vector2i(1, 1)
	},
	"selected" :{
		"name" : "selected",
		"placable" : true,
		"atlasPos" :  [0, Vector2i(5, 2)],
		"size" : Vector2i(1, 1)
	},
	"selected_2" :{
		"name" : "selected",
		"placable" : true,
		"atlasPos" :  [0, Vector2i(5, 3)],
		"size" : Vector2i(2, 2)
	},
	"obstacle" :{
		"name" : "obstacle",
		"placable" : false,
		"atlasPos" :  [0, Vector2i(2, 2)],
		"size" : Vector2i(1, 1),
		"scenePath" : "res://scenes/tileScenes/rock.tscn"
	},
	"big_tree" :{
		"name" : "big_tree",
		"placable" : false,
		"atlasPos" : [0, Vector2i(3, 3)],
		"size" : Vector2i(2, 2),
		"scenePath" : "res://scenes/tileScenes/big_tree.tscn"
	}
}
const selectDic = {
	1 : "selected",
	2 : "selected_2"
}

@export var genGrass : bool = true
@export var genObstacle : bool
func _ready():
	if genGrass: generateGrass()
	if genObstacle: generateObstacles()
	print(tileDic)

func _process(_delta):
	mouseMapPos = local_to_map(get_global_mouse_position())
	clearSelectIndicator()
	
	print(get_layers_count())
	
	if Input.is_action_just_pressed("lmb"):
		print(mouseMapPos)
	
	if Input.is_action_just_pressed("rmb"):
		clearTile(1, mouseMapPos)
	
	if Input.is_action_just_pressed("debug") and selectSize == 2:
		createTile(1, mouseMapPos, "big_tree")
	
	if Input.is_action_just_pressed("size_1"):
		selectSize = 1
	
	if Input.is_action_just_pressed("size_2"):
		selectSize = 2
	
	setSelected()
	pass

func clearSelectIndicator():
	for x in mapSize:
		for y in mapSize:
			if get_cell_tile_data(2, Vector2(x, y)) != null:
				erase_cell(2, Vector2i(x, y))

func setTile(layer: int, mapCoords : Vector2 , tileName : String, ignoreCheck = false):
	"""
	Instantiates a grid object without a packaged scene
	"""
	var data = tileData[tileName]
	var xBounds = mapCoords.x + data["size"].x
	var yBounds = mapCoords.y + data["size"].y
	
	if not ignoreCheck:
		if str(Vector2(mapCoords)) not in tileDic.keys():
			return
		if not selectedisPlacable():
			return
	
	# Sets cell
	set_cell(layer, mapCoords, data["atlasPos"][0], data["atlasPos"][1])
	for x in range(mapCoords.x, xBounds):
		for y in range(mapCoords.y, yBounds):
			tileDic[str(Vector2(x, y))] = {
				"name" : data["name"],
				"placable" : data["placable"],
				"atlasPos" : data["atlasPos"],
				"size" : data["size"]
			}
			tileDic[str(Vector2(x, y))]["localCoords"] = Vector2(x - mapCoords.x, y - mapCoords.y)
	return

func createTile(layer: int, mapCoords : Vector2 , tileName : String, ignoreCheck = false):
	"""
	Instantiates a grid object with its packaged scene
	"""
	var data = tileData[tileName]
	var xBounds = mapCoords.x + data["size"].x
	var yBounds = mapCoords.y + data["size"].y
	
	if not ignoreCheck:
		if str(Vector2(mapCoords)) not in tileDic.keys():
			return
		if not selectedisPlacable():
			return
	
	# Sets cell
	set_cell(layer, mapCoords, data["atlasPos"][0], data["atlasPos"][1])
	for x in range(mapCoords.x, xBounds):
		for y in range(mapCoords.y, yBounds):
			tileDic[str(Vector2(x, y))] = {
				"name" : data["name"],
				"placable" : data["placable"],
				"atlasPos" : data["atlasPos"],
				"size" : data["size"]
			}
			tileDic[str(Vector2(x, y))]["localCoords"] = Vector2(x - mapCoords.x, y - mapCoords.y)
	
	# Instantiates packaged scene
	var path : PackedScene = load(data["scenePath"])
	var instance = path.instantiate()
	get_parent().add_child.call_deferred(instance)
	instance.global_position =  to_global(map_to_local(mapCoords))
	return

func clearTile(layer: int, coords:Vector2):
	var xBounds = coords.x + selectSize
	var yBounds = coords.y + selectSize
	for x in range(coords.x, xBounds):
		for y in range(coords.y, yBounds):
			erase_cell(layer, Vector2i(x, y))

func selectedisPlacable() -> bool:
	var xBounds = mouseMapPos.x + selectSize
	var yBounds = mouseMapPos.y + selectSize
	for x in range(mouseMapPos.x, xBounds):
		for y in range(mouseMapPos.y, yBounds):
			if not str(Vector2(x, y)) in tileDic.keys() or not tileDic[str(Vector2(x, y))]["placable"]:
				return false
	return true

var prev : bool
func setSelected():
	if selectedisPlacable() != prev:
		print(selectedisPlacable())
	if selectedisPlacable():
		setTile(2, mouseMapPos, selectDic[selectSize], true)
	prev = selectedisPlacable()
	return

func generateGrass():
	const grassVariants = ["grass_1", "grass_2"]
	for x in mapSize:
		for y in mapSize:
			setTile(0, Vector2(x, y), grassVariants.pick_random(), true)

func generateObstacles():
	for x in mapSize:
		for y in mapSize:
			var rng = RandomNumberGenerator.new()
			var value = rng.randf_range(0.0, 1.0)
			if value >= 0.8:
				createTile(1, Vector2(x, y), "obstacle", true)