Kalia and the Sprite Sorting Order


Hello all! Today I would like to get into a topic that has been very important to the development of Kalia and the Fire Staff since the beginning, and that is very important to pretty much any game built out of 2D sprites. What could be so important, it has to be something intricate, right? Actually, I'm talking about something very simple: which sprites should go in front of others!

What do I mean by that? Well, gaze into this neat screenshot of my game:

Everything looks fine. The trees at the very bottom stand in front of the rubble behind them. Kalia is tucked neatly between the lamp post and the piles of rubble, which in turn are clearly lying in front of the buildings at the very top. Overall, there's a decent sense of depth, that everything is placed on this environment in a way that makes sense. So let's ruin it, shall we?

Oof, this looks messy. The trees are now rendering behind the rubble, Kalia is rendering over the lamp post and the buildings are rendering on top of the rest of the rubble. And we can count ourselves lucky that I didn't mess up the orders even further, or we could have the floor tiles rendering on top of everything and making the game completely unplayable!

The reason why this happens is simple: the game engine cannot tell in what order it should render its sprites by default. Sure, you placed a bunch of floor tiles, props and a character, but to the engine all it has are sprites that need to be rendered in whatever order. However, all 2D game engines should have means for you as the developer to explicitly tell them what the actual order shall be. In this devlog, we will explore some of these methods. Bear in mind that this will be presented from an Unity point of view, but your engine of choice should have at least one equivalent available (or even others that cannot be covered with Unity!).

Method 1: Z-Ordering

Okay, so why is this an issue for 2D games, but not for 3D ones? Well, that's because 3D games can make use of Z-Ordering. This term might seem scary to a newbie, but it basically means "just sort everything back to front, dummy!". Things that are further from the camera get rendered first, then as we get closer new things get rendered on top of the first ones, in a neat order until the closest object gets rendered (at least that's the simple explanation for the process). So what's the problem with our 2D scene? Well, let's see it from another perspective...

It turns out, all our sprites are placed on a 3D space, but they're also all squashed together on the XY plane! So, even if the engine is trying to apply Z-Ordering to them, there's just no way to sort them back to front, so they all get rendered in a random order instead! Unity does allow us to move sprites along the Z axis however, so maybe we could just do that? For example, bringing the ground tiles 10 units back?

This is one method to sort your sprites, via their Z axis positioning! However, some things should be noted here: first, not all 2D game engines might allow for this method (Unity does because it is actually a 3D engine posing as a 2D engine). Second, even if this is possible, moving your sprites around might change how your game looks in unintended ways depending on whether you're using an orthographic or perspective-based camera. Perspective cameras render things that are further away smaller than things that are closer, as you'd expect in a 3D game. While this can be used for cool effects like parallax scrolling and give your 2D game some depth, it can also ruin your visuals if you intend on using Z-Ordering to sort your sprites:

But what if my engine is on a XY plane, with no Z axis to sort things by?

Method 2: Sort by Layer/Value

Remember on the second image in this devlog, how even though the props were all over the place, the ground still rendered nicely behind everything? That's thanks to their sorting order. In KatFS, sprites currently can belong in one out of 8 different layers, which are then ordered first to last. The ground tiles are in the second layer while everything else was in the fourth, so the ground would still render behind everything else.

But how can you possibly sort hundreds of sprites with only eight layers? Wouldn't you have to create one layer for every sprite that should have an specific spot in the sorting order? Fortunately, Unity has another layer to this system: sorting values. That's as simple as putting a number in, and higher numbers get rendered in front of the lower ones. For example, the ground actually has two tile sets, one for the streets and another for the sidewalks and curbs, with the street having a lower value than the sidewalks thus getting rendered underneath them.

I'm certain all 2D game engines have at the very least one out of these two (if not, what are they doing???). However, KatFS still presents one problem: sprites that are on the same layer and should have the same priority still need to be rendered on top of one another in a specific order. That lamp post, Kalia and the rubble all have the same level of priority, but they need to be rendered in a certain order. To complicate matters further, Kalia can move around, and depending on where she is, the order can change! How could we handle this?

KatFS's Sprite Sorting Challenges

So here we have two goblin snipers. One is in front of the rubble, while the other is partially behind it. These guys are not static, they can move around. How do we ensure they're always properly sorted in relation to everything else around them? Well, the answer is as simple as it seems - things that are further on the "bottom" of the environment are always in front of things that are "above" them, so why not just use their Y position? (Y-Ordering?). However, this is not a built-in feature of most engines (at least not Unity), so we'll have to code it ourselves using Unity's available methods. Higher Y-value means further back, so why not set the sort value of everything to Y-value times -1?

Well, this works in principle, but... Sort values in Unity are integers, and two sprites with Y = 1.2 and Y = 1.5 are gonna get the same value. Okay, let's multiply everything by -1000 then to account for decimals! This actually worked for a while, but then another issue became apparent during development of the second chapter of the demo: we hit the integer cap too quickly once our levels expanded too much in either Y direction.

Currently the palliative solution has been to reduce the precision to just once decimal (multiply by -10), however there could be more elegant ways to approach this. One would be to sort everything relative to Kalia, with her having a sort value of 0 and everything else getting its value based on the Y distance to her resulting in a sliding scale, but maybe that's a topic for another devlog.

And that's a wrap up! This has been a topic I've wanted to touch on after it's been relevant for so long in KatFS's development, and we haven't even gone as far as I'd like to, but this devlog has already grown large enough. Maybe next time, I'll touch upon the silhouette system? Anyway, until next time!

Get Kalia and The Fire Staff Pre-Alpha

Download NowName your own price

Comments

Log in with itch.io to leave a comment.

Great method of sorting elements!! Good job!!

(+1)

Thanks for checking it out! :]

You’re welcome :D