godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.2k stars 21.21k forks source link

Tileset: Neither Autotile nor Atlas Tile Priority allow "per Tile" priority #36972

Open golddotasksquestions opened 4 years ago

golddotasksquestions commented 4 years ago

Godot version: 3.2.1.stable

OS/device including version: Win64

Issue description: My goal is to have a Tile with 8 Subtiles and every time I paint a tile, a random one out of those 8 is picked. This is what the "Priority" tab in the Tileset is for.

Both Atlas texture as well as a Autotile have Priority tab. So I assumed a Tile with 8 identical bitmasks, should provide me with 8 randomly chosen Tiles, if every tile is set to the default 1/8 priority. At least according to GDQuest, 1/8 should mean that out of 8 painted tiles, the probability for each subtile to appear is 1.

I would expect this to work, however what seems to be the case is that priority only takes effect, if there are multiple tiles for the same bitmask, and only if the bitmask rules return true.

As a consequence, despite Atlas Tiles having a "Priority" tab, it seems to have absolutely no purpose or effect: tileset_priority_atlas

Autotiles without a bitmask set will also show no effect of priority, just like with Atlas tiles: tileset_priority_autotile_nobitmask Note the 1/0 there.

If you set the 3x3 bitmask to fill the entire tile, all tiles surrounded by other tiles, will be affected by "priority", but not those that are not surrounded at all sides: tileset_priority_autotile_full

If you set the 3x3 bitmask only in the center of each tile, the opposite is the case, only tiles not surrounded by any other tiles will be affected by the priority setting: tileset_priority_autotile_center

The desired result however, would be to allow the user control over which tiles are set according to priority and which are not. The way bitmaps are currently set up, seem to make the priority feature either not working or useless.

See it in action: tileset_priority

Minimal reproduction project: Tileset_Priority_issue.zip

PS: If you wonder why Atlas tiles don't show up in the right color: https://github.com/godotengine/godot/issues/36964

zzz-assault commented 4 years ago

Just stumbled over this issue, as I wanted to optimize my proc gen programm with ATLAS instead of AUTO_TILE. And I can confirm, that the priority system of ATLAS has no effect at all, it will always pick 1st tile / icon tile.

Regarding AUTO_TILE, here the priority system is working for my needs, you just have to use the WILDCARD function of the bitmask settings (i. e. set all 9 bits to WILDCARD).

golddotasksquestions commented 4 years ago

you just have to use the WILDCARD function of the bitmask settings (i. e. set all 9 bits to WILDCARD

@zzz-assault How? I can't find anything about a wildcard in the Tileset docs, be it the tutorial or the API, be it 3.2 or latest.

zzz-assault commented 4 years ago

@golddotasksquestions Wildcard Bits can be set by using "Shift + LMB" in the autotile editor. They are marked with a blue checker board pattern.

You can find more details in the PR #27565

And i'm sure that there should exist a youtube tutorial, just search for wildcard.

golddotasksquestions commented 4 years ago

Thanks, but what does shift-clicking do? What does "adding a wildcard" mean in the context of Tileset bitmasks? There is no tutorial on Youtube and no documentation. I don't understand C++ code. If my goal is to have random Tiles placed, what should my wildcard/bitmask map look like? If I fill the whole tile with wildcards and set adjacent tile, the new adjacent tile will swap out already placed tiles as well. The same is true if the center bit is set red in a 3x3 minimal and surrounding bits are wildcards. If there is one the center bit set, and it is set as wildcard, the effect is the same as if you would set a regular red bit in the center.

zzz-assault commented 4 years ago

I can't provide any documentation or tutorial, but bitmask means, that it's trying to match correct tile-images based on corresponding tiles. The WILDCARD simply ignores this bit (it's irrelevant if it's hit or not hit the same tile), so it's possible to use less images for all combinations (example: if you don't need a corner tile, you could WILDCARD this bit the relevant tiles) .

For your use case, set ALL 9 (means also center) bits of the 3x3 minimal to WILDCARD, then it should work.

golddotasksquestions commented 4 years ago

Thanks for the explanation!

For your use case, set ALL 9 (means also center) bits of the 3x3 minimal to WILDCARD, then it should work.

Unfortunately for my usecase it does not work because tiles that have already been set will change if there is an adjacent tile being set. I suppose this is what the Atlas priority would suitable for, but with Atlas tiles priority exists but does not work at all.

zzz-assault commented 4 years ago

Lucky you, while looking at the ATLAS Tilemap mode, I've found the missing part to get it running within the editor -> you need to enable priority in the TILEMAP for the ATLAS tile, then it should work as you expect.

enable-priority

BUT: I haven't found a way to get it working for "proc gen" content, I assume there is a deadlock / fixed connection between the editor setting (mentioned above) and the priority system. Need to check it more in detail.

zzz-assault commented 4 years ago

@golddotasksquestions With the "enable priority" flag and also the PR created (hopefully gets merged soon), all mentioned issues should be covered. Or still anything not working?

golddotasksquestions commented 4 years ago

I have no idea how I could have missed that. Maybe I just have only looked at that spot when I had an Autotile selected. In that case it says "Disable Autotile". Anyway, thanks a lot @zzz-assault !

With the "enable priority" flag and also the PR created (hopefully gets merged soon), all mentioned issues should be covered. Or still anything not working?

Yes! Being able to use that feature when generating Tilemaps would be very much desired!

EDIT: After testing for a while with Atlastiles Priority enabled, I noticed the surrounding tiles changing again, but only when erasing the second time! :( I guess this means it's not completely fixed ...

EDIT2: checked in 3.2.2 beta2 and it's the same.

erasing_atlastiles_neighbors_issue

zzz-assault commented 4 years ago

@golddotasksquestions Yes, I know this behavoir. It is also stated in the PR (as additional remark). But the fix for it is not yet included in the PR, as this could have negative impact on parallel used AUTO-TILES -> therefore I put it to discussion in the PR.

Additional Remark: (not done change) I would also delete the following code in "TileMapEditor::_set_cell", as all ATLAS tile interactions are done based on the actual "cell", only in this case (which is deletion of tiles in the Tilemap Editor) it's updating the "bitmask_area" (3x3 field of cells), which causes also to reset all surrounding tiles. I don't think that this was the intention of the implementation and could also confuse users (only drawback I can see = it could have an impact on AUTO-TILES directly surrounding the deleted ATLAS tile). Remark: no need to change to "update_cell_bitmask" as the cell is set to empty in this case (-1).

  } else {
      node->update_bitmask_area(Point2(p_pos));
  }
guilhermefelipecgs commented 4 years ago

After testing for a while with Atlastiles Priority enabled, I noticed the surrounding tiles changing again, but only when erasing the second time! :( I guess this means it's not completely fixed ...

This happens because we need to guarantee that surrounding tiles that have bitmask (if is autotile for example) will be updated correctly. The way the tilemaps are implemented, we cannot distinguish which tile type was used (atlas, auto or single) for each cell.

Therefore, when deleting, we always need to update.

guilhermefelipecgs commented 4 years ago

And if you're using a random tile (based on priority), I don't see a problem updating it.

AllenKll commented 4 years ago

There's a lot of discussion about Atlas, but regarding autotile, is there a fix for this planned too?

guilhermefelipecgs commented 4 years ago

@AllenKll Autotile already works, but you need to use a 3x3 (minimal or not) bitmask and setup wildcards to get the same result.

Like this: Screenshot from 2020-05-23 14-07-27

golddotasksquestions commented 4 years ago

@AllenKll @guilhermefelipecgs As of Godot 3.2.2. beta3, this Autotile set up (center bit, plus wildcard all around) has the same issue that exists when erasing the Atlas tiles: the neighboring, already set tiles get changed too. Only difference is with Atlas tiles it only happens when erasing, with Autotiles it happens when erasing or drawing tiles next to existing tiles. I suppose that's what AllenKll meant.

guilhermefelipecgs commented 4 years ago

@golddotasksquestions For autotile this is expected, it necessary to recalculate the bitmask/priority every time you draw/erase.

golddotasksquestions commented 4 years ago

@guilhermefelipecgs I don't understand why you say this is expected. If I put the wildcard all around, I would expect no change, regardless what happens around.

golddotasksquestions commented 3 years ago

I just tested this issue in Godot 3.4 and it is still present.

func _ready():
    for x in 10:
        for y in 5:
            $TileMap.set_cell(x, y, 0)

When you try to set an Atlas Tile in code, it won't take the Priority setting into account at all. The "Priority" checkmark in the Editor also makes no difference.

This make Atlas Tiles useless for procedural generation. Which is bad, because the only alternative (Autotiles), will also change the neighboring tiles.