ID:2656004
 
Not a bug
BYOND Version:514.1547
Operating System:Windows 10 Pro 64-bit
Web Browser:Chrome 88.0.4324.150
Applies to:Dream Seeker
Status: Not a bug

This is not a bug. It may be an incorrect use of syntax or a limitation in the software. For further discussion on the matter, please consult the BYOND forums.
Descriptive Problem Summary:
VIS_UNDERLAY still fails to underlay objects.

Numbered Steps to Reproduce Problem:
1) Add the VIS_UNDERLAY flag to a /mob or /obj on a turf.
2) Add the turf to a translucent turf's vis_contents.
3) Observe how the object is above the translucent turf.

Code Snippet (if applicable) to Reproduce Problem:
https://cdn.discordapp.com/attachments/387073926045368320/ 811397659159035919/vis_issue.zip

Expected Results:
Objects appear below the turf

Actual Results:
They appear above

Does the problem occur:
Every time? Or how often? Yes
In other games? N/A
In other user accounts? N/A
On other computers? N/A

When does the problem NOT occur?
N/A

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked?
Forever as far as I know

Workarounds:
Setting everything to VIS_INHERIT_PLANE and creating a bunch of separate /atom/movables on the turf to hold the vis_contents with decreasing plane height so objects stack correctly
Thanks. I'll take a look at your test case and see what's up.
Lummox JR resolved issue (Not a bug)
There is no bug here. The objects are maintaining their original layers. Adding VIS_INHERIT_LAYER to the open space doesn't really help, though, because the way the open spaces are handled is fundamentally incorrect.

What you need to do for a lower level to display from a higher one is to use an object with KEEP_TOGETHER to lump each turf and all its contents—or better for rendering, a whole group of turfs, maybe every 8 or 10 tiles or so.

Here's an approach that will work (updated, code has been tested):

#define LOWER_FLOOR_PLANE -100 // first plane for lower floors
#define MAIN_FLOOR_DISTANCE 9 // "distance" from camera

// create new/obj/lowerplane(1), new/obj/lowerplane(2), etc. as globals, and add to client.screen at login
obj/lowerplane
appearance_flags = PLANE_MASTER | NO_CLIENT_COLOR
plane = LOWER_FLOOR_PLANE
screen_loc = "CENTER" // so it can be added to client.screen
New(z_delta) // how many levels down is this?
plane = initial(plane) - (z_delta-1)
color = list("#d00", "#0d0", "#00d", "#000d", "#2222")
transform = matrix(MAIN_FLOOR_DISTANCE / (z_delta+MAIN_FLOOR_DISTANCE), MATRIX_SCALE)
var/list/lowerplanes = new

atom/plane = FLOAT_PLANE

// the object that has the actual turf vis_contents
obj/lowerfloor
appearance_flags = KEEP_TOGETHER
vis_flags = VIS_INHERIT_LAYER

obj/floorpost
vis_flags = VIS_HIDE
layer = TURF_LAYER-0.5

proc/Fill()
var/X=x, Y=y, Z=z
var/X0=max(X-1,1), Y0=max(Y-1,1)
var/X1=min(X+8,world.maxx), Y1=min(Y+8,world.maxy)
var/turf{T1; T2}
var/P = LOWER_FLOOR_PLANE
// offset this to line up with the southwest-most turf in visual contents
transform = matrix(32*(X0-X), 32*(Y0-Y), MATRIX_TRANSLATE)

// add a dummy object at the northeast corner so the engine knows to keep this post in view
var/obj/dummy = new
dummy.icon = null
dummy.transform = matrix(32*(X1-X), 32*(Y1-Y), MATRIX_TRANSLATE)
vis_contents += dummy

while(--Z > 0)
var/obj/lowerfloor/O = new
O.plane = P--
vis_contents += O
T1 = locate(X0,Y0,Z)
T2 = locate(X1,Y1,Z)
O.vis_contents = block(T1,T2)
// look for lower floors we might need
if(!(locate(/obj/floorpost) in locate(X,Y,Z))) break

proc/FillSpaces()
var/X,Y,Z
var/turf/T
var/obj/floorpost/FP
var/list/posts = new
for(var/turf/openspace/O)
if((Z=O.z) <= 1) continue
X=O.x; Y=O.y
T = locate(((X-1)&~7)+1, ((Y-1)&~7)+1, Z)
if(!T) continue
FP = locate() in T
if(!FP)
FP = new/obj/floorpost(T)
posts[FP] = null
for(FP in posts) FP.Fill()

world/New()
..()
FillSpaces()

mob/Login()
..()
for(var/i in 1 to world.maxz-1)
if(i > lowerplanes.len) lowerplanes += new/obj/lowerplane(i)
client?.screen += lowerplanes[i]

That code requires that the turf/openspace/New() you have be removed.
Apparently I just didn't understand what underlays did. I thought they forced an object to be rendered under it, but that only works if it's FLOAT.

The KEEP_TOGETHER mention helped though
A word of warning: While testing the code I provided I discovered two bugs with visual bounds that are a bit of a problem. So the solution I provided will work more properly in 514.1548.

[edit]
I thought there was a workaround but apparently I was wrong. Anyway the visual bounds issue will be fixed in the next release.

One workaround that might work is to give the floorpost object a transparent icon that's 320x320.