Portponky / better-terrain

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

Decoration terrain and seeded random tiles #21

Closed torcado194 closed 1 year ago

torcado194 commented 1 year ago

Another fairly large PR.

New features:

Decoration Terrains

This adds the new terrain type "Decoration". Decoration terrains can be assigned to tile terrains just like categories. When a tile terrain has a decoration, decoration tiles will be added to surrounding cells when placed, and will similarly be removed when removing the source tiles. Decoration tile placement is based on rules specified in the terrain, like peering bits but slightly different (the center square represents the current decoration tile, each surrounding square represents the existence of a source tile at that location. So, a decoration tile with a bottom square enabled will be placed above source tiles while drawing, if that cell is empty). Multiple possible decoration choices will be chosen randomly based on tile probability, just like normal tile placement. Only decoration tiles can be added or removed based on neighbors. if a normal tile exists in the tilemap, it won't be affected. Decoration tiles also cannot be drawn directly.

Seeded Random Tiles

This sets up RNG seeding for tile updates. This can be toggled with a button on the dock

https://github.com/Portponky/better-terrain/assets/9218934/70462826-3178-4d20-aa0e-9a5279eb8270

Notes: I'm not sure if I caught every necessary function change with the addition of the new terrain type (such as the checks in swap_terrains). For the most part I tried to copy all relevant code pertaining to Categories.

I considered adding an option to set/change the seed manually, with a number input field. If i were to add this I think it would make most sense as a per-terrain option, so that you can change the seed for one terrain and know that it won't cause unwanted changes to placed tiles from other terrains. I also considered making the "shuffle random" toggle a per-terrain option (not confident about that, but if so it would make sense placed next to the seed field)

The random shuffle toggle is handled as a variable inside BetterTerrain.gd, I notice there's little other state in this file so this change may go against convention, but the alternative solution would require passing a seed and shuffle data down through all of the update and weighted selection calls, so this solution seemed ideal. (if the per-terrain seed and shuffle options were to be added, this data could be grabbed off the terrain in the weighted selection functions and remove the need to store that info in these variables)

I needed to increase the TERRAIN_SYSTEM_VERSION, and subsequently changed the _update_terrain_data function to accommodate the new decorations slot. I'm glad that function exists!

Thanks!

Portponky commented 1 year ago

Hi, these are both interesting changes. I'll have to check them out and have a play around. The decorations are quite a departure from the way in which Better Terrain in designed, but they seem really cool/useful so I'll be open minded.

univeous commented 1 year ago

I'm not sure if off-topic but it reminds me of LDtk. If you guys haven't seen it before, I highly recommend giving it a try :)

Implementing LDtk-like rule behavior in this plugin might require too much work, but it may be enlightening.

Portponky commented 1 year ago

I think with the decoration type in this PR, Better Terrain can do the same level of autotiling as LDtk. I haven't used LDtk, just seen youtube videos, so I don't know for sure.

torcado194 commented 1 year ago

I did get the impression something like this may be against the plugin's philosophy, that tiles should only be created or removed when painted explicitly, and which is further evidenced by the enforced center bit, both of which I agree with wholeheartedly. (drawing ties with the built-in terrain editor is obnoxious with how it mangles everything nearby). But of course, something like this is simply impossible without being able to place neighboring tiles. I had considered a solution where decoration terrains were designated to their own layer which couldn't be drawn on, just to further prevent that situation. But I found that even on the same layer this solution was never intrusive or buggy, since it only replaces empty cells or matching decoration cells.

Yes, LDtk was part of the inspiration for this change. Really, I just want a workflow in which I can design an entire map by painting freely without needing to place any tiles individually. I tried out LDtk, and even though there is an importer for Godot, ultimately decided it would be more worthwhile to try to bring this plugin up to my ideal feature set (especially for cohesion, so I can do everything within Godot instead of swapping programs constantly). There's still a few things LDtk can do with tiles that can't be done here without a major redesign, but yeah with this change it covers most of the major usability features.

Also important to note, this PR and #22 conflict in many areas, so if and once one is merged I'll have to update the other to resolve those (particularly regarding the TERRAIN_SYSTEM_VERSION and its data structure changes). So it may be less work to hold off on review until then.

Portponky commented 1 year ago

Initially the philosophy was indeed to keep cell changes strictly constrained inside the terrain types. That was a reaction to the built-in system, which generally causes problems by violating this. However, I'm not strict about this. If modifying blank tiles offers a meaningful feature, that is controlled and understood by the user, then I don't see a problem with it.

In fact I believe this decoration tile style will let me implement correct corner-based tile terrain...

Portponky commented 1 year ago

There's a bug where you can draw peering bits of the decoration type. They don't show up but they affect the matching rules.

https://github.com/Portponky/better-terrain/assets/33663279/4066ab7f-7f98-4712-8e81-1c52168e87d2

There is also a bug about deleting terrain types or atlases that I caused at least once. I'll have a look at the code to see if I can figure out what I did.

On a side note, corner based offset tiles can be achieved for a single type (as visible in the video). I wonder if a more generic form of this decoration type could be designed? It's very interesting.

torcado194 commented 1 year ago

Thanks for the thorough testing!

Good catch with the peering bits bug, should be fixed.

That corner-based terrain is really interesting, I never would have considered that functionality with this feature.

Portponky commented 1 year ago

I opened an issue to discuss the specific implementation of the decoration type: https://github.com/Portponky/better-terrain/issues/25

Portponky commented 1 year ago

Closing, as it is rolled into https://github.com/Portponky/better-terrain/pull/26 which will be merged to main soon.

Note that any tileset terrains created using this branch will probably be in a invalid state with main/future versions.