Is it possible to add custom information to a tile (not tile set) in a tile map layer?

I’m using a tile map layer to create a world for a 2D Zelda-like game (seen from above). I want to create a sort of teleport between cells: when standing over one cell, the player gets automatically transported to the other. Ideally I would like to be able to specify both ends of the portal directly on the tile map (layer) on the editor (e.g., the destination coordinates for the other ‘side’ of the portal).
I know that I can add custom information to a tile set, but that would imply creating a new tile type for every single portal position. That’s very cumbersome.
The ideal workflow would be to click on a tile over the tile map layer, have a place with “custom” data specific to that tile, and add the information there.
I haven’t been able to find anything like this, have I missed something?

There are some solutions of how I have come up:

Every tile has its own data

In this situation, you should not place responsibility on the tile map. Instead, use a separate grid to store the map, and visualize it in the tile map by setting the tiles. After all, rendering and defining physics behaviors (such as collision shapes) is what tile maps are supposed to do.

Some of the tiles need to be marked

You could consider taking a not-so-good (yeah, looks weird) method. Initialize them at runtime, unfortunately, I couldn’t find a way to set it in the editor either.

I developed a level editor (which exports .tscn files) in my platformer, so I planned editing levels in-game after completing the editor.

Thanks for your reply.

After all, rendering and defining physics behaviors (such as collision shapes) is what tile maps are supposed to do.

Yeah, I get the impression that the TileMapLayer is mostly meant for side scrollers and not top-down. For example, I don’t need physics and terrains at all.

So far I have two layers: one shows the terrain (water, mountain, etc.) and the other I use for meta information: player and creatures starting positions, and the mark “portals”. Then I store in code a list of portals, specifying for each the coordinates. This works but it’s a pity that I cannot “mark” directly over the tile map where a portal should take me to.

I didn’t quite get it. I mean, it’s great for top-down, you can paint it in the editor, or generate the tiles in runtime (like Minecraft chunks). This reminds me of the dual-grid system.

I haven’t looked at this latest incarnation of TileMaps in GODOT.
Unless this aspect has been changed then you still need physics to enable collisions on Tiles.

I don’t need collisions. :wink:

In the end, I decided to have 4 special tiles (portal 1 to 4) that I place around the map in pairs, one for each entry/exit point of the portal. I scan the used tiles when I load the level and store a reference to each pair. This means I have a hard limit of only 4 portals per level (which of course I could increase to many more), but it works and I can still use the tile editing functionality.

It would be great, though, if each Tile in the map could have a dictionary of arbitrary data that I can modify through the editor.

I might have understood what you’re looking for now. It’s not related to tilemaps, use ordinary nodes instead, which can be moved and inspected in the editor. The only thing to be concerned about is detecting the portal. There are two easy ways I came across:

  • Projecting the node position to the tile coordinate
    var tile_coord := tile_map.local_to_map(portal.global_position)
    
    and simple checks with that coord to integrate with your current tilemap system.
  • Create an Area node for the portal, and one for the player. This should be your first choice.

You could do this by creating your own cell class that you overlay over the tilemap. When you instantiate each cell related to the tiles you store a resource with export var that has all the needed info for your unique tile. When you move to a tile/interact with it, you can use the tilemap coords to search a cell dictionary using those coords. This will give you the resource ref with the associated variables. Voila.

That’s an interesting idea, but is far as I can tell from the documentation, there is no cell class. Do you mean TileData?
But if I’m going to create custom cassles, I would just replace TileMapLayer, I think.

No, I am talking about using class NameHere, and create custom class that you then would use with the coordinance of the tilemap to create a dictionary with the tileid as key, and store the info you want in there.

That way you can easily search the unique cell class data by using your tilemap to find coords that you use as the key to find the data in the dictionary.

class Cell

var unique1
var unique2

func _init(arg1,arg2):
unique1 = arg1
unique2 = arg2

Thanks for the suggestion, and sure, I can do something like that, but my original question is about using TileMapLayer for storing additional information (as it’s already well integrated with the Godot Editor and would make editing maps way easier), but it’s clearly not possible.

The reason I suggested this method was because when I tried to do the same thing I wasn’t able to find a solution.

The custom cell class solution is also very flexible and allows you to store as much info as you want/need. In tandem with a tilemap it allows easy setup and searching as well.

I have used this method as well to create a pseudo gridmap in 3d, without using the GridMap node.

If you want to store information associated with your tilemap, I feel like this may be the best solution for you.

As far as your specific desire, to have portals that you can change coords via editor you could do this with @export var. While you are then setting up the custom cell class when you set the data for the cell, you would have a check if they are at the coord for portal, and setup the data for the portal cell.

I assume you need the following functionalities:

  • Easily edit the portals and their destinations in the editor
  • Get the portal from a coordinate
  • Get the destination from the portal
  • Check whether the player is at the portal

So essentially, you need to detect portals and edit the destination. You could create the portal as a scene, with @export var destination. Thus, you can create it by instantiating the scene, edit the destination (can be another portal node or a Vector2) in the inspector, and detect it by a global dictionary or Area2D nodes.

There’s a feature called scene tiles, allows you to make, well, scenes as tiles. Unfortunately, you can’t edit the node in the inspector because the scene tiles are instantiated in the first frame.