Tile_map.set_cells_terrain_connect not working as expected

Godot Version

4.3.dev3

Question

I have a wang terrain set with this bitmask:

image

When I paint this terrain onto the TileMap it works just as expected.

Godot_v4.3-dev3_win64_gh0GtNbgIY

But when I try to achieve the same result using tile_map.set_cells_terrain_connect it does not work.
For some reason, I have to include the neighbor cells to get the same result as in the editor.

func _generate():
	tile_map.clear()
	
	var cells := {}
	
	for x in 10:
		cells[Vector2i(x, 0)] = null
	
	tile_map.set_cells_terrain_connect(0, cells.keys(), 0, 0) # nothing happens
func _generate():
	tile_map.clear()
	
	const NEIGHBORS := [
		Vector2i.LEFT,
		Vector2i.RIGHT,
		Vector2i.UP,
		Vector2i.DOWN,
		Vector2i(-1, -1),
		Vector2i(-1, 1),
		Vector2i(1, -1),
		Vector2i(1, 1)
	]
	
	var cells := {}
	
	for x in 10:
		cells[Vector2i(x, 0)] = null
		
		for neighbor in NEIGHBORS:
			cells[Vector2i(x, 0) + neighbor] = null
	
	tile_map.set_cells_terrain_connect(0, cells.keys(), 0, 0) # the tiles get drawn

It gets really funky when I try to add cells in the y direction. The code below leads to this tilemap.
I have no clue where the tile in the red rectangle comes from.

func _generate():
	tile_map.clear()
	
	const NEIGHBORS := [
		Vector2i.LEFT,
		Vector2i.RIGHT,
		Vector2i.UP,
		Vector2i.DOWN,
		Vector2i(-1, -1),
		Vector2i(-1, 1),
		Vector2i(1, -1),
		Vector2i(1, 1)
	]
	
	var cells := {}
	
	for x in 10:
		cells[Vector2i(x, 0)] = null
		
		for neighbor in NEIGHBORS:
			cells[Vector2i(x, 0) + neighbor] = null
	
	for y in 10:
		cells[Vector2i(0, y)] = null
		
		for neighbor in NEIGHBORS:
			cells[Vector2i(0, y) + neighbor] = null
	
	
	tile_map.set_cells_terrain_connect(0, cells.keys(), 0, 0)

I have tried using both dictionaries and arrays for this. Neither work for the terrain set. The code is correct though. When I use this code it works as expected.

for cell in cells:
	tile_map.set_cell(1, cell, 0, Vector2i(1, 1))

Is there something wrong with my bitmask or what am I missing here?

The first one likely is intended behaviour, since it makes tile setting via code a lot more predictable.

For the second problem your code really doesnt seem to be the problem, so Id guess the terrain connect is faulty.
You already have a method that works, so use it ig?
Performance wise it doesnt really matter

1 Like

Sorry, I forgot to clarify.I’m working on a procedural level generator, so I need to place the tiles through code…

Yes, placing the tiles through code is what I had in mind, Im referring to simply using

for cell in cells:
	tile_map.set_cell(1, cell, 0, Vector2i(1, 1))

instead of

tile_map.set_cells_terrain_connect(0, cells.keys(), 0, 0)

since that apparently works?

1 Like

Unfortunately, that’s not an option, I need the tiles to connect automatically

Assigning the center bits to the terrain should help (explanation here).

However, autotiling in Godot 4 is not very accurate and so it is not intended to be used at runtime (see Refactor Terrain Tile Matching Algorithm for Accuracy and Determinism · Issue #7670 · godotengine/godot-proposals · GitHub). My plugin Terrain Autotiler will place tiles accurately if that’s all you need. But I recommend Better Terrain as an autotiling replacement as it has more features and frequent updates.

2 Likes

It’s very sad to hear that autotiling in Godot 4 is not intended to be used at runtime. Your plugin looks great! I really like the additional clarity you provide when painting the tilemap. I have experimented with BetterTerrain before and I’ll go with that. Thank you very much for your help!

1 Like