TileMapLayer not updating certain terrain cells after using erase_cell() at runtime

Godot Version

v4.3.beta3.official [82cedc83c]

Question

When I place terrain using the terrain painter in “connect mode” while in the editor, all of my walls place and remove properly while updating neighboring tiles. However, when using a code solution at runtime, certain tiles are not updated properly when erasing a cell.

Only the top and left neighbor tiles are affected, and only under specific tile circumstances. Adding a tile always works as intended.

Here’s a video of the issue: https://i.imgur.com/axDT6UA.mp4 (can’t upload as I’m a new user)

The terrain painting on the pertinent tileset:

The placement and removal functions:

func PlaceWall(): # Called when left click is held
	var tileMousePos := wallTiles.local_to_map(get_global_mouse_position()) as Vector2i
	var tileData := wallTiles.get_cell_tile_data(tileMousePos) as TileData
	
	if !tileData:
		wallTiles.set_cell(tileMousePos, 1, Vector2i(0,0))
		wallTiles.set_cells_terrain_connect([tileMousePos], 0, 0, false)


func EraseWall(): # Called when right click is held
	var tileMousePos := wallTiles.local_to_map(get_global_mouse_position()) as Vector2i
	var tileData := wallTiles.get_cell_tile_data(tileMousePos) as TileData
	
	if tileData:
		var surroundingCells := wallTiles.get_surrounding_cells(tileMousePos) as Array
		
		wallTiles.erase_cell(tileMousePos)
		#wallTiles.update_internals() # Didn't affect anything
		#wallTiles.notify_runtime_tile_data_update() # Also nothing
		
		for cellPos in surroundingCells:
			if wallTiles.get_cell_tile_data(cellPos):
				wallTiles.set_cells_terrain_connect([cellPos], 0, 0, false)

I’ve read that the TileMapLayer feature is still a bit buggy when used at runtime, so I’m hoping that the issue is just an easy mistake on my part.

If any more info is needed I’m happy to provide it, thanks!

1 Like

A simple workaround that I’ve found is to call .erase_cell() then .set_cell() on each filled cell returned by .get_surrounding_cells() in my EraseWall function. It feels hacky, but terrain connections now function as expected.

(I won’t mark this as the solution as I don’t believe it to be intended)

In case anybody stumbles upon this post later on, I have figured out the solution. erase_cell() and set_cell() both share functionality with set_cells_terrain_connect(), so you only need the latter assuming you require terrain connections.

For now I’m setting the terrain parameter (the third argument within set_cells_terrain_connect()) to -1 for cell deletion, which doesn’t seem to have any unintended issues thus far.