What Is and Isn't Tilemap good for?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By ZeroPointOneZero
:warning: Old Version Published before Godot 3 was released.

I’m fairly new and find Tilemap a weird thing. I understand it was intended primarily for static terrain, but I’m sure I’m not the first person to question what else it can be used for. I spent a long time trying to think what Tilemap is and isn’t good for but I can’t really decide on anything.


From what I understand Tilemap can do:

  • You can attach a script that attaches variables to various IDs
    indirectly. So if you have say a grass tile and a dirt tile next to
    it, you can detect that there is a dirt tile next to the grass tile
    and spread it.
  • You can also seem to “move” tiles so if there’s a dragon tile at
    (0,0) you can move it to say (0,1) by simply erasing the old dragon
    and making a new dragon at (0,1)
  • You can also change tiles into non-tiles via script if necessary.
    (Like turning an egg tile into an NPC non-tile entity)

What you can’t seem to do:

  • Is rotate or translate tiles which makes it awkward to add moving
    platforms into the mix or just cool-looking rotating tiles.
  • Is make non-sprite tiles, which makes the possibility of making ASCII games impossible
  • Can’t easily edit or alter the Tileset
  • Can’t really give scripts to individual tiles (Like say if you had an elf npc at (0,0) and an elf npc at (10,0) you can’t have different AI between the 2)

So Tilemap can do a lot of things, but also has a lot of shortcomings.
It makes me wonder if you should or shouldn’t use Tilemap for various projects.

Would you guys consider it to be appropriate to use Tilemap for creation of the following projects:

  • Chess/Checkers
  • Conway’s Game of Life
  • Rougelikes (you’d have to use sprites)
  • Terarria(or a 2D Minecraft) clone
  • Harvest Moon clone
  • Bejeweled/Puzzle Quest clone
  • Inventory and/or GUI menu

I’m sure it’s probably possible to make all of the following with Tilemap but is it worth it and is it the right way to do things? If not, what would alternative measures be?

Hopefully it is not too complicated a question. Just wanted to know alternative opinions on this.

:bust_in_silhouette: Reply From: puppetmaster-

You can do what ever you wan’t with tilemap, but not directly with the tilemap node.

As en example look at this project darkhours.

You can use the tilemap node also as an data object for your game levels.

  • Tile as starting position for player/monster.

  • Tile as position for special tiles door/button/traps. (replace them on loading with scene)

:bust_in_silhouette: Reply From: Zylann

I use tilemap for its initial purpose: build all parts of the world that are tiled so it’s more efficient to edit and more efficient for the engine to render. It’s like a terrain of static things.

If I ever need to add something that can move, rotate or mark a trigger position, I would do that with a node, not a tile (or use a script, read below).

Sometimes I use another layer of Tilemap for marking areas, but mostly because they are bound to tiles as well with the same constraints.

For the same reason the Particles node exists instead of a bunch of Sprites flying around, I see Tilemap as both a tool and engine optimizations technique. Optimizing requires constraints (using a grid is one) but that doesn’t mean you are limited to what Tilemap provides. You can think differently to add new features to it.

For example, in my game I needed to make some tiles emit particles. The “node” way would be to add a Particles node to every tile, but it’s tedious and wastes a huge amount of time and resources the bigger your map is. So instead, I’ve gone through the “tile” way: I created a script that picks a random position one time per frame on the visible world rectangle, and if this lies into a specific type of tile, I draw a particle from the script (no need for nodes). It is surprisingly cheap for a pure GDScript technique :slight_smile:

Another example: I need to make a tile “bump”, so it really creates a moving sprite for a brief instant. Tilemap doesn’t allow that. So what I did is to spawn an animated sprite only at the required position, then hide it when the animation is finished. If the whole tile was moving, I would have removed the tile and spawned its animated version as a node, and when it’s done I would place again the static tile.

The games you listed can perfectly use the tilemap, although I’m not sure yet how performant it would be for Conway’s game of Life or the tiny tiles of Terraria (maybe it is? would be worth trying, always test before optimizing stuff).
You can implement techniques like I described to get the extra effects.
The only bit I’m not sure of is frame-by-frame animated tiles. Sure you can script that too, but I’m surprised Godot doesn’t have support for it.

