New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option - Draw all layers as if it were a single layer #1274

Open
stevetranby opened this Issue May 9, 2016 · 14 comments

Comments

Projects
None yet
3 participants
@stevetranby

stevetranby commented May 9, 2016

This would allow viewing isometric tilemaps with multiple "wall" layers so that you could separate tiles in different layers for organization, but then have a Layer[0] tile in front of a Layer[4] tile if it would have drawn in front had both tiles been added to the same layer.

Map Tile Size: 32 x 16
Tileset Tile Size: 32 x 64
Tileset 1 @ 0,0 in Layer 2 (overlaps Layer 1 or 2 tiles that extend vertical above)
Tileset 1 @ 1,1 in Layer 1 (overlaps Layer 2 tiles that extend vertical above the tile base)
Tileset 1 @ 2,2 in Layer 0

Not sure I'm making sense, and I can take a screenshot or two if needed.

Most games probably don't need this functionality, but it would be a nice polished feature to make the editor superior for detailed isometric maps.

This may cause many of the renderer frameworks/libraries to render differently than what Tiled shows, and as such this is a more advanced option toggle that can be hidden in some preferences or sub-menu.

Let me know if this would be easy to implement. Possibly I'll look writing the render code myself and present for having others write the hopefully small GUI code to integrate a toggle.

@bjorn

This comment has been minimized.

Show comment
Hide comment
@bjorn

bjorn May 10, 2016

Owner

