## About The Pull Request
Lets you copy characters in the character customizer. This'll be useful
if you ever want to create variants of your character or Need to move
characters to different slots.
This needs large scale testing, I couldn't break anything on local but
given this involves tinkering with saves better safe than sorry.
## Why It's Good For The Game
I saw a complaint on discord about having to delete characters to
reorganize the list, this resolves that.
This also lets you create a "base" character to use as a template or to
generate variants of an existing character without making them from
scratch or editing them.
## Proof Of Testing
<details>
<summary>Screenshots/Videos</summary>
Soon....
</details>
## Changelog
🆑
qol: You can now copy your characters into other slots.
/🆑
---------
Co-authored-by: xPokee <catmc8565@gmail.com>
## About The Pull Request
Despite what the code comments said we can rename them and we should
because they make no sense
## Why It's Good For The Game
The save file keys for cat features should have cat in the name and not
human
## Changelog
🆑
server: renamed feature_human_ears and feature_human_tail to
feature_cat_ears and feature_cat_tail respectively
/🆑
## About The Pull Request
If someones delete a keybind this runtime will appear.
<img width="689" height="172" alt="image"
src="https://github.com/user-attachments/assets/1fd9c6c3-00a7-4890-89ba-002943a06a32"
/>
This pr preverents it
## Why It's Good For The Game
Fixes are good, bugs are bad (except hk)
## Changelog
Not player faced
## About The Pull Request
A verb is now available on localhost called `"Export Save as Dev
Preferences"`
This exports your current savefile to `/config/dev_preferences.json`
If you then connect to your localhost as a guest, it will load
`dev_preferences.json` as your preference datum
This allows for devs testing the game locally to load preferences for
guests.
(Guests connecting to live servers are completely unaffected.)
## Why It's Good For The Game
Initially I only did this because the recent keybinding changes have
destroyed my muscle memory when testing w/o logging in.
But as I worked on it I thought of a few other usecases, like when
implementing preference version migration - the dev preference is never
saved which means you can re-compile as much as you want without needing
to revert your save manually.
Savefile versioning is quite robust, but it relied a lot on comments to
explain why exactly it worked (such as needing to explain that
error/empty states were negative integers only because any valid
savefile version would be a positive integer). Anyways, let's spell it
out a lot more using `#define` values and dmdoccing said values in order
to make the whole system a bit more cohesive.
This also corrects an issue that has irked me for a while, which is that
we call and go through `update_preferences()` or `update_character()`
_every single time_. `SAVEFILE_VERSION_MAX` is essentially just a
placeholder, it's not checked against anything! Let's use that in one of
the new macros we created so we can slim down on the proc call overhead
(as well as whole branches of code) that we iterate through every single
time we load a savefile. Like we were generating a backup json every
single run without fail, let's trim that out when it's not necessary.
More clear for people operating on this code in the future as well as
does a lot less work. Win win.
Tested it and it migrated my savefile from 48 -> 49 without any ill
effect. Let me know if we want to have the redundancy behavior baked in
where we call these procs/enter code branches every single time though-
I would rather just bake the code in that way rather than live in a
world of confusion on why it operates that way.
🆑
server: Savefile migration has been tweaked a bit, though there
realistically shouldn't be any issues with this. Keep a wary eye out
though.
/🆑
## About The Pull Request
Savefile versioning is quite robust, but it relied a lot on comments to
explain why exactly it worked (such as needing to explain that
error/empty states were negative integers only because any valid
savefile version would be a positive integer). Anyways, let's spell it
out a lot more using `#define` values and dmdoccing said values in order
to make the whole system a bit more cohesive.
This also corrects an issue that has irked me for a while, which is that
we call and go through `update_preferences()` or `update_character()`
_every single time_. `SAVEFILE_VERSION_MAX` is essentially just a
placeholder, it's not checked against anything! Let's use that in one of
the new macros we created so we can slim down on the proc call overhead
(as well as whole branches of code) that we iterate through every single
time we load a savefile. Like we were generating a backup json every
single run without fail, let's trim that out when it's not necessary.
## Why It's Good For The Game
More clear for people operating on this code in the future as well as
does a lot less work. Win win.
## Changelog
Tested it and it migrated my savefile from 48 -> 49 without any ill
effect. Let me know if we want to have the redundancy behavior baked in
where we call these procs/enter code branches every single time though-
I would rather just bake the code in that way rather than live in a
world of confusion on why it operates that way.
🆑
server: Savefile migration has been tweaked a bit, though there
realistically shouldn't be any issues with this. Keep a wary eye out
though.
/🆑
## About The Pull Request
Borg me dogtag is a loadout item instead of a quirk
## Why It's Good For The Game
The quirk doesn't do anything
## Changelog
🆑 Melbert
del: "Cyborg Pre-screened dogtag" quirk. It's a loadout item now.
/🆑
## About The Pull Request
Borg me dogtag is a loadout item instead of a quirk
## Why It's Good For The Game
The quirk doesn't do anything
## Changelog
🆑 Melbert
del: "Cyborg Pre-screened dogtag" quirk. It's a loadout item now.
/🆑
Implements https://hackmd.io/@tgstation/SkeUS7lSp , rewriting Dynamic
from the ground-up
- Dynamic configuration is now vastly streamlined, making it far far far
easier to understand and edit
- Threat is gone entirely; round chaos is now determined by dynamic
tiers
- There's 5 dynamic tiers, 0 to 4.
- 0 is a pure greenshift.
- Tiers are just picked via weight - "16% chance of getting a high chaos
round".
- Tiers have min pop ranges. "Tier 4 (high chaos) requires 25 pop to be
selected".
- Tier determines how much of every ruleset is picked. "Tier 4 (High
Chaos) will pick 3-4 roundstart[1], 1-2 light, 1-2 heavy, and 2-3
latejoins".
- The number of rulesets picked depends on how many people are in the
server - this is also configurable[2]. As an example, a tier that
demands "1-3" rulesets will not spawn 3 rulesets if population <= 40 and
will not spawn 2 rulesets if population <= 25.
- Tiers also determine time before light, heavy, and latejoin rulesets
are picked, as well as the cooldown range between spawns. More chaotic
tiers may send midrounds sooner or wait less time between sending them.
- On the ruleset side of things, "requirements", "scaling", and
"enemies" is gone.
- You can configure a ruleset's min pop and weight flat, or per tier.
- For example a ruleset like Obsession is weighted higher for tiers 1-2
and lower for tiers 3-4.
- Rather than scaling up, roundstart rulesets can just be selected
multiple times.
- Rulesets also have `min_antag_cap` and `max_antag_cap`.
`min_antag_cap` determines how many candidates are needed for it to run,
and `max_antag_cap` determines how many candidates are selected.
- Rulesets attempt to run every 2.5 minutes. [3]
- Light rulesets will ALWAYS be picked before heavy rulesets. [4]
- Light injection chance is no longer 100%, heavy injection chance
formula has been simplified.
- Chance simply scales based on number of dead players / total number
off players, with a flag 50% chance if no antags exist. [5]
[1] This does not guarantee you will actually GET 3-4 roundstart
rulesets. If a roundstart ruleset is picked, and it ends up being unable
to execute (such as "not enough candidates", that slot is effectively a
wash.) This might be revisited.
[2] Currently, this is a hard limit - below X pop, you WILL get a
quarter or a half of the rulesets. This might be revisited to just be
weighted - you are just MORE LIKELY to get a quarter or a half.
[3] Little worried about accidentally frontloading everything so we'll
see about this
[4] This may be revisited but in most contexts it seems sensible.
[5] This may also be revisited, I'm not 100% sure what the best / most
simple way to tackle midround chances is.
Other implementation details
- The process of making rulesets has been streamlined as well. Many
rulesets only amount to a definition and `assign_role`.
- Dynamic.json -> Dynamic.toml
- Dynamic event hijacked was ripped out entirely.
- Most midround antag random events are now dynamic rulesets. Fugitives,
Morphs, Slaughter Demons, etc.
- The 1 weight slaughter demon event is gone. RIP in peace.
- There is now a hidden midround event that simply adds +1 latejoin, +1
light, or +1 heavy ruleset.
- `mind.special_role` is dead. Minds have a lazylist of special roles
now but it's essentially only used for traitor panel.
- Revs refactored almost entirely. Revs can now exist without a dynamic
ruleset.
- Cult refactored a tiny bit.
- Antag datums cleaned up.
- Pre round setup is less centralized on Dynamic.
- Admins have a whole panel for interfacing with dynamic. It's pretty
slapdash I'm sure someone could make a nicer looking one.


