## About The Pull Request
- If a cable is destroyed by an explosion, all rooms within 64-100 (it's
a probability) tiles AND which are connected to the same powernet as the
split cable will have their lights flicker 1-3 times.
- Also adds a verb for visualizing powernets.
- Reduces cable integrity from 300 to 50.
- Cables have innate 75% bomb armor when under a floor tile.
## Why It's Good For The Game
- A big devastating explosion a few doors down is, usually, not felt at
all outside of the screen shake. This adds a bit more ambience to the
effect - you hear a big explosion, your screen goes wild, and the lights
cut for just a second.
- Verb just makes it easier to trace powernets.
- I found it a little ridiculous that cables have 300 integrity, the
same as most furniture. This ultimately makes them a lot more vulnerable
to stuff like acid and fire.
- To compensate for their drastically reduced integrity, I gave cables a
considerable boost to explosive resistance while concealed under the
floor. This prevents bombs from outright shredding all cables in a 50
mile radius. (Devastating explosions will still one-tap them, but heavy
explosions will on average take two blasts.)
## Changelog
🆑 Melbert
add: If a cable is destroyed by an explosion, all rooms within 64-100
(it's a probability) tiles AND which are connected to the same powernet
as the split cable will have their lights flicker 1-3 times.
balance: Cable integrity has been reduced from 300 to 50
balance: Cables have an innate 75% bomb resistance while under floor
tiles
/🆑
## About The Pull Request
This is a big one so please bear with me, wounds are complicated
### Max Potential Wound Rolls
We've decreased the max contributed damage to wound rolls from 35 to 25.
This results, after the exponent, a max possible wound roll of 1 to 91
before any modifiers (assuming the attack, after armor, is 25 or above).
The minimum value to wound is still 5.
### Wound Escalation Penalties
Most wounds were contributing significant numbers per wound type to the
potential for a new wound to occur. Getting wounded once meant you were
getting wound a lot, but actually getting past that first wounding may
be the tricky part.
We have significantly reigned in the wound penalty that having a wound
contributes, and instead utilize the series wound penalty to allow same
type wounds to escalate themselves faster as a priority. Having wounds
still makes you more wound vulnerable, just not to such an extreme
degree.
The priority here for what wounds matter most for contributing to
overall wounding vulnerability is ``Infected BURNS > BURNS >
SLASH|PIERCE > BLUNT.``
### Wound Armor
Wound armor, unlike all other kinds of armor, was used as a additive
value to the wound roll modifiers rather than a multiplicative value.
We have reworked how wound armor is determined by changing how wound
modifiers are calculated.
Firstly, we're passing our entire injury roll into the
``check_woundings_mod()`` proc, as we're not treating this as a proc
that just adds values anymore.
Secondly, bare wound bonus only applies if there is no potential wound
protection from any source, as expected. But it comes last in the
calculations.
Thirdly, wound protection is applied to the injury roll last, after
wound bonuses from the attack, wound bonuses from other wounds and wound
bonuses from a disabled limb are applied. This does not include serial
wound bonuses, which are determined outside of this proc.
Wound protection comes from two sources. Clothing and limb wound
resistance. Your chest and head have an amount of wound resistance so
long as they are not mangled in any fashion. Being mangled means having
either a hairline fracture or a weeping avulsion wound.
Wound protection reduces the final injury roll by a percentage. Say our
roll is 50, and we have effectively 50% wound protection. The final roll
would be 25.
### ~~Wound Armor on Clothing~~ Reverted
~~Most clothing have had their wound armor values changed. As a loose
rule, I used the highest of melee or bomb armor, except where that value
was 100, in which case I used the lowest instead. I'm basing this
decision on how embeds are calculated, which is attack type agnostic.~~
~~Some armor have inconsistent values because they are alternative
armors to an existing armor type or are hyperspecialized armor.
Ablative, bulletproof and security vests all share a value of 35,
despite the former two not having decent melee or bomb armor.~~
~~Some clothing missing wound armor that should have had them now have
wound armor.~~
~~This may need a bit of scrutiny in case one or two seem weirdly high.
Some have maybe become too low. Its a bit hard to say.~~
### The ``bare_wound_bonus`` variable
I changed it to ``exposed_wound_bonus`` to better represent when it
applies. You can be naked and still not be affected by this bonus if the
limb has wound resistance.
## Why It's Good For The Game
I'm not promising anything with this PR, but this is an attempt to
sanity check the values on wounds so that we're not seeing what the data
that determined the removal of beheading presented. An extreme
over-representation of tier 3 wounds. ~~And, from that, maybe I can
argue for beheadings coming back. That's my goal. I think beheadings
happened so much because the numbers were in need of work.~~ Well okay I
just wanna make wounds a bit more workable actually more than I want
beheadings.
Why is it that tier 3 wounds were so over-represented? Because wounds
will often force more severe wounds of other types by merit of any
wounds existing at all on a limb. Having **_a_** wound makes you more
wound prone for any kind of wound, and not just making you more likely
to suffer a more severe type of the same wound.
The threshold mechanic was intended to simulate making a wound worse,
but oddly just made a limb broadly more prone to getting worse from any
kind of attack to such a degree that future wound rolls of different
types were often going to start at the threshold necessary to be a tier
3 wound.
Dismemberment, mind you, requires you to suffer a flesh wound while you
have a bone wound of tier 2 or higher (with tier 3 giving a bonus to
this). You can do this readily via just a sharp weapon, because having a
mangled limb causes the wound to turn into a bone wound. Technically,
this is meant to be less likely as the effective damage for this wound
is halved. But the wound bonus from having a flesh wound was almost
always significant enough to kick your new bone wound up to a tier 3.
In other words; its not surprising that you saw so many beheadings,
because the system wanted to behead you as fast as it possibly can
thanks to all these escalating values.
Wound armor was only applied as a flat reduction on the roll. The
average for wound armor was 10. After receiving a single wound, you can
expect wound rolls to reach upwards of 100, even if the actual damage
roll was not particularly high, due to wound stacking bonuses form being
wounded.
This meant that wounds, if they happened, came thick and fast after the
first, regardless of what your protection might be to wounds. It was
just a matter of getting past the initial bump.
This is why effects that forced wounds were so powerful. They basically
made a given limb more prone to taking a wound without having to deal
with the protection problem first.
Finally, this is just a broad flaw with the system that is not its
fault. It is actually a problem that isn't a problem. Most people in the
game are not wearing helmets that protect their head. So most people are
going to suffer from a higher proclivity of being wounded if people are
aiming for the head. There is this...kind of cargo cult belief that
aiming for the head means you do more damage, or can stun someone if
you're lucky or what have you. It's entirely nonsense, but it has a
grain of truth in that people rarely wear, or even have access too,
headwear that provides wound protection or any protection at all. People
have jumpsuits, which are universally wound protected, but that isn't
true of the head. Look, the point is, they're not aiming at the head
because it is usually less armored, its for other reasons but it just so
happens to become true due to wounds and how wounds roll their type.
To soften this issue, I've decided to treat wound resistance as armor
until the limb suffers a tier 3 wound. This way, hits to the head MAY
not necessarily escalate to tier 3 instantly as they would on live even
from relatively low power weapons. Some weapons have very low force, but
have extreme bare wound bonuses. This should be less likely after this
change. I doubt this will necessarily make high damage high wound
weapons like energy swords any less prone to cutting you clean open, but
it might thanks to the reduction to contributed damage to the injury
roll. The system is now _a bit more random_.
## Changelog
🆑
balance: Wounds do not make you as vulnerable to suffering wounds of all
types as before. Instead, wounds make you more vulnerable to suffering
worse versions of themselves as a priority.
balance: Wound armor is now more impactful when protecting you from
wounds when you have already been wounded.
balance: Your head and chest are more difficult to wound until they have
been mangled; either from suffering from a weeping avulsion or a
hairline fracture.
code: Changed the variable for bare_wound_bonus to exposed_wound_bonus
to better explain what that variable is doing.
/🆑
---------
Co-authored-by: Jeremiah <42397676+jlsnow301@users.noreply.github.com>
## About The Pull Request
As detailed in #91431, PR #91379 misplaced a few semicolons and broke
the functionality for these three admin tools. Only the object panel was
fixed, but the mob and turf panels remain broken. This fixes it, the
exact same issue was/is the problem.
## Why It's Good For The Game
Restores admin functionality that is currently missing.
## Changelog
🆑
fix: create mob and create turf both function correctly again.
/🆑
## About The Pull Request
This PR aims to clean or bring up to date portions of code about dna,
the dna console and mutations. This includes taking care of or removing
some of the awful choices like the pratically useless
`datum/mutation/human` pathing, or the class variable, in favor of using
sources to avoid potential issues with extraneous sources of a mutation.
The files changed are over a hundred just because I removed the
`datum/mutation/human` path, but the actual bulk of the code is mainly
shared between the datum/dna.dm, _mutations.dm and dna_console.dm.
## Why It's Good For The Game
Mutation shitcode is hurting my future plans for infusions a little.
Also it's a much needed refactor. Drafted 'till I'm sure it works
without issues.
## Changelog
🆑
refactor: Refactored mutation code backend. Report any issue.
/🆑
## About The Pull Request
Refactors most of blood handling code untouched by #90593 and completely
rewrites all blood decals, components and reagents.
- Blood types now have behavioral flags which allow them to control
where they leave decals/DNA/viruses. Oil no longer transfers DNA and
viruses with it, while podpeople water-blood doesn't leave visible
decals on turfs and items, but still can be picked up by DNA scanners.
- Multiple blood types have received unique handling - liquid
electricity blood now glows in the dark, oil trails are flammable and
lube ones are slippery. Oil blood can be restored with fuel, lube with
silicon and slime with stable plasma (as normal plasma already passively
regenerates their blood), instead of everything using iron. Saline
solution only supplements on iron-based blood and won't do anything to
help with bloodloss for species who rely on different blood types.
(Roundstart this applies only to Ethereals)
- All blood logic has been moved away from the blood reagent itself into
a blood element that is assigned to the blood reagent by default, and to
any reagent that's drawn from a mob as their "blood" (in
``transfer_blood_to``). This means that blood you draw from lizards will
be green and have lizard's blood description instead of mentioning red
blood cells, Ethereal "blood" will actually contain their DNA and genes,
etc.
- Refactored all blood decals. Blood states are no more, everything is
now handled via blood DNA. Credits to MrMelbert and Maplestation, as a
significant amount of code has been taken from
https://github.com/MrMelbert/MapleStationCode/pull/436 and many of his
followup PRs. Oil and xenomorph splatters are now subtypes of blood,
blood drying is now animated, blood trails now curve and can be
diagonal.
- Rewrote bloodysoles and bloody_spreader components, credits to Melbert
again for the former, while latter now makes more sense with its
interactions. Bloody soles no longer share blood DNA with your hands.
- Ported Melbert's bloody footprint sprites and bot-blood-spreading
functionality.
- Removed all species-side reagent interactions, instead they're handled
by said species' livers. (This previously included exotic blood
handling, thus the removal)
- Slightly optimized human rendering by removing inbetween overlay
holders for clothing when they're not needed.
- Blood-transmitted diseases will now get added to many more decals than
before.
- Cleaned up and partially refactored replica pods, fixed an issue where
monkeys/manipulators were unable to harvest mindless pods.
- Exotic bloodtype on species now automatically assigns their blood
reagent, without the need to assign them separately.
- Clown mobs now bleed (with colorful reagent instead of blood during
april fools), and so do vatbeasts (lizard blood)
- Implemented generic procs for handling bleeding checks, all sorts of
scanners now also correctly call your blood for what it is.
- Podpeople's guts are now lime-green like their organs, instead of
being weirdly greyish like their water-blood. (Their bleeding overlays
are still grey, as they're bleeding water)
- Slimepeople now can bleed. Their jelly is pale purple in color, but
their wound overlays copy their body color.
- Injecting/spraying/splashing/etc mob with a reagent preserves its
data, so you could theoretically recycle fine wines from someone's
bloodstream
- Fixed burdened chaplain's sect never actually giving a blessing when
applying effects, and giving a blessing when nothing can be healed.
Inverted check strikes again.
- Closes#91039
#### Examples
A lot of blood here has dried, visually the blood colors are almost
exactly the same as before either of the blood refactors.


## About The Pull Request
Prettier (an auto formatter) is set to only run within the tgui folder
currently. This removes that limitation, allowing it to automatically
format all supported files in the repo (.js, .html, .yml
[etc](https://prettier.io/docs/))
I made a few exceptions for bundled and generated files
## Why It's Good For The Game
I'm of the opinion that code should look uniform and am lazy enough to
want CTRL-S to format files without having to think beyond that
## Changelog
Should have used `typecacheof()` instead of `typesof()` to properly
configure the blacklist.
Multi-z has `obj/effect/abstract` being applied to lots of turfs that
need to be ignored.
## About The Pull Request
Due to the atmos complexity, this was split off from:
- #90998
This takes the atmos gas mixture from a turf and converts it into a
string for saving via the `map_export` verb. The behavior is as follows:
- Space and wall turfs atmos are skipped
- Rounds all gases to 0.01 decimal for their individual mole value
- Any gases less than 0.01 moles get skipped
This does not keep track of active fires since those have hotspots,
active turfs, etc., which is way more complicated to save. Another
caveat is the amount of characters the map reader needs to write is much
larger since every turf (besides space/walls) will have different atmos
due to mobs breathing, airlocks opening, etc. so I made this setting
into a `SAVE_ATMOS` flag that you can apply when saving.
This also keeps track of air inside of canisters.
## Why It's Good For The Game
Atmospherics changes to the station can now be saved properly.
## Changelog
🆑
qol: `map_export` admin verb can now save atmos for turfs and air
canisters
/🆑
## About The Pull Request
When using the `map_export` admin verb the following things are fixed:
- All objects density, anchored, opacity, atom_integrity, and
resistance_flags vars are saved
- Multi-tile objects being spammed on all tiles the sprite reaches
- Dirt decals error icon
- Airlocks error icon and to save welded state
- Dark Wizard Simple Mobs error icon
- Closets to save welded, open, and locked states
- Air alarms to save name
- Air scrubbers/vents to save name and welded states
- APCs to save name, charge, cell, lighting, equipment, and
environmental states
- APCs spawning a duplicated terminal underneath it when one already
exists
- SMES to save charge, input, and output states
- Holodecks to revert any holodeck turfs to the empty turf and skip
saving any hologram items
- Photos and Paintings error icons
- Bloody Footprints error icons
- False Walls error icons
- Docking Ports runtimes because the map template var would change
- Effects (lasers, portals, beams, sparks, etc.) saving when they should
be omitted
I would have loved to get `component_parts` to save for machines and
turf decals, but perhaps that is for another day since it requires
complicated solutions.
Here are some before and after pictures:




## Why It's Good For The Game
Better map saving code.
## Changelog
🆑
fix: Fix `map_export` admin verb not properly saving a massive amount of
objects.
/🆑
## About The Pull Request
Rewrote the planemaster debugger to be more legible and useful. Planes
are now clustered based on their dependants, all buttons have been moved
to the header, connections are highlighted when hovering over nodes and
you can see filter type and blend mode when clicking the node (deleting
a connection is done through a button in the tooltip)

## Why It's Good For The Game
Old planemaster debugger is horrifically jank to use, has broken visual
offsets for all nodes, connections and buttons, and is in a single
thousand line long file.
## Changelog
🆑
refactor: Refactored the planemaster debugger tool
/🆑
## About The Pull Request
For some reason, when you cancelled summoning an ERT it would say that
you could not find any candidates (there wasn't a poll to begin with,
the summon was cancelled), so I moved messaging to
`proc/make_emergency_response_team()` so that we can better communicate
that.
## Changelog
🆑 tonty
admin: Cancelling an ERT summon will now say so instead of saying there
were no candidates
/🆑
## About The Pull Request
- Address
https://github.com/tgstation/tgstation/pull/90476#discussion_r2051701283.
Makes pill bottle code cleaner
- Datumized some more storage values(monkey guncase toolbox & crafter
toolbox) making their init slightly faster
- Moved all standard storage subtypes(bags, boxes, lockboxes etc) that
is scattered across various files & folders in the codebase into their
respective files under `code/game/objects/item/storage` folder.
This means for e.g. if you want to see all boxes in the game you can
find them in `code/game/objects/item/storage/boxes` folder & don't have
to go looking for hidden subtypes in various module files or folders
where they were hidden away.
Makes looking for stuff & modifying these storages much saner & easier
## Changelog
🆑
code: organized storage subtypes under the same files & folders
/🆑
---------
Co-authored-by: _0Steven <42909981+00-Steven@users.noreply.github.com>
## About The Pull Request
So
A) Modifying traits pretty self explanatory was a missing check
B) imo given the type of data that can be seen in vv this shouldnt be
exposed to literally anyone with an admin datum especially considering
actually showing it to someone else and editing it is R_admin and
r_varedit
the giant diff is just indentation change
Showing vv to other players is unaffected by this
## Changelog
🆑
fix: fixed some vv issues
/🆑
---------
Co-authored-by: TiviPlus <572233640+TiviPlus@users.noreply.com>
Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com>
## About The Pull Request
This PR:
- Converts all of the blood types into their own datums, which can be
set up to have their own colors, descriptions, and other fun unique
properties. For example, the clown blood that is constantly randomizing
itself.
- Converts all the blood decals into greyscale, which in turn eliminates
the need for separate xeno sprites. They both use the same ones now.
- Audit of blood splatters/gibs/bodyparts/organs to make sure that they
are getting the correct forensic data applied to them.
- For the admins: Adds a clown blood smite.
My primary goal with was to make the appearance of the new sprites look
almost indistinguishable to the original ones.
I consider this a "first pass", as in there are still some further
refactors I would like to do on the backend side, but am satisfied with
it enough to push it forward as a first step towards a better blood
system! I didn't want to do too much at once because of A) fatigue and
B) easier to test things to make sure I'm not breaking something
important this way.
This has been test-merged on Nova for over a week now and has been going
great, so I finally got around to upstreaming the bones to TG. Although
I did test it a bit you may want to TM it just in case I missed some
things when copying it over.
## About The Pull Request
What it was doing was by and large fine, HOW it was doing it SUCKED
I've cleaned it up and the nearby code some, notable hits include:
- random if check in secrets ui that was totally unused
- proc called add that actually set
- lists not defined as such
- stupid var names
- proc args which did nothing
- code which did nothing
- oververbose code
- proc/var names with no spacing at all
Note: This might have changed behavior accidentally, I've done my best
to test but we'll need to look out for issue reports in coming days.
## Why It's Good For The Game
I was working on bitflag code and saw red, now it's 2 hours later.
## Changelog
🆑
code: Brought browser code up to standard with the rest of the codebase
admin: Hey lads, I cleaned up how non TGUI windows work on the backend,
please let me know if anything is broken! PING ME MOTHERFUCKER
/🆑
## About The Pull Request
Fixes#90510
I added the overlay when only smites that destroyed the body had the
divine smite flag, then I added the flag to a bunch more things. Oops
## Changelog
🆑 Melbert
fix: Fix divine smites making you glow forever
/🆑
## About The Pull Request
Title. If compiled on 515 the game screen will be black
## Why It's Good For The Game
There is no reason for it to exist if connecting from 515 is not allowed
## About The Pull Request
##### Disclaimer - Some of the code/icons/sounds were ported from TMGC.
Introducing more weather types! And yes, you can now have rain be
reagent based!
<details>
<summary>Regular Rain</summary>

