From ea1e6ff95fb48e198162f2bb99448777bc7f9e06 Mon Sep 17 00:00:00 2001
From: SkyratBot <59378654+SkyratBot@users.noreply.github.com>
Date: Fri, 25 Nov 2022 15:27:27 +0100
Subject: [PATCH] [MIRROR] Adds a preference that disables intensive rendering
on different multiz layers [MDB IGNORE] (#17737)
* Adds a preference that disables intensive rendering on different multiz layers (#71218)
## About The Pull Request
It's kinda hacky, but it is nearly the same as just rendering one z
layer.
We allow people to ENTIRELY REMOVE most plane masters from their screen.
This has the side effect of disabling most visual effects (AO is a big
one) which saves a LOT of gpu.
We rely on planes being essentially layers to ensure things render in
the proper order. (outside of some hackyness required to make parallax
work)
I've kept parallax and lighting enabled, so visuals will still look
better then multiz pre plane cube.
It does also mean that things like FOV don't work, but honestly they
didn't work PRE plane cube, and FOV's implementation makes me mad so I
have a hard time caring.
Reduces gpu usage on my machine on tram from 47% to 32%, just above the
27% I get on meta.
I'm happy with this.
Oh also turns out the parallaxing had almost no cost. Need to remove it
as a side effect of what I'm doing but if I could keep it I would.
There's still room for in between performance options, like disabling
things like AO on lower z layers, but I didn't expect it to make a huge
impact, so I left things as is
Also fixes a bug with paper bins not respecting z layer. It came up in
testing and annoyed me
## Why It's Good For The Game
Ensures we can make multiz maps without running into client performance
issues, allows users to customize performance and visual quality.
## Changelog
:cl:
add: Adds a new rendering option to the gameplay preferences. You can
now limit the rendering intensity of multiz levels. This will make
things look a bit worse, but run a LOT better. Try it out if your
machine chokes on icebox or somethin.
/:cl:
Co-authored-by: Mothblocks <35135081+Mothblocks@ users.noreply.github.com>
* Adds a preference that disables intensive rendering on different multiz layers
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Co-authored-by: Mothblocks <35135081+Mothblocks@ users.noreply.github.com>
---
code/__DEFINES/layers.dm | 18 +++++
code/__HELPERS/_planes.dm | 2 +
code/_onclick/hud/parallax.dm | 16 +++-
code/_onclick/hud/rendering/plane_master.dm | 75 ++++++++++++++++++-
.../hud/rendering/plane_master_group.dm | 27 ++++++-
code/_onclick/hud/rendering/render_plate.dm | 4 +
code/controllers/subsystem/mapping.dm | 9 +++
code/datums/components/fov_handler.dm | 4 +-
code/modules/cargo/centcom_podlauncher.dm | 2 +-
.../client/preferences/ambient_occlusion.dm | 2 +-
.../client/preferences/multiz_performance.dm | 21 ++++++
code/modules/mob/living/ventcrawling.dm | 8 +-
code/modules/mob/mob.dm | 2 +-
code/modules/paperwork/paperbin.dm | 5 +-
tgstation.dme | 1 +
.../game_preferences/multiz_performance.tsx | 12 +++
16 files changed, 191 insertions(+), 17 deletions(-)
create mode 100644 code/modules/client/preferences/multiz_performance.dm
create mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/multiz_performance.tsx
diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm
index 8680212a0ba..d68948ce0bd 100644
--- a/code/__DEFINES/layers.dm
+++ b/code/__DEFINES/layers.dm
@@ -236,3 +236,21 @@
///Plane master controller keys
#define PLANE_MASTERS_GAME "plane_masters_game"
#define PLANE_MASTERS_COLORBLIND "plane_masters_colorblind"
+
+//Plane master critical flags
+//Describes how different plane masters behave when they are being culled for performance reasons
+/// This plane master will not go away if its layer is culled. useful for preserving effects
+#define PLANE_CRITICAL_DISPLAY (1<<0)
+/// This plane master will temporarially remove relays to non critical planes if it's layer is culled (and it's critical)
+/// This is VERY hacky, but needed to ensure that some instances of BLEND_MULITPLY work as expected (fuck you god damn parallax)
+/// It also implies that the critical plane has a *'d render target, making it mask itself
+#define PLANE_CRITICAL_NO_EMPTY_RELAY (1<<1)
+
+#define PLANE_CRITICAL_FUCKO_PARALLAX (PLANE_CRITICAL_DISPLAY|PLANE_CRITICAL_NO_EMPTY_RELAY)
+
+/// A value of /datum/preference/numeric/multiz_performance that disables the option
+#define MULTIZ_PERFORMANCE_DISABLE -1
+/// We expect at most 3 layers of multiz
+/// Increment this define if you make a huge map. We unit test for it too just to make it easy for you
+/// If you modify this, you'll need to modify the tsx file too
+#define MAX_EXPECTED_Z_DEPTH 2
diff --git a/code/__HELPERS/_planes.dm b/code/__HELPERS/_planes.dm
index 1af0b636514..d8306c356d4 100644
--- a/code/__HELPERS/_planes.dm
+++ b/code/__HELPERS/_planes.dm
@@ -63,6 +63,8 @@
#define PLANE_TO_TRUE(plane) ((SSmapping.plane_offset_to_true) ? SSmapping.plane_offset_to_true["[plane]"] : plane)
/// Takes a plane, returns the offset it uses
#define PLANE_TO_OFFSET(plane) ((SSmapping.plane_to_offset) ? SSmapping.plane_to_offset["[plane]"] : plane)
+/// Takes a plane, returns TRUE if it is of critical priority, FALSE otherwise
+#define PLANE_IS_CRITICAL(plane) ((SSmapping.plane_to_offset) ? !!SSmapping.critical_planes["[plane]"] : FALSE)
/// Takes a true plane, returns the offset planes that would canonically represent it
#define TRUE_PLANE_TO_OFFSETS(plane) ((SSmapping.true_to_offset_planes) ? SSmapping.true_to_offset_planes["[plane]"] : list(plane))
/// Takes a render target and an offset, returns a canonical render target string for it
diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm
index 05f3f6e48cc..a4b20d521fe 100755
--- a/code/_onclick/hud/parallax.dm
+++ b/code/_onclick/hud/parallax.dm
@@ -2,9 +2,15 @@
/datum/hud/proc/create_parallax(mob/viewmob)
var/mob/screenmob = viewmob || mymob
var/client/C = screenmob.client
+
if (!apply_parallax_pref(viewmob)) //don't want shit computers to crash when specing someone with insane parallax, so use the viewer's pref
+ for(var/atom/movable/screen/plane_master/parallax as anything in get_true_plane_masters(PLANE_SPACE_PARALLAX))
+ parallax.hide_plane(screenmob)
return
+ for(var/atom/movable/screen/plane_master/parallax as anything in get_true_plane_masters(PLANE_SPACE_PARALLAX))
+ parallax.unhide_plane(screenmob)
+
if(!length(C.parallax_layers_cached))
C.parallax_layers_cached = list()
C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_1(null, screenmob)
@@ -23,7 +29,7 @@
// We could do not do parallax for anything except the main plane group
// This could be changed, but it would require refactoring this whole thing
// And adding non client particular hooks for all the inputs, and I do not have the time I'm sorry :(
- for(var/atom/movable/screen/plane_master/plane_master in screenmob.hud_used.get_true_plane_masters(PLANE_SPACE))
+ for(var/atom/movable/screen/plane_master/plane_master as anything in screenmob.hud_used.get_true_plane_masters(PLANE_SPACE))
if(screenmob != mymob)
C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen
C.screen += plane_master
@@ -39,7 +45,7 @@
var/mob/screenmob = viewmob || mymob
var/client/C = screenmob.client
C.screen -= (C.parallax_layers_cached)
- for(var/atom/movable/screen/plane_master/plane_master in screenmob.hud_used.get_true_plane_masters(PLANE_SPACE))
+ for(var/atom/movable/screen/plane_master/plane_master as anything in screenmob.hud_used.get_true_plane_masters(PLANE_SPACE))
if(screenmob != mymob)
C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen
C.screen += plane_master
@@ -50,7 +56,13 @@
var/mob/screenmob = viewmob || mymob
if(SSmapping.level_trait(screenmob.z, ZTRAIT_NOPARALLAX))
+ for(var/atom/movable/screen/plane_master/white_space as anything in get_true_plane_masters(PLANE_SPACE))
+ white_space.hide_plane(screenmob)
return FALSE
+
+ for(var/atom/movable/screen/plane_master/white_space as anything in get_true_plane_masters(PLANE_SPACE))
+ white_space.unhide_plane(screenmob)
+
if (SSlag_switch.measures[DISABLE_PARALLAX] && !HAS_TRAIT(viewmob, TRAIT_BYPASS_MEASURES))
return FALSE
diff --git a/code/_onclick/hud/rendering/plane_master.dm b/code/_onclick/hud/rendering/plane_master.dm
index 048b7185a42..9a37ee05a49 100644
--- a/code/_onclick/hud/rendering/plane_master.dm
+++ b/code/_onclick/hud/rendering/plane_master.dm
@@ -1,5 +1,6 @@
// I hate this place
INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master)
+
/atom/movable/screen/plane_master
screen_loc = "CENTER"
icon_state = "blank"
@@ -51,6 +52,18 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master)
/// Planes with this set should NEVER be relay'd into each other, as that will cause visual fuck
var/multiz_scaled = TRUE
+ /// Bitfield that describes how this plane master will render if its z layer is being "optimized"
+ /// If a plane master is NOT critical, it will be completely dropped if we start to render outside a client's multiz boundary prefs
+ /// Of note: most of the time we will relay renders to non critical planes in this stage. so the plane master will end up drawing roughly "in order" with its friends
+ /// This is NOT done for parallax and other problem children, because the rules of BLEND_MULTIPLY appear to not behave as expected :(
+ /// This will also just make debugging harder, because we do fragile things in order to ensure things operate as epected. I'm sorry
+ /// Compile time
+ /// See [code\__DEFINES\layers.dm] for our bitflags
+ var/critical = NONE
+
+ /// If this plane master is outside of our visual bounds right now
+ var/is_outside_bounds = FALSE
+
/atom/movable/screen/plane_master/Initialize(mapload, datum/plane_master_group/home, offset = 0)
. = ..()
src.offset = offset
@@ -116,7 +129,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master)
/// Returns TRUE if the call is allowed, FALSE otherwise
/atom/movable/screen/plane_master/proc/show_to(mob/mymob)
SHOULD_CALL_PARENT(TRUE)
- if(force_hidden)
+ if(force_hidden || is_outside_bounds)
return FALSE
var/client/our_client = mymob?.client
@@ -166,6 +179,45 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master)
else
unhide_plane(our_mob)
+/atom/movable/screen/plane_master/proc/outside_bounds(mob/relevant)
+ if(force_hidden || is_outside_bounds)
+ return
+ is_outside_bounds = TRUE
+ // If we're of critical importance, AND we're below the rendering layer
+ if(critical & PLANE_CRITICAL_DISPLAY)
+ if(!(critical & PLANE_CRITICAL_NO_EMPTY_RELAY))
+ return
+ var/client/our_client = relevant.client
+ if(!our_client)
+ return
+ for(var/atom/movable/render_plane_relay/relay as anything in relays)
+ if(!relay.critical_target)
+ our_client.screen -= relay
+
+ // We here assume that your render target starts with *
+ if(render_target)
+ render_target = copytext_char(render_target, 2)
+ return
+ hide_from(relevant)
+
+/atom/movable/screen/plane_master/proc/inside_bounds(mob/relevant)
+ is_outside_bounds = FALSE
+ if(critical & PLANE_CRITICAL_DISPLAY)
+ if(!(critical & PLANE_CRITICAL_NO_EMPTY_RELAY))
+ return
+ var/client/our_client = relevant.client
+ if(!our_client)
+ return
+ for(var/atom/movable/render_plane_relay/relay as anything in relays)
+ if(!relay.critical_target)
+ our_client.screen += relay
+
+ // We here assume that your render target starts with *
+ if(render_target)
+ render_target = "*[render_target]"
+ return
+ show_to(relevant)
+
/atom/movable/screen/plane_master/clickcatcher
name = "Click Catcher"
documentation = "Contains the screen object we use as a backdrop to catch clicks on portions of the screen that would otherwise contain nothing else. \
@@ -173,6 +225,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master)
plane = CLICKCATCHER_PLANE
appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR
multiz_scaled = FALSE
+ critical = PLANE_CRITICAL_DISPLAY
/atom/movable/screen/plane_master/clickcatcher/Initialize(mapload, datum/plane_master_group/home, offset)
. = ..()
@@ -192,6 +245,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master)
If you want something to look as if it has parallax on it, draw it to this plane."
plane = PLANE_SPACE
appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR
+ critical = PLANE_CRITICAL_FUCKO_PARALLAX // goes funny when touched. no idea why I don't trust byond
///Contains space parallax
/atom/movable/screen/plane_master/parallax
@@ -205,6 +259,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master)
blend_mode = BLEND_MULTIPLY
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
multiz_scaled = FALSE
+ critical = PLANE_CRITICAL_FUCKO_PARALLAX
/atom/movable/screen/plane_master/parallax/Initialize(mapload, datum/plane_master_group/home, offset)
. = ..()
@@ -225,6 +280,21 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master)
// Overlay so we don't multiply twice, and thus fuck up our rendering
add_relay_to(GET_NEW_PLANE(plane, offset), BLEND_OVERLAY)
+// Hacky shit to ensure parallax works in perf mode
+/atom/movable/screen/plane_master/parallax/outside_bounds(mob/relevant)
+ if(offset == 0)
+ remove_relay_from(GET_NEW_PLANE(RENDER_PLANE_GAME, 0))
+ is_outside_bounds = TRUE // I'm sorry :(
+ return
+ return ..()
+
+/atom/movable/screen/plane_master/parallax/inside_bounds(mob/relevant)
+ if(offset == 0)
+ add_relay_to(GET_NEW_PLANE(RENDER_PLANE_GAME, 0))
+ is_outside_bounds = FALSE
+ return
+ return ..()
+
/atom/movable/screen/plane_master/gravpulse
name = "Gravpulse"
documentation = "Ok so this one's fun. Basically, we want to be able to distort the game plane when a grav annom is around.\
@@ -407,6 +477,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master)
render_relay_planes = list(RENDER_PLANE_LIGHTING)
blend_mode_override = BLEND_ADD
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ critical = PLANE_CRITICAL_DISPLAY
/// This will not work through multiz, because of a byond bug with BLEND_MULTIPLY
/// Bug report is up, waiting on a fix
@@ -420,6 +491,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master)
render_target = O_LIGHTING_VISUAL_RENDER_TARGET
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
blend_mode = BLEND_MULTIPLY
+ critical = PLANE_CRITICAL_DISPLAY
/atom/movable/screen/plane_master/above_lighting
name = "Above lighting"
@@ -444,6 +516,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master)
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
render_target = EMISSIVE_RENDER_TARGET
render_relay_planes = list()
+ critical = PLANE_CRITICAL_DISPLAY
/atom/movable/screen/plane_master/emissive/Initialize(mapload)
. = ..()
diff --git a/code/_onclick/hud/rendering/plane_master_group.dm b/code/_onclick/hud/rendering/plane_master_group.dm
index 48c3ed00388..d3b9902171d 100644
--- a/code/_onclick/hud/rendering/plane_master_group.dm
+++ b/code/_onclick/hud/rendering/plane_master_group.dm
@@ -11,7 +11,6 @@
var/list/atom/movable/screen/plane_master/plane_masters = list()
/// The visual offset we are currently using
var/active_offset = 0
-
/// What, if any, submap we render onto
var/map = ""
@@ -94,7 +93,8 @@
// It's hard, and potentially expensive. be careful
/datum/plane_master_group/proc/transform_lower_turfs(datum/hud/source, new_offset, use_scale = TRUE)
// Check if this feature is disabled for the client, in which case don't use scale.
- if(!our_hud?.mymob?.client?.prefs?.read_preference(/datum/preference/toggle/multiz_parallax))
+ var/mob/our_mob = our_hud?.mymob
+ if(!our_mob?.client?.prefs?.read_preference(/datum/preference/toggle/multiz_parallax))
use_scale = FALSE
// No offset? piss off
@@ -115,8 +115,15 @@
scale_by = 1
var/list/offsets = list()
+ var/multiz_boundary = our_mob?.client?.prefs?.read_preference(/datum/preference/numeric/multiz_performance)
+
// We accept negatives so going down "zooms" away the drop above as it goes
for(var/offset in -SSmapping.max_plane_offset to SSmapping.max_plane_offset)
+ // Multiz boundaries disable transforms
+ if(multiz_boundary != MULTIZ_PERFORMANCE_DISABLE && (multiz_boundary < abs(offset)))
+ offsets += null
+ continue
+
// No transformations if we're landing ON you
if(offset == 0)
offsets += null
@@ -132,11 +139,23 @@
for(var/plane_key in plane_masters)
var/atom/movable/screen/plane_master/plane = plane_masters[plane_key]
- if(!plane.multiz_scaled || !plane.allows_offsetting)
+ if(!plane.allows_offsetting)
continue
var/visual_offset = plane.offset - new_offset
- if(plane.force_hidden || visual_offset < 0)
+ // we get like 47 -> 42 from just no AO/displace on lower levels. 39 with no FOV blocking
+ // 31 with only barebones lower planes
+
+ // Basically uh, if we're showing something down X amount of levels, or up any amount of levels
+ if(multiz_boundary != MULTIZ_PERFORMANCE_DISABLE && (visual_offset > multiz_boundary || visual_offset < 0))
+ plane.outside_bounds(our_mob)
+ else if(plane.is_outside_bounds)
+ plane.inside_bounds(our_mob)
+
+ if(!plane.multiz_scaled)
+ continue
+
+ if(plane.force_hidden || plane.is_outside_bounds || visual_offset < 0)
// We don't animate here because it should be invisble, but we do mark because it'll look nice
plane.transform = offsets[visual_offset + offset_offset]
continue
diff --git a/code/_onclick/hud/rendering/render_plate.dm b/code/_onclick/hud/rendering/render_plate.dm
index 5c0bc5b985f..47c1c495382 100644
--- a/code/_onclick/hud/rendering/render_plate.dm
+++ b/code/_onclick/hud/rendering/render_plate.dm
@@ -13,6 +13,8 @@
layer = -1
plane = 0
appearance_flags = PASS_MOUSE | NO_CLIENT_COLOR | KEEP_TOGETHER
+ /// If we render into a critical plane master, or not
+ var/critical_target = FALSE
/**
* ## Rendering plate
@@ -119,6 +121,7 @@
plane = RENDER_PLANE_LIGHTING
blend_mode_override = BLEND_MULTIPLY
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ critical = PLANE_CRITICAL_DISPLAY
/atom/movable/screen/plane_master/rendering_plate/lighting/show_to(mob/mymob)
. = ..()
@@ -251,6 +254,7 @@
relay.blend_mode = blend_to_use
relay.mouse_opacity = mouse_opacity
relay.name = render_target
+ relay.critical_target = PLANE_IS_CRITICAL(target_plane)
relays += relay
// Relays are sometimes generated early, before huds have a mob to display stuff to
// That's what this is for
diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm
index a0f5096226e..0ae858b3fc6 100644
--- a/code/controllers/subsystem/mapping.dm
+++ b/code/controllers/subsystem/mapping.dm
@@ -47,6 +47,8 @@ SUBSYSTEM_DEF(mapping)
var/list/plane_offset_blacklist
/// List of render targets that do not allow for offsetting
var/list/render_offset_blacklist
+ /// List of plane masters that are of critical priority
+ var/list/critical_planes
/// The largest plane offset we've generated so far
var/max_plane_offset = 0
@@ -111,6 +113,7 @@ SUBSYSTEM_DEF(mapping)
plane_to_offset["[FLOAT_PLANE]"] = 0
plane_offset_blacklist = list()
render_offset_blacklist = list()
+ critical_planes = list()
create_plane_offsets(0, 0)
initialize_biomes()
loadWorld()
@@ -802,6 +805,9 @@ GLOBAL_LIST_EMPTY(the_station_areas)
generate_offset_lists(old_max + 1, max_plane_offset)
SEND_SIGNAL(src, COMSIG_PLANE_OFFSET_INCREASE, old_max, max_plane_offset)
+ // Sanity check
+ if(max_plane_offset > MAX_EXPECTED_Z_DEPTH)
+ stack_trace("We've loaded a map deeper then the max expected z depth. Preferences won't cover visually disabling all of it!")
/// Takes an offset to generate misc lists to, and a base to start from
/// Use this to react globally to maintain parity with plane offsets
@@ -833,6 +839,9 @@ GLOBAL_LIST_EMPTY(the_station_areas)
if(plane_offset != 0)
continue
+ if(initial(master_type.critical) & PLANE_CRITICAL_DISPLAY)
+ critical_planes[string_plane] = TRUE
+
plane_offset_to_true[string_plane] = plane_to_use
plane_to_offset[string_plane] = plane_offset
diff --git a/code/datums/components/fov_handler.dm b/code/datums/components/fov_handler.dm
index 1316f7ff7e0..10f58186991 100644
--- a/code/datums/components/fov_handler.dm
+++ b/code/datums/components/fov_handler.dm
@@ -22,7 +22,7 @@
qdel(src) //no QDEL hint for components, and we dont want this to print a warning regarding bad component application
return
- for(var/atom/movable/screen/plane_master/plane_master in mob_parent.hud_used.get_true_plane_masters(FIELD_OF_VISION_BLOCKER_PLANE))
+ for(var/atom/movable/screen/plane_master/plane_master as anything in mob_parent.hud_used.get_true_plane_masters(FIELD_OF_VISION_BLOCKER_PLANE))
plane_master.unhide_plane(mob_parent)
blocker_mask = new
@@ -36,7 +36,7 @@
/datum/component/fov_handler/Destroy()
var/mob/living/mob_parent = parent
- for(var/atom/movable/screen/plane_master/plane_master in mob_parent.hud_used.get_true_plane_masters(FIELD_OF_VISION_BLOCKER_PLANE))
+ for(var/atom/movable/screen/plane_master/plane_master as anything in mob_parent.hud_used.get_true_plane_masters(FIELD_OF_VISION_BLOCKER_PLANE))
plane_master.hide_plane(mob_parent)
if(applied_mask)
diff --git a/code/modules/cargo/centcom_podlauncher.dm b/code/modules/cargo/centcom_podlauncher.dm
index 0f185c0effc..baec0b57829 100644
--- a/code/modules/cargo/centcom_podlauncher.dm
+++ b/code/modules/cargo/centcom_podlauncher.dm
@@ -105,7 +105,7 @@
var/datum/plane_master_group/planes = cam_screen.display_to(holder.mob)
if(!renderLighting)
- for(var/atom/movable/screen/plane_master/instance in holder.mob.hud_used.get_true_plane_masters(LIGHTING_PLANE, planes.key))
+ for(var/atom/movable/screen/plane_master/instance as anything in holder.mob.hud_used.get_true_plane_masters(LIGHTING_PLANE, planes.key))
instance.set_alpha(100)
cam_background = new
diff --git a/code/modules/client/preferences/ambient_occlusion.dm b/code/modules/client/preferences/ambient_occlusion.dm
index 1a58b065968..cf8bf28c1e5 100644
--- a/code/modules/client/preferences/ambient_occlusion.dm
+++ b/code/modules/client/preferences/ambient_occlusion.dm
@@ -6,5 +6,5 @@
/datum/preference/toggle/ambient_occlusion/apply_to_client(client/client, value)
/// Backdrop for the game world plane.
- for(var/atom/movable/screen/plane_master/rendering_plate/game_world/plane_master in client.mob?.hud_used?.get_true_plane_masters(GAME_PLANE))
+ for(var/atom/movable/screen/plane_master/plane_master as anything in client.mob?.hud_used?.get_true_plane_masters(GAME_PLANE))
plane_master.show_to(client.mob)
diff --git a/code/modules/client/preferences/multiz_performance.dm b/code/modules/client/preferences/multiz_performance.dm
new file mode 100644
index 00000000000..7591401f2d8
--- /dev/null
+++ b/code/modules/client/preferences/multiz_performance.dm
@@ -0,0 +1,21 @@
+/// Boundary for how many z levels down to render properly before we start going cheapo mode
+/datum/preference/numeric/multiz_performance
+ category = PREFERENCE_CATEGORY_GAME_PREFERENCES
+ savefile_key = "multiz_performance"
+ savefile_identifier = PREFERENCE_PLAYER
+
+ minimum = MULTIZ_PERFORMANCE_DISABLE
+ maximum = MAX_EXPECTED_Z_DEPTH - 1
+
+/datum/preference/numeric/multiz_performance/create_default_value()
+ return -1
+
+/datum/preference/numeric/multiz_performance/apply_to_client(client/client, value)
+ // Update the plane master group's layering
+ var/datum/hud/my_hud = client.mob?.hud_used
+ if(!my_hud)
+ return
+
+ for(var/group_key as anything in my_hud.master_groups)
+ var/datum/plane_master_group/group = my_hud.master_groups[group_key]
+ group.transform_lower_turfs(my_hud, my_hud.current_plane_offset)
diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm
index fc139e00762..646659a6255 100644
--- a/code/modules/mob/living/ventcrawling.dm
+++ b/code/modules/mob/living/ventcrawling.dm
@@ -110,18 +110,18 @@
client.images -= current_image
pipes_shown.len = 0
pipetracker = null
- for(var/atom/movable/screen/plane_master/lighting in hud_used.get_true_plane_masters(LIGHTING_PLANE))
+ for(var/atom/movable/screen/plane_master/lighting as anything in hud_used.get_true_plane_masters(LIGHTING_PLANE))
lighting.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#4d4d4d")
- for(var/atom/movable/screen/plane_master/pipecrawl in hud_used.get_true_plane_masters(PIPECRAWL_IMAGES_PLANE))
+ for(var/atom/movable/screen/plane_master/pipecrawl as anything in hud_used.get_true_plane_masters(PIPECRAWL_IMAGES_PLANE))
pipecrawl.hide_plane(src)
return
// We're gonna color the lighting plane to make it darker while ventcrawling, so things look nicer
// This is a bit hacky but it makes the background darker, which has a nice effect
- for(var/atom/movable/screen/plane_master/lighting in hud_used.get_true_plane_masters(LIGHTING_PLANE))
+ for(var/atom/movable/screen/plane_master/lighting as anything in hud_used.get_true_plane_masters(LIGHTING_PLANE))
lighting.add_atom_colour("#4d4d4d", TEMPORARY_COLOUR_PRIORITY)
- for(var/atom/movable/screen/plane_master/pipecrawl in hud_used.get_true_plane_masters(PIPECRAWL_IMAGES_PLANE))
+ for(var/atom/movable/screen/plane_master/pipecrawl as anything in hud_used.get_true_plane_masters(PIPECRAWL_IMAGES_PLANE))
pipecrawl.unhide_plane(src)
var/obj/machinery/atmospherics/current_location = loc
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 6b0d03fdf87..5ef7d4d5da4 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1142,7 +1142,7 @@
/mob/proc/sync_lighting_plane_alpha()
if(!hud_used)
return
- for(var/atom/movable/screen/plane_master/rendering_plate/lighting/light_plane in hud_used.get_true_plane_masters(RENDER_PLANE_LIGHTING))
+ for(var/atom/movable/screen/plane_master/light_plane as anything in hud_used.get_true_plane_masters(RENDER_PLANE_LIGHTING))
light_plane.set_alpha(lighting_alpha)
///Update the mouse pointer of the attached client in this mob
diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm
index 8a1665014f7..032e24b12a6 100644
--- a/code/modules/paperwork/paperbin.dm
+++ b/code/modules/paperwork/paperbin.dm
@@ -152,7 +152,7 @@
/obj/item/paper_bin/update_overlays()
. = ..()
- var/static/reference_paper
+ var/static/obj/item/paper/reference_paper
if (isnull(reference_paper))
reference_paper = new /obj/item/paper
@@ -163,6 +163,9 @@
bin_overlay = mutable_appearance(icon, bin_overlay_string)
if(total_paper > 0)
+ if(total_paper > length(paper_stack))
+ SET_PLANE_EXPLICIT(reference_paper, initial(reference_paper.plane), src)
+ reference_paper.update_appearance() // Ensures all our overlays are on the right plane
for(var/paper_number in 1 to total_paper)
if(paper_number != total_paper && paper_number % PAPERS_PER_OVERLAY != 0) //only top paper and every nth paper get overlays
continue
diff --git a/tgstation.dme b/tgstation.dme
index 2ebc8f0228c..74564061078 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -2830,6 +2830,7 @@
#include "code\modules\client\preferences\jobless_role.dm"
#include "code\modules\client\preferences\mod_select.dm"
#include "code\modules\client\preferences\multiz_parallax.dm"
+#include "code\modules\client\preferences\multiz_performance.dm"
#include "code\modules\client\preferences\names.dm"
#include "code\modules\client\preferences\ooc.dm"
#include "code\modules\client\preferences\parallax.dm"
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/multiz_performance.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/multiz_performance.tsx
new file mode 100644
index 00000000000..1d3a70f144c
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/multiz_performance.tsx
@@ -0,0 +1,12 @@
+import { createDropdownInput, Feature } from '../base';
+
+export const multiz_performance: Feature = {
+ name: 'Multi-Z Detail',
+ category: 'GAMEPLAY',
+ description: 'How detailed multi-z is. Lower this to improve performance',
+ component: createDropdownInput({
+ [-1]: 'Standard',
+ 1: 'Medium',
+ 0: 'Low',
+ }),
+};