- Maybe some other things.
See readme for more info.
Will you see a massive change in how rounds play out? My hunch says
rounds will spawn less rulesets on average, but it's ultimately to how
it's configured
🆑 Melbert
refactor: Dynamic rewritten entirely, report any strange rounds
config: Dynamic config reworked, it's now a TOML file
refactor: Refactored antag roles somewhat, report any oddities
refactor: Refactored Revolution entirely, report any oddities
del: Deleted most midround events that spawn antags - they use dynamic
rulesets now
add: Dynamic rulesets can now be false alarms
add: Adds a random event that gives dynamic the ability to run another
ruleset later
admin: Adds a panel for messing around with dynamic
admin: Adds a panel for chance for every dynamic ruleset to be selected
admin: You can spawn revs without using dynamic now
fix: Nuke team leaders get their fun title back
/🆑
(cherry picked from commit 4c277dc572)
## About The Pull Request
Implements https://hackmd.io/@tgstation/SkeUS7lSp , rewriting Dynamic
from the ground-up
- Dynamic configuration is now vastly streamlined, making it far far far
easier to understand and edit
- Threat is gone entirely; round chaos is now determined by dynamic
tiers
- There's 5 dynamic tiers, 0 to 4.
- 0 is a pure greenshift.
- Tiers are just picked via weight - "16% chance of getting a high chaos
round".
- Tiers have min pop ranges. "Tier 4 (high chaos) requires 25 pop to be
selected".
- Tier determines how much of every ruleset is picked. "Tier 4 (High
Chaos) will pick 3-4 roundstart[1], 1-2 light, 1-2 heavy, and 2-3
latejoins".
- The number of rulesets picked depends on how many people are in the
server - this is also configurable[2]. As an example, a tier that
demands "1-3" rulesets will not spawn 3 rulesets if population <= 40 and
will not spawn 2 rulesets if population <= 25.
- Tiers also determine time before light, heavy, and latejoin rulesets
are picked, as well as the cooldown range between spawns. More chaotic
tiers may send midrounds sooner or wait less time between sending them.
- On the ruleset side of things, "requirements", "scaling", and
"enemies" is gone.
- You can configure a ruleset's min pop and weight flat, or per tier.
- For example a ruleset like Obsession is weighted higher for tiers 1-2
and lower for tiers 3-4.
- Rather than scaling up, roundstart rulesets can just be selected
multiple times.
- Rulesets also have `min_antag_cap` and `max_antag_cap`.
`min_antag_cap` determines how many candidates are needed for it to run,
and `max_antag_cap` determines how many candidates are selected.
- Rulesets attempt to run every 2.5 minutes. [3]
- Light rulesets will ALWAYS be picked before heavy rulesets. [4]
- Light injection chance is no longer 100%, heavy injection chance
formula has been simplified.
- Chance simply scales based on number of dead players / total number
off players, with a flag 50% chance if no antags exist. [5]
[1] This does not guarantee you will actually GET 3-4 roundstart
rulesets. If a roundstart ruleset is picked, and it ends up being unable
to execute (such as "not enough candidates", that slot is effectively a
wash.) This might be revisited.
[2] Currently, this is a hard limit - below X pop, you WILL get a
quarter or a half of the rulesets. This might be revisited to just be
weighted - you are just MORE LIKELY to get a quarter or a half.
[3] Little worried about accidentally frontloading everything so we'll
see about this
[4] This may be revisited but in most contexts it seems sensible.
[5] This may also be revisited, I'm not 100% sure what the best / most
simple way to tackle midround chances is.
Other implementation details
- The process of making rulesets has been streamlined as well. Many
rulesets only amount to a definition and `assign_role`.
- Dynamic.json -> Dynamic.toml
- Dynamic event hijacked was ripped out entirely.
- Most midround antag random events are now dynamic rulesets. Fugitives,
Morphs, Slaughter Demons, etc.
- The 1 weight slaughter demon event is gone. RIP in peace.
- There is now a hidden midround event that simply adds +1 latejoin, +1
light, or +1 heavy ruleset.
- `mind.special_role` is dead. Minds have a lazylist of special roles
now but it's essentially only used for traitor panel.
- Revs refactored almost entirely. Revs can now exist without a dynamic
ruleset.
- Cult refactored a tiny bit.
- Antag datums cleaned up.
- Pre round setup is less centralized on Dynamic.
- Admins have a whole panel for interfacing with dynamic. It's pretty
slapdash I'm sure someone could make a nicer looking one.