This is a very tricky issue to implement with the way Tiled works currently, because everything is drawn per layer and not all layers are tile layers. There's two possible directions I've considered to resolve this:

  • Try to make it work anyway and somehow deal with the fact that in the future, tile layers need not all have the same size nor all use the same tile size (once issue #149 is implemented).
  • Make tile layers "3D" with a default thickness of 1 but the option to increase it, and of course adjusting the tools to work nicely with this.

I'm leaning towards the second option. Though it raises several questions about the UI and the tools, I think it is design-wise more realistic than the first one.

Another thing that would have to be decided, is whether to allocate a single block of memory for such layers, or whether to instead allocate "stacks" of tiles. Of course, another alternative is to simulate a block of memory with a sparse data structure. In the end though, these are all implementation details that should generally not affect the UI.

Owner

bjorn commented May 10, 2016

This is a very tricky issue to implement with the way Tiled works currently, because everything is drawn per layer and not all layers are tile layers. There's two possible directions I've considered to resolve this:

  • Try to make it work anyway and somehow deal with the fact that in the future, tile layers need not all have the same size nor all use the same tile size (once issue #149 is implemented).
  • Make tile layers "3D" with a default thickness of 1 but the option to increase it, and of course adjusting the tools to work nicely with this.

I'm leaning towards the second option. Though it raises several questions about the UI and the tools, I think it is design-wise more realistic than the first one.

Another thing that would have to be decided, is whether to allocate a single block of memory for such layers, or whether to instead allocate "stacks" of tiles. Of course, another alternative is to simulate a block of memory with a sparse data structure. In the end though, these are all implementation details that should generally not affect the UI.

@bjorn bjorn added the feature label May 10, 2016

@stevetranby

This comment has been minimized.

Show comment
Hide comment
@stevetranby

stevetranby May 10, 2016

Interesting. Yeah we use the cocos2d-x tilemap renderer. We've customized it, but I think the default version handles this z-ordering correctly if specified with the custom property ("cc_vertexz" = "automatic") using the depth buffer.

I'm not sure what you mean by "a thickness of 1"?

Our current renderer determines depth order using something along the lines of order the isometric rows from top to bottom as back to front and then use the right down ordering to add a small precision offset to mitigate z-fighting.

It's an interesting problem when having to deal with object layers as well ... as usual possibly semi-unique to our needs. I'll have to look further into how a renderer should deal with object layers. For the most part cocos2d-x renderer, for example, doesn't really handle "tile" objects in object layers well, if at all. I'm also working on a new (or enhanced) tile map parser renderer for cocos2d-x that may need to think about this issue.

A similar features allowing 3D tile placement with a height coordinate as given in the TilemapKit example renderer would probably have the same or similar solution.

In the end creating an in-game tile editor may be the best solution for a game with needs that are this specific and somewhat complex.

stevetranby commented May 10, 2016

Interesting. Yeah we use the cocos2d-x tilemap renderer. We've customized it, but I think the default version handles this z-ordering correctly if specified with the custom property ("cc_vertexz" = "automatic") using the depth buffer.

I'm not sure what you mean by "a thickness of 1"?

Our current renderer determines depth order using something along the lines of order the isometric rows from top to bottom as back to front and then use the right down ordering to add a small precision offset to mitigate z-fighting.

It's an interesting problem when having to deal with object layers as well ... as usual possibly semi-unique to our needs. I'll have to look further into how a renderer should deal with object layers. For the most part cocos2d-x renderer, for example, doesn't really handle "tile" objects in object layers well, if at all. I'm also working on a new (or enhanced) tile map parser renderer for cocos2d-x that may need to think about this issue.

A similar features allowing 3D tile placement with a height coordinate as given in the TilemapKit example renderer would probably have the same or similar solution.

In the end creating an in-game tile editor may be the best solution for a game with needs that are this specific and somewhat complex.

@bjorn

This comment has been minimized.

Show comment
Hide comment
@bjorn

bjorn May 13, 2016

Owner

We've customized it, but I think the default version handles this z-ordering correctly if specified with the custom property ("cc_vertexz" = "automatic") using the depth buffer.

Right, you could use the depth buffer for this, but only when you don't use pixels with partial transparency. In general, Tiled supports alpha-layered images so it will have to make sure to render the tiles in the right order. Also, it currently uses the QPainter rendering API, which does not support a depth buffer.

I'm not sure what you mean by "a thickness of 1"?

I mean that currently a tile layer is a 2D grid of cells, which is the same as a 3D grid of cells with a thickness of 1, so that would be the default.

In the end creating an in-game tile editor may be the best solution for a game with needs that are this specific and somewhat complex.

Yeah, that or cope with not 1:1 visuals and have a quick reload feature in your engine to make up for it. Your needs do not sound that specific to me though. Adding 3D positioning of layers and objects is something I want to work towards eventually, also in the context of parallax support.

Owner

bjorn commented May 13, 2016

We've customized it, but I think the default version handles this z-ordering correctly if specified with the custom property ("cc_vertexz" = "automatic") using the depth buffer.

Right, you could use the depth buffer for this, but only when you don't use pixels with partial transparency. In general, Tiled supports alpha-layered images so it will have to make sure to render the tiles in the right order. Also, it currently uses the QPainter rendering API, which does not support a depth buffer.

I'm not sure what you mean by "a thickness of 1"?

I mean that currently a tile layer is a 2D grid of cells, which is the same as a 3D grid of cells with a thickness of 1, so that would be the default.

In the end creating an in-game tile editor may be the best solution for a game with needs that are this specific and somewhat complex.

Yeah, that or cope with not 1:1 visuals and have a quick reload feature in your engine to make up for it. Your needs do not sound that specific to me though. Adding 3D positioning of layers and objects is something I want to work towards eventually, also in the context of parallax support.

@MarceColl

This comment has been minimized.

Show comment
Hide comment
@MarceColl

MarceColl Mar 1, 2017

Contributor

Taking this issue too in order to solve #1255

@bjorn, would this completely replace the isometric renderer then?

Contributor

MarceColl commented Mar 1, 2017

Taking this issue too in order to solve #1255

@bjorn, would this completely replace the isometric renderer then?

@bjorn

This comment has been minimized.

Show comment
Hide comment
@bjorn

bjorn Mar 1, 2017

Owner

@MarceColl It doesn't really affect the basic workings of each individual renderer, but each will need to be adapted to handle the cells in the tile layer they're rendering in drawTileLayer as stacks of tiles.

I wonder a little how we could avoid affecting a huge amount of existing code. I suppose the Cell class should be changed to store a list of tiles, but that of course affects its API. I would suggest that you keep the existing member functions of Cell working by having them modify the first entry in its list of tiles. Then we can incrementally go over all the code using those functions and see how they should be changed.

Owner

bjorn commented Mar 1, 2017

@MarceColl It doesn't really affect the basic workings of each individual renderer, but each will need to be adapted to handle the cells in the tile layer they're rendering in drawTileLayer as stacks of tiles.

I wonder a little how we could avoid affecting a huge amount of existing code. I suppose the Cell class should be changed to store a list of tiles, but that of course affects its API. I would suggest that you keep the existing member functions of Cell working by having them modify the first entry in its list of tiles. Then we can incrementally go over all the code using those functions and see how they should be changed.

@bjorn

This comment has been minimized.

Show comment
Hide comment
@bjorn

bjorn Mar 1, 2017

Owner

It doesn't really affect the basic workings of each individual renderer, but each will need to be adapted to handle the cells in the tile layer they're rendering in drawTileLayer as stacks of tiles.

Also, since rendering a single "tile stack" will be independent of the renderer, it makes sense to delegate this to the CellRenderer class, which is shared between all renderers.

Owner

bjorn commented Mar 1, 2017

It doesn't really affect the basic workings of each individual renderer, but each will need to be adapted to handle the cells in the tile layer they're rendering in drawTileLayer as stacks of tiles.

Also, since rendering a single "tile stack" will be independent of the renderer, it makes sense to delegate this to the CellRenderer class, which is shared between all renderers.

@MarceColl

This comment has been minimized.

Show comment
Hide comment
@MarceColl

MarceColl Mar 1, 2017

Contributor

So if I've understood correctly your idea is to assign a height h to a layer, and each cell of that layer can have a stack of x tiles, each tile of height h. The CellRenderer draws this stacked tiles one on top of the other essentially creating pseudo-3D using 2D tile images. The stack can grow upwards (walls), downwards (like in #1255) or both.

Now, the problem I see is in the tooling. Existing tools only work on the level-0 tile of the stack (2D grid = 3D grid with thickness 1). I have no idea how you could make the stamp brush to be able to edit all the layers without a lot of work by the user, I feel like it would be a pain to work with.

Now, here's an idea. We restrict the use of "3D tiling" to terrains. The terrain creation window should be revamped to work with stacks. We add a new section that shows all the tiles stacked, with the ability to add new layers in between. Also the possibility to group layers and specify that the group can grow (so that if you increase the size of the stack Tiled knows which tiles it can repeat).

This allows the user to:

  • Create the terrain with the stack layers
  • Change the ordering of the stack layers of the whole map at the same time without a lot of work.
  • Be able to individually change the size of the stack while easily specifying which stack layers will shrink/grow.

Things we would have to do (Im probably missing things @bjorn):

  • Change the Cell class to hold stacks of tiles.
  • Change the CellRenderer class to render stacks of tiles
  • Change the renderers to render from top to bottom ignoring layers except to prioritize inside a single cell.
  • Change the terrain window to work with stacks.
  • Change the terrain brush to work with stacks.
  • Add a way to grow/shrink the stack of an individual cell in both directions from the UI

Problems I see at first glance,

  • How does the stamp brush work with the stacked tiles. Does it allow to individually change visible parts of a stack? Do the changes persist when you change the terrain definition? How can you reset to use the terrain definition again?
  • How do we draw objects? How do we decide if they are behind or in front of a stack?

I see also some optimizations we can do if we go this route, but we can discuss them once we have decided if this is a good way to go with this.

Contributor

MarceColl commented Mar 1, 2017

So if I've understood correctly your idea is to assign a height h to a layer, and each cell of that layer can have a stack of x tiles, each tile of height h. The CellRenderer draws this stacked tiles one on top of the other essentially creating pseudo-3D using 2D tile images. The stack can grow upwards (walls), downwards (like in #1255) or both.

Now, the problem I see is in the tooling. Existing tools only work on the level-0 tile of the stack (2D grid = 3D grid with thickness 1). I have no idea how you could make the stamp brush to be able to edit all the layers without a lot of work by the user, I feel like it would be a pain to work with.

Now, here's an idea. We restrict the use of "3D tiling" to terrains. The terrain creation window should be revamped to work with stacks. We add a new section that shows all the tiles stacked, with the ability to add new layers in between. Also the possibility to group layers and specify that the group can grow (so that if you increase the size of the stack Tiled knows which tiles it can repeat).

This allows the user to:

  • Create the terrain with the stack layers
  • Change the ordering of the stack layers of the whole map at the same time without a lot of work.
  • Be able to individually change the size of the stack while easily specifying which stack layers will shrink/grow.

Things we would have to do (Im probably missing things @bjorn):

  • Change the Cell class to hold stacks of tiles.
  • Change the CellRenderer class to render stacks of tiles
  • Change the renderers to render from top to bottom ignoring layers except to prioritize inside a single cell.
  • Change the terrain window to work with stacks.
  • Change the terrain brush to work with stacks.
  • Add a way to grow/shrink the stack of an individual cell in both directions from the UI

Problems I see at first glance,

  • How does the stamp brush work with the stacked tiles. Does it allow to individually change visible parts of a stack? Do the changes persist when you change the terrain definition? How can you reset to use the terrain definition again?
  • How do we draw objects? How do we decide if they are behind or in front of a stack?

I see also some optimizations we can do if we go this route, but we can discuss them once we have decided if this is a good way to go with this.

@MarceColl

This comment has been minimized.

Show comment
Hide comment
@MarceColl

MarceColl Mar 1, 2017

Contributor

I will try to create a mockup of how the terrain creation tool could be tonight when I get home, so that it's easier to visualize.

Contributor

MarceColl commented Mar 1, 2017

I will try to create a mockup of how the terrain creation tool could be tonight when I get home, so that it's easier to visualize.

@MarceColl

This comment has been minimized.

Show comment
Hide comment
@MarceColl

MarceColl Mar 2, 2017

Contributor

@bjorn do you think this is a good way to go?

Another thing that we should consider:

  • How do we represent stacked tiles in exports, particularly something like in csv
Contributor

MarceColl commented Mar 2, 2017

@bjorn do you think this is a good way to go?

Another thing that we should consider:

  • How do we represent stacked tiles in exports, particularly something like in csv
@bjorn

This comment has been minimized.

Show comment
Hide comment
@bjorn

bjorn Mar 2, 2017

Owner

@MarceColl I really appreciate your thoughts on this, but I have had no time yet to read it carefully and answer your questions. I will try to get to it this evening.

Owner

bjorn commented Mar 2, 2017

@MarceColl I really appreciate your thoughts on this, but I have had no time yet to read it carefully and answer your questions. I will try to get to it this evening.

@MarceColl

This comment has been minimized.

Show comment
Hide comment
@MarceColl

MarceColl Mar 2, 2017

Contributor

Sure, no problem.

I will try to get the mockup for this evening too.

Contributor

MarceColl commented Mar 2, 2017

Sure, no problem.

I will try to get the mockup for this evening too.

@bjorn

This comment has been minimized.

Show comment
Hide comment
@bjorn

bjorn Mar 2, 2017

Owner

@MarceColl Sorry, I'm swamped because of the recent interest due to GSoC 2017 acceptance there is so much to respond to and my evening is still not much longer than 1 hour. I'll have to postpone this another time.

Owner

bjorn commented Mar 2, 2017

@MarceColl Sorry, I'm swamped because of the recent interest due to GSoC 2017 acceptance there is so much to respond to and my evening is still not much longer than 1 hour. I'll have to postpone this another time.

@MarceColl

This comment has been minimized.

Show comment
Hide comment
@MarceColl

MarceColl Mar 2, 2017

Contributor

@bjorn no problem I understand man. I've had to delay the mockup for another day too beacuse of university chores.

Looking forward to discussing this with you in some days.

Contributor

MarceColl commented Mar 2, 2017

@bjorn no problem I understand man. I've had to delay the mockup for another day too beacuse of university chores.

Looking forward to discussing this with you in some days.

@bjorn

This comment has been minimized.

Show comment
Hide comment
@bjorn

bjorn Mar 6, 2017

Owner

So if I've understood correctly your idea is to assign a height h to a layer, and each cell of that layer can have a stack of x tiles, each tile of height h. The CellRenderer draws this stacked tiles one on top of the other essentially creating pseudo-3D using 2D tile images. The stack can grow upwards (walls), downwards (like in #1255) or both.

I didn't mean the height of a layer to be the height of each tile. What I meant was that you specify a certain maximum height (in tiles) on the tile layer (the maximum stack size), and associate a height (in pixels) with each tile, which is used when drawing the stack. We don't necessarily need the maximum stack size of course, and could instead allocate memory dynamically. I'm just a bit worried about the performance impact.

Now, the problem I see is in the tooling. Existing tools only work on the level-0 tile of the stack (2D grid = 3D grid with thickness 1). I have no idea how you could make the stamp brush to be able to edit all the layers without a lot of work by the user, I feel like it would be a pain to work with.

I think the tools would need some kind of "stack mode". By default, the stamp brush and eraser would replace the entire stack with whatever tile you're placing. But in stack mode, the stamp brush would place tiles on top of the stack, and the eraser would erase tiles from the top, for example.

I don't think the stacks work very well with terrains, or at least I don't see it being a very common combination. As you can see in the screenshot at #1255, the terrain transitions are done very differently and likely on-tile transitions would look quite strange when combined with the height variations, though it would of course be possible. My suggestion would be for the terrain brush to just modify the first layer, leaving anything stacked on top alone.

I must admit that I don't really understand why you would restrict the height map to the terrain tool. Maybe you can still do your mockup, which could help explain things.

How do we draw objects? How do we decide if they are behind or in front of a stack?

I think objects do not mix at all with this feature. They are entirely separate beasts, which is also why I think this feature needs to work within a tile layer rather than being something that works to combine multiple layers, because it would cause problems for any object layers in between.

Of course, this does mean we'll probably be looking to introduce something object-like to tile layers in the future, since they do still have their use.

Owner

bjorn commented Mar 6, 2017

So if I've understood correctly your idea is to assign a height h to a layer, and each cell of that layer can have a stack of x tiles, each tile of height h. The CellRenderer draws this stacked tiles one on top of the other essentially creating pseudo-3D using 2D tile images. The stack can grow upwards (walls), downwards (like in #1255) or both.

I didn't mean the height of a layer to be the height of each tile. What I meant was that you specify a certain maximum height (in tiles) on the tile layer (the maximum stack size), and associate a height (in pixels) with each tile, which is used when drawing the stack. We don't necessarily need the maximum stack size of course, and could instead allocate memory dynamically. I'm just a bit worried about the performance impact.

Now, the problem I see is in the tooling. Existing tools only work on the level-0 tile of the stack (2D grid = 3D grid with thickness 1). I have no idea how you could make the stamp brush to be able to edit all the layers without a lot of work by the user, I feel like it would be a pain to work with.

I think the tools would need some kind of "stack mode". By default, the stamp brush and eraser would replace the entire stack with whatever tile you're placing. But in stack mode, the stamp brush would place tiles on top of the stack, and the eraser would erase tiles from the top, for example.

I don't think the stacks work very well with terrains, or at least I don't see it being a very common combination. As you can see in the screenshot at #1255, the terrain transitions are done very differently and likely on-tile transitions would look quite strange when combined with the height variations, though it would of course be possible. My suggestion would be for the terrain brush to just modify the first layer, leaving anything stacked on top alone.

I must admit that I don't really understand why you would restrict the height map to the terrain tool. Maybe you can still do your mockup, which could help explain things.

How do we draw objects? How do we decide if they are behind or in front of a stack?

I think objects do not mix at all with this feature. They are entirely separate beasts, which is also why I think this feature needs to work within a tile layer rather than being something that works to combine multiple layers, because it would cause problems for any object layers in between.

Of course, this does mean we'll probably be looking to introduce something object-like to tile layers in the future, since they do still have their use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment