Quality of Life feature suggestions

I’ve recently begun proper level production in Tiled and I’m working with many complex maps rather than playing around with a few simple maps, and I’ve run into a bunch of little bottlenecks and annoyances. This is a big list of QoL features I’d love to see in Tiled that would reduce my headaches :] I’ve mentioned some of these elsewhere, but I’m repeating them just for completion’s sake.

  • Allow toggling visibility of other maps in the World. The dozens of other maps on the screen can be a distraction, especially when maps overlap. I’d like to add new maps to the World as soon as possible, but as it is, I have to leave it until I’ve mostly finished working on the map. When world visibility is Off, then the other maps should only be visible while using the World tool.
  • Allow setting an anchor point when using stamps, so that random stamps of varying sizes can be used more predictably and precisely. For example, I often need to place trees in specific locations on the ground, but if my random stamps have different heights, then it’s very difficult to get the base of the tree where I want it. An alternative to this would be the option to randomly select a single stamp, and then keep that stamp active until it is placed (at which point, a new stamp would be randomly selected), instead of selecting a new stamp every time the cursor moves.
  • When selecting objects, prioritize objects in the currently selected layer, rather than objects in the topmost object layer.
  • Allow deselecting everything with a hotkey/menu item (e.g. Ctrl+D), both tiles and objects, regardless of which type of layer is currently active. I often find myself having to go back to the Select and Select Objects tools just to deselect things after I’m done with them.
  • Allow pinning the current view/scroll position in a tileset in the tile palette. Currently, when a tile is selected with right-click, the tileset view scrolls to show the tile. This is often useful, but for many of my uses, it isn’t, and requires me to have to scroll back through my tileset in both X and Y to get back to where I’d actually want to sample tiles.
  • When selecting an object via the Objects list, if it’s already in view, don’t center the view on it. My maps are often small enough that they fit on the screen, and selecting objects this way just means I have to reposition the view again and again. Since this is useful for maps with many objects though, this different behaviour should be optional.
  • Show the object’s colour in the Objects list, instead of showing the default blue colour. I have objects with similar names, and colours (corresponding to object type) help in distinguishing them.
  • When highlighting a layer, have an option for a light colour as the fade colour. The dark default doesn’t work well with dark tiles, as they blend in.

Now that Tiled has Projects, a few other features I’ve wanted for a while finally make sense:

  • Search for layers and objects by name and/or object type within a project. While my game is in development, I have numerous placeholders, and it would be nice to be able to get a list of all the placeholders to replace them with their final data later.
  • Get a list of all the values for a particular property (including custom properties) within a project, and the maps where the layers/objects with those property is located, ideally as text that can be copied. Having them all in one place would make it easier to look for typos and nonsense values. It would also be useful to be able to find maps, layers, or objects of a specific type that lack particular properties, to find ones where I’d forgotten to enter them.
  • Generate usage frequency data for the tiles in the tileset(s) used in a project, both for a particular map, and in the project as a whole. This would be very useful for finding unused and underused tiles, so that I can use them more or replace them with something more useful. It would be cool to get this presented as a heat map with the same dimensions as the tileset image, perhaps even displayed over the tileset image in the tileset editor.
  • Allow mass-exporting maps in a project to a particular directory. There should be an option to export only opened maps, or to export all maps. When exporting unopened maps, they should be opened, exported, and then closed. This would make things less tedious when changing the export options, or making changes to many maps.
  • Allow setting the tile layer format and possibly other map properties (including custom properties) for many maps at once.
  • When a tileset image changes size, allow updating all the maps in a project rather than just the currently open maps.

Some of these could be accomplished via scripts once projects are available via the scripting API, but I’d love to see them as included features.

1 Like

Created https://github.com/bjorn/tiled/issues/2859 for this.

I like this idea, and thanks for reminding me that we already discussed this half a year ago. :slight_smile:

I think that’s generally a good idea, but I worry a little about it being less intuitive since people would generally expect the top-most to be selected first. Also, not everybody may be using the groups in a way that makes this feature useful.

What if we would only do this, when “Highlight Current Layer” is enabled?

That’s what Ctrl+Shift+A does already, whereas Ctrl+D duplicates the selected objects. But you can change those keys if you want.

Created https://github.com/bjorn/tiled/issues/2860 for this.

Yeah, I can imagine this changing of view position can get quite annoying. Since selected objects are generally quite clearly highlighted I don’t think we need to make this change optional.

A nice idea! Of course they’re currently always blue because it’s using the icons I had made for the different object types. It will be an interesting exercise to make those colored dynamically, maybe even making them small miniatures of the actual shape of the object. I’ve created https://github.com/bjorn/tiled/issues/2861 for this.

Opened https://github.com/bjorn/tiled/issues/2862 for this.

I won’t create a lot of small issues about this now and I can’t commit to implementing them quickly either because most of them represent significant challenges. But, they do all match the long-term goal of the projects feature.

  • Regarding searching for objects in any map in the project, or searching for properties with certain values, the challenge is that it would require loading all maps in the project. For most projects, this will not represent much of an issue, but for some it will. To enable it in a scalable way, I think we need:

    • To categorize each file in the project with an asset type, so that we can quickly get a list of “all maps”. Unfortunately, we can’t rely on the extension here in the general case, since for example a .json file can be anything. This categorization needs to happen asynchronously and should be cached.

    • To change the way maps are loaded, such that we can load maps without loading all the images they reference, given that loading the images is the slowest part and takes the most memory.

    • To make the search field that pops up when using “Open File in Project” customizable with different filters and to make its search asynchronous to avoid laggy UI when searching lots of maps.

  • Generating usage frequently information for tiles, mass-exporting of maps or changing the tile layer format for many maps at once are all features that as you said are things that are good to do with scripts. But the scripting API needs to be extended to enable it. Right now I’d rather make it easier to find and share scripts than to hardcode such features, since anything I’ll implement will often lack flexibility for some person’s needs. The Projects issue is still open as a reminder to add a scripting API.

  • Finally, regarding the tileset image change of width (changing height doesn’t need updates to maps), my goal here is to change the tileset definition such that existing tile IDs are not affected. A mass update to all maps, stamps, templates, etc. should really not be required after such a change, and avoiding this is probably worth a breakage in compatibility (which should not be hard to update for). I’ve created issue https://github.com/bjorn/tiled/issues/2863 about this.

Thanks a lot for all the feedback!

1 Like

Thanks for the tip on Ctrl+Shift+A, I completely missed that one!

And yay, I’m glad you think some of these suggestions are good!

I’d rather see it as an preference option in the editor rather than depending on another option, so that people whose layer/group setups make sense with this can enable it. Enabling Highlight Current Layer with H is about as much trouble as hiding the meddlesome groups, at least for me.

I like the extra capabilities offered by this option, but I think it should be a new Tileset type (“Spritesheet”?), instead of replacing the current basic tileset. Though you say it shouldn’t be hard to update for, it’s still an unnecessary hassle. I also think the current style is very convenient and simple to work with in engine code, and worth keeping around just for that. I’d give up all ability to auto-update maps on resize before I give up this type of tileset ):

As for the searching features, since Object properties are stored as plaintext within map files, would grepping the files without loading them as Maps/Tilesets be an option? That’s what I basically do now, outside of Tiled. The regex is different depending on the file type, but the regex could be decided based on extension (I think ignoring files with unfamiliar extensions would be fair for this), and I don’t think it’s important to distinguish between filesets and maps when doing property searches (and tilesets won’t match object regex anyway).

While typing this up, I remembered another QoL thing I’ve run into, though this one’s probably more of a me problem:
In Photoshop, I can quickly show/hide several layers by clicking on one visibility icon and dragging to others, and it’ll set their visibility to be the same:
togglevisibility
I often try to do this in Tiled out of habit, but it drags the layer in the layer stack instead. It would be nice if Tiled had this same feature, or at least didn’t drag the layer if I click+drag on the eye or lock icons rather than the rest of the layer.

The current approach has a downside that I think is quite important, which is that the library needs to duplicate the logic with which Tiled sets up the tile rectangles. It means supporting the “spacing” and “margin” parameters exactly like Tiled does, which is frequently a source of errors. Actually storing the sub-rectangle of each tile should simplify the job of the library, which then only needs to read in this extra information to know which tiles to render.

Also note that compatibility will be retained as long as no tileset image width-change happened at all, which is still rather rare. And of course as long as the tile rectangles are not customized in some way, but that’s up to the user.