- Maybe some other things.
## Why It's Good For The Game
See readme for more info.
Will you see a massive change in how rounds play out? My hunch says
rounds will spawn less rulesets on average, but it's ultimately to how
it's configured
## Changelog
🆑 Melbert
refactor: Dynamic rewritten entirely, report any strange rounds
config: Dynamic config reworked, it's now a TOML file
refactor: Refactored antag roles somewhat, report any oddities
refactor: Refactored Revolution entirely, report any oddities
del: Deleted most midround events that spawn antags - they use dynamic
rulesets now
add: Dynamic rulesets can now be false alarms
add: Adds a random event that gives dynamic the ability to run another
ruleset later
admin: Adds a panel for messing around with dynamic
admin: Adds a panel for chance for every dynamic ruleset to be selected
admin: You can spawn revs without using dynamic now
fix: Nuke team leaders get their fun title back
/🆑
Part 1 by grungussuss: https://github.com/tgstation/tgstation/pull/87529

gives players more control over how loud they want certain sounds to be
🆑 Rengan
sound: the volume that vox, admin sound, insturments play at can now be
tweaked in preferences, check your preferences!
sound: Elevator now uses ambience volume preference, jukeboxes uses
instrument volume preference and end of round musics uses admin music
volume preference.
/🆑
## About The Pull Request
Fixes https://github.com/Bubberstation/Bubberstation/issues/2879
The reason for the issue seems rooted in skyrat's own port of the
original json configs on tg (or perhaps the loads of changes they've
made to it over the years). This pr patches it so that characters won't
reset between rounds.
original fixes by smartkar
## Why It's Good For The Game
Guess
## Proof Of Testing
<details>
<summary>Screenshots/Videos</summary>

