ID:1920040
 
BYOND Version:508
Operating System:Windows 7 Pro 64-bit
Web Browser:Chrome 44.0.2403.155
Applies to:Dream Seeker
Status: Open

Issue hasn't been assigned a status value.
Descriptive Problem Summary: The original topic is here. You'll see the issue in action and a discussion on it there.

Unfortunately, so far our efforts in finding the source of the problem have fallen short of results. We all posted our graphics card information in that topic, and while I didn't see anything that stuck out, you might.

There's little concrete information to go on, but the facts so far:
  • Two users are having problems. Both clients experiencing the problem are using Windows 10.
  • One of the two aforementioned users tested in both the webclient and DS and the problem persisted.


Numbered Steps to Reproduce Problem: Inconclusive.

Code Snippet (if applicable) to Reproduce Problem:
proc/shadowed_maptext(text, text_color = "#fff", x = 0, y = 0, width = 256, height = 256, offset = 1, shadow_dir = SOUTH, shadow_color = "#000")
var obj/temp = new/obj
temp.maptext = "<span style=\"color:[shadow_color];\">[text]</span>"
temp.maptext_width = width
temp.maptext_height = height
temp.maptext_x = x + ((shadow_dir & (EAST | WEST)) ? ((shadow_dir & EAST && offset) || -offset) : (0))
temp.maptext_y = y + ((shadow_dir & (NORTH | SOUTH)) ? ((shadow_dir & NORTH && offset) || -offset) : (0))
temp.layer = FLOAT_LAYER
temp.underlays += temp.appearance

temp.maptext = "<span style=\"color:[text_color];\">[text]</span>"
temp.maptext_x = 0
temp.maptext_y = 0
temp.layer = MOB_LAYER + 1
temp.overlays += temp.appearance
return temp


Expected Results: Maptext with a shadow attached.

Actual Results: Maptext without a shadow, or with partial shadow applied. (Only occurs in some cases.)

Does the problem occur:
Every time? Or how often? Every time on a problem machine; no issues otherwise.

When does the problem NOT occur? On some variable machines, it works, and on others, it displays wacky behavior (see original topic above).
I don't think this is a maptext issue; I think it's something with the fact that you're using FLOAT_LAYER and a big icon.

The behavior is obviously wrong, although I think the original code is questionable; it doesn't make much sense to me for the main layer to be MOB_LAYER+1 but the shadow to be FLOAT_LAYER.

I think in this case the layers are working out like so:

turf - float - obj - mob+1

DS's layering sort is actually inferior to the webclient's and I think in this case, the float is being resolved like so:

turf(1) - turf(2) - obj - mob+1

Whereas the better form used by the webclient is:

turf - obj(1) - obj(2) - mob+1

...because the float is resolved at the atom level.

That alone doesn't explain this, but I think this may be interacting with the code that handles big icons, so that big turfs try to put other turfs behind them. It's something else I can look into. The very simplest solution is to improve the "unfloat" code, which would basically take the big icon handling off the table.
In response to Lummox JR
Looking at it again, I do think the FLOAT_LAYER is unnecessary.

A couple questions:
  • When you say big icon, are you referring to the maptext_width/height values?
  • Wouldn't the order be: obj_layer -> float_layer -> obj_layer -> mob_layer+1?
In response to FKI
Yes, I'm referring to the maptext_width/height. The code that handles big turfs--and pushes other same-layer icons to the back--is atom-agnostic so it doesn't care if it's a turf or an obj, or what. Nor does it care if it's an overlay.

But no, the order would not be obj - float - obj - mob+1, because the first atom is a turf, not an obj. Your obj has only three icons: the float-layer underlay, the obj itself which has no icon, and the overlay at mob+1.

DS's behavior with floats is actually a little broken, but in ways that haven't typically mattered much because of the way overlays get sorted at the server end before appearances are sent. But when it comes time to "unfloat", it does something roughly like this:

if(count > 1) {
// unfloat overlays
layer = icons[0];
for(i=1; i<count; ++i) {
if(icons[i].layer > 0) layer = icons[i].layer;
else if(layer > 0) icons[i].layer = layer;
}
// unfloat underlays
layer = icons[count-1];
for(i=count-2; i>=0; --i) {
if(icons[i].layer > 0) layer = icons[i].layer;
else if(layer > 0) icons[i].layer = layer;
}
}

In simple terms, going forward through the list it takes the last positive layer, and uses that to replace any negative (floating) layers it finds. Then it does the same going backward.

The new behavior will do this on a per-atom basis. Currently DS does this per tile, using the area and turf followed by the objs and mobs on that tile. That's in line with the reference's description of FLOAT_LAYER.
In response to Lummox JR
Ah, I see. Anything that can be done to help the users experiencing issues? Maybe removing the float setting and/or reducing the maptext's size?
IMO, I'd keep the layering simple. Maybe have a single SHADOW_LAYER that's not close to the turf layer (e.g., TURF_LAYER+0.5) and the text could be FLY_LAYER--which actually already is MOB_LAYER+1, so it's the same thing but simpler to write.

If this is for a library, I'd suggest simply setting defaults and letting the user override them.