Godot 3.1.1
Hello, I'll try to be brief as there's a lot I want to cover, but I'm not trying to be disrespectful :)
I've been using the Godot tilemap/tileset and while it's got the basics good, it is failing in so many areas making it viable for use in a game limited, when you compare the features against most tilemapping engines. They are to do with the IDE, the tilemap, the tileset and the IDE. A few changes and it'll be great I'm sure. I'm new to it all so if I'm missing something obvious I apologise.
All my issues may be resolved by writing boilerplate code or adjusting how things are done, but the main premise is the whole point of a tilemap is it should encompass the entire map design and be self-contained.
I'll start with the basics first. This is just one main issue, but it's a pretty big one. I think it's all to do with working on maps that are not 'trivial' in size.
There is no cell selection, so there is no means of cut/copy/paste. This results in some pretty big problems:
a. You are starting your map which contains 100 rooms, many of there share similar parts (e.g. the floor layout on a topdown map, the entire room as it's a link room, the base section of a sideways platformer), a set of columns in a room, etc. (not altas sprites). If you want to repeat those at the minute you have to literally draw everything one cell at a time. This makes it near enough impossible to create a large game.
b. I've created my game, tweaked my character code and realised that a lot of platforms are one cell too high and need to be moved down. Currently I am knackered! I have to literally draw over everything one cell at a time. I may as well stop and give up.
c. There is actually a bigger issue with this, but I'll leave it for further down :)
I'm creating a large map and I know the screen size because the viewport is shown, however move past that screen and there is no clue how big my viewport is in tiles so I have to remember the width/height and drawing unlinked rooms is pretty hard. What is needed is an ability to have repeated thicker gridlines at vertical/horizontal repeats so I know where to put each level equally in the map. This is probably useful regardless of a tilemap and a good IDE update for the editor
Almost every issue relates to this: there is no abstraction in the tilemap/set - a tilemap contains a basic sequence of longs that state the position and tileset id, and the tileset points directly to a single tile element. This leads to the following problems that cannot be fixed with this basic structure.
Meta data
a. You have a tile, You want to add a 'weight' to it so when you're working out routes you know the cost of going over the tile, i.e. this is water, land, mud, lava, a door, etc.
b. You have a tile and when the player moves over it you update the score
c. You have tiles that trigger some basic custom text on the screen, you want to hold it within the map, e.g. when you trigger a tile you get a status update on screen
Layered blocks
This is not about layers, it's about individual blocks.
a. You have a side scrolling tilemap and you have tiles, it's a basic soil with the top layer being grass. You also have another for ice, lava, mud, etc. You then decorate each one with something, e.g. a fossil, a diamond to make them less uniform. You then want to modify them in real-time. At the minute you would have to create 100 tiles to accommodate this.
b. You have a door tile that represents open and shut, you could add/remove tile ids but really what you want to do is simply show/hide a tile 'layer'
This is because you can only store 1 tile per location with 1 graphic. If you could add layered blocks per tile it would fix this.
The solution is to add an extra layer on top so that instead of tilemaps storing tilemap id you store block id, so no actual change to the structure is required at a superficial level. When I say block id I mean a level on top of a tile to hold tile and meta data for a location.
Let me show you a picture of a sample that explains all of this. Here we have a block not a tile and as such we can have the block layers mentioned as well as custom data.
a. You have a door with a neon light that flashes on and off
b. You have a radar tower with a basic rotating dot to signify it is working
c. You are creating a beautiful secret of mana type game and want a very basic waterfall or water animation
I'm not saying tilesets need a full animation player adding, but I am saying that, and again it's down to this one cell one tile id thing, some ability to animate is needed. Most simple tilemap engines let you specify a range of tile ids and an interval and a few basic methods to start/stop. That is all required.
I know before I start you are going to say this is available via multiple tilemaps, but it's not the same thing.
In a tilemap you need everything self-contained and that includes layers. Take a simple example of 4 layer map. Layer 1 is the ground, 2 is the player level, 3 is the foreground, layer 4 is an invisible layer where you put all your triggers, switches, etc for controlling the map logic. They are all linked and related. Moving them out to three tilemaps makes no sense. If for no reason than the following which are pretty much impossible using separate tilemaps
a. All the tilemap meta-data is per tilemap, so changing it in 1 means you have to change it in all of them to be consistent, and if you have many levels you have to change all of them
b. Layers are usually linked, so when you delete a tile you need to clear all the layers down (because your layers make up a layered scene, e.g. ground/doorway/cables in a topdown map). If the single tilemap had layers you could simply click a button on the IDE to work on 'all layers' at once
c. Going back to my issue on lack of copy/paste, if this was implemented you want to be able to select and move multiple layers at once. With multiple tilemaps you simply cannot do this.
I'm sure all this is easily my lack of knowledge as I'm just at the stage of playing at the minute, but I can see a lack of some functionality in the APIs, and are probably easily fixed with a bit of code, but it might be nice to have them built in
a. With a given screen or world location in pixels, what tile am I at?
b. A tilemap camera. If you have a tilemap that you do not want to be linked to the player (i.e. a scrolling game), e.g. a flip screen, or your tilemap screens are not necessarily to be drawn in the whole screen (e.g. you have a status bar) you have to create your own custom camera using the canvas layer. Would be nice to have a simple drag and drop camera2D controller
Change tilemap tile_data to point to data blocks not tileset ids (you could extend tileset data to add metadata, etc) but you lose any ability to dynamically change the data per tile
Change tilemap tile_data to have multiple tile_data items, one per layer
Create a basic tileblock containing a pointer to multiple tilesets along with metadata and an animation/sequence of blocks for animation
I expect you didn't get this far, but thanks anyway ;-)
- is not true, you can select multiple tiles and copy and paste them. IIRC you can even rotate said copied part.
I am referring to on the actual screen when you have a tilemap selected, not in the tileset editor, i.e. when drawing your map. None of the toolbar items work so when you select pan, select, nothing happens. All you can do is draw tiles. You can't even move around the screen - because you cannot select pan you have to either deselect the tilemap, use the middle mouse button or the scrollbars.
Unless I am completely wrong by this bit. If I am great, that's one thing, but the IDE is a minor gripe...
Simply, a tilemap in a game is nothing if you cannot easily animate the tiles. Godot does not provide this.
Isn't AnimatedTexture
specially made just for that?
@chucklepie, regarding your idea of layers, you're absolutely right about decorations, imo (static flowers, or patches of grass over dirt); you could currently do it with multiple Tilemaps, but the performance would be bad. However, I strongly think that all _active objects_ (let's call them that) shouldn't be part of Tilemap. Doors, towers, enemies, triggers, items to be picked up are something fundamentally different than the (mostly) static terrain represented by Tilemap. Since the map has usually orders of magnitude more tiles than there will be active objects, the cost of implementing them using Sprite+Area should be minimal - and we don't complicate the Tilemap logic. Besides that, this allows you to make more advanced things, like I dunno, towers over water, and doesn't force you to make multiple versions of an object tile for different terrain (tower on grass, tower on snow..). Also, since all these objects are Nodes, you can use groups, signals.. If Tilemap were to support all of that. it would probably have to contain half of the engine ;)
Another use for layers would be that you have a tilemap with tiles made for autotiling where the "dead space" (as in not bitmapped) is transparent. This is great for combining tiles, since you can layer any autotile over any other tile for transitioning between water, grass, dirt for example.
See the below example, which is a great tilemap from the Liberation Pixel Cup, where all the natural autotiling regions incoorporate transparency for this usecase.
Right now, this can be achieved by using multiple tilemaps, but I think adding the possibility to have layers would greatly increase the usefullness of tilemaps in this scenario.
EDIT: related to this great proposal https://github.com/godotengine/godot-proposals/issues/1769 even though the author argues against having layers for this usecase.
Closing in favor of https://github.com/godotengine/godot-proposals/issues/1769, as feature proposals are now tracked in the Godot proposals repository.
Most helpful comment
@chucklepie, regarding your idea of layers, you're absolutely right about decorations, imo (static flowers, or patches of grass over dirt); you could currently do it with multiple Tilemaps, but the performance would be bad. However, I strongly think that all _active objects_ (let's call them that) shouldn't be part of Tilemap. Doors, towers, enemies, triggers, items to be picked up are something fundamentally different than the (mostly) static terrain represented by Tilemap. Since the map has usually orders of magnitude more tiles than there will be active objects, the cost of implementing them using Sprite+Area should be minimal - and we don't complicate the Tilemap logic. Besides that, this allows you to make more advanced things, like I dunno, towers over water, and doesn't force you to make multiple versions of an object tile for different terrain (tower on grass, tower on snow..). Also, since all these objects are Nodes, you can use groups, signals.. If Tilemap were to support all of that. it would probably have to contain half of the engine ;)