Neither terrain nor Wang can handle a "blob" tileset

I have the following set of 47 tiles, which happen to be a complete “blob” tileset as suggested in the Wang brush documentation.


The terrain brush fundamentally cannot handle these. Terrain is defined by corners, which means the maximum number of distinct tiles is 2^4 = 16, whereas I have 47 distinct tiles. (There is obviously no way, for example, to encode the 1×1 tile in a terrain definition.) But that’s not a big surprise — terrain support is designed for transitions, whereas these are edges.

I was really excited about the Wang support, both because I thought it might solve this problem, and because it would even be able to draw random variations (e.g., stick an occasional decoration in where an otherwise solid black tile would go). Unfortunately, even though this is a cromulent Wang set, it still doesn’t work. The setup looks like this:

(I’m not sure whether the green is helpful here or not, but I can’t have a set of only 1 color and there doesn’t seem to be a Wang eraser, so I suspect I need it.)

If I try to draw on an empty layer with the Wang brush, absolutely nothing happens. If I use the Wang brush to draw on existing terrain, I can only poke corner holes by using the green corner, otherwise nothing happens:


If I use the regular brush in Wang mode, I get a tile arrangement that is technically correct, but not quite what I was going for:


I think the problem is that I don’t have “maximal” pattern coverage. If I start with an empty layer and try to draw either corners or edges, I’d end up with tiles that have no Wang colorings except for either one or more corners or one or more edges. But this “blob” arrangement has no tiles like that, and given the aesthetic, it can’t have tiles like that. If two tiles touch at a corner, then either they must touch at the adjacent edges as well, or they aren’t actually connected — after all, there’d be nowhere for the art to go. I can’t encode this rule in Tiled, and since it ignores any coloring attempt that has no valid tile — I assume because the colors are referenced from the tile and not actually stored separately in the map — there’s no way to change a tile from “completely uncolored” to “colored on a corner and its adjacent edges”.

I believe this would work if Tiled had explicit support for the blob rule — that a colored corner requires colored edges — but I don’t know the right way to fit that into the existing and highly generic Wang implementation. For one, it only makes sense if edges and corners use the same set of colors, whereas the two sets are independent right now. More awkwardly, it only works in this particular case if “nothing” is an explicit color — otherwise, given my example setup above, there’s no reason that red corners should force red edges but green corners should not.

But even then, I’m not sure how I’d draw the 1×1 tile using the Wang brush. Perhaps the core problem is that these tiles are ultimately defined by their centers, which is the one place in a tile that neither terrain nor Wang understand.

If it helps, the one tool I’ve used that can actually do this is Godot, which recently got an “autotile” feature. It’s not documented at all, and the configuration UI is really clumsy, but it’s basically magic once it’s set up. You assign tile connections as a bitmask (here set to “3×3 minimal”, but there are also “2×2” and “3×3” modes):

And then you just draw.

Peek 2020-08-02 13-09

I would love to be able to do this in Tiled, and in fact I think Tiled could do it better — I also have a variant of these tiles with grass on top, which Godot’s bitmask can’t express, but which Tiled’s multiple Wang colors potentially could.

The problem is indeed the incompleteness of the tileset, and Tiled doesn’t handle that particularly elegantly, even for well-known subsets like the blob tileset. When using Wang tiles, Tiled also doesn’t understand “empty” as a valid choice, and with a tileset like this, that’s an issue.

Fortunately, you can set up automapping to give you equivalent results:

Here is the rulefile I made, but since it’s made with a tileset consisting only of the image you included, you’ll probably need to rebuild it with the actual tileset. (7.3 KB)
There are 47 input_Ground layers, one filled with each of the tiles, so that “Automap While Drawing” produces correct results regardless of what’s been automapped already and regardless of which tile you draw with. The things to pay attention to are the regions_output and regions_input layers, and the arrangement of the tiles in any of the input_Ground layers.
This ruleset could be made more robust in interating with other tiles by removing the strictEmpty property and replacing all the empty slots with inputnot_Ground layers containing the tiles of this tileset, so that instead of looking for empty cells, the rules match any cells not part of this tileset as “empty”.


