Open Portponky opened 2 years ago
Really in support with these ideas! After testing tilemaps with my usual workflows, I think everything they can do is very powerful and ready for Godot 4 stable, but terrains stick out like a sore thumb in that regard.
I think you've identified the issue well. Making it so every autotile is part of a specific terrain covers every realistic use case of tilemaps I can think of, yet this workflow is super weird to use. I don't think different use cases should be supported to its detriment.
Even if UX is not good with this, for 4.0 stable I believe that having cohesive tilesets that can accomplish anything users commonly need should be a way bigger priority than having a good polished UX and UI, as those can be done in later versions. So IMO this proposal should be considered seriously while Godot 4 is still in beta.
I'm not sure about removing terrain sets, but I do agree they're a bit useless right now, at least I can't think of any reasons they should exist. But I think the ability to group terrains would be nice in order to make matching between big groups of tiles more straightforward and less error-prone. For example by making all tiles from the "Platforms" set always match with all tiles from the "Solid Tiles" set, instead of having to pick if you want them to connect with grass, sand, rock, bricks, dirt, etc... for every terrain type. Though I suppose this may be a rare use case, as most games would use different transition tiles.
Enforce that all of a terrain’s tiles have the center bit of that terrain type. Essentially, remove ‘centerless’ terrain tiles
I don't think this can happen. Some border tiles may need such a behavior in the 3x3 mode, as a transition may cover either a third or two third of a tile, and depending on that the center bit might be set or no.
Remove the concept of terrain ‘sets’, instead just define individual terrains with connection types.
The problem with that is that different kind of matching mode, like "matching sides" and "matching corners and sides" should be able to co-exist with each other in a single atlas, they are use cases for it. The terrain sets make this simpler than setting it up per-tile, and make it clear about which tile can connect to each other.
Make terrain tiles’ peering bits match multiple terrains (duplicate of https://github.com/godotengine/godot-proposals/issues/4689 )
This shouldn't be done at the bit level, but at the terrain level. Otherwise it will be super tedious to setup.
Tidy up some curious API (such as the removal of the ignore_empty_terrains flag)
This flag is needed so that empty tiles do not become a constraint in some areas. It's a bit like the "ignore bit" in 3.x if I am not mistaking. But I am open to suggestions regarding this.
I'm not sure about removing terrain sets, but I do agree they're a bit useless right now, at least I can't think of any reasons they should exist.
This is mainly for performance, and because different sets are needed anyway when you use different matching modes.
Ah, makes sense about the different matching modes. Would they still needed if center terrain bits were enforced?
I don't think this can happen. Some border tiles may need such a behavior in the 3x3 mode, as a transition may cover either a third or two third of a tile, and depending on that the center bit might be set or no.
May I see an example of this that would be impossible/cucumbersome to implement without enforced center bits?
Ah, makes sense about the different matching modes. Would they still needed if center terrain bits were enforced?
Yes. Center bits used not to be here before and the algorithm could (kind of) work anyway, so that's unrelated.
I suppose that, maybe, it would be possible to get rid of the terrain sets, though I wonder how it would work when mixing the 3 different modes together. I guess the "matching sides" and the "matching corners" can work with the "matching sides and corners" mode, but "matching sides" and "matching corners" would not work together. I guess it's something that could be done and would simplify things, so I am not against it. (It's a huge refactor though)
May I see an example of this that would be impossible/cucumbersome to implement without enforced center bits?
Basically any tile with a thin border, which would be mainly empty but would serve as a transition from a terrains to void. But well, enforcing the center bit does not make a lot of sense anyway, and I am not sure what that means and what that would solve. The "empty terrain" is kind of a terrain in the algorithm anyway, so I am not sure what it would be helpful for.
Ah I see, so its use case is tiles that are from the "empty" terrain, but have content nonetheless. OK, I'm convinced their existence makes sense. But I think we should still somehow make it so the center terrain of each tile on the tilemap is always preserved unless the user changes it. Tiles from the empty terrain (no center bit) could be kept, but they should be the only scenario where a tile pops up without the user placing it, since in that case, they keep empty terrain empty.
But I think we should still somehow make it so the center terrain of each tile on the tilemap is always preserved unless the user changes it.
I guess that could work. Maybe it's the most expected behavior but it has an implication. Right now, painting a terrain with this setup:
Leads to this:
https://user-images.githubusercontent.com/6093119/195345912-b3f6d5b3-d80f-4b30-9829-f0b08743f026.mp4
While with that new system it would lead to this:
https://user-images.githubusercontent.com/6093119/195346282-b495581d-cca6-42f9-9b94-92f7a672166b.mp4
That means the algorithm would do no effort to make things match, but would be more predictable I guess.
Tiles from the empty terrain (no center bit) could be kept, but they should be the only scenario where a tile pops up without the user placing it, since in that case, they keep empty terrain empty.
I think this is kind of a bug, I agree that a tile should not be modified if its terrain pattern matches the one selected by the algorithm. So if a tile is not a terrain or is from the wrong terrain set, it should not be removed but stay as-is instead.
I'm still unconvinced that centerless tiles make sense. Is there an actual concrete use case, rather than a hypothetical one? Such as a game or tileset from a user which can be best satisfied with centerless tile constraints.
If you're describing something like this:
That was thrown together quickly with Godot 3.5 and some tiles from Open Game Art. If you wanted to transition tiles to void (or between void and other tiles) then why wouldn't something like this be appropriate? It's easy to do and very logical.
With centerless tiles, what happens when you erase a tile? Should it paint a different terrain tile if there's a centerless tile with a valid connection?
That was thrown together quickly with Godot 3.5 and some tiles from Open Game Art. If you wanted to transition tiles to void (or between void and other tiles) then why wouldn't something like this be appropriate? It's easy to do and very logical.
Sure it make sense for a simple layout, but you may want to have, for example, a tile with grass on a side, tall grass on the other, and void in the middle. The terrain system allows this flexibility and it should be kept. To make it clear, "no terrain" behaves almost exactly like any other terrain. There's no reason to remove it, it won't simplify anything.
With centerless tiles, what happens when you erase a tile? Should it paint a different terrain tile if there's a centerless tile with a valid connection?
Yes, exactly. It tries to make the center bit match your expectations, then adapt the surroundings (the tile itself but if needed the surrounding tiles also) to what you are asking of.
Sure it make sense for a simple layout, but you may want to have, for example, a tile with grass on a side, tall grass on the other, and void in the middle. The terrain system allows this flexibility and it should be kept. To make it clear, "no terrain" behaves almost exactly like any other terrain. There's no reason to remove it, it won't simplify anything.
It seems like the simplest answer would be for the user to consider those tiles as one type or the other, and let the terrain handle the transition normally. That the centre of the tile happens to be empty (graphically) is not a use case that should be informing the design, or at least, I don't think so.
Is this use case worth all the complexity that centerless tiles bring to the system? Especially considering how easily it could be handled otherwise.
Is this use case worth all the complexity that centerless tiles bring to the system? Especially considering how easily it could be handled otherwise.
I don't really understand what make you think that. No, I don't think it would make things simpler, the terrain algorithm has to handle any kind of transitions from one terrain to the other (that's the whole point of terrains vs autotiles). So removing one special terrain (as I explained the "no terrain" is considered like any other terrain, it's simply a terrain like the others) won't make things simpler, it's the exact same thing but with one terrain less.
@groud I'm not sure what the gifs show exactly - I suppose they show examples of placing terrain in connect mode. In such a tileset, I still think the current behavior gets in the way, because it assumes what other tiles you're gonna plant. In the gif, the initially placed tile became the bottom right one, but maybe the user wanted it to be the top left one and was about to draw that little square, but then the tilemap got in the way. And then they try to erase those unintended tiles, probably leading to more artifacts.
So I think just defaulting to a wrong type of tile until valid neighbors are set up by the user would be the better behavior.
@Portponky Maybe erasing centerless tiles could be made invalid and only possible by changing the adjacent terrain that made the centerless tile appear.
@groud I'm not sure what the gifs show exactly - I suppose they show examples of placing terrain in connect mode. In such a tileset, I still think the current behavior gets in the way, because it assumes what other tiles you're gonna plant.
Yeah, it's in the connect mode. Basically what it mean is that, if we don't modify the surrounding tiles' center bits at all cost, then there might be situations where no valid transitions can be found, and things will end up in an "invalid state", even in simple cases like that one. But if that's fine to everyone, I guess it should be quite straightforward to modify.
@Portponky Maybe erasing centerless tiles could be made invalid and only possible by changing the adjacent terrain that made the centerless tile appear.
I'm of the opinion that erasing a tile should leave it blank. That's what I would expect and find useful. I'm interested to hear what others expect.
I'm of the opinion that erasing a tile should leave it blank. That's what I would expect and find useful. I'm interested to hear what others expect.
But there are valid use cases where it can be useful not to have that behavior. For example, take that picture and imagine that the bottom layer is in fact a custom water shader, that is not using tiles:
I with your solution, it is impossible to draw a path of water (of less than a tile, like we have here) in the grass terrain.
I wouldn't say impossible, but you're right that is a difficult use case for what I have suggested.
I would make two terrains, one for the grass and one for the shoreline. The grass would just be a terrain with a single tile, and the shoreline would be a 47 tile set with match corners/sides. Instead of matching the usual 47 tile set, I would invert it and make the peering bits match grass.
https://docs.godotengine.org/en/stable/_images/autotile_template_3x3_minimal.png
Like this image, but the white would match grass, and the purple would have no peering bit (and be transparent graphically). Then, I could draw the grass and surround it with the shoreline to show the water through.
So it's definitely possible, though perhaps a little bit messy for this particular use case.
I'm of the opinion that erasing a tile should leave it blank. That's what I would expect and find useful. I'm interested to hear what others expect.
You want to make it so painting terrains makes a contract with Godot that a certain tile is a certain terrain type, and I super agree with this. But then for consistency, this should probably extend to empty tiles too.
if we have empty terrain tiles (no center bit), they appear automatically, without you painting them. It's just the empty terrain adjusting to having a matching transition tile for its new neighbors, without changing its terrain, sort of identical to normal terrains. By this logic, erasing them should be essentially the same as trying to erase empty tiles. Kind of like how erasing a transparent pixel does nothing.
I can see how this would be confusing, but I think it would be a good workflow for terrain painting for the people who want to use centerless tiles. Whaddya think?
I've not used it a whole lot, but when trying to learn how the current terrain system works I found centreless tiles pretty unintuitive, especially with the added confusion of having both terrains and terrain sets. I'm still not sure I fully understand them, they're tiles that are part of a terrain set but which aren't "part" of any actual terrain?
The setup Portponky suggests seems a lot more intuitive to use to me, even if there's potentially slightly more set-up involved in specifying the connections, although I think a decent UI could mitigate most of that.
if we have empty terrain tiles (no center bit), they appear automatically, without you painting them. It's just the empty terrain adjusting to having a matching transition tile for its new neighbors, without changing its terrain, sort of identical to normal terrains. By this logic, erasing them should be essentially the same as trying to erase empty tiles. Kind of like how erasing a transparent pixel does nothing.
I can see how this would be confusing, but I think it would be a good workflow for terrain painting for the people who want to use centerless tiles. Whaddya think?
The problem which I see with centerless tiles is twofold.
It's a feature that forces the design down this path, without offering any strong advantages. Yes, it can sometimes make certain kinds of transitions slightly easier to design, but at the cost of a more restricted terrain feature across the board.
As before, my interest would be in finding out if there are users that need the functionality of centerless tiles more than, say, any of the autotile features that have regressed because of this. I really doubt it, but I'd be happy to see.
@Portponky Sorry but I think there's really a misunderstanding here.
Firstly, they require the tilemap to alter tiles the user has not clicked on. This is just part of how they work. Of course the change is from 'empty tile' to 'tile with no center bit', but it does mean it's putting content down and bringing tiles into the purview of the terrain without the user painting on them.
This is not true, as I mentioned a lot of time already, whether or not clicking a tile affects its neighbors or not is unrelated to whether you paint an empty terrain or a any other terrain. They work the exact same, and your proposal of making "empty tiles" a special case is not really needed, and wont solve issues when you are painting a terrain over another one. So for me that's not going to happen, the algorithm behavior just need to be adapted to what users expect the most.
If we want to make sure the algorithm does not modify the surrounding tiles' center bits, it's rather easy to do. That means tiles will have a greater chance to have wrong transitions, but I think it should help with the algorithm not doing what we expect from it.
Secondly, they require terrains to be organised in sets (or some other way) so the centerless tiles know how to connect (e.g. sides, corners...), which means adding restrictions into terrain interaction.
This is false too, those are completely unrelated. Sets were already here before I brought back the center bit. They are needed to know which terrains work with each others, and that's why the matching mode is defined per terrain-set.
As I mentioned earlier, terrain sets could be removed. That probably means that we will have to find a way to make terrains with different modes work together, but it should not be too hard to do.
your proposal of making "empty tiles" a special case is not really needed
My proposal is literally the opposite of this. The first change I suggested is to directly take special behaviour away from the empty terrain type.
and wont solve issues when you are painting a terrain over another one
I have gifs of a coded example demonstrating that it does indeed solve this issue. They are in the initial proposal.
I would make two terrains, one for the grass and one for the shoreline. [...]
Here is an example of how this would behave in practice with my suggested changes.
As I said, definitely possible. I put little red Xs in the unconnected cells so they could be tidied up.
Loving the discussion! Though so far it's mostly just us three, and I am a bit worried if we're trying to pull the TileMap cart in three different directions, like the Swan, Pike, and Crawfish fable.
So to summarize:
We haven't really discussed yet the elephant in the room: How connections are made. If I gather correctly, the current system tries to find the best matching tile, using modified WFC. It puts a lot of accent on neighboring tiles' center bits, but may consider other bits too. Meanwhile, Portponky's mock-up only considers center bits and as such is a simple and still performant algorithm. IMO this approach is a lot more intuitive and is how things should be as well.
As I said, definitely possible. I put little red Xs in the unconnected cells so they could be tidied up.
It's nice that making a new terrain can accomplish this with your mock-up! But to be honest, the Shore terrain does feel like just a replacement of what empty terrain could do on its own. It's not too bad, though it's marginally worse in terms of usability, since it's one extra terrain, can leave out empty tiles without the user knowing (the red X), and you need to draw it manually.
But me and groud think the empty terrain should be a valid center bit (that is, no center bit), while Portponky mostly disagrees.
As i understand the terrain system, an empty map consists of empty terrains surrounded by empty terrains. In terrain mode, not tiles are painted and erased but only center bits and the algorithm is responsible for finding the best tile.
So I was against disallowing empty center bits.
But what about the interaction between terrain tiles and non-empty non-terrain tiles? https://github.com/godotengine/godot/issues/67143 This could be solved by disallowing empty center bits, I am just not sure if it is worth it.
We haven't really discussed yet the elephant in the room: How connections are made. If I gather correctly, the current system tries to find the best matching tile, using modified WFC. It puts a lot of accent on neighboring tiles' center bits, but may consider other bits too. Meanwhile, Portponky's mock-up only considers center bits and as such is a simple and still performant algorithm. IMO this approach is a lot more intuitive and is how things should be as well.
The current system tries to match a tiles peering bits to neighbouring peering bits using WFC.
As i understand the above proposal: For each cell, a tile is selected whose peering bits best fit the neighboring center bits.
This simplified system can not fully utilize a tileset like this:
This is because the transitions are doubled. There are dirt tiles bordering grass and grass tiles bordering dirt.
If each tile only looks at the center bits of its neighbors your result will be:
With the current WFC based system you will get one these by random:
Nevertheless, if a perfect tile cannot be found, scoring to find the best alternative should work in both systems.
Me and Portponky think terrains should never be drawn automatically, while groud is 50/50 on the idea.
I support the idea that the center bit of a cell should never be changed by the algorithm. That's the reason why I don't use the new system yet. I'm building a rogueliky game with procedurally generated maps and I always prefer to get broken transitions to getting incorrect terrain type.
The current system tries to match a tiles peering bits to neighbouring peering bits using WFC.
It has some elements in common with WFC, but it is not WFC, and nor should it be. It's most like a locally consistent constraint solver ( https://en.wikipedia.org/wiki/Local_consistency ) without the backtracking one would usually use.
This simplified system can not fully utilize a tileset like this:
No system in Godot can fully utilize this tileset, because this tileset is based on corner constraints, and you do not work with corner constraints through Godot. It doesn't matter if it's via the editor, via gdscript api, or whether using terrains as they are, my suggested terrains, or autotiles from Godot 3. It's like trying to fit a square peg in a round hole.
A good approach to using full corner constraints in Godot would be to store a dictionary of corner constraint values and then manually updating tiles based on that. That will handle all those tiles correctly in a completely consistent way. It's what I have done when making a Boulderdash clone in the past.
If set up with part of the tileset that makes sense in terms of how Godot utilizes tilemaps, say by using only the top half of the image, then all systems seem to provide the same level of functionality as Godot 3's 2x2 autotiles. Namely, there are certain tile shapes that cannot be expressed (such as a 3x3 donut shape), but the behavior is otherwise quite acceptable.
This is because the transitions are doubled. There are dirt tiles bordering grass and grass tiles bordering dirt.
My simplified suggestion can indeed handle 2-tile transitions. This tileset isn't a good example from a graphical point of view, the sand tiles in my example in the original post show it more neatly.
With the current WFC based system you will get one these by random:
Random output is not a good result imo.
No system in Godot can fully utilize this tileset, because this tileset is based on corner constraints, and you do not work with corner constraints through Godot.[...] If set up with part of the tileset that makes sense in terms of how Godot utilizes tilemaps, say by using only the top half of the image [...]
No, this is exactly my point. The current system can work with both parts of the tileset by matching the corner peering bits.
But I was wrong about the random part. Currently, which transition you get seems to be dependent on order of painting.
I spent a bit of my time working on a PR: https://github.com/godotengine/godot/pull/67390 I guess it fixes most of the issues you mention.
No, this is exactly my point. The current system can work with both parts of the tileset by matching the corner peering bits.
I see what you mean. I experimented with it, also produced this amended tileset with the missing tiles:
I believe you can make any construction with enough space and clicking around. There's a lot of currying-like behavior going on - you have to learn the distinction between drawing over multiple tiles and drawing with single clicks on single tiles.
Overall I would not use this in places where I've used corner matching tiles in the past. Usually for doing digging in a 2d situation, like in a Rocks and Diamonds / Boulderdash clone. This is because I would be very uncertain how API calls would translate into actual changes on screen, especially considering the amount of fiddling around it took to get something good in the editor. None the less, some may find it useful.
Anyway, this is all presenting very specific use cases without a concrete example (as in, found by a user when making an actual game). To reiterate, my problem is that I've made dozens of small puzzle and action games with Godot 3, and I can't use the 4.0 tilemap terrains to fill the gaps left behind from autotiles. I am completely blocked by this. My games simply don't work. Showing me edge cases where the current system can do something hypothetical is fine (and analysis of hypotheticals is indeed useful), but it doesn't solve the large functional gap that has occured.
As a further example of why this inconsistent behavior is problematic, here's a clip from the same puzzle game above. When you solve the level, it builds part of the city. In Godot 3, I had to code in special behavior to get the bridge over the river working. It needed a specific bridge tile with autotile scripts allowing it to connect in various ways.
Okay, in Godot 4 those autotile methods are gone, but this should be easy for the terrain system, right? Unfortunately, this case cannot be handled by the terrain system as it is currently. It will only connect the road over the bridge if it changes from water to road.
Tileset used, if you want to try it for yourself:
That's not a convoluted example I had to come up with, it's just a game I was working on and tried to port. This should be a slam dunk for the terrain system, but it isn't.
Okay, in Godot 4 those autotile methods are gone, but this should be easy for the terrain system, right? Unfortunately, this case cannot be handled by the terrain system as it is currently. It will only connect the road over the bridge if it changes from water to road.
I think this is an expected behavior though. When you are painting water with the connecting tool, that means you want the center bit to be of the given painted terrain. It is thus normal that you end up with a tile with water in its center and not a tile with road.
I guess we could change the behavior if we made the algorithm try to connect to tiles of different terrains. Like, here, placing the road tile would try to find a transition tile from water to terrain. Right now, it simply tries to modify the tile you are painting on the least possible, and only connects the to tiles with the same terrain as the one you are painting. Implementing such a transition may be complex though, as we may need "soft constraints" when searching for a transition tiles. Indeed, in that case, the transition bit can either be of the painted's one, or the destination one (like here, you have either a transition made of water, or one made of road).
This should not be too difficult to implement, but I think this behavior should probably be optional, as I guess some users may not want to connect to surrounding tiles if they are not from the same terrain type.
But this, in any case, should not impact how the core of the algorithm stays implemented. The new system allows a lot of use case that were not possible before, like the path tool for example, which allows drawing thin lines that don't connect at all but to previous tiles you have just painted.
I think this is an expected behavior though. When you are painting water with the connecting tool, that means you want the center bit to be of the given painted terrain. It is thus normal that you end up with a tile with water in its center and not a tile with road.
Agreed
This has nothing to do with center bits. Let me clarify.
The bridge only appears when changing from water to road.
This is annoying in the editor, but even worse, it's an enormous problem when trying to place tiles during gameplay from a script.
My game copies the tiles out of the puzzle solution into the world. It cannot work with this kind of system. I would need to code special behaviour for every level with this situation. It's a massive step down from Godot 3.
That's just one example from this game.There are others above. Plenty of other people also have problems.
This has nothing to do with center bits. Let me clarify.
Of course it has to do with center bits. The logic for connecting a tile to another is whether or not they share the same center bit or not. That's why placing road tile connects to road tiles, but does not connect it to water tile. Please re-read what I wrote in my previous comment.
This is annoying in the editor, but even worse, it's an enormous problem when trying to place tiles during gameplay from a script.
Well, if you say so. As you show it yourself it is easily worked around by placing water tiles before road tiles. As I explained, the current system may not fit your use case but can fits others' use cases. So it should be optional if we implement a more flexible connection system.
Edit: by optional I mean a checkbox in the editor (or another painting mode IDK) and as an argument in the TileMap API, not a global settings.
My game copies the tiles out of the puzzle solution into the world. It cannot work with this kind of system. I would need to code special behaviour for every level with this situation. It's a massive step down from Godot 3.
If you need copying the whole level, you can simply copy the tiles directly and not paint them with the terrain system. It does not make a lot of sense to use the terrain system to do that. Worst case, if you want to have tile variations (like two tiles with the same tile variations), I would probably store a full tile's terrain pattern instead (thus, not only the center terrain but also the peering bits). Though, to be honest, I think it would be a bit easier to do if we exposed TileData::get_terrains_pattern()
and TileMapCell get_random_tile_from_terrains_pattern(int p_terrain_set, TerrainsPattern p_terrain_tile_pattern);
one way or another.
No, really, this has nothing to do with center bits. The center bits are the same in both cases.
Same thing happens without center bits set.
As you show it yourself it is easily worked around by placing water tiles before road tiles.
No, that doesn't work. It only works if you put a water tile then replace it with a road tile.
If you need copying the whole level, you can simply copy the tiles directly and not paint them with the terrain system.
As in the video, the autotile system made the pieces of the city connect together as it's building. It's an effect I put together quite quickly and easily. I'm not super attached to this particular example, the point is that any time someone attempts to connect a design at runtime they are likely to end up in this pitfall.
No, really, this has nothing to do with center bits. The center bits are the same in both cases.
I mean, it's not because the result is the same in your situation that they do not matter. Here, the removal of the center bit likely caused tiles to be "less likely" to be chosen. But since all are missing the center tile, they all got their internal score (the one that determine which tile should be used given a set of terrain constraints) lowered by the same amount. As a consequence, the same tiles get chosen anyway.
No, that doesn't work. It only works if you put a water tile then replace it with a road tile.
Yeah that's what I meant, sorry if it was not clear.
But anyway, I am not going to continue discuss that forever. The current internal data and algorithms are what they are, allowing a lot of new useful behaviors (like drawing paths), so I will not accept a rework that would remove those new features. I however understand your issue, and I am pretty sure it should be possible to implement a solution while still keeping the current possibilities of the new system.
So to sum up:
Just to make sure I understood the conclusion. So deterministic behavior is still in the cards, as a boolean on a per TileMap basis?
By deterministic I mean that the center bits are enough to determine what the terrain looks like, if the bitmasks are complete.
Well, that's obviously very disappointing to hear for me, but I still hope for the best.
I will look into making a plugin to implement terrains in a way which is useful for those who are struggling with the existing one. That's probably a better approach to making everyone happy.
Describe the project you are working on
General 2D games, though I have a focus on puzzle or casual games which rely heavily on tilemaps.
Describe the problem or limitation you are having in your project
The terrain system in 4.0 is a replacement for the autotiling system in 3.x. Whilst it is designed to be more powerful and usable, it has a number of issues and behaviors that impact its usability. It also regresses on a number of features from autotiling.
Editing terrains affects neighboring tiles in unexpected ways, often altering their type.
https://user-images.githubusercontent.com/33663279/195207033-23d72638-dfee-409b-8011-7ba7d2160881.mp4
https://user-images.githubusercontent.com/33663279/195207050-1a79e320-0318-47c8-b9c9-5a7ee354afdb.mp4
Terrain sets do not play nicely at all.
https://user-images.githubusercontent.com/33663279/195207224-e4d5bcf8-8fd6-4817-a21c-f4b9550cde10.mp4
No substitute for
_is_tile_bound
in 3.x. No way to make different types of terrain interact like you could in 3.x with autotiling.https://user-images.githubusercontent.com/33663279/195207296-eceb0041-2880-454f-bc95-3544b6cfe491.mp4
Results depend on painting order.
https://user-images.githubusercontent.com/33663279/195207535-40f7207a-d705-4d8a-9a23-386b9af6e94c.mp4
There are other similar behaviors, but hopefully you get the idea.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
There are four key changes which I believe will both improve the usability of the terrain system, and push it beyond what 3.x could do:
ignore_empty_terrains
flag)Whilst each has a justification, the overall goal would be to reduce the complexity of the terrain matching algorithm, whilst also increasing its flexibility and stability of behavior. There are two key ideas here: solidifying the data-centric design of tilemaps, and linearizing the constraint satisfaction problem.
Enforcing that each terrain tile is correlated with a terrain type gives fixed constraints for fitting terrains. This is also generally good for the user, as the terrain types they place are invariant. If a user places a ‘water’ tile, for example, that should be adhered to by the engine, and not changed to a better fitting tile of a different terrain type at a later time. Any game with precision design is going to have that requirement (e.g. platform games).
Grouping terrains into terrain sets, as a feature, adds some complexity and constraint to the user, but terrain sets don’t really seem to offer any specific advantage. I understand that they are there to limit/define terrain interactions, but seeing as no such restriction existed with Godot 3’s autotiles, it feels like the terrain sets are only there because a similar feature exists in other editors such as Tiled.
Multiple peering bits to allow generalized connections between tiles will linearize the constraint satisfaction problem that occurs when trying to pick tiles for terrains. It would allow individual cells of the tilemap to select terrain tiles without needing to propagate constraints to their neighbors, nor care about how their neighbors connect to them (if at all). That way, tiles can be picked in any order, via a simple search of the possible options, and will behave consistently.
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
When a tile needs to connect to its neighbors, it looks at all the tiles matching its current tile’s terrain type. For each tile, it checks the peering bit arrays against the neighboring tile terrain types. These are graded and the tiles that gets the best score is placed.
I have taken some time to mock up how this would appear:
https://user-images.githubusercontent.com/33663279/195207979-6fd7e174-2247-4892-a7ab-4a1accbbc714.mp4
https://user-images.githubusercontent.com/33663279/195207989-c1e98662-20e1-4f1a-b823-c042613a87c5.mp4
These were calculated using the following scores for peering bit (arrays) for connections to neighbors:
If this enhancement will not be used often, can it be worked around with a few lines of script?
The terrain system will be used in a significant amount of 2D games, both in terms of editing and designing levels, and in playing them too. It will be used very often.
Is there a reason why this should be core and not an add-on in the asset library?
The terrain system itself is a vital feature. For example, here is a user requesting that they want to make a layout in a similar (but simpler) way to the incredibly popular game Celeste: https://github.com/godotengine/godot-proposals/issues/4689#issuecomment-1168638364 Godot should be able to do such a common and popular design out of the box.