Basically, my game generates its level tiles by the cell layout of a csv file. However, this is an issues due to how the forward axis in Godot is -Z. This causes the csv layout in the document to be in reverse when the tiles are placed in the scene based off of the for iterator number, as the tiles will be placed out in the backward direction of +Z.
How the grid generation works
Here’s a example of the csv sheet layout.
BORDER | BORDER | BORDER | BORDER | BORDER | BORDER | BORDER | BORDER | BORDER |
BORDER | RAND | RAND | RAND | RAND | RAND | RAND | EL | BORDER |
BORDER | RAND | RAND | RAND | RAND | RAND | RAND | RAND | BORDER |
BORDER | RAND | RAND | RAND | RAND | RAND | RAND | RAND | BORDER |
BORDER | RAND | RAND | RAND | RAND | RAND | RAND | RAND | BORDER |
BORDER | RAND | G/100 | G/100 | G/100 | G/100 | G/100 | G/100 | BORDER |
BORDER | RAND | G/100 | RAND | G/100 | G/100 | EL | G/100 | BORDER |
BORDER | RAND | G/100 | G/100 | G/100 | G/100 | G/100 | G/100 | BORDER |
BORDER | RAND | RAND | RAND | RAND | RAND | RAND | RAND | BORDER |
BORDER | RAND | G/100 | RAND | RAND | RAND | RAND | RAND | BORDER |
BORDER | RAND | RAND | RAND | RAND | RAND | RAND | RAND | BORDER |
BORDER | BORDER | BORDER | BORDER | BORDER | BORDER | BORDER | BORDER | BORDER |
Lets look at the function that creates the tiles in the Godot scene.
func make_grid_of_tiles_based_on_layout_size(layout_size: Vector2i) -> void:
# make row
for x in range(0, layout_size.x):
tiles.append([])
# make column
for row in tiles.size():
for x in range(0, layout_size.y):
tiles[row].append([])
# instantiate a tile object and give it the world position based off of its place in the array
for row_index in range(0, tiles.size()):
for item_index in range(0, tiles[row_index].size()):
var tile: NavTile = TILE_TEMPLATE.instantiate()
tile.tile_position = Vector2i(row_index, item_index)
tiles[row_index][item_index] = tile
# adds object to scene as child of the object navigation_tiles
navigation_tiles.add_child(tile)
This creates the following tile hierarchy.
All good. 12 is the amount of rows in the csv file and 9 is the amount of columns.
To be able to see the files they must be assigned a type. Here’s the function for that.
func solve_as_is(arr: Array) -> void:
for row_index in range(arr.size()):
for item_index in range(arr[row_index].size()):
var tile: NavTile = tiles[row_index][item_index]
var tile_type: String = parse_type_of_tile(arr[row_index][item_index])
# match_string_to_dictionary returns an int which indicated which type the tile is supposed to be. this function does nothing relevant to the problem of the tile layouting so it is not relevant to the topic.
var type_match: GlobalsTiles.Types = match_string_to_dictionary(tile_type)
tile.type = type_match
In the function above we look into the array arr that contains the layout data from the csv sheet which is written at the top of the post. It fetches the tile that is in the array Tiles based on the position in the array increment over the length of the arr that represents the cells of the csv.
So:
tile = tiles[row_index][item_index] = arr[row_index][item_index]
which means
tile = tiles[1][7] = arr[1][7] = "EL"
However, since in Godot -z is forward and we are layout out the tiles in the positive z axis we get a mirrored layout of what is in the csv file.
Potential fixes, with their quirks and the fixes for their quirks
Invert the row of the csv
By reversing the rows the csv data the mirror effect is fixed.
func solve_by_reverse_row_array(arr: Array) -> void:
# workaround #1:
# do row in reverse
for row_index in range(arr.size()):
var reverse_index = arr[row_index].size() - 1
for item_index in range(arr[row_index].size()):
var tile: NavTile = tiles[row_index][item_index]
var tile_type: String = parse_type_of_tile(arr[row_index][reverse_index])
var type_match: GlobalsTiles.Types = match_string_to_dictionary(tile_type)
tile.type = type_match
tile.capture_shape_context()
tile.adapt_shape_to_config()
tile.update_neighbors()
reverse_index = reverse_index - 1
This causes the tiles to still be placed downwards in the +Z direction, while being the exact layout as in the csv sheet.
Issue
Now the array is also inverted.
E.g
tiles[1][1]
is now “el”, while tiles[1][7]
is “RAND”.
Solution
Reverse the row arrays.
At the end of the solve_by_reverse… function insert.
for row in tiles:
row.reverse()
Evaluation
I don’t know many milliseconds it takes to reverse an array by n length, but this seems ok.
The tiles are placed downward in the +Z direction with this solution, if that is the desired result.
Invert the position of the tiles and all game objects acting on its coordinate system
Here the function solve_as_is is used, as shown at to top of the post.
Then in the make_grid_of_tiles_based_on_layout_size() function also shown above, this line is changed so that the position of the tile is added in the -z axis.
tile.tile_position = Vector2i(row_index, -item_index)
The grid layout then becomes as in the csv, and the array of tiles is also created in the manner of the csv tile.
Issue
However now also the navigation and anything that does anything with tile coordinates also needs to be negated in the z axis.
Solution
When setting the tile position of any object, they must have their z axis negated as well.
var tile_position: Vector2i :
get:
return tile_position
set(value):
tile_position.x = value.x
tile_position.y = value.y
position = Vector3(value.x * 4, 0, -value.y * 4)
Evaluation
I haven’t taken this solution further but it seems like this will at some point create issues when everything must be negated.
However now the tiles are placed such that the row goes along the -Z axis, which is different from the previous solution so it might meet another desired result.
Conclusion
Well I do hope this won’t be the conclusion to it all. I hope there will be more discussions and solutions posted in this thread below.