Yyyeah, I’d seen automapping suggested in an older thread, but I suspected I’d need the 47 input layers (plus even more to match special pieces like slopes) and wasn’t looking forward to setting them up. But thank you for doing it for me. :slight_smile: Maybe I should write a script to generate an automap for an arbitrary set of blob tiles, since I always arrange them the same way.

1 Like

If you’ve got things like sidescroller slopes, it would be much easier to set up automapping rules that are meant to be applied once, not while you’re painting. It’s a lot less fun-looking and makes iterating more annoying, but it works and requires much simpler rules, since you only need to account for one type of tile as your input.

Wouldn’t I still have to account for every type of tile to be able to modify the terrain later? Or have to replace a bunch of tiles with the input tile by hand before running the rules.

I did end up writing a script to generate a map file, and while I didn’t teach it about slopes yet, it handles the grass/dirt variance well enough. (It loses the grass in some cases only because I didn’t make grass variants for every possible tile with a top surface.)

Peek 2020-08-04 12-24

The grass tops are added by a separate rule file; unfortunately it doesn’t seem possible to automatically erase them when they should no longer be there.

Correct, the simpler method only works on an initial set-up and cannot be easily iterated on. For my own game, which is very heavy in slopes and variant tiles, I handled the main layers (the ones with the gameplay stuff, the ones that need the most iteration) with custom tools because it was easier for me. I currently only use Automap for background terrain, which doesn’t need frequent changes and is easy to iterate on.

As for the remaining grass tiles, perhaps you’re missing rules that explicitly erase the grass tiles when they’re above an empty tile?

I only have a couple variants thusfar, and generating the rules file automatically makes that easier to swallow, but I very well might live to regret this. :slight_smile:

I do have such a rule, but it doesn’t work; it seems that an empty tile in an output region is simply ignored, not erased. There’s a DeleteTiles property for the entire map, but that seems intended for deleting the entire layer and then recreating it solely from rules.

I found a thread mentioning this, and it sounds like erasing tiles via automapping has never been possible. A property for the output layer that enabled erasing would certainly be handy.

1 Like

Ah, that’s annoying D: The documentation makes it sound like it should be doable, but I guess the only real option is to not draw a tile at all.

One more reason that for complex tilesets, “Automap while painting” is sadly not a good idea >:

It appears the DeleteTiles only erases tiles in the intersection of the region where any input layers have tiles and the region you have modified. So indeed this option doesn’t affect the grass tiles both because they’re outside the modified region as well as because the input layer is empty at that location.

I’m not sure what behavior would make more sense in the case of “Automapping while drawing”. If we’d erase more tiles we could very well end up erasing parts of previously applied outputs that will not get re-applied within the edited region (which I guess is something that could happen already now).

For the case where automapping is applied to the entire map I could definitely consider changing this behavior so that all output layers are cleared entirely. It’s still fine as a map option rather than an output layer option I think, or would you ever expect to have some layers you want to erase and some that you don’t want to erase, within the same rule? I can’t really think of a use-case for that.

Thanks for this detailed analysis and highlighting the problem with the Wang brush! It’s not the first time it has come up (especially @eishiya has been asking for changes to this tool as well). I’m definitely planning to have a look into changing this tool to cover the blob case as well. I’ll also check out this feature in Godot.

Regarding the relevance of the center, actually in Wang theory it does not play a role because it is about whether tiles connect at the sides. But I see in this case we need it to distinguish the empty tile from the unconnected tile. The terrain tool did not have that need, because it changes only the corners of the tiles.

There are a few changes I’ll be trying:

  • Removing the distinction between corner and edge colors, since we don’t need it. If somebody wants to have separate colors for corners and edges this remains possible in any case.

  • For tileset marking and editing reasons, introduce a selection at the Wang set level whether the set is based on “Edges” (for roads / fences), “Corners” (like terrain tool) or “Both”. Maybe would be good to include “Blob” as explicit choice so we can apply its restrictions.

  • Enable “erasing” with the Wang brush, or essentially make transitions to “no color” work.

In addition, the Wang tool currently only understands perfect matches. When one can’t be found, it aborts the operation entirely. I think it should behave more like the terrain tool, modifying adjacent tiles to allow for the desired change. But this will be a rather more tricky change, and it should not be needed for “complete” sets.

1 Like