Begin, the Lag Wars Have (#21839)

<img width="700" height="848" alt="image"
src="https://github.com/user-attachments/assets/e0db50af-35db-43c7-b78e-6c1ea5ac569c"
/>

you take a tiny little two year LOA and this happens
this PR hits some large lag culprits:
- UpdateOverlays() getting spammed by human/update_icon. This was 0.85%
of server CPU time during the event. Doesn't sound like a whole lot but
it's insane. 99% of it was caused by sloppy duplicate calls of
update_icon in set_dir (as well as update icon itself!). Refactored to
stop that
- Makes Follow menu update manually, which cuts down on the 2.8 million
REF() calls it made during the event. This was ~1% of CPU time including
ui_data as well.
- Gets rid of a bunch of random runtimes and some lighting-related
harddels.
- NanoUIs now clean themselves up when their owner qdels rather than
forcing the owner to do REF(src) and close all matching UIs. saves us
~0.1% server cpu time! wowza!
This commit is contained in:
Wildkins
2026-02-09 23:20:48 +00:00
committed by GitHub
parent 6ad39a46f7
commit 3d183d7262
19 changed files with 103 additions and 80 deletions
+3 -3
View File
@@ -132,13 +132,12 @@
set category = "Ghost"
set desc = "Follow and haunt a mob."
var/datum/tgui_module/follow_menu/GM = new /datum/tgui_module/follow_menu(usr)
GM.ui_interact(usr)
GLOB.follow_menu.ui_interact(src)
// This is the ghost's follow verb with an argument
/mob/abstract/ghost/proc/ManualFollow(var/atom/movable/target)
if(!target)
return
return FALSE
//Stops orbit if there's any; TG doesn't do this, but if you don't it breaks the orbiting reference
//if you are jumping from one mob to another, hence why we're doing it here
@@ -154,6 +153,7 @@
to_chat(src, SPAN_NOTICE("Now following \the <b>[target]</b>."))
update_sight()
return TRUE
/mob/abstract/ghost/proc/update_sight()
//if they are on a restricted level, then set the ghost vision for them.
@@ -109,9 +109,9 @@
var/datum/sprite_accessory/hair/hair = GLOB.hair_styles_list[h_style]
var/datum/sprite_accessory/facial_hair/facial = GLOB.facial_hair_styles_list[f_style]
if(!facial.keep_as_skeleton && f_style)
if(facial && !facial.keep_as_skeleton)
f_style = "Shaved"
if(!hair.keep_as_skeleton && h_style)
if(hair && !hair.keep_as_skeleton)
h_style = "Bald"
update_hair(0)
@@ -1466,7 +1466,7 @@
self = 1
if ((src.species.flags & NO_BLOOD) || (status_flags & FAKEDEATH))
to_chat(usr, SPAN_WARNING(self ? "You have no pulse." : "[src] has no pulse!"))
to_chat(usr, SPAN_WARNING("[self ? "You have" : "[src] has"] no pulse!"))
return
if(!self)
@@ -38,7 +38,6 @@
var/size_multiplier = 1 //multiplier for the mob's icon size
var/damage_multiplier = 1 //multiplies melee combat damage
var/icon_update = 1 //whether icon updating shall take place
var/default_lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
@@ -122,9 +122,9 @@
/mob/living/carbon/human/set_dir(var/new_dir, ignore_facing_dir = FALSE)
. = ..()
if(. && tail_style)
update_tail_showing(1)
update_tail_showing(!lying)
if(lying)
update_icon(forceDirUpdate = TRUE)
update_icon(TRUE)
/mob/living/carbon/human/Move()
. = ..()
@@ -995,7 +995,9 @@
/datum/species/proc/handle_stance_damage(var/mob/living/carbon/human/H, var/damage_only = FALSE)
var/static/support_limbs = list(
BP_L_LEG = BP_R_LEG,
BP_L_FOOT = BP_R_FOOT
BP_L_FOOT = BP_R_FOOT,
BP_R_LEG = BP_L_LEG,
BP_R_FOOT = BP_L_FOOT
)
var/has_opposite_limb = FALSE
@@ -104,26 +104,29 @@ There are several things that need to be remembered:
var/list/overlays_raw[TOTAL_LAYERS] // Our set of "raw" overlays that can be modified, but cannot be directly applied to the mob without preprocessing.
var/previous_damage_appearance // store what the body last looked like, so we only have to update it if something changed
#define UPDATE_ICON_IGNORE_DIRECTION_UPDATE -1
// Updates overlays from overlays_raw.
/mob/living/carbon/human/update_icon(var/forceDirUpdate = FALSE)
if (QDELETED(src))
return // No point.
var/update_lying = (lying_prev != lying) || forceDirUpdate || size_multiplier != 1
var/draw_specific_icon = (!lying || species.prone_icon)
if(update_lying && draw_specific_icon)
update_inv_l_hand(FALSE)
update_inv_r_hand(FALSE)
update_hud() //TODO: remove the need for this
ClearOverlays()
if(cloaked)
icon = 'icons/mob/human.dmi'
icon_state = "body_cloaked"
AddOverlays(list(overlays_raw[L_HAND_LAYER], overlays_raw[R_HAND_LAYER]))
else if (icon_update)
SetOverlays(list(overlays_raw[L_HAND_LAYER], overlays_raw[R_HAND_LAYER]))
else
var/list/ovr = list()
if (icon != stand_icon)
icon = stand_icon
var/list/ovr = list()
// We manually add each element instead of just using Copy() so that lists are appended instead of inserted.
for (var/item in overlays_raw)
if (item)
@@ -137,18 +140,20 @@ There are several things that need to be remembered:
var/icon/aura_overlay = icon(A.icon, icon_state = A.icon_state)
ovr += aura_overlay
AddOverlays(ovr)
if (((lying_prev != lying) || forceDirUpdate || size_multiplier != 1) && forceDirUpdate != UPDATE_ICON_IGNORE_DIRECTION_UPDATE)
if(lying && !species.prone_icon) //Only rotate them if we're not drawing a specific icon for being prone.
var/matrix/M = matrix()
SetOverlays(ovr)
if(update_lying) //Only rotate them if we're not drawing a specific icon for being prone.
var/matrix/M = matrix()
M.Scale(size_multiplier)
if(draw_specific_icon)
M.Translate(0, 16*(size_multiplier-1))
animate(src, transform = M, time = ANIM_LYING_TIME)
else
switch(src.dir)
if(SOUTH,EAST)
M.Turn(90)
else
M.Turn(-90)
M.Scale(size_multiplier)
M.Translate(1,-6)
animate(src, transform = M, time = (forceDirUpdate ? 0 : ANIM_LYING_TIME))
@@ -157,15 +162,6 @@ There are several things that need to be remembered:
if(istype(src.r_hand, /obj/item/gun) && lying)
HeldObjectDirTransform(slot_r_hand, src.dir)
else
update_inv_l_hand(FALSE)
update_inv_r_hand(FALSE)
update_icon(UPDATE_ICON_IGNORE_DIRECTION_UPDATE)
var/matrix/M = matrix()
M.Scale(size_multiplier)
M.Translate(0, 16*(size_multiplier-1))
animate(src, transform = M, time = ANIM_LYING_TIME)
UpdateOverlays()
lying_prev = lying
@@ -196,9 +192,7 @@ There are several things that need to be remembered:
animate(item_image, transform = item_transform)
overlays_raw[layer] = item_image
update_icon(UPDATE_ICON_IGNORE_DIRECTION_UPDATE)
#undef UPDATE_ICON_IGNORE_DIRECTION_UPDATE
update_icon()
//DAMAGE OVERLAYS
//constructs damage icon for each organ from mask * damage field and saves it in our overlays_raw list (as a list of icons).
@@ -1245,7 +1239,7 @@ There are several things that need to be remembered:
overlays_raw[L_HAND_LAYER] = null
if(update_icons)
update_icon(forceDirUpdate = TRUE)
update_icon(TRUE)
/mob/living/carbon/human/update_inv_r_hand(update_icons = TRUE)
if (QDELETED(src))
@@ -1284,7 +1278,7 @@ There are several things that need to be remembered:
overlays_raw[R_HAND_LAYER] = null
if(update_icons)
update_icon(forceDirUpdate = TRUE)
update_icon(TRUE)
/mob/living/carbon/human/update_inv_wrists(var/update_icons=1)
if (QDELETED(src))
@@ -1389,7 +1383,7 @@ There are several things that need to be remembered:
if(species.tail && !(mutations & HUSK) && !(mutations & SKELETON) && !(wear_suit && wear_suit.flags_inv & HIDETAIL))
var/icon/tail_s = get_tail_icon()
overlays_raw[tail_layer] = image(tail_s, icon_state = "[tail_style]_s")
animate_tail_reset()
animate_tail_reset(FALSE)
update_tail_accessory(FALSE)
if(update_icons)
@@ -1414,7 +1408,7 @@ There are several things that need to be remembered:
return tail_icon
/mob/living/carbon/human/proc/set_tail_state(var/mob_state)
/mob/living/carbon/human/proc/set_tail_state(var/mob_state, var/update = TRUE)
if(!tail_style)
return
@@ -1428,8 +1422,7 @@ There are several things that need to be remembered:
if(tail_overlay && species.tail_animation)
if(tail_overlay.icon_state != mob_state)
tail_overlay.icon_state = mob_state
update_tail_accessory()
update_icon()
update_tail_accessory(update)
return tail_overlay
return null
@@ -1461,11 +1454,11 @@ There are several things that need to be remembered:
/mob/living/carbon/human/proc/animate_tail_fast()
set_tail_state("[tail_style]_loop")
/mob/living/carbon/human/proc/animate_tail_reset()
/mob/living/carbon/human/proc/animate_tail_reset(var/update = TRUE)
if(stat != DEAD && !lying)
set_tail_state("[tail_style]_idle")
set_tail_state("[tail_style]_idle", update)
else
set_tail_state("[tail_style]_static")
set_tail_state("[tail_style]_static", update)
/mob/living/carbon/human/proc/animate_tail_stop(var/update_icons=1)
set_tail_state("[tail_style]_static")