Well, it’s a workaround you can use now using a text editor, but I don’t think it’s a good idea to use this approach within Tiled. I’d want to show results using more context than the file name, like the name of the relevant object and an icon depending on its type, and this would require rather more complex searching in the file so that in the end it should be better to just load the file (which should be fast enough, if we do it without loading the images and cache the result).

Yeah, I’ve often considered this but haven’t set out on adding that. I expected there to be an issue about this already but couldn’t find it, so I’ve opened this issue about it.

1 Like

Don’t forget that a lot of people roll their own import code that supports only the small subset of Tiled features they actually use, so I suspect a lot of people’s code currently doesn’t support margins and spacing at all, or does them in a separate way that gives the same results as their settings in Tiled.

Using subrectangles wouldn’t simplify the job precisely because it would require an additional data lookup. Currently, the tile ID in a cell tells us both where the tile is in the tileset image and what animations and other properties are attached to that cell, so storing a layer’s data version can be done with just an int array. If the tileID no longer tells us the location, that means having to build a lookup table of tile locations to refer to every time a time is loaded into the drawable or updated for animation. Doable, not very complicated, but still annoying, precisely the sort of annoyance one generally wants offloaded to the editor, not the game engine.

One certainly could just leave their existing code as-is and hope they never resize the image or otherwise modify tile IDs, but then if they do need to resize the image, they’re left either having to redo their code or their maps, when this is something that could (and imho should) be handled by the editor. I know it’s difficult and error-prone, but I feel like this sort of thing comes with the territory :'D

Alright, I have a patch now that adds the following preference:

Though with the wording I picked now, I realized it might be expected that this applies to more than just clicking objects. In this case, would you expect that when doing a rectangular multi-object selection, that it will also filter out objects from other layers, as long as the selection does not exclusively contain objects from other layers?

That’s a very good point. Unfortunately it would mean we can’t get rid of the need for adjusting tile indexes across all assets. Although, maybe this kind of thing is better suited as a manual operation rather than trying to automate it. The user may know exactly when it needs to be done, and if there was an explicit action or script function that can be called then it can be triggered as needed. That way we at least get rid of the generally broken workflow we have now.

And for supporting tilesets with explicitly defined rectangles per tile, we can indeed introduce a new tileset type.

I believe I asked for this at some point, but maybe I just thought I did. I think it’s much better as a manual operation, with options to handle changing the width of the tileset and the tile size at once. This stuff definitely doesn’t need to be done automatically.

With “prefer”, I’d expect multi-select to select the same objects that would be highlighted/click-selected in this mode, i.e. any that are on the preferred layers and any that are on other layers and not completely overlapped within the selection by objects on preferred layers. I don’t know how useful that is though.

Alright, I’ve opened https://github.com/bjorn/tiled/issues/2866 about this.

Yeah, me too. I’ve opened a pull request for this feature and will look into implementing the group selection behavior later.

1 Like

Cool!

I forgot to mention, I think the adjustment should be something that the user can batch on several maps at once, if possible. Set the adjustment properties once, fire it off, and go get a drink while Tiled opens the maps and adjusts them.

Tangential: I hadn’t thought about this because I use one tileset per map, but does the adjustment work correctly on multi-tileset maps? That is, if tileset1 gets resized, do maps using tileset1 and tileset2 get the tileset2 firstgid and indices adjusted?

As for group selections, when I use them, I usually only want to select things within the selected group, even if there are other objects in range in other groups. That doesn’t match the current behaviour or the behaviour I described above xP I suspect this is one of those things highly depending on how exactly a person uses object groups, so perhaps a separate preference option for group selections might be good.

For now I’ll consider this a good use-case for scripting, rather than something to support in the UI.

The firstgid doesn’t need to be adjusted, since there’s no ambiguity about which tile a map is referring to when there are overlapping tilesets (it’s always the tile from the tileset with the higher firstgid). It will get updated upon saving the map, but this is essentially unrelated to the adjusting of tile indices to account for a changed column count.

So the behavior I have in mind is similar to the behavior on clicking. When you try to select a group of objects, but none of them belong to a currently selected layer, then rather than ignoring the action it will select all of them (and potentially change the selected layer). If only some of them belong to selected layers, then only those are going to be selected.

I think this strikes a good balance between being useful and not in your way, but of course the current behavior will still be available as well (and I’m considering to apply the new behavior by default only when highlighting of the selected layers is enabled).

1 Like