</details>
<details>
<summary>Blood Rain</summary>

</details>
<details>
<summary>Acid Rain</summary>

</details>
You can even make it rain ants, plasma, or drugs. All of their effects
get applied to turfs, objects, and mobs depending on the weather options
you select.
Did I mention... there is thunder?
<details>
<summary>Thunder Strikes</summary>

</details>
<details>
<summary>Sand Storms</summary>

</details>
Despite all this new stuff, none of it has been directly added to the
game but the code can be used in the future for:
- Wizard event - Similar to lava on floor, but this time make the
reagent random or picked from a list and give wizard immunity
- Chaplain ability - Maybe make this a benefit or ability once enough
favor has been obtained
- Admin events - I have added a BUNCH of admin tooling to run customized
weather events that let you control a lot of options
- New station maps/biomes for downstreams (Jungle Station, etc.)
- Change Ion storms to use the new weather system that triggers
EMP/thunder effects across the station
- IceBox could get plasma rain
- Lavaland could get thunder effects applied to ash storms
Relevant PRs that removed/added some of the weather stuff I used:
- #60303
- #25222
---
#### Attribution
- Rain sprites were added via [novaepee](https://github.com/novaepee) in
https://github.com/tgstation/TerraGov-Marine-Corps/pull/9675
- Sand sprites were added via [TiviPlus](https://github.com/TiviPlus)
(who commissioned them from bimmer) in
https://github.com/tgstation/TerraGov-Marine-Corps/pull/4645
- Rain sounds [already existed on
tg](https://github.com/tgstation/tgstation/pull/25222#discussion_r106794579)
and were provided by provided by Cuboos, using Royalty Free sounds,
presumed under default tg sound license - Creative Commons 3.0 BY-SA
- Siren sound is from siren.wav by IFartInUrGeneralDirection --
[Freesound](https://freesound.org/s/46092/) -- License: Attribution 4.0
The original `siren.ogg` sound used on a lot of SS13 servers doesn't
seem to have any attribution that I could locate. The sound was added
about 15 years ago. So I just looked for a somewhat similar sounding
siren noise on Freesound.
## Why It's Good For The Game
More weather customization!
## Changelog
🆑
add: Added new weather types for rain and sandstorms. Rain now uses a
reagent that gets exposed to the turfs, mobs, and objects. There is also
a thunder strike setting you can apply to any weather.
add: Hydro trays and soil will now add reagents to their trays when
exposed to a chemical reaction. (weather, shower, chem spills, foam
grenades, etc.)
add: Weather temperature now affects weather reagents and mobs body
temperature.
bal: Snowstorm temperature calculations were tweaked to allow universal
weather temperature effects.
sound: Added weather sounds from TGMC for rain and sirens (attributed to
Cuboos and IFartInUrGeneralDirection )
image: Added weather images from TGMC for rain and sand storms
(attributed to Novaepee and Bimmer)
refactor: Refactored a lot of the weather code to be more robust
admin: Admins can now control more weather related options when running
weather events. The weather admin verbs have been moved to their own
"Weather" category under the Admin tab.
/🆑
---------
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
## About The Pull Request
various uis (tgui-say, vv, player panel, anything using
`/datum/browser`) would not correct for dpi. they now do
we also have a preference to allow you to have smaller windows that are
zoomed out, instead of larger windows that are not zoomed
#### of note, this does require a small change to the usage of css
viewport units, like `vh` and `vw`. they need to be fed through the
`vp(100vw)` function first. there was only one such unit in the codebase
on 4k monitor with 200% scaling:
fixed (pref on default)

pref disabled

## Why It's Good For The Game
516 fucked with uis again and this unfucks them a bit
## Changelog
🆑
qol: there's a new UI preference called UI scale which allows people
that use windows scaling to have their UIs original size with the
contents zoomed out, instead of the default, which is the UIs being
larger with the contents "normal" size
fix: various UIs did not respect windows scaling, they now do
/🆑
---------
Co-authored-by: harryob <55142896+harryob@users.noreply.github.com>
## About The Pull Request
There's now a button in Interviews that lets you directly jump to a
person's centcom ban database, which also works if the client
disconnects.
The button is red (idk if we have any flashing color to make it REALLY
stand out) and has special tooltip if they have any server permabans in
the database.
## Why It's Good For The Game
There's an admin request to allow servers to ban bad players from the
centcom database meant for streamer servers to avoid griefers, which I
wasn't the biggest fan of. Instead I thought this would be a harmless
addition, letting admins see if a player joining their server is a known
griefer BEFORE letting them in, directly from the interview menu- while
letting them know if they have a permaban without having to even click
anything. Gives admins an easier time in finding griefers before they
log on without automation that may cause false positives.
## Changelog
🆑
admin: Interviews now has a button to open a player's Centcom ban list,
which will be in red if they have existing server permabans.
/🆑
## About The Pull Request
As the title says.
`init_order` is no more, subsystems ordering now depends on their
declared dependencies.
Subsystems can now declare which other subsystems need to init before
them using a list and the subsystem's typepath
I.e.
```dm
dependencies = list(
/datum/controller/subsystem/atoms,
/datum/controller/subsystem/mapping
)
```
The reverse can also be done, if a subsystem must initialize after your
own:
```dm
dependents = list(
/datum/controller/subsystem/atoms
)
```
Cyclical dependencies are not allowed and will throw an error on
initialization if one is found.
There's also a debug tool to visualize the dependency graph, although
it's a bit basic:

Subsystem load ordering can still be controlled using `init_stage`, some
subsystems use this in cases where they must initialize first or last
regardless of dependencies. An error will be thrown if a subsystem has
an `init_stage` before one of their dependencies.
## Why It's Good For The Game
Makes dealing with subsystem dependencies easier, and reduces the chance
of making a dependency error when needing to shift around subsystem
inits.
## Changelog
🆑
refactor: Refactored subsystem initialization
/🆑
## About The Pull Request
This won't actually do anything on live, since those are all set to
UTC±0 currently
Pins logging and IC uses of time2text to UTC±0 instead of using the
system timezone (byond default)
Timezones not being set to utc0 caused issues before (and is again)
All timezones are now passed explicitly to make it more likely it's
cargo culted properly at least
Deletes worldtime2text cus it was gameTimestamp default args
## Why It's Good For The Game
Server timezone changes probably shouldn't affect logging, round times,
file hashes, IC time, when you caught fish, etc
## Changelog
🆑
refactor: Logging and IC timestamps will now always use UTC±0 and not be
affected by server system timezone changes
fix: Station and round times will not longer be incorrect if the system
timezone is not UTC±0
/🆑
---------
Co-authored-by: TiviPlus <572233640+TiviPlus@users.noreply.com>
## About The Pull Request
Reverts the storage initialization refactor and all subsequent related
PRs.
The original PR is below our standards both for code quality and
testing, and is majorly flawed at its core. This has been discussed with
other maintainers and headcoder(s?) over on discord. A lot of changes
from the PR could be brought over later, but in its current state it
should not have been merged.
- Closes#90322
- Closes#90313
- Closes#90315
- Closes#90320
- Closes#90312
- Closes#90344
## Why It's Good For The Game
This PR causes a series of major issues which cannot be resolved without
either completely rewriting a lot of the original PR, or bad code.
Not matching our standards is grounds for not merging a PR, and the fact
that a PR should not have been merged is a reason for a revert.
## Changelog
🆑
fix: Fixed a series of storage-related bugs caused by a refactor PR.
/🆑
## About The Pull Request
As the title says. Also moves lobby music to use variable instead of the
timer subsystem since it needs to track on client time rather than
server time and variable cooldowns are more relevant for this usecase.
## Why It's Good For The Game
Removes the need for admins to stop all playing sounds. Also, people
with admin sounds turned off will still be able to hear the lobby music
so their experience is improved.
Makes the web sound cooldown timings more consistent, hopefully.
## Changelog
🆑
admin: Play Internet Sound will now automatically stop lobby music and
prevent lobby music from playing at roundend whilst active.
/🆑
## About The Pull Request
this makes it so the `_winget` wrapper actually _returns_ what `winget`
returns.
## Why It's Good For The Game
this wrapper is literally useless otherwise
## Changelog
🆑
fix: Fixed the _winget SDQL2/Lua wrapper, so it actually returns the
return value of winget.
/🆑
🆑
config: Added `TTS_HTTP_TIMEOUT_SECONDS` for setting the maximum
duration TTS HTTP requests can run for before being aborted.
/🆑
DNM because we need the rust-g PR to get released:
https://github.com/tgstation/rust-g/pull/210
Crit prio because rounds will not restart if there are hung TTS requests
and the TTS server is absolute dogshit and doesn't prevent them.
## About The Pull Request
This PR should fix the problem of small previews in TGUI once and for
all (I hope).
What was causing it? Because TGUI takes a long time to open, that's why
previews were generated broken (small).
On Byond 515 this problem was not so noticeable as the interfaces opened
faster, but with the release of 516 it became much worse.
Previews were generated inside a window that was not yet open, so the
scale was broken, sometimes the window would open before the preview was
done and sent, usually with small interfaces, or when reopening.
I'm not very good at working with signals, and to tell the truth this is
my second experience with them, so I hope I did it right.
## Why It's Good For The Game
No more small map previews
<details> <summary> Video </summary>
https://github.com/user-attachments/assets/834f3820-cc6a-4f65-90e5-d6bb2a118bcf
</details>
## Changelog
🆑
fix: Fixed small character preview, color matrix preview, mech preview,
and other previews with uses ByondUI map
/🆑
---------
Co-authored-by: Gaxeer <44334376+Gaxeer@users.noreply.github.com>
## About The Pull Request
[cleans up poor namespacing on light debugging
tools](93cc9070d5)
[Implements a pathfinding visualization
tool](ed91f69ac4)
It holds a set of inputs from the client, and uses them to generate and
display paths from source/target. Left click sets the source, right
click sets the target.
Pathmap support too, if no target is set we display the paths from every
turf in the map to the source, if one is set we build a path TO it from
the source.
I had to add COMSIG_MOB_CLICKON to observers to make this work (tho idk
why it didn't exist already), I also removed the everpresent colorblind
datum from admin datums, only needs to exist if they're using it.
[Adds a mutable_appearance helper that dirlocks them, wallening port
which I thought might be useful here, and will likely be useful
elsewhere in
future](87f752e7c3)
[Fixes an infinite loop in pathmaps if we tried to pull a cached path to
an unreachable target, && not ||
4head](10086a655d)
[Fixes JPS not dealing with border objects properly. They violate some
of the assumptions JPS makes, so we need to backfill them with checks.
These basically read as (if the thing that should normally take this
path can't reach this turf, can
we?)](f56cc4dd43)
## Why It's Good For The Game
Maybe deals with #80619?
Adds more robust testing tools for pathfinding, should allow people to
better understand/debug these systems. I added this with the idea of
adding multiz support but I don't have the time for that rn.
JPS will work around thindows better, that's nice.
https://file.house/IrBiR0bGxoKw1jJJoxgMRQ==.mp4
## Changelog
🆑
fix: Fixed our pathfinding logic getting deeply confused by border
objects
admin: Added clientside displayed pathfinding debug tools, give em a go
/🆑
## About The Pull Request
This fixes the `_ispath` SDQL2 / Lua wrapper: it always passed two
arguments, meaning it couldn't be used to just simply check if something
was a path _at all_.
In addition, I just added wrapper around `is_type_in_typecache` (as it's
a define), as that's the whole reason I was using `_ispath` anyways, so
it can't hurt.
## Why It's Good For The Game
things working properly is nice
## Changelog
🆑
fix: The _ispath SDQL2/Lua wrapper can now be used to actually check if
something is a path.
code: Added the _is_type_in_typecache wrapper, for SDQL2 / Lua scripts.
/🆑
---------
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
## About The Pull Request
We were nullchecking this instead of falsey checking it (TAKE THAT
ISNULL POSTERS) so it'd see FALSE, go "oh that's not null", and then try
and link clients to 0. Dumb
## About The Pull Request
A Huge chunk of changes just comes from moving existing storage code
into new files & seperating `atom_storage` code into its own subtype
under the already existing `storage/subtypes` folder.
With that the changes in this PR can be organized into 3 categories.
**1. Refactors how `/obj/item/storage/PopulateContents()` initializes
storages**
- Fixes#88747 and every other storage item that has a similar variant
of this problem
The problem with `PopulateContents()` is that it allows you to create
atoms directly inside the storage via `new(src)` thus bypassing all the
access restrictions enforced by `/datum/storage/can_insert()` resulting
in storages holding stuff they shouldn't be able to hold.
Now how this proc works has been changed. It must now only return a list
of items(each item in the list can either be a typepath or a solid atom
or a mix of them in any order) that should be inserted into the storage.
Each item is then passed into `can_insert()` to check if it can fit in
the storage.
If your list contains solid atoms they must be first moved
to/Initialized in nullspace so `can_insert()` won't count it as already
inserted. `can_insert()` has now also been refactored to throw stack
traces but explaining exactly why the item could not fit in the storage
thus giving you more debugging details to fix your stuff.
A large majority of changes is refactoring `PopulateContents()` to
return a list instead of simply creating the item in place so simple 1
line changes & with that we have fixed all broken storages(medical
toolbox. electrical toolbox, cruisader armor boxes & many more) that
hold more items they can handle
**2. Organizes initialization of `atom_storage` for storage subtypes.**
All subtypes of `/obj/item/storage` should(not enforced) create their
own `/datum/storage/` subtype under the folder `storage/subtypes` if the
default values are not sufficient. This is the 2nd change done across
all existing storages
Not only does this bring code cleanliness & organization (separating
storage code from item code like how `/datum/wire` code is separated
into its own sub folder) but it also makes storage initialization
slightly faster (because you are not modifying default values after
`atom_storage` is initialized but you are directly setting the default
value in place).
You now cannot & should not modify `atom_storage` values inside
`PopulateContents()`. This will make that proc as pure as possible so
less side effects. Of course this principle is not enforced and you can
still modify the storage value after `Initialize()` but this should not
be encouraged in the future
**3. Adds support for automatic storage computations**
Most people don't understand how `atom_storage` values work. The comment
here clearly states that
55bbfef0da/code/game/objects/items/storage/toolbox.dm (L327-L329)
Because of that the linked issue occurs not just for medical toolbox but
for a lot of other items as well.
Which is why if you do not know what you doing, `PopulateContents()` now
comes with a new storage parameter i.e. `/datum/storage_config`
This datum allows you to compute storage values that will perfectly fit
with the initial contents of your storage. It allows you to do stuff
like computing `max_slots`, `max_item_weight`, `max_total_weight` etc
based on your storage initial contents so that all the contents can fit
perfectly leaving no space for excess.
## Changelog
🆑
fix: storages are no longer initialized with items that can't be put
back in after taking them out
refactor: storage initialization has been refactored. Please report bugs
on github
/🆑
## About The Pull Request
Makes wrapper procs to support working with bitflags as defined "things"
rather then EXCLUSIVELY numbers, mostly for getting random flags.
I've ~~also added a unit test to prevent bitfields from being double
defined~~ stolen some code form moth to make double definitions here a
compile error.
This does rely on people actually using the bitfield lists, essentially
upgrading them from breaking just admin debug to POTENTIALLY breaking
game logic (slightly). Would like input on this @tgstation/commit-access
## Why It's Good For The Game
More tools for feature coders to play with, more sane code
## About The Pull Request
Added visual overlays for all arm implants, HUD implants (not the
headrev one), internal thrusters, breathing tube, nutriment pumps and
reviver implant.



Additionally, added a wrapper for eye color setting which solves the
issue where non-pref sourced eyecolors got reset after changing them,
and changed how blinking works so now update_body calls don't force you
to blink.
## Why It's Good For The Game
Gives you incredible drip (which makes augments feel more impactful) and
allows others to see if you have certain important augments (reviver)
that could matter.
As for technical changes, both were required for this to HUDs to work
nicely and fix some bugs as a side effect.
## Changelog
🆑
add: Certain implants now have visuals when implanted
fix: You no longer blink when you adjust your clothing
fix: Fixed an issue where some NPC/midround humans would not get their
eye color set correctly
/🆑
## About The Pull Request
- Adds `dustself` admin verb
- Adds Dust admin smite
- Does what it says on the tin
- Adds Divine smites
- Variations of smites that come with the prayer sound and special
effects - so you can get the message across that this is a punishment
from god.
https://github.com/user-attachments/assets/1cf89ece-3e89-4135-a984-79ca10c278a6
## Why It's Good For The Game
- Request. Parity for `gibself`
- Request. Parity with "Gib"
- Request. Someone wanted to add some more flair to smites so I obliged.
## Changelog
🆑 Melbert
admin: Adds "Dustself"
admin: Adds "Dust" smite. Does what it says on the tin
admin: Adds "Divine" smites. They are variations of normal smites themed
around divine intervention.
/🆑
## About The Pull Request
Adds a new Retcon smite, it makes the person fade out into nothingness
with a configurable timer, deletes their records and reopens their job
slot, as if they were never there at all.
I was also annoyed that to play around with temporary_atom I had to
slowy add a component, and it doesn't really have much of a reason to BE
a component, so I refactored it into an atom level proc called
fade_into_nothing
## Why It's Good For The Game
The smite is useful for when you wanna get rid of someone who had to
leave roundstart and whatnot, on top of just being funny. the refactor
is also good because i can now put that proc on build mode and go to
town.
## Changelog
🆑
add: Added new mechanics or gameplay changes
add: Added more things
del: Removed old things
qol: made something easier to use
balance: rebalanced something
fix: fixed a few things
sound: added/modified/removed audio or sound effects
image: added/modified/removed some icons or images
map: added/modified/removed map content
spellcheck: fixed a few typos
code: changed some code
refactor: refactored some code
config: changed some config setting
admin: messed with admin stuff
server: something server ops should know
/🆑
---------
Co-authored-by: Jacquerel <hnevard@gmail.com>
Ports the helpers from
https://github.com/BeeStation/BeeStation-Hornet/pull/12240
This should fix some more of the 516 issues that I've seen while giving
a quick check through the code
The remaining browse should work now.
Also fixing another sass warning while being on it.
## About The Pull Request
## Why It's Good For The Game
## Changelog
🆑
fix: tgui say 516 will no longer change channels when the button is used
to drag it
fix: tgui say 516 will no longer leak radio messages into the wrong
channel
fix: runechat flickering when faded up messages fade out
/🆑
## About The Pull Request
Replaces the asset subsystem's spritesheet generator with a rust-based
implementation (https://github.com/tgstation/rust-g/pull/160).
This is a rough port of
https://github.com/BeeStation/BeeStation-Hornet/pull/10404, but it
includes fixes for some cases I didn't catch that apply on TG.
(FWIW we've been using this system on prod for over a year and
encountered no major issues.)
### TG MAINTAINER NOTE

### Batched Spritesheets
`/datum/asset/spritesheet_batched`: A version of the spritesheet system
that collects a list of `/datum/universal_icon`s and sends them off to
rustg asynchronously, and the generation also runs on another thread, so
the game doesn't block during realize_spritesheet. The rust generation
is about 10x faster when it comes to actual icon generation, but the
biggest perk of the batched spritesheets is the caching system.
This PR notably does not convert a few things to the new spritesheet
generator.
- Species and antagonist icons in the preferences view because they use
getFlatIcon ~~which can't be converted to universal icons~~.
- Yes, this is still a *massive* cost to init, unfortunately. On Bee, I
actually enabled the 'legacy' cache on prod and development, which you
can see in my PR. That's why I added the 'clear cache' verb and the
`unregister()` procs, because it can force a regeneration at runtime. I
decided not to port this, since I think it would be detrimental to the
large amount of contributors here.
- It is *technically* possible to port parts of this to the uni_icon
system by making a uni_icon version of getFlatIcon. However, some
overlays use runtime-generated icons which are ~~completely unparseable
to IconForge, since they're stored in the RSC and don't exist as files
anywhere~~. This is most noticeable with things like hair (which blend
additively with the hair mask on the server, thus making them invisible
to `get_flat_uni_icon`). It also doesn't help that species and antag
icons will still need to generate a bunch of dummies and delete them to
even verify cache validity.
- It is actually possible to write the RSC icons to the filesystem
(using fcopy) and reference them in IconForge. However, I'm going to
wait on doing this until I port my GAGS implementation because it
requires GAGS to exist on the filesystem as well.
#### Caching
IconForge generates a cache based on the set of icons used, all
transform operations applied, and the source DMIs of each icon used
within the spritesheet. It can compare the hashes and invalidate the
cache automatically if any of these change. This means we can enable
caching on development, and have absolutely no downsides, because if
anything changes, the cache invalidates itself.
The caching has a mean cost of ~5ms and saves a lot of time compared to
generating the spritesheet, even with rust's faster generation. The main
downside is that the cache still requires building the list of icons and
their transforms, then json encoding it to send to rustg.
Here's an abbreviated example of a cache JSON. All of these need to
match for the cache to be valid. `input_hash` contains the transform
definitions for all the sprites in the spritesheet, so if the input to
iconforge changes, that hash catches it. The `sizes` and `sprites` are
loaded into DM.
```json
{
"input_hash": "99f1bc67d590e000",
"dmi_hashes": {
"icons/ui/achievements/achievements.dmi": "771200c75da11c62"
},
"sizes": [
"76x76"
],
"sprites": {
"achievement-rustascend": {
"size_id": "76x76",
"position": 1
}
},
"rustg_version": "3.6.0",
"dm_version": 1
}
```
### Universal Icons
Universal icons are just a collection of DMI, Icon State, and any icon
transformation procs you apply (blends, crops, scales). They can be
convered to DM icons via `to_icon()`. I've included an implementation of
GAGS that produces universal icons, allowing GAGS items to be converted
into them. IconForge can read universal icons and add them to
spritesheets. It's basically just a wrapper that reimplements BYOND icon
procs.
### Other Stuff
Converts some uses of md5asfile within legacy spritesheets to use
rustg_hash_file instead, improving the performance of their generation.
Fixes lizard body markings not showing in previews, and re-adds eyes to
the ethereal color preview. This is a side effect of IconForge having
*much* better error handling than DM icon procs. Invalid stuff that gets
passed around will error instead of silently doing nothing.
Changes the CSS used in legacy spritesheet generation to split
`background: url(...) no-repeat` into separate props. This is necessary
for WebView2, as IE treats these properties differently - adding
`background-color` to an icon object (as seen in the R&D console) won't
work if you don't split these out.
Deletes unused spritesheets and their associated icons (condiments
spritesheet, old PDA spritesheet)
## Why It's Good For The Game
If you press "Character Setup", the 10-13sec of lag is now approximately
0.5-2 seconds.
Tracy profile showing the time spent on get_asset_datum. I pressed the
preferences button during init on both branches. Do note that this was
ran with a smart cache HIT, so no generation occurred.

Much lower worst-case for /datum/asset/New (which includes
`create_spritesheets()` and `register()`)

Here's a look at the internal costs from rustg - as you can see
`generate_spritesheet()` is very fast:

### Comparison for a single spritesheet - chat spritesheet:
**Before**

**After**

## Changelog
🆑
fix: Fixed lizard body markings and ethereal feature previews in the
preference menu missing some overlays.
refactor: Optimized spritesheet asset generation greatly using rustg
IconForge, greatly reducing post-initialization lag as well as reducing
init times and saving server computation.
config: Added 'smart' asset caching, for batched rustg IconForge
spritesheets. It is persistent and suitable for use on local, with
automatic invalidation.
add: Added admin verbs - Debug -> Clear Smart/Legacy Asset Cache for
spritesheets.
fix: Fixed R&D console icons breaking on WebView2/516
/🆑
## About The Pull Request
just cleaning out the cobwebs
Mixed usr/src, using set on a proc /datum/o
casting atom but taking datums
## Changelog
🆑
code: cleaned up some mass var edit code
/🆑
---------
Co-authored-by: TiviPlus <572233640+TiviPlus@users.noreply.com>
## About The Pull Request
Converts `/datum/player_details` into `/datum/persistent_client`.
Persistent Clients persist across connections. The only time a mob's
persistent client will change is if the ckey it's bound to logs into a
different mob, or the mob is deleted (duh).
Also adds PossessByPlayer() so that transfering mob control is cleaner
and makes more immediate sense if you don't know byond-fu.
## Why It's Good For The Game
Clients are an abstract representation of a connection that can be
dropped at almost any moment so putting things that should be stable to
access at any time onto an undying object is ideal. This allows for
future expansions like abstracting away client.screen and managing
everything cleanly.
## About The Pull Request
Mobs without clients or prefs now get default values instead of informed
default values, preventing runtimes in Spawn Debug Full Crew. Also made
the ***second*** warning much clearer and only appear when the user
isn't localhost, similarly to Start Now.
Totally not related to a recent incident on live servers, nope. Surely
not.
## Changelog
🆑
fix: Spawn Debug Full Crew no longer runtimes
admin: Spawn Debug Full Crew now explicitly warns you a second time if
you're attempting to use it as a non-localhost user.
/🆑
## About The Pull Request
Adds `Policy Panel` admin verb. It opens up a very plain, very simple
tgui that shows you a dropdown of all `policy.json` entries, allowing
you to refer to them if necessary.
There's also a search bar.

## Why It's Good For The Game
Half request, half something I thought would be useful.
While admins could VV into config and find the `policy.json`, they
generally appreciate something more user-facing.
## Changelog
🆑 Melbert
admin: Adds the Policy Panel verb, which shows you all the policy the
server has set.
/🆑