ID:2396205
 
Applies to:DM Language
Status: Open

Issue hasn't been assigned a status value.
Layering at the moment is linear which restricts some very nice looking possible features involving effect layers. Sometimes you want something that would normally be on a lower layer to be on top of something that would normally be on a higher layer.

In our case it's planes. Lighting planes are (usually) placed on top of every object in the world. However there are some really nice effects you can get by making certain objects ignore that lighting plane.

Normal layering


Layering the computer screens over the lighting


This was done in https://github.com/tgstation/tgstation/pull/39973

As you can see it's already possible to an extent with existing features, just layer the screen over lighting and you get some nice looking glow effects. However there is a major flaw as I state in the pr above: you can't get rendered on top of *just* the lighting layer. Any object that should be on top of one of these glow effects will instead be rendered underneath unless it also gets layered on top of lighting.

My suggestion is to make it possible for objects to be layered on top of specific planes. This would allow you to do things like make the end of a cigarette glow but not be a mysterious glowing dot when under a pile of other items.
This allows a new layer of immersion in my eyes.
More than just computer screens, a few examples follow such as the e-sword, PDAs, any sort of device laying on the ground that would feature this.

I'm surprised this wasn't a thing sooner and want it ASAP.
Maybe it'd be possible to hear Lummox's opinion on this?
Really all you need is the ability to put a plane on another plane. Then you could render all the pass-through cutouts but then also render opaque stuff as black blobs overlayed in layering order. Then just add the final result to the lighting plane.
I do this in my project by making a lighting mask for stuff that should be "above" the lights, and for the generalized lights that glow, it gets a higher effective layer than the mask, lighting it up as expected.

It works, but it's not the best as I need to create an image (or add to vis_contents) for each and every mob that can move over that lighting object. Would be a huge benefit to have the ability to do it in hardcode.
Gonna refer something that was said to Lummox in Discord:

TerXIII06/22/2018
Odd question for you.
Is there a way to treat an object in vis_contents identically to an underlay?
I've got an animation I'm trying to move over to vis_contents ATM.

Essentially, that hammer animation is being handled by manually adding and removing an overlay and an underlay object.
Updating it frame by frame.
But I'm running into a number of issues.
1) vis_contents don't act like overlays and /images, in that they don't sync icon_states or directions with their parents (which is nice)
2) All the mob's overlays and underlays are rendered with FLOAT_LAYER to keep them from popping out of proper perspective. It's the only way I can get this playing nice is using an object in underlays with all the frames behind the player in one icon, and alll the frames in front of the player on the other icon, which is an object added to overlays.

TerXIII06/22/2018
I could probably fix the FLOAT_LAYER problem using KEEP_TOGETHER on the player ot make sure that the player is always rendered with all overlays on a single layer, and I could actually use vis_contents, animate(), and a single icon to flip the frames.
Except that changing the direction of the object mid-frame will cancel the animate() call.
And also that every time the player changes directions, the vis_contents component would have to be synced to the player's direction.
Which is a non-issue, as I've already got the tool use action tied to the player's Move()/Relocate() calls, so in theory any time dir changes, I can hook it, provided I always change dir by using a naive Relocate proc.
You've talked in the past for some kind of flagging system for appearances that affect how they are rendered when used as overlays or attached to a root object.
I believe Tom also mentioned it long, long ago.
I believe a number of these problems could be addressed via a set of flags:

apperance/var/vis_flags = 0

VIS_LAYER_SELF 0
VIS_LAYER_OVER 1
VIS_LAYER_UNDER 2
VIS_LAYER_SEPARATE 3

VIS_RESET_DIR 8
VIS_RESET_ICON 16
VIS_RESET_ICON_STATE 32
VIS_RESET_MOUSE_OPACITY 64


Bits 0 & 1 are layering rules.

VIS_LAYER_SELF means that the object uses its own layer to render according to the default rules for the container.
VIS_LAYER_OVER means that the object is treated as an overlay regardless of layer, plane, or rules for the container.
VIS_LAYER_UNDER means that the object is treated as an underlay regardless of the layer, plane, or rules for the container.
VIS_LAYER_SEPARATE means that while the object is ostensibly attached to the root object, it layers as though it is not part of the root container at all.

VIS_RESET_DIR means that the overlay, vis_obj, or image uses its own direction to determine direction.
VIS_RESET_ICON means that overlay never attempts to use the parent's icon to determine its own, even if null.
VIS_RESET_ICON_STATE means that the overlay never attempts to use the parent's icon_state to determine its own, even if null.
VIS_RESET_MOUSE_OPACITY means that overlay has its own unique influence on mouse_opacity.
(edited)
Of course, this would break any current use of vis_contents, and /image, as the behavior is inconsistent across the board.
So it's not an ideal solution...
I dunno.
Maybe a better solution is for bit 0 to mean ALL_DEFAULT, which doesn't really make sense at all, because it cancels out every other bit in the flag sequence.
But it would allow the inconsistent behavior to persist without breaking.
Actually, flag 0 should be VIS_OVERRIDE, which must be on for any flags to change, which would allow any value where bit 0 is off to mean do the default thing.
Which is kinda clunky, but better than the alternative of break fucking everything.

Lummox JR06/22/2018
A big question for me is whether the parent and child should both support flags or if only one side should; because it makes sense that the way visual contents are treated should depend on the purposes of the container, but I also see a point in exceptions. Also, I wonder if some kind of option for a layer or plane delta would be appropriate.
One thing I'd like to get into 513 is some concept of plane organization, so that planes can be grouped in a more logical way. It might make a lot of sense in certain games for multiple planes to be summarily affected by the same transform, filter, etc. which would be like plane masters having children.
TerXIII06/22/2018
Those are all solid questions.
In the weird wild world of BYOND's server-side rendering cues, this stuff gets complicated fast.



Sorry about the formatting, but the gist of the above is that I feel like generalizing the behavior in overlays/underlays where overlays and underlays can take icon, icon_state, etc. cues from their parent, could actually address this issue. One of the major problems with doing this manually is all the work that you've got to do in terms of updating and animating stuff. If there were a way to specify that a graphic should update like an overlay when in vis_contents, a good chunk of this issue could be easily solved without a lot of work for the developer.
The feature I used as an example is more indicative of a lack in certain engine features than anything. There's more than one way to solve it and all of them should allow for all sorts of interesting things beyond what I said. It's certainly possible to get around the problem but none of the solutions are particularly elegant.

We are still in a beta, if we were to add a breaking change to vis_contents now it should be fine. Ideally both sides should be able to modify how they get rendered.