I know, this is heretical thinking, but allow me to make my point.
In investigating SIDE_MAP, Atomix and I worked together to pin down a sorting issue that has been present for some time, and I relayed to him my method for using SIDE_MAP that doesn't have sorting problems: "Don't use bound_x/y".
The following test demonstrates the layering problems of large icons with bound_x/y offsets:
This test shows that these layering problems don't exist when you use pixel_w/z to offset the vis bounds to better fit the phys bounds:
Furthermore, this issue is compounded by how bound_x complicates dealing with collision and movement in the engine.
Currently, in order to calculate an atom's position, you must:
(x-1) * TILE_WIDTH + step_x + bound_x
(y-1) * TILE_HEIGHT + step_y + bound_y
Similarly, with movement:
Move(locate(1,1,z),0,bound_x + global_x, bound_y + global_y)
Furthermore, there is a standing series of bugs with how objects are positioned and placed on the map.
When the world starts up, the player attempts to move to the first tile that is open on the map. However, if you add a bound_x,y of 32,32 to the player, instead of their BOUNDING BOX being placed on (1,1,1), they will actually spawn on (2,2,1). This problem also exists with map editor placement, where if we have a 32x32 bounding box, with an 8x8 bound_x/y, the object will be placed 8px up and to the right of where you try to place it on the tile grid. This means you either have to hard-code negative step_x/y values on any type you give a bound_x/y offset to, or you need to manually adjust the placement of the objects.
See how the player's bounding box is on the wrong turf?
Neither of these problems exists with pixel_w/z offsets to reposition the sprite, rather than positioning the bounding box according to the sprite.
Left: bound_x=8; Right: pixel_w = -8
It is my argument, that bound_x/y is engine cruft that needs to go. It unnecessarily complicates things to the point that even the math that the engine tries to use to keep track of it, is so heavily broken that despite posting multiple bugs over the years showing that something is wrong, the problem has been ignored to avoid dealing with the chainsaw noises thinking about it summons.
Let's imagine a world without bound_x/y doing this stuff.
Instead, let's pull bound_x/y out of the consideration for the object's position in the world, and remove it from Move().
Now, when a mob is spawned into the world, or placed on the map, it shows up where it is supposed to, and its step_x/y variables can never go negative. step_x/y will ALWAYS be between 0 and TILE_SIZE-1.
When calculating the global position of an object, you will now be able to just do:
(x-1) * TILE_WIDTH + step_x
(y-1) * TILE_HEIGHT + step_y
When Move()ing a mob to a global pixel position, you can now just:
Move(locate(1,1,z),0,global_x,global_y)
And finally, when objects DO have bound_x/y assigned, the engine actually interprets this as a visual offset along -pixel_w, -pixel_z. What this means is, the drawing position of the sprite itself is what is changed, rather than the position of the bounding box. Where the engine would calculate the visual bounds of an object, instead of + pixel_w, it'd be: + pixel_w - bound_x, +pixel_z - bound_y. This would be direction-agnostic, and would most likely fix most of the problems that we have with client.dir being broken.