Files
Bubberstation/code/game/objects/items/storage/boxes/engineering_boxes.dm
Tim 78ff108529 Sound Optimizations and Debug Tools (#88517)
## About The Pull Request
I was digging through sound code trying to add a few misc `.ogg`'s when
I noticed a horrifying revelation. Sound calculations are broken as
fuck. At first I didn't think it was a big deal until I remembered this
comment in another PR:


![chrome_6rspeYVig1](https://github.com/user-attachments/assets/04c3fa79-c267-43ae-a77f-85b0e8d3108f)

I asked for the profile logs:

```
                                                           Profile results (total time)
Proc Name                                                                                          Self CPU    Total CPU    Real Time     Overtime        Calls
----------------------------------------------------------------------------------------------    ---------    ---------    ---------    ---------    ---------
/proc/playsound                                                                                       4.771       26.841       26.902        0.347       153938
/mob/proc/playsound_local                                                                             9.511       15.689       15.891        0.724       429391

/mob/living/say                                                                                       0.125       19.064       19.945        0.000         2550
/mob/living/carbon/updatehealth                                                                       0.878        8.305        8.341        0.013        49847
/mob/living/carbon/proc/handle_organs                                                                 1.486        9.263        9.300        0.000        70977
/obj/item/organ/internal/on_life                                                                      0.415        0.455        0.561        0.000       340312
/mob/living/carbon/Life                                                                               0.758       30.085       30.123        0.000        71933
/mob/living/proc/Life                                                                                 5.509       39.404       39.512        0.000       401951
```


Yeah, that is _really_ bad. Especially since it is a hot proc that is
used half a million times. Optimizing this would help a decent amount.
So now you are probably wondering, what exactly is the problem?! Let's
take a look.

https://www.desmos.com/calculator/sqdfl8ipgf

Sounds are being broadcast on a large radius which is typically about
~17 tiles. Since the volume of a sound is reduced by distance, the
further away the sound is, the quieter it becomes. You would think, hey
that's fine! Sounds become inaudible at the 17 tile distance limit
right? Except no, they generally become inaudible about 2/3rds of the
way there. (~10 tile range) Sound volume is between 1-100. When the
sound volume is lower than 3, it becomes (pretty much) inaudible.

This means most of the sounds that are being spammed in game everywhere,
you can't even hear!!!

To fix this we used two major optimizations:

1. Add a `SOUND_AUDIBLE_VOLUME_MIN` to ignore any sound lower than this
volume and calculate an audible distance
2. Use the new audible distance to drastically shorten the tile range of
mob listeners using `get_hearers_in_view()`

To give you an idea of how much better this is:

Sounds that had a range of 17x17 (289 turfs) are now 12x12 (144 turfs).
There is also large range machinery like the SM that has a 40x40 (1600
turfs) that is now 30x30 (900 turfs).

It's quite an improvement.

I also went and added a debugging tool to the admin/debug equipment set
that can be found in the debug box. It is a pair of earmuffs that when
worn has any sounds sent to the mob via a `to_chat` message displaying
the sounds max range, distance from player, volume, and sound name. It
is highly recommend to walk while wearing the earmuffs since walking
stops your mob from emitting footstep sounds.

## Why It's Good For The Game
The speed of sound is now faster than ever. Please don't break the sound
barrier.

## Changelog
🆑
refactor: Sound has been heavily optimized and will now ignore low
volume sounds from far away.
admin: Add debugging sound earmuffs to admin equipment inside the debug
box. Wear them to determine a sounds max range, distance, volume, and
sound name. Highly recommended to walk otherwise you will get spammed
with footstep sounds.
/🆑
2024-12-27 18:42:51 -08:00

125 lines
4.7 KiB
Plaintext

// This file contains all boxes used by the Engineering department and its purpose on the station. Also contains stuff we use when we wanna fix up stuff as well or helping us live when shit goes southwardly.
/obj/item/storage/box/metalfoam
name = "box of metal foam grenades"
desc = "To be used to rapidly seal hull breaches."
illustration = "grenade"
/obj/item/storage/box/metalfoam/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/grenade/chem_grenade/metalfoam(src)
/obj/item/storage/box/smart_metal_foam
name = "box of smart metal foam grenades"
desc = "Used to rapidly seal hull breaches. This variety conforms to the walls of its area."
illustration = "grenade"
/obj/item/storage/box/smart_metal_foam/PopulateContents()
for(var/i in 1 to 7)
new/obj/item/grenade/chem_grenade/smart_metal_foam(src)
/obj/item/storage/box/material
name = "box of materials"
illustration = "implant"
/obj/item/storage/box/material/Initialize(mapload)
. = ..()
atom_storage.max_specific_storage = WEIGHT_CLASS_GIGANTIC //This needs to be set here too because the parent type overrides it again
/obj/item/storage/box/material/PopulateContents() //less uranium because radioactive
var/static/items_inside = list(
/obj/item/stack/sheet/iron/fifty=1,
/obj/item/stack/sheet/glass/fifty=1,
/obj/item/stack/sheet/rglass=50,
/obj/item/stack/sheet/plasmaglass=50,
/obj/item/stack/sheet/titaniumglass=50,
/obj/item/stack/sheet/plastitaniumglass=50,
/obj/item/stack/sheet/plasteel=50,
/obj/item/stack/sheet/mineral/plastitanium=50,
/obj/item/stack/sheet/mineral/titanium=50,
/obj/item/stack/sheet/mineral/gold=50,
/obj/item/stack/sheet/mineral/silver=50,
/obj/item/stack/sheet/mineral/plasma=50,
/obj/item/stack/sheet/mineral/uranium=20,
/obj/item/stack/sheet/mineral/diamond=50,
/obj/item/stack/sheet/bluespace_crystal=50,
/obj/item/stack/sheet/mineral/bananium=50,
/obj/item/stack/sheet/mineral/wood=50,
/obj/item/stack/sheet/plastic/fifty=1,
/obj/item/stack/sheet/runed_metal/fifty=1,
)
//This needs to be done here and not in Initialize() because the stacks get merged and fall out when their weight updates if this is set after PopulateContents()
atom_storage.allow_big_nesting = TRUE
atom_storage.max_slots = 99
atom_storage.max_specific_storage = WEIGHT_CLASS_GIGANTIC
atom_storage.max_total_storage = 99
generate_items_inside(items_inside,src)
/obj/item/storage/box/debugtools
name = "box of debug tools"
icon_state = "syndiebox"
/obj/item/storage/box/debugtools/Initialize(mapload)
. = ..()
atom_storage.allow_big_nesting = TRUE
atom_storage.max_slots = 99
atom_storage.max_specific_storage = WEIGHT_CLASS_GIGANTIC
atom_storage.max_total_storage = 99
/obj/item/storage/box/debugtools/PopulateContents()
var/static/items_inside = list(
/obj/item/card/emag=1,
/obj/item/construction/rcd/combat/admin=1,
/obj/item/disk/tech_disk/debug=1,
/obj/item/flashlight/emp/debug=1,
/obj/item/geiger_counter=1,
/obj/item/healthanalyzer/advanced=1,
/obj/item/modular_computer/pda/heads/captain=1,
/obj/item/pipe_dispenser=1,
/obj/item/stack/spacecash/c1000=50,
/obj/item/storage/box/beakers/bluespace=1,
/obj/item/storage/box/beakers/variety=1,
/obj/item/storage/box/material=1,
/obj/item/uplink/debug=1,
/obj/item/uplink/nuclear/debug=1,
/obj/item/clothing/ears/earmuffs/debug = 1,
)
generate_items_inside(items_inside,src)
/obj/item/storage/box/plastic
name = "plastic box"
desc = "It's a solid, plastic shell box."
icon_state = "plasticbox"
foldable_result = null
illustration = "writing"
custom_materials = list(/datum/material/plastic = HALF_SHEET_MATERIAL_AMOUNT) //You lose most if recycled.
/obj/item/storage/box/emergencytank
name = "emergency oxygen tank box"
desc = "A box of emergency oxygen tanks."
illustration = "emergencytank"
/obj/item/storage/box/emergencytank/PopulateContents()
..()
for(var/i in 1 to 7)
new /obj/item/tank/internals/emergency_oxygen(src) //in case anyone ever wants to do anything with spawning them, apart from crafting the box
/obj/item/storage/box/engitank
name = "extended-capacity emergency oxygen tank box"
desc = "A box of extended-capacity emergency oxygen tanks."
illustration = "extendedtank"
/obj/item/storage/box/engitank/PopulateContents()
..()
for(var/i in 1 to 7)
new /obj/item/tank/internals/emergency_oxygen/engi(src) //in case anyone ever wants to do anything with spawning them, apart from crafting the box
/obj/item/storage/box/stickers/chief_engineer
name = "CE approved sticker pack"
desc = "With one of these stickers, inform the crew that the contraption in the corridor is COMPLETELY SAFE!"
illustration = "label_ce"
/obj/item/storage/box/stickers/chief_engineer/PopulateContents()
for(var/i in 1 to 3)
new /obj/item/sticker/chief_engineer(src)