TileData has wrong value for flip_h, filp_v and transpose when accessed
Tested versions
- Reproduced in both v4.5.dev5.official [64b09905c] and v4.4.1.stable.mono.official [49a5bc7b6]
System information
Godot v4.5.dev5 - Windows 10 (build 19045) - Multi-window, 2 monitors - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 2060 - Intel(R) Core(TM) i5-7400 CPU @ 3.00GHz (4 threads)
Issue description
When editing a tilemap in the editor, you can set the rotation / flip of a tile. This value is able to be accessed programmatically through both the is_cell_flipped_h, is_cell_flipped_v, and is_cell_transposed functions on the TileMapLayer class, and the flip_h, flip_v, and transpose properties of the TileData class. However, when accessed, the TileMapLayer functions return an accurate result, but the TileData properties always give a value of false.
Steps to reproduce
The attached project contains a small tilemap with four tiles, each one with a different orientation. When running the project, the console outputs what the TileData class and the TileMapLayer class think the flip_h, flip_v, and transpose of each tile is. TileData returns all false values whereas TileMapLayer returns the correct values.
Minimal reproduction project (MRP)
Can confirm this, but I think this is a documentation issue, rather than a bug, the method in question returns the raw data from the TileSet directly, and the tile itself in the TileSet is not flipped or transposed
There's no bug here indeed, should be better documented. I'll open a PR for the class reference later.
There are 2 separate sets of transform flags (flips+transpose):
- Per TileSet (alternative) tile, stored in TileData (as
flip_h,flip_v,transposeproperties). I call them per-tile flags. - Per TileMapLayer cell, stored as 3 bits of the alternative tile id set for the given TileMapLayer cell (obtainable with
is_cell_flipped_h,is_cell_flipped_v,is_cell_transposedTileMapLayer methods). I call them per-cell flags.
Why are there 2 sets like that? In the initial 4.0 TileMap implementation there were only per-tile flags. So if the user wanted to e.g. rotate a tile they'd need to create a separate alternative tile just for that. This was cumbersome. To simplify things per-cell flags were added later, in 4.2 (#80144). Thus now we have 2 sets of flags (per-tile flags were not deprecated, they should work as before per-cell flags were added).
But note that how per-tile and per-cell flags are being combined is kinda inconsistent/buggy in both v4.5.dev5.official [64b09905c] and v4.4.1.stable.mono.official [49a5bc7b6]. Specifically, depending on the per-tile flags, e.g. rotating a tile "right" within the editor might instead result in visually rotating it "left"[^1], see the example below. However, given I think nobody reported anything about that, it's rather unlikely that anyone actually uses both per-tile and per-cell flags at the same time. 🙃 Anyway, combining per-tile and per-cell flags should be fixed as a part of #107080 which will be included in 4.5.beta1, now per-cell flags are being applied "independently" on top of the per-tile flags, which should make things consistent UX-wise.
Example
An alternative tile with no per-tile flags set, drawn in a row by rotating it "right"/clockwise (leftmost is not rotated, each next is rotated right one more time). The result is correct / the same in both v4.4.1.stable.official [49a5bc7b6] and v4.5.dev.custom_build [03bd8ba9c] (current master):
However, after setting per-tile flip_h, the previously drawn row of tiles becomes a rotate-left sequence in v4.4.1.stable.official [49a5bc7b6] instead of the originally drawn rotate-right sequence. Also pressing rotate-right in the editor when drawing tiles visually rotates the tile left. In the current master (after #107080) the original relative per-cell transforms should be preserved no matter how you'll modify per-tile flags later (a rotate-right tile sequence will remain a rotate-right tile sequence etc.).
| v4.4.1.stable.official [49a5bc7b6] | v4.5.dev.custom_build [03bd8ba9c] (current master) |
|---|---|
[^1]: Why? Within the TileSet editor there are only per-tile flags applied to the created/shown alternative tiles, meaning this is what the user sees and thus this is what should be treated as the "base tile" to which the per-cell flags are being applied to. Meaning conceptually the per-tile flags need to be applied first, then per-cell flags on top of such transformed tile. These being 2 seperate steps was previously not taken into account when combining flags.
Also for reference here's how the flags are being combined currently: https://github.com/godotengine/godot/blob/03bd8ba9c23d31f8f658f97093fd3f2e4a0f9031/scene/2d/tile_map_layer.cpp#L2647-L2659 (I don't think it needs to be anyhow exposed (with a new method etc.). As mentioned transforming just the per-cell flags should be consistent currently (no matter the per-tile flags) so it should be fine to modify them directly. 🤔)