PurpleKingdomGames / indigo

An FP game engine for Scala.
https://indigoengine.io/
MIT License
641 stars 60 forks source link

Reversing depth sorting #223

Open davesmith00000 opened 3 years ago

davesmith00000 commented 3 years ago

Depth sorting is unintuitive. This was a decision made back in the mists of time for reasons I can't recall any more. Doing this would be a breaking change.

This stacks our boxes as expected:

Layer(
  boxA,
  boxB,
  boxC
)

C is on top of B is on top of A.

This works fine too:

Layer(
  boxA.withDepth(0),
  boxB.withDepth(0),
  boxC.withDepth(0)
)

You would expect that to be the equivalent of:

Layer(
  boxA.withDepth(1),
  boxB.withDepth(2),
  boxC.withDepth(3)
)

But in fact that reverses the order, since depth describes distance from the camera - the bigger the number the further away. So you really need to do:

Layer(
  boxA.withDepth(3),
  boxB.withDepth(2),
  boxC.withDepth(1)
)
davesmith00000 commented 3 years ago

Is this subjective? Flash was "0 is infinitely far away and adding depth brought things closer" which is what I'm suggesting above. In an isometric game, that means the closest block has the greatest depth. 🤪 Maybe this is a non-issue.

davesmith00000 commented 2 years ago

The follow up complication is that Layers work the opposite way.

Layer(boxA),
Layer(boxB),
Layer(boxC)

Does the expected thing.

Layer(boxA).withDepth(1),
Layer(boxB).withDepth(2),
Layer(boxC).withDepth(3)

Does the same thing.

Layer(boxA).withDepth(3),
Layer(boxB).withDepth(2),
Layer(boxC).withDepth(1)

Is reversed with C now on the bottom.

Layers work like a cake. Entities work on distance from camera. Confusing?

Depth is not a bad name for the entity... depth from camera. So a solution is to rename Layer depth to, perhaps, Order?

Sintrastes commented 2 years ago

Basically, to get overlaying of sprites to work correctly (i.e. if I stand in front of an NPC, my player sprite will be drawn on top of the NPC, if I stand behind the NPC, the NPC sprite will be drawn on top of my player sprite) my ideas was to use the y coordinate of each entity as the depth.

So currently, to get that to work, I have to do some math.

Maybe it would be useful to use both modes of operation, and have this be configurable by layer?

Sintrastes commented 2 years ago

Actually... My math might be off there. I need some more coffee.

sjrd commented 2 years ago

I ran into this today. What annoyed me was not the non-intuitive direction (it was well documented, and I am an RTFM person). What annoyed me is that the default depth was the nearest possible, which means I could not put a selected few nodes in front of the default, which applies to all my other nodes.

Clearly, there can be use cases where you want a selected few nodes to be behind the default depth, as well, so just inverting everything will only move the problem.

My suggestion would be to make sure that the default depth is "in the middle", i.e., that you can put things both in front of and behind the default depth. Making negative depths meaningful would solve this, for example.

davesmith00000 commented 2 years ago

This is a related issue, suggesting being able to disable depth sorting for things the user has explicitly sorted themselves (depth sorting is an expensive CPU side operation): https://github.com/PurpleKingdomGames/indigo/issues/233

davesmith00000 commented 2 years ago

Depending on the game, you may actually want different depth management options. One of the problems here has been trying to please everyone. We could add more options to the game config, such as camera near / far planes and ascending / descending sorting options.