godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.11k stars 69 forks source link

Create an option for TileMapLayer to chose the horizontal alignment #9882

Closed agrimminck closed 2 months ago

agrimminck commented 3 months ago

Describe the project you are working on

An RPG which uses grid movement and many of the tile sprites occupy more than one cell, one cell is 32x32 and the walls shown below are 64x64

Describe the problem or limitation you are having in your project

This issue does not let me put y-sorted tilemap walls, which are bigger than one cell, to be put horizontally like shown below.

a0743e969f68042b5802680cd2f6c480ba086e93

image

P.S. This also happens in the TileMap class for godot 4.2.1

Describe the feature / enhancement and how it helps to overcome the problem or limitation

To let the TileMapLayer align tiles horizontally like they can be y-sorted

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Have a parameter which tells the TileMapLayer how it will align the tiles horizontally, if it will be left-to-right or right-to-left

If this enhancement will not be used often, can it be worked around with a few lines of script?

No, I have been tinkering around a lot around this issue and I have not found any way to go around this.

I found this while searching the internet, but it makes the tile map invert its y-sorting too, so it does not solve the problem.

Is there a reason why this should be core and not an add-on in the asset library?

No, if this were to be an addon I think it would be completely fine

groud commented 3 months ago

Sadly there's no simple way to implement that. TileMap's Y-sorting relies on the underlying rendering server Y-sorting feature, which does not feature a way to chose an X-sort direction. So this basically require an X-sort direction to be implement in the rendering server, which is quite difficult task (at least to me), and a bit independent from the TileMap system itself.

kleonc commented 3 months ago

@groud Actually after https://github.com/godotengine/godot/pull/73813 all tiles with the same(ish)-y-sort-origin are rendered using the same canvas item (quadrant) within the rendering server, thus the order of tiles in each such y-row is not affected by y-sorting as y-sorting only sorts separate canvas items. The tile order in each such y-row depends purely on the order in which the draw commands are issued for the given y-row canvas item. Hence I think reversing the order horizontally should be trivial, as it's a matter of sorting the in-quadrant tiles (for y-sorting enabled quadrants are y-rows) with a comparator with x-check reversed (so the default one, already used for disabled y-sorting):

(As always, unless I'm missing something. :upside_down_face:)

groud commented 3 months ago

@groud Actually after https://github.com/godotengine/godot/pull/73813 all tiles with the same(ish)-y-sort-origin are rendered using the same canvas item (quadrant) within the rendering server, thus the order of tiles in each such y-row is not affected by y-sorting as y-sorting only sorts separate canvas items. The tile order in each such y-row depends purely on the order in which the draw commands are issued for the given y-row canvas item. Hence I think reversing the order horizontally should be trivial, as it's a matter of sorting the in-quadrant tiles (for y-sorting enabled quadrants are y-rows) with a comparator with x-check reversed (so the default one, already used for disabled y-sorting):

Oh you are right, I forgot I changed it to work that way haha. You are probably right then, we can probably implement that in the TileMap itself!

agrimminck commented 3 months ago

@groud Actually after godotengine/godot#73813 all tiles with the same(ish)-y-sort-origin are rendered using the same canvas item (quadrant) within the rendering server, thus the order of tiles in each such y-row is not affected by y-sorting as y-sorting only sorts separate canvas items. The tile order in each such y-row depends purely on the order in which the draw commands are issued for the given y-row canvas item. Hence I think reversing the order horizontally should be trivial, as it's a matter of sorting the in-quadrant tiles (for y-sorting enabled quadrants are y-rows) with a comparator with x-check reversed (so the default one, already used for disabled y-sorting):

(As always, unless I'm missing something. 🙃)

So you can make that TileMapLayer does not inverse the x-sorting when y-sort is enabled?? That would be so awesome! I would greatly appreciate that!

kleonc commented 3 months ago

So you can make that TileMapLayer does not inverse the x-sorting when y-sort is enabled?? That would be so awesome! I would greatly appreciate that!

Yes, as mentioned the implementation would be super simple.


Note that for y-sorting enabled currently it's drawing right to left because that's how it used to work in the previous versions, see https://github.com/godotengine/godot/pull/73813#issuecomment-1729381779.

But if we're going to add a toggle for the x-ordering when y-sorting then I wonder if it would make sense for us to change the default x-ordering for y-sorting, so by default toggling y-sorting would not change the x-ordering like it currently does (https://github.com/godotengine/godot/issues/92729). Doing so would be a little compatibility breaking but more consistent in the end. And if someone depended on the right-to-left ordering then they'd need to just toggle the x-ordering to fix the compat breakage when upgrading the version. @groud Decision up to you I guess. :slightly_smiling_face:

Either way it should be fine, changing the behavior will be a toggle away anyway. Just something to consider.


Also note that it could potentially be a general toggle for x-ordering, not just for when y-sorting is enabled. But changing the x-ordering when y-sorting is disabled would also require changing how quadrants are sorted (as they're no longer y-rows in such case). Which is absolutely doable / not too hard. But given that:

the rendering would be susceptible to artifacts anyway, regardless of x-ordering, see e.g. https://github.com/godotengine/godot/issues/74257#issuecomment-1452726277.

So maybe x-ordering could be useful in some specific case when not using y-sorting, maybe not. Not sure, thus I think making it just for y-sorting is the way to go. And potentially adding support for no y-sorting in the future if it will be requested / there will be a specific use case shown.


And the hardest problem: what should be the name of this property? :upside_down_face:

(+Although it's technically a new feature I hope we could still sneak in into 4.3 because of how simple it is. I guess such property could be marked as experimental just in case, for safety? :thinking:)

agrimminck commented 3 months ago

So you can make that TileMapLayer does not inverse the x-sorting when y-sort is enabled?? That would be so awesome! I would greatly appreciate that!

...

That's nice! For my project I would only need the "x-sorting" to be left to right and not invert itself, I don't know how many people would benefit for the option to choose the x-sorting feature.

Thank you for your kindness. I hope I could get my hands into my project with this feature fixed so I can build houses and more complex scenarios!

groud commented 3 months ago

But if we're going to add a toggle for the x-ordering when y-sorting then I wonder if it would make sense for us to change the default x-ordering for y-sorting, so by default toggling y-sorting would not change the x-ordering like it currently does (https://github.com/godotengine/godot/issues/92729).

Yes, the default should be modified. The X-sorting should not change when using Y-sorting, I'd consider this as a bug TBH.

Also note that it could potentially be a general toggle for x-ordering, not just for when y-sorting is enabled. But changing the x-ordering when y-sorting is disabled would also require changing how quadrants are sorted (as they're no longer y-rows in such case). Which is absolutely doable / not too hard. But given that:

I think this would be premature work, I can't think of a lot of use cases where you would need X-sorting but no Y-sorting. So I wouldn't bother for now.

And the hardest problem: what should be the name of this property? 🙃

I'm thinking X-draw-order-reversed, something like that. By default, it would draw left-to-right (opposite of now)

(+Although it's technically a new feature I hope we could still sneak in into 4.3 because of how simple it is. I guess such property could be marked as experimental just in case, for safety? 🤔)

It's half a bugfix, but we need the toggle to "keep compat" with the previous buggy behavior. So yeah, I'd be up to have it in 4.3.

agrimminck commented 3 months ago

Yes, the default should be modified. The X-sorting should not change when using Y-sorting, I'd consider this as a bug TBH.

I posted it as a bug on this thread https://github.com/godotengine/godot/issues/92682#event-13023144455