Tilemap layers and sprite ordering (DEF-1184)


#1

Hello.

I have a “map” game object (with z = 0) with tile map. It has two layers (foreground with z = 1 and background with z = -1).

I have a “character” game object (with z = 0) with sprite (z = 0).

I expect that a character sprite will be rendered between tile map layers, but all layers are rendered bellow or after the character (depending on character sprite z).

I found that i can move each layer to own tilemap and draw them separately, but it makes too hard to edit them and keep them synchronized.

Screenshots: https://yadi.sk/d/yCMCAZ7SoE5mM
On the first screenshot tilemap with two levels, foreground is active.
On the second — game screenshot with sprite z = 0 (you can see character position as a collision sphere).
On the third — game screenshot with sprite z = 0.5 (you can see that character is drawn on the top of both tilemap layers).


Tilemap Z order and graphic problem (SOLVED)
#2

Yes, currently each component is sorted as a whole. Tilemap layers are not separated in sorting. We have discussed internally if that would be possible to solve but there is no definite plan as far as I know.


#3

Hm, we should really look into fixing that. I think most developers would expect the behaviour described by @Aleksandr_Derbenev.


#4

There’s already a Jira ticket for this: DEF-1184. No release date set.


#5

Is it posible to increase priority of this issue? It will be really useful for isometric-view games.


#6

@Ingela_Garneij is the one responsible for the backlog. Ingela, what’s the prio of this issue?


#7

I’d be interested in this too.
Is it possible to do a parent/child relationship between the map and objects on the map?
For example - add the sprite as a child to the map and if the map moves the character will stay in place (relative to the map).


#8

You can do that. Put the sprite and map in separate game objects and set one GO as parent to the other. See http://www.defold.com/ref/go#set_parent


#9

I cannot be any more specific than during Q2, since priorities constantly change


#10

@britzl Hm, we should really look into fixing that. I think most developers would expect the behaviour described by @Aleksandr_Derbenev.

@Aleksandr_Derbenev

Your question is exactly what I was looking for! I expected that the z-position of any layer inside a tilemap, is somewhat global, and I could render my dynamically spawned gameobjects in between of two layers of a single tilemap. But that’s not the case!

Some observations

I thought that material tags and render.predicates might solve that issue. I read about materials and render.predicates. As far as I understand the docs, predicates are only useful for controlling the draw-order of a bunch of components through the render_script. Given that a render.predicate has one tag (which is assigned to two different materials, which in turn are assigned to two separate components), I would have expected that both components would merge into a single draw-call (because of the same material tag). That’s not the case either!
Instead, a render.predicate is basically a selector that says: “draw components with certain material tags before|after others”. This way you don’t need to manage a ton of predicates, but rather sum some of them up to one predicate and manage that.

Solution

I ended up splitting my single “game-world-tilemap” into multiple “rooms”. Obstacles like pillars and walls (that I can go behind and in-front) are now each on a separate tilemap. At the end I stitched my world from all these building-blocks and done z-sorting on them when needed.

PS: I’ll see how performance will be, once the map grows. If it drops, I might be able to solve that with collections (chunks of “rooms”), which I’d load and unload at runtime, depending on current camera position…


#11

Components in the same predicate are batched if they are the same type, has the same texture (atlas) and same Z. Batching is very aggressive for performance reasons but the currentl problem is that tilemaps are batched separately from sprites which causes the problem you see.


#12

@sicher Good to know how they work. Thanks for the additional information on this!


#13

It seems that this issue still persists?


#14

Yes, I’m afraid so. Not sure when we’ll get around to fixing it. @Sara?


#15

Just encountered this problem as well, would love to see it fixed :slight_smile:


#16

Yes, we haven’t forgotten this, and we’d still like to revisit this. Hopefully, we’ll get to it when we will start working on culling for tilemaps etc. There are several things ahead of this in the queue though, so ETA is unclear :confused:


#17

Just to voice my concern about this tilemap issue as well, and the Z ordering approach in general, as a new user, the layer ordering and Z sorting has been a continuous source of confusion, having Z specified at multiple levels (game object, tilemap, layer, sprite) leads to all kinds of unexpected results.

While the object and sprite Z behavior is understandable and manageable, the tilemap layer behavior limits its usability terribly and a fix would be quite a welcomed improvement.

In the mean time, can anyone suggest a reasonable solution or workaround?


#18

I agree. With the recent influx of new users, many with ambitions to do tilebased games, it’s justifiable to improve the tilemap implementation (ping @saraglaser).

The suggested solution that was provided on Slack with Tiled and one tilemap per layer is probably a good way forward.


#19

Yep, I suggested that solution to myself :). As I understand it, the Tiled Defold plugin exports a Defold tilemap so it will suffer from the same problems, and editing a level in multiple tilemaps is rather cumbersome (with either Tiled or the Defold tilemap editor).

I could try splitting the layers into tilemaps at runtime but the tilemap manipulation functions seem a bit limited too, all I see is set/get_tile, so I’d have to load my map, copy it tile by tile into the layer tilemaps, then unload the original, sounds about right? Seems like this process can increase the loading time significantly, especially for larger maps.

Also, are there any potential runtime performance issues caused by having a dozen or more tilemaps?