What if I use standing layers?
Well, if it works for your project, you shouldn't worry too hard about it. Converting to a proper SIDE_MAP setup is going to take a little bit of work, but if you are asking why the standing layer hacks several of us have handed out at the insistence of the community, it's rooted in how BYOND works under the hood.
BYOND tells the client how to draw stuff. This is called an appearance. Any objects in the world that looks the exact same as another all share an appearance. This cuts down on the complexity of network traffic, but it has a hidden cost: The more unique appearances you have, the longer it takes to change how objects look. This is because each time you change an object's variables that affect what they look like, BYOND has to check if the appearance exists, and if not, create it. We call this appearance churn.
The way the standing layer hack works, is we change the layer of objects just a little bit based on their y position on the map. This means that you can have the exact same tree on three different tiles side-by side, and they will all share the same appearance. However, if the trees are all on different tiles on the Y axis, now you have the same-looking tree using 3 unique appearances. Worse, every time a player, projectile, or npc moves, their appearance churns to fix their layering.
Golly gee, wouldn't it be great if BYOND could just draw things that layer how you want?
Recent Developments
This last month, Atomix (meme01), Clouddspider (kumorii) and I have been working hard to produce test environments that highlight the deficiencies in SIDE_MAP format. Lummox JR has been kind enough to take a look at our testing environments and to get down to the cause of these issues.
At the time of writing, SIDE_MAP works extremely well now. There's still a few improvements that need to happen and some new features that are coming in 516 that will make it even better, but I'd consider it ready for active development.
What does it do?
Contrary to popular belief, SIDE_MAP isn't for creating games that look like this:
Don't be fooled by the name. SIDE_MAP doesn't have anything to do with sidescrollers. In fact, sidescrollers can be done in BYOND with either TOPDOWN_MAP format and SIDE_MAP.
Here, I'll show you what I mean:
Notice how the sprites draw over the player in the above image when they are closer to the bottom of the screen, and they draw behind the player when they are closer to the top of the screen? This kind of effect could be done with SIDE_MAP. But it's a sidescroller! You just said they aren't for side scrollers!
Right. So here's where the misconception comes in: Just because the game is a sidescroller doesn't mean you should use SIDE_MAP.
Okay, that's obviously top-down! Again, no. Notice how the sprites reorder themselves based on which is closest to the bottom of the screen? This is SIDE_MAP too.
Okay. So what does TOPDOWN_MAP look like?:
And this:
Again, TOPDOWN_MAP and SIDE_MAP are not related to sidescrollers or "top down" games in the way that games journalists use the term to describe videogames. Instead, what they refer to, is what factors sprites will consider when drawing to determine their depth.
Legend:
FACTOR INFLUENCED BY --------------------------------------------------------------------------------------------- Plane atom.plane Subplane atom.layer BACKGROUND_LAYER, EFFECTS_LAYER, TOPDOWN_LAYER Layer atom.layer Sequence internal The order that the item was originally to be drawn before sorting Physical Y loc,bounds The Y location of the object's bounding box Physical X loc,bounds The X location of the object's bounding box
TOPDOWN_MAP cares about:
Plane > Subplane > Layer > Sequence
SIDE_MAP cares about:
Plane > Subplane > Physical Y > Layer > Physical X (center) > Sequence
The difference between the two mapping formats, is that the higher up you move on the map, the further "back" you are when in SIDE_MAP, but when using TOPDOWN_MAP, plane and layer are king. SIDE_MAP also allows objects of a higher layer to be overlapped by objects of a lower layer.
The rules for this are tough to grasp at first. So let's take a look:
Same Layer:
Objects on the same layer will interlayer with each other. The object with the closer "front" bounds wins.
Different Layers:
The object on the lower layer will only overlap the object on the higher layer if its rear bounds are in front of the higher layer object's front bounds.
How do I use it?
SIDE_MAP isn't plug & play. You need to rethink how your world uses BYOND's baked in layering a little bit. You need to start thinking in 3D and not just 2D to get the most out of it.
Let's show you the entry-level setup for SIDE_MAP:
//reconfigure the default areas:
#undef AREA_LAYER
#undef TURF_LAYER
#undef OBJ_LAYER
#undef MOB_LAYER
#define AREA_LAYER (1 + BACKGROUND_LAYER)
#define TURF_LAYER (2 + BACKGROUND_LAYER)
#define OBJ_LAYER 3
#define MOB_LAYER 3
//change the map format:
world
map_format = SIDE_MAP
//set ATOMs to the new layers.
area
layer = AREA_LAYER
turf
layer = TURF_LAYER
obj
layer = OBJ_LAYER
mob
layer = MOB_LAYER
We're moving areas and turfs to BACKGROUND_LAYER. But notice how we're not adding objs or mobs to BACKGROUND_LAYER?
This is because we're going to consider objects and mobs as "standing" by default, and we're going to consider turfs and areas as "flat" by default. By moving turfs and areas to their own sub-plane, we're preventing them from inter-layering with the player by default.
In some games, the interlayering with the player is desired, but for your average "floor" tile, you will want them on BACKGROUND_LAYER by default to keep them from even considering interacting with players and standing decorations.
If an object "stands up", meaning you can walk behind it and in front of it, you should not set it to BACKGROUND_LAYER, but instead set it to a normal layer, probably the same layer as the player.
New tricks:
In topdown map, if you wanted to make someone jump, you'd animate() their pixel_y. But in SIDE_MAP, pixel_y affects the layering of an object. BYOND provides you pixel_z, which doesn't impact layering in SIDE_MAP mode, and provides the same offset behavior as pixel_y when the client's drawing direction is default.
We also have pixel_w, which is like pixel_x, but is always the same direction regardless of the client's drawing direction. If you choose to use client.dir in your project, pixel_w will be quite handy to you.
Acknowledgements
I really appreciate everyone who helped me test and diagnose the issues with this map format. Especially Atomix (meme01), who really got my gears turning about the problem last week. And I'd really like to thank Lummox for fixing this. It's absolutely huge for your average game developer. It just works now, and that's what matters. If you are as appreciative as I am about this being fixed, please throw some support BYOND's way.
There's no real need for a demo project. Try it out for yourself!
Snippet #22.5 here.
When using SIDE_MAP, it's really important that you use FLOAT_LAYER and FLOAT_PLANE for overlays.
But FLOAT_LAYER is kind of hard to work with, because FLOAT_LAYER+1 doesn't float anymore.
Well, did you know you can undefine FLOAT_LAYER and redefine it further below zero? FLOAT_LAYER is -1 by default, but any negative layer has floating behavior.
Now you can use FLOAT_LAYER+1..999 to handle your various clothing and effect layers that ride along with the player.
Godspeed!