To save tilemaps we need to mess with ResourceSaver and save the part of the scene tree at the root of the tilemap layers. We can mess with ownership so that the tilemaps are owned by a “mapgen” object and sprites and such are owned by some other object. This acts as a filter so only the tilemaps get saved. The level is reloaded as a scene then placed into the game’s scene at the appropriate node. This works better on large “infinite” sandbox maps if the map is generated (and saved) in chunks of fixed size. Each chunk would have a parent node root with the tilemap as a child. Within a chunk the upper left tile is always 0,0 and when loading a chunk the root node of the chunk is translated to move the loaded chunk into the correct world space coordinate position. So for instance you’d load the origin chunk and translate it 0,0 but the x+1 chunk (assuming 16x16 chunks) would have the root node moved to 16*tile_width,0 the x-1 chunk -16*tile_width,0 the y+1 chunk 0,16*tile_height the y-1 chunk 0,-16*tile_height the x+1,y+1 chunk 16*tile_wdith,16*tile_height, etc.

There are caveats if multiple layers are used. If the layers are fixed (don’t move relative to other layers) it’s okay to generate the chunks in such a way that each chunk has all the layers within that chunk region. This would net the best compromise between file/object count and flexibility (map layers cannot scroll independently).

If however the layers use parallax and thus move relative to one another then each layer needs it’s own chunk system (a separate chunk ends up being made at each layer). This creates a large number of files and could be slow due to the large number of additional objects in the scene.

Mobiles (sprites) need a bit more work to move correctly on such maps since their movement scripts need to child them to the appropriate chunk’s tilemap. Easiest way to move such an object is to temporarily set_parent() it to a non-visible “black hole” object, calculate which chunk and position modulo, set_parent() it to the appropriate tilemap within the chunk (based on layer the object should be in) set its translation to ( world_x % (chunk_width * tile_width) , world_y % (chunk_height * tile_height) )

PS: There’s also all sorts of edge cases to watch out for such as moving a sprite to a location with no chunk (should one be created/generated?) or if the chunk is not loaded (it needs to be loaded in). Chunks could load on the fly if small enough and only one or two need to load but when a whole region of chunks need to load a loading screen with progress bar might be appropriate. Et cetera.

gau_veldt | 2018-10-29 00:27

:bust_in_silhouette: Reply From: eons

Tilemaps are great for maps based on static map of tiles (…) but not limited to them, the class have a lot of exposed data you can use.

You can change specific tiles, assign full tilemaps to paths and even negate scale to mirror a tilemap.
Is possible to animate individual texture of tiles too (moving texture region).

Of course, if your game is not “tiled”, there is no point on making stuff more complex with a tilemap.
Even Tiled offer Background and Object layers for things that are not “tiled” so you can use the tile layers just for the tilemap proper.

-A chess game will have the full state in an array or something like that, no place for a tilemap here, just a bunch of sprites for representation.
-Conway’s Game of Life could be possible, but again, using the tilemap as representation (since you can access and modify individual positions), I can think using a cellular automata like Loren Schmidth for live generation.
-Roguelikes, like is the best for the genre when generating maps, of course, the interactive objects will not be part of the tilemap node (maybe a few like simple doors).
-Terraria, well, you can make blocks/areas of tilemaps one next to the other, biome based tilemap generation, adding removing “wall” tiles (like this) , you will need a lot of extra data (more nodes maybe) for non-tilemap objects in each area and a lot of work on optimization for loading and saving region data.
-Harvest moon, for the general maps, yes, for the rest you will need to make structures (a good class hierarchy, groups design, etc.) to make your life easier.
-I still have a lot of problems looking for the best approach of match-X type puzzles in Godot but using Tilemap no, oh, gods, no.
-GUI? NO, please, use Control and learn to work with themes.

Would you use a Tilemap if you were going to not use it to draw tiles during design time but create it all from code? For a game like the Ultimas where you have looped maps. I didn’t see an easy way to do looping directly with Tilemap but if drawing the tiles from code would be fairly easy. But at that point does TileMap give you any advantages versus just drawing to the viewport?

DigitalMan | 2019-12-02 20:35