Portponky / better-terrain

Terrain plugin for Godot 4
The Unlicense
502 stars 24 forks source link

Feature: Auto-transformations #31

Closed torcado194 closed 1 year ago

torcado194 commented 1 year ago

Now that https://github.com/godotengine/godot/pull/80144 is merged, I think it would be a perfect time to make use of this feature in Better Terrain to introduce automatically flipped/rotated tile alternatives.

I wanted to bring this up as an issue first to start a discussion about it, because I think you'd have a better idea of how the implementation would work.


Here's the problem I'm trying to solve. I have a basic tileset with 48 tiles like so:

image

When painting tiles in the game, I want to reduce obvious texture repetition as much as possible. For this design, every angle is uniform (top-facing tiles look no different than bottom-facing tiles, etc.). I can utilize this aspect of the design to very easily make alternative sections by simply rotating the individual tiles in the base set 3 times:

image

This gives a lot more variation without any more work. (i could do this another 4 times by flipping them, but it's a lot more obvious seeing two flipped tiles next to each other than two rotated tiles near each other.)

So I have a tileset setup like this (with duplicates for background layers): image

This works great, but it feels a little unnecessary, and also makes the plugin a lot slower.


I've been thinking about a better way to do this for a while, and I think this would be ideal.

My idea is this: auto-transformation options. Terrain tiles can optionally have auto-transformation enabled for them. This would create duplicate tile entries in the terrain for each transformation, and also transform their peering bits in the same way.

I have two possible implementation ideas:

1. Auto-transformation options per terrain In the terrain options will be a new list of toggles:

With any of these toggles enabled, the terrain will effectively duplicate its existing tiles with the respective transformations applied as part of the new set of tiles for the terrain. So, every tile will have the same auto-transformations.

2. Auto-transformation options per tile A new “view” would be added to the dock, alternative to the “peering bit” view. In this view, hovering over a tile will show a grid of these same options as icons that you can toggle to specify which transformations are enabled for it: image

(thinking about it more, probably better would be a painting mode where these 4 options are togglable in the toolbar and you paint on tiles to apply that option set)

Option 2 gives more control (and is the one I think I prefer), but its results could still be handled with option 1 by creating multiple terrains for each specific transformation set needed. (My specific case could be handled with option 1, but I would have to move some of the additional tiles out)

Now when drawing tiles, it will include (for instance) rotated tiles from other sections of the tileset in the placement choices. So in my example I could replace all 4 duplicate sections with a single section with the "rotate 90" option enabled.

This would also allow a full tileset to be extremely simple with only 6 tiles: image

to allow painting any of the basic 16: image

Handling the flipping/rotation of the sprite, collider, occlusion, etc. is already handled by the linked PR. The only thing that would need to be handled here is calculating the resulting peering bit transformations. The area I'm least confident in with this implementation is how the duplicate tile data should be handled; when should it be created, where it would sit in the terrain data, how it integrates with the tile picking functions.

Any input would be appreciated! Thanks :)

Portponky commented 1 year ago

I saw this was coming a while back, good to see it's been implemented and will be available soon (I'll have to check out the dev builds).

My initial reaction was something along the lines of the icons on the tile view, as per your mockup no. 2. As it's implemented via alternate tile ids, it should be possible to integrate it with Better Terrain fairly seamlessly. I'll have a poke around at the weekend and see what I can implement.

torcado194 commented 1 year ago

awesome, great to hear! Let me know if there's anything I could do to help otherwise. I may make a proof of concept UI for it

Portponky commented 1 year ago

I've implemented a test version which uses a function set_tile_symmetry_type to alter how tiles can behave. The types are

enum SymmetryType {
    NONE,
    MIRROR,
    FLIP,
    REFLECT,
    ROTATE_CLOCKWISE,
    ROTATE_COUNTER_CLOCKWISE,
    ROTATE_180,
    ROTATE_ALL,
    ALL
}

As it turns out, it was independent of tile grid type and other terrain logic, so this update won't even need a version upgrade. It adds the rotated/flipped tiles into the cache before calculating terrain updates.

It needs more testing, and a way to assign the symmetry in the UI. I'm thinking a drop down list of types which you apply to tiles, represented by icons.

Here it is in action:

https://github.com/Portponky/better-terrain/assets/33663279/fafcbe14-83e7-46c1-a374-655314cc78ba

Portponky commented 1 year ago

I've put it on the branch symmetry if you want to give it a shot.

torcado194 commented 1 year ago

Wonderful work!! Thanks so much, this works great.

I haven't done much rigorous testing, I'll do that soon. In the meantime, I've made a fork that adds some UI. It looks and functions like this:

sx-1538

the fork is here: https://github.com/torcado194/better-terrain/tree/symmetry which I can submit as a PR if you'd like :) (it doesn't integrate with the copy/paste feature yet, I can add that before submitting) it is done

Portponky commented 1 year ago

:rofl: you're so fast! I was just roughing out a first attempt, it's very similar, though your icons are so much better:

image

Quick suggestions:

Thanks so much!

torcado194 commented 1 year ago

haha nice, yeah very similar!

yep can do :) I added the break because I hide peering bits in symmetry painting mode (it's just a lot of visual clutter), so that visually distinguishes the sections. But selecting tiles to copy/paste also handles symmetry, so there's overlap anyway.

PR: https://github.com/Portponky/better-terrain/pull/33