</details>
It saves the character on creation and works fine after re-accessing the
savefile
## Changelog
🆑
fixes: fixes the issue where characters would reset after a round or on
switching character slots
/🆑
## About The Pull Request
Part 1 by grungussuss: https://github.com/tgstation/tgstation/pull/87529

## Why It's Good For The Game
gives players more control over how loud they want certain sounds to be
## Changelog
🆑 Rengan
sound: the volume that vox, admin sound, insturments play at can now be
tweaked in preferences, check your preferences!
sound: Elevator now uses ambience volume preference, jukeboxes uses
instrument volume preference and end of round musics uses admin music
volume preference.
/🆑
## About The Pull Request
Was just scrolling through the Paradise github since they seem to have
more work done for 516 to see if there's anything I can port over, found
this and thought why not.
Ports parts of https://github.com/ParadiseSS13/Paradise/pull/25105
Specifically, updaing all hrefs to use the internal ``byond://``, and
adding it to grep.
## Why It's Good For The Game
More work towards 516.
## Changelog
Nothing player-facing.
## About The Pull Request

## Why It's Good For The Game
gives players more control over how loud they want certain sounds to be
## Changelog
🆑 grungussuss
sound: the volume that ship ambience, ambience, radio noise and
announcements play at can now be tweaked in preferences, check your
preferences!
/🆑
## About The Pull Request
When loading values from the savefile for keybinds, it overrode the
default values with null if not found.
## Why It's Good For The Game
Resolves https://github.com/tgstation/tgstation/issues/72804
## Changelog
* Adds informed default values for a bunch of preferences (to produce less outlandish random characters)
* Update felinid.dm
* Update lizard.dm
* Update monkey.dm
* [READY] the unfuckening of clothing rendering (#79784)
refactors clothing visors to use the same system, including masks being
toggled and stuff like riot helmets toggling using the same system and
welding helmets and such
adds a handler that updates all visuals in slots that an item has
obscured, each visual proc calls that so you no longer have weird shit
happening like having to hardcode a proc for heads where you need to
also update hair, mask, glasses everytime you put on an item
one thing here i could also do is make check_obscured_slots return the
HIDEX flags instead of item slots, because in 99% of cases its hardcoded
to be ran against specific slots (like eye code running it against the
glasses slot), but maintainers didnt seem to like that :/
fuck this 2003 bullshit
theres like several bugs here i fixed but i forgot them all and they are
small
---------
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: SpaceLoveSs13 <68121607+SpaceLoveSs13@users.noreply.github.com>
## About The Pull Request
Goes through a bunch of character preferences and adds informed default
values which produce less wacky results.
Basically part 2 of #84443 . Preference randomization now results in a
character similar to that pictured in the original pr.
Of course, you can still make your character look as wacky as ever.

## Why It's Good For The Game
Basically, fully random characters look horrendous, and unless you're
playing a non-human, you stick out like a sore thumb if you hardcore
random or just decide to random appearance.
Ultimately, full-random people will stick out less, which I think is
good.
## Changelog
🆑 Melbert
qol: Random player characters now look less like rainbow vomit and more
like some of the most average people you know.
/🆑
* Adds Character Loadout Tab to preferences (with just a small handful of items to start)
* step one rip out all the old nasties
* fixes, current bugs: donator lock, ckey lock, one item in case
* opps
* sanity checks, fixed, donator implementation, ckey locking. fixes.
* wew
* final fixes
* Update loadout_categories.dm
* Update loadout_items.dm
* Update loadout_items.dm
* Update declarations.dm
---------
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: Gandalf <9026500+Gandalf2k15@users.noreply.github.com>
Co-authored-by: SpaceLoveSs13 <68121607+SpaceLoveSs13@users.noreply.github.com>
I didn't see https://github.com/tgstation/tgstation/pull/83989 and that
is on me. The UX of it is not suitable enough for preferences menu.
- New row with only one entry makes the UI look much worse and adds too
much blank space
- The deleting confirmation prompt is a weird amount of work and also
doesn't tell you when you get it wrong
- A weird amount was being handled in JavaScript
This reverts the PR and just starts over. You can see the UX here.
https://github.com/tgstation/tgstation/assets/35135081/8106bca7-8c01-41da-8ede-e33a5a548583
## Changelog
🆑
qol: Dramatically improves delete character UI and UX.
/🆑
## About The Pull Request
Adds a button to delete characters, and when deleted it flips to the
nearest character, wow(the last character can't be deleted(I guess)).
### Video:
https://github.com/tgstation/tgstation/assets/78199449/3ad1157a-6c1c-4fb2-9b0d-1da791cad989
## Why It's Good For The Game
Once you know how to create characters, you sometimes want to be able to
delete them.
The reasons for this can be... as simple as freeing up a slot, or
deleting them in order to remake them.
I think this is quite a useful feature that should have been there
before.
## Changelog
🆑 Vishenka0704
qol: Ability to delete characters(yourself)
/🆑
* Trimming the fat
* Trimming the fat
* Update mushpeople.dm
* Adds colorblindness as a mild brain trauma (#76527)
What the title says.
The brain trauma makes the whole screen monochrome until cured.

I feel like the current pool for mild brain traumas is quite lame, this
helps spice it up a bit with something that is quite annoying and
distracting but not game breaking (as mild brain traumas should
generally be).
🆑
add: Added colorblindness as a mild brain trauma.
/🆑
---------
Co-authored-by: san7890 <the@san7890.com>
* Fix species `var/hair_color` not being used for, well, hair color (#82168)
`var/hair_color` for species was intended to be used as a "this species
uses this type of hair color thing"
But at some point that got completely lost and now it's only used for
sprite accessories
This fixes that. That means Slimepeople now have properly slimey hair.
And Ethereals are less snowflake once more.
🆑 Melbert
fix: Fixed Slimepeople's hair not matching their slimey colors.
/🆑
* Revert "Fix species `var/hair_color` not being used for, well, hair color (#82168)"
This reverts commit c4cb756.
* Revert "Adds colorblindness as a mild brain trauma (#76527)"
This reverts commit eb815f5.
* Update _species.dm
* unused var
* Caps list..
* Update mushpeople.dm
* Update mushpeople.dm
* Update mushpeople.dm
* Update mushpeople.dm
* Update mushpeople.dm
* Attempts to fix CI errors
* Update cap.dm
* Update _external_organ.dm
* Update monkey.dm
* Revert "Update monkey.dm"
This reverts commit 29f54c8.
* Revert "Update _external_organ.dm"
This reverts commit 8de5ea7.
* Update _external_organ.dm
* Revert "Update _external_organ.dm"
This reverts commit 644cc56.
* Fix CI maybe?
* Update cap.dm
* Update DNA.dm
* Some cleanup/updating to upstream
* Update global_lists.dm
* Mush
* Update mushpeople.dm
* Hopefully the last fix
* Doing this differently
* Update organ.dm
* Update organ.dm
* Update organ.dm
* Update organ.dm
* Update organ.dm
* OK
* Update organ.dm
* Update podpeople.dm
* maybe
* Hm
* Hm
* Will this break things?
* Revert "Will this break things?"
This reverts commit bd288c6.
* Test
* Update organ.dm
* Update organ.dm
* Revert "Update organ.dm"
This reverts commit ca77ff9.
* Update organ.dm
* .
* .
* .
* Update snail.dm
* Monkeys now use height offset (and monkey tail works) (#81598)
This PR adds the ability for monkeys to wear any jumpsuit in the game,
and adds support for them to wear things like coats, gloves, and shoes
(though this cannot be obtained in-game and is solely achieved through
admins, which I also improved a bit upon by adding a defined bitfield
for no equip flags).
This reverts a lot of changes from
tgstation/tgstation#73325 - We no longer check
height from limbs and such to bring sprites down, instead monkeys now
work more similarly to humans, so the entire PR was made irrelevant, and
I didn't really want to leave around dead code for the sake of having a
human with longer legs.
I've now also added support for Dwarfism, which makes monkeys look even
smaller. Very minor change but at least now the mutation doesn't feel
like it does literally nothing to monkeys (since they can already walk
over tables).
Here's a few examples of how it can appear in game (purely for
demonstration, as it is currently intentionally made impossible to
obtain in-game, though if someone wants to change that post-this PR now
that support is added, feel free):
Tails have been broken for a while now, the only reason you see them
in-game is because they are baked into the monkey sprites. This fixes
that, which means humans can now get monkey tails implanted into them
(hell yeah) and monkeys can have their tails removed (also hell yeah)
* Removes unneeded files
* Revert "Removes unneeded files"
This reverts commit 6469d37.
* .
* ok
* Update tails.dm
* Update monkey.dm
* Fix monkey screenshot test
* Update species.dm
* Update reinf_walls.dm
* Maintenance
---------
Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com>
Co-authored-by: Mal <13398309+vinylspiders@users.noreply.github.com>
Co-authored-by: ChungusGamer666 <82850673+ChungusGamer666@users.noreply.github.com>
Co-authored-by: san7890 <the@san7890.com>
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
Co-authored-by: vinylspiders <13398309+vinylspiders@users.noreply.github.com>
* Fixes smoothing breaking if a map is loaded post init (#81526)
## About The Pull Request
We'd finish a set of atom creation, then try and smooth those atoms The
problem is they might try and smooth with an uninitialized neighbor,
which wouldn't have its smoothing vars parsed.
This fixes that by pooling "to be smoothed" things into a list based off
the source of the init stoppage, which we then release when we're done.
Also fixes things staying in mapload, even during a sleep. This can
cause massive headaches so it's good to avoid.
This has a cost but it's minuscule (on the order of like 0.006s (6ms
over all of init), so I'm happy with it.
## Why It's Good For The Game
Closes#77040
## Changelog
🆑
fix: Maps loaded in after roundstart will no longer have broken
smoothing
/🆑
* Fixes smoothing breaking if a map is loaded post init
---------
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
## About The Pull Request
We'd finish a set of atom creation, then try and smooth those atoms The
problem is they might try and smooth with an uninitialized neighbor,
which wouldn't have its smoothing vars parsed.
This fixes that by pooling "to be smoothed" things into a list based off
the source of the init stoppage, which we then release when we're done.
Also fixes things staying in mapload, even during a sleep. This can
cause massive headaches so it's good to avoid.
This has a cost but it's minuscule (on the order of like 0.006s (6ms
over all of init), so I'm happy with it.
## Why It's Good For The Game
Closes#77040
## Changelog
🆑
fix: Maps loaded in after roundstart will no longer have broken
smoothing
/🆑
* Makes TTS blips/enabled into one pref (#76558)
## About The Pull Request

I actually do not know how to test this locally as I don't know how to
set TTS up, hope it works.
## Why It's Good For The Game
It's 2 buttons, one only works depending on the other, I don't think it
makes sense.
## Changelog
🆑
qol: The TTS and TTS Blips option is now one choiced preference.
/🆑
* Makes TTS blips/enabled into one pref
---------
Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
## About The Pull Request

I actually do not know how to test this locally as I don't know how to
set TTS up, hope it works.
## Why It's Good For The Game
It's 2 buttons, one only works depending on the other, I don't think it
makes sense.
## Changelog
🆑
qol: The TTS and TTS Blips option is now one choiced preference.
/🆑
## About The Pull Request
When loading values from the savefile for keybinds, it overrode the
default values with null if not found.
## Why It's Good For The Game
Resolves https://github.com/tgstation/tgstation/issues/72804
## Changelog
## About The Pull Request
Part of a prior PR that was closed (#72562). This version does not add
the check in CI.
## Why It's Good For The Game
The work is already done, so I figured why not.
## Changelog
N/A Nothing player facing
Co-authored-by: Jeremiah Snow <jlsnow301@pm.me>
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
## About The Pull Request
Makes it to where if you connect as a guest preferences don't error out
the ass
Resolves https://github.com/tgstation/tgstation/issues/72268
## Why It's Good For The Game
Easier local debugging, and for servers that let guests join
## Changelog
🆑
server: Preferences now support guests
/🆑
* JSON Savefiles | Player Saves use JSON
* few fixups
* yeah this will need a migration in the future to use a different tree for skyrat stuff
* this can be null
* forgot to sanitize these ones
* TM st
* get it working
* Update code/modules/client/preferences_savefile.dm
Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>
Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may
not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull
request process. -->
TODO:
- [x] DOCUMENT SHIT
- [x] UPDATE DOCUMENTATION
## About The Pull Request
Adds a new datum, which is intended to be a replacement for the stock
savefile type, json_savefile
As you can imagine, this is essentially just a wrapper around a json
file for reading/writing/manipulation that is intended to be a dropin
replacement for savefiles
It also have the ability to import stock savefiles and parse them into a
json tree
<!-- Describe The Pull Request. Please be sure every change is
documented or this can delay review and even discourage maintainers from
merging your PR! -->
## Why It's Good For The Game
Permission obtained from MSO and Mothblocks.
<!-- Argue for the merits of your changes and how they benefit the game,
especially if they are controversial and/or far reaching. If you can't
actually explain WHY what you are doing will improve the game, then it
probably isn't good for the game in the first place. -->
## Changelog
<!-- If your PR modifies aspects of the game that can be concretely
observed by players or admins you should add a changelog. If your change
does NOT meet this description, remove this section. Be sure to properly
mark your PRs to prevent unnecessary GBP loss. You can read up on GBP
and it's effects on PRs in the tgstation guides for contributors. Please
note that maintainers freely reserve the right to remove and add tags
should they deem it appropriate. You can attempt to finagle the system
all you want, but it's best to shoot for clear communication right off
the bat. -->
Not player facing, tested locally exhaustively to ensure it doesnt break
shit
🆑
/🆑
<!-- Both 🆑's are required for the changelog to work! You can put
your name to the right of the first 🆑 if you want to overwrite your
GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the
icon ingame) and delete the unneeded ones. Despite some of the tags,
changelogs should generally represent how a player might be affected by
the changes rather than a summary of the PR's contents. -->
Co-authored-by: Kyle Spier-Swenson <kyleshome@gmail.com>
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
Co-authored-by: san7890 <the@san7890.com>