unexpected get_cell_tile_data() behaviour

Godot Version

4.4.1

Im having difficulty understanding the way get_cell_tile_data() works

The current code yields a grid with tiles of same colour

TileMapLayer is a hex grid

Code below is directly attached to the TileMapLayer node

initiation code:

	for x in 10:
		TileData_real.append([])
		for y in 10:
			var tile = _maketile( Vector2i(x,y), map_to_local(Vector2i(x,y)) )
			set_cell(Vector2i(x,y), 0, Vector2i(0,0))
			_setcolour( tile, Vector2i(x,y) )
			TileData_real[x].append(tile)

the bit of code from the “_setcolour()” function not behaving as expected:

	var tile_onmap = get_cell_tile_data(map_pos)
	print(map_pos)
	print(tile_onmap)

console output:

(0, 0)
<TileData#30836524382>
(0, 1)
<TileData#30836524382>
(0, 2)
<TileData#30836524382>
(0, 3)
<TileData#30836524382>
(0, 4)
<TileData#30836524382>
[...]

You can see what that is in the TileData docs. You should be able to play with tile_onmap.modulate and the like, though I expect it will change every cell on the map that uses that tile.

What are you hoping to make this do?

I have already read the tilemaplayer and tiledata docs

image below is a result of the current code:

You’re setting all the cells to the tile at (0, 0). If you modify that tile, it will modify it every place it shows up in the tilemap. If you want different colors, you need to use different tiles.

how can i achieve this effect with thousands of colours?

That depends. What effect are you trying to achieve? Are you basically making an image except with tiles for pixels?

This is what the previous code did, it was based off of signals and a singular object tile

You could try setting the modulate property on the tile in your init loop.

func _ready() -> void:
	var TileData_real = []
	for x in 100:
		TileData_real.append([])
		for y in 144:
			var tile = _maketile( Vector2i(x,y), map_to_local(Vector2i(x,y)) )
			set_cell(Vector2i(x,y), 0, Vector2i(0,0))
			_setcolour( tile, Vector2i(x,y) )
			TileData_real[x].append(tile)

func _setcolour(tile: WorldTile, map_pos: Vector2i) -> void:
	#
	#long code that sets colourfinal from values in tile var
	#
	var tile_onmap = get_cell_tile_data(map_pos)
	print(map_pos)
	print(tile_onmap)
	tile_onmap.modulate = colourfinal

This is the current and only code responsible for tile and class interaction

What does _maketile() do?

tile_onmap.modulate sets the modulation color for a given tile, and I believe everywhere you use that tile you’ll see the same color. If you change the color subsequently, all locations using that tile will become that color.

If you look at your code, you’re calling _set_cell() with all sorts of map coordinates, but only one set of atlas coordinates (0, 0), which means you’re setting every cell on the map to the same tile.

I’m assuming you’ve left some code out, here. As it stands, there’s no definition for _maketile(), and you apparently aren’t using your giant 14400 entry TileData_real array; it gets created as a function-local variable in _ready(), built up in the loop, but only ever written to, not read.

_maketile() assigns classes’ variables with various generative noises

TileData_real is a temporary array created for future use and project expansion

If you look at your code, you’re calling _set_cell() with all sorts of map coordinates, but only one set of atlas coordinates (0, 0), which means you’re setting every cell on the map to the same tile.

^
Does it mean i have to use set_cell(Vector2i(x,y), 0, Vector2i(x,y)) instead? Will that automatically create these coordinates?

If you want each cell to be its own tile (which seems to be what you’re trying to do here?), then yes, you probably want something like:

func prep_map(map: TileMapLayer, map_size: Vector2i) -> Array:
    var tdata: Array = []
    for y in map_size.y:
        for x in map_size.x:
            var vec: Vector2i = Vector2i(x, y)
            var tile = _make_tile(map, vec, colour)
            map.set_cell(vec, 0, vec)
            tdata.append(tile)

    return tdata

func cell_from_tdata(tdata: Array, map_size: Vector2i, cell: Vector2i):
    return tdata[(map_size.x * cell.y) + cell.x]