## About The Pull Request
It's just a partial cleanup of
anti-[STYLE](https://github.com/tgstation/tgstation/blob/master/.github/guides/STYLE.md)
code from /tg/'s ancient history. I compiled & tested with my helpful
assistant and damage is still working.
<img width="1920" height="1040" alt="image"
src="https://github.com/user-attachments/assets/26dabc17-088f-4008-b299-3ff4c27142c3"
/>
I'll upload the .cs script I used to do it shortly.
## Why It's Good For The Game
Just minor code cleanup.
Script used is located at https://metek.tech/camelTo-Snake.7z
EDIT 11/23/25: Updated the script to use multithreading and sequential
scan so it works a hell of a lot faster
```
/*
//
Copyright 2025 Joshua 'Joan Metekillot' Kidder
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
//
*/
using System.Text.RegularExpressions;
class Program
{
static async Task Main(string[] args)
{
var readFile = new FileStreamOptions
{
Access = FileAccess.Read,
Share = FileShare.ReadWrite,
Options = FileOptions.Asynchronous | FileOptions.SequentialScan
};
FileStreamOptions writeFile = new FileStreamOptions
{
Share = FileShare.ReadWrite,
Access = FileAccess.ReadWrite,
Mode = FileMode.Truncate,
Options = FileOptions.Asynchronous
};
RegexOptions regexOptions = RegexOptions.Multiline | RegexOptions.Compiled;
Dictionary<string, int> changedProcs = new();
string regexPattern = @"(?<=\P{L})([a-z]+)([A-Z]{1,2}[a-z]+)*(Brute|Burn|Fire|Tox|Oxy|Organ|Stamina)(Loss)([A-Z]{1,2}[a-z]+)*";
Regex camelCaseProcRegex = new(regexPattern, regexOptions);
string snakeify(Match matchingRegex)
{
var vals =
matchingRegex.Groups.Cast<Group>().SelectMany(_ => _.Captures).Select(_ => _.Value).ToArray();
var newVal = string.Join("_", vals.Skip(1).ToArray()).ToLower();
string logString = $"{vals[0]} => {newVal}";
if (changedProcs.TryGetValue(logString, out int value))
{
changedProcs[logString] = value + 1;
}
else
{
changedProcs.Add(logString, 1);
}
return newVal;
}
var dmFiles = Directory.EnumerateFiles(".", "*.dm", SearchOption.AllDirectories).ToAsyncEnumerable<string>();
// uses default ParallelOptions
// https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.paralleloptions?view=net-10.0#main
await Parallel.ForEachAsync(dmFiles, async (filePath, UnusedCancellationToken) =>
{
var reader = new StreamReader(filePath, readFile);
string oldContent = await reader.ReadToEndAsync();
string newContent = camelCaseProcRegex.Replace(oldContent, new MatchEvaluator((Func<Match, string>)snakeify));
if (oldContent != newContent)
{
var writer = new StreamWriter(filePath, writeFile);
await writer.WriteAsync(newContent);
await writer.DisposeAsync();
}
reader.Dispose();
});
var logToList = changedProcs.Cast<KeyValuePair<string, int>>().ToList();
foreach (var pair in logToList)
{
Console.WriteLine($"{pair.Key}: {pair.Value} locations");
}
}
}
```
## Changelog
🆑 Bisar
code: All (Brute|Burn|Fire|Tox|Oxy|Organ|Stamina)(Loss) procs now use
snake_case, in-line with the STYLE guide. Underscores rule!
/🆑
## About The Pull Request
Alternative to 3️⃣(#92591), which has been fatally shot.
Makes it so that His Grace can be turned into Her Grace via a
xenobiology gender-change potion. Her Grace turns the souls of the
consumed into confetti, creating a nice party atmosphere.
Also adds pronoun helpers for /atom/s, as they weren't there before.
## Why It's Good For The Game
I thought this was a good idea
<img width="934" height="153" alt="image"
src="https://github.com/user-attachments/assets/aff7abe0-86b6-47e1-a8e6-2c233544e9aa"
/>
It's a silly little variation, and it's purely voluntary. Couldn't hurt.
## Changelog
🆑
add: His Grace will now drink gender-change potions
/🆑
---------
Co-authored-by: Thunder12345 <Thunder12345@users.noreply.github.com>
## About The Pull Request
Quite simple - this changes every direct mention of a mob in a
`notify_ghosts` message to use `[mob.real_name]` instead of just `[mob]`
## Why It's Good For The Game
makes things less confusing - ghosts can see easily their actual
identity anyways, so it's not like there's much of a reason _not_ to do
this.
## Changelog
🆑
qol: Ghost notifications will now use the real names of mobs when
something happens (i.e no more "Unknown has completed an ascension
ritual!")
/🆑
Title makes the pr sound cooler than it actually is 😏
## About The Pull Request
Splits Artistic Toolbox into a painting related one, and a crafting
related one.
Artistic Toolbox now includes Crayons, 2 Spray Cans, Paint Palette, and
3 Buckets of Adaptive Paint.

Crafter Toolbox includes Crayons, Camera, Film Cartridge, Chisel, and
various colors of Pipe Cleaners.

(camera is kind of a placeholder for more 'crafty' future additions)
Removes crowbar from artistic toolbox cause i thought it was weird.
Renames fishing toolbox.
Gives fishing toolbox its own inhands.
Renames artistic toolbox inhands.
Replaces some crayon/chisel/pipe cleaner spawns with artistic and
crafter toolboxes on various maps.
## Why It's Good For The Game
i think it'll be useful in the future and sometimes i wanna map in a
painting toolbox without a billion pipecleaners in it
also hot pink toolbox duh

## Changelog
🆑
add: Adds a crafters toolbox storing chisels and pipecleaners. Artistic
toolbox now stores various painting supplies instead.
/🆑
## About The Pull Request
get_atom_on_turf would return the last movable in chain, even if it was
passed a type, which is not the behavior most people would expect and
thus had led to errors in multiple other segments of code. Additionally,
#90436 also has unintentionally made stabilized crossbreeds work
regardless of their storage depth which was an intentional limiter -
this restores said behavior.
- Closes#90498
- Closes#90497
## Why It's Good For The Game
Runtimes bad, and so are unintentional change to game's balance.
## Changelog
🆑
fix: Fixed runtimes caused by stabilized crossbreeds
fix: Fixed an unintentional buff to stabilized crossbreeds, they now
once again need to be put in your backpack or pockets.
/🆑
## About The Pull Request
<details>
- renamed ai folder to announcer
-- announcer --
- moved vox_fem to announcer
- moved approachingTG to announcer
- separated the ambience folder into ambience and instrumental
-- ambience --
- created holy folder moved all related sounds there
- created engineering folder and moved all related sounds there
- created security folder and moved ambidet there
- created general folder and moved ambigen there
- created icemoon folder and moved all icebox-related ambience there
- created medical folder and moved all medbay-related ambi there
- created ruin folder and moves all ruins ambi there
- created beach folder and moved seag and shore there
- created lavaland folder and moved related ambi there
- created aurora_caelus folder and placed its ambi there
- created misc folder and moved the rest of the files that don't have a
specific category into it
-- instrumental --
- moved traitor folder here
- created lobby_music folder and placed our songs there (title0 not used
anywhere? - server-side modification?)
-- items --
- moved secdeath to hailer
- moved surgery to handling
-- effects --
- moved chemistry into effects
- moved hallucinations into effects
- moved health into effects
- moved magic into effects
-- vehicles --
- moved mecha into vehicles
created mobs folder
-- mobs --
- moved creatures folder into mobs
- moved voice into mobs
renamed creatures to non-humanoids
renamed voice to humanoids
-- non-humanoids--
created cyborg folder
created hiss folder
moved harmalarm.ogg to cyborg
-- humanoids --
-- misc --
moved ghostwhisper to misc
moved insane_low_laugh to misc
I give up trying to document this.
</details>
- [X] ambience
- [x] announcer
- [x] effects
- [X] instrumental
- [x] items
- [x] machines
- [x] misc
- [X] mobs
- [X] runtime
- [X] vehicles
- [ ] attributions
## Why It's Good For The Game
This folder is so disorganized that it's vomit inducing, will make it
easier to find and add new sounds, providng a minor structure to the
sound folder.
## Changelog
🆑 grungussuss
refactor: the sound folder in the source code has been reorganized,
please report any oddities with sounds playing or not playing
server: lobby music has been repathed to sound/music/lobby_music
/🆑
## About The Pull Request
Same idea as #82656 but for ctrl click & ctrl shift click cause why not
- Does your signal & `can_perform_action()` checks using
`interaction_flags_click` flags before delegating the event down to
`ctrl_click()` proc.
- The one new change now is that `ctrl_click()` proc is now blocking,
meaning returning `CLICK_ACTION_SUCCESS` or `CLICK_ACTION_BLOCKING` will
stop the object from getting grabbed/pulled. So remember to return these
values if you want to stop the grab action or return `NONE` if you want
to process the click but still want the object to get grabbed as well
## Changelog
🆑
refactor: Ctrl click & Ctrl shift click has been refactored. Please
report bugs on GitHub
/🆑
## About The Pull Request
I'm still not satisfied with how ghost notifications work. This gives
every notification with a source (99% of all notifications, in other
words) a link to jump/orbit. Currently, notifications with "play"
interactions would only get the interact link, so jumping to the source
was pretty annoying.
It removes posting the entire message in the alert tooltip, as some got
pretty lengthy and it didn't seem to fit. To replace this, they will
always use headers
After:



NOTIFY_JUMP and NOTIFY_ORBIT have been merged, since the only difference
seems to be whether it's a turf. The result shaves off some redundant
lines of code, since most-every usage of notify_ghosts uses
NOTIFY_ORBIT.
## Why It's Good For The Game
More standardization for the ghost notification system. Adds a few alert
headers that never had them. All in all, makes it easier for creators to
throw alerts at ghosts
## Changelog
🆑
qol: Nearly every ghost alert should now feature a "VIEW" button, even
those with click interaction.
del: Ghost alerts no longer show the entire message in the tooltip,
instead have been replaced with titles.
/🆑
## About The Pull Request
This helps clean up my favorite helper proc in the whole codebase,
`notify_ghosts()`.
The notify_suiciders, ignore_mapload, and flashwindow args are GONE.
They have been replaced with the notify_flags bitflag argument. This was
intended to make deadchat announcements a bitflag argument too, but
those got reverted right before I originally wanted to submit this PR.
The on-screen popup now shows the notification body when you hover it
with your mouse again. The format is now `[notify_ghosts message] --
[click action (orbit/jump/play)]`
Every single `notify_ghosts()` call has been changed to multiline format
and has been given trailing commas. Pretty!
## Why It's Good For The Game
Cleans up a proc that is very popular and going through a lot of changes
at the time.
Allows for further flexibility when this proc inevitably gets tweaked or
improved. 12 -> 10 args is an improvement, and it doesn't impact the
helper's flexibility at all.
## Changelog
🆑 Rhials
code: The notify_ghosts proc has been cleaned up. Please report any
abnormal changes in deadchat notification behavior.
qol: The on-screen deadchat popups now contain the notification blurb
when hovered with your mouse again.
/🆑
## About The Pull Request
- Adds Roach Infusion to the DNA infuser.
- Bonuses include:
- All infused organs are 2x as healthy, notably your heart: Meaning
getting revived after being dead a while is easier
- When being attacked from behind or while lying down, take 50% less
damage from brute attacks
- Lose disgust 32x faster, making it a non-issue
- Higher toxin purge threshold (5 units, up from 3)
- Virus resistance (same as spaceacillin)
- 100 innate bomb armor, preventing explosions from gibbing you
- 90 innate bio armor
- Immunity to appendicitis, radiation, and to being gibbed by nuclear
bombs
- Downsides include:
- Knockdowns are 3x as long
- get 3x as hungry
- Ingest reagents to your stomach 1.5x slower
- Take 2x as much damage from toxins
- Toxins over the purge threshold deal 4x more liver damage (effectively
2x, as the liver has 2x health)
- Becoming a bug
- Roaches are gross
- Adds a way to kill roaches without having them splat. If they are
sprayed with bug spray, they will simply fall over, and can be scooped
up.
https://github.com/tgstation/tgstation/assets/51863163/5078c493-9e28-42cb-ae51-45fa25b67a34
## Why It's Good For The Game
More content for the DNA infuser, which benefits greatly from variety.
While initially it may seem like a lot of bonuses, a lot of them are
very niche, with the exception being the brute resilience which is the
big "actually useful" bonus you gain.
The infusion is intended to be given to Engineers, offering innate
Radiation immunity to allow them to work on the Supermatter without
needing a rad suit. Likewise, if the work goes south and the Supermatter
goes boom, their body will more than likely survive the blast.
## Changelog
🆑 Melbert
add: Adds the Roach infusion to the DNA infuser. Do you want to survive
a nuclear apocalypse? Visit genetics today.
add: Adds a way to kill Roaches without splatting them. Visit botany for
a spray bottle of pestkiller.
qol: Infuser book is more book-like
fix: DNA infuser correctly gives on-success feedback messages
/🆑
---------
Co-authored-by: Jacquerel <hnevard@gmail.com>
## About The Pull Request
Adds announce_to_ghosts()/notify_ghosts() calls to a bunch of different
things.
**THIS INCLUDES:**
- Powersink being activated/reaching critical (explosion) heat capacity.
- His Grace being awoken.
- Hot Potatoes being armed.
- Ascension Rituals being completed.
- Eyesnatcher victims.
- Ovens exploding as a result of the Aurora Caelus event.
- Wizard Imposter spawns.
- Rock-Paper-Scissors with death as the result of Helbital consumption.
- BSA impact sites.
- Spontaneous Appendicitis.
- The purchasing of a badass syndie balloon.
- The Supermatter beginning to delaminate.
This was everything that I could think of that would be worth announcing
to deadchat. These were all chosen with consideration to questions like
"how easy would it be to spam deadchat with this?" and "will observers
actually see the interesting thing happen, or just the aftermath?".
Not gonna lie, I've really become an observer main as of recently. Maybe
that's being reflected in my recent PRs. Who's to say? Deadchat
Announcement Variety Pack 2 will probably never come out. Sorry.
## Why It's Good For The Game
Gives deadchat a better indiciation of when/where something **REALLY
FUNNY** is about to happen. Draws attention to certain things that are
likely to gather an audience anyways, but sooner (for your viewing
pleasure). In simple terms, it helps the observers observe things
better.
Some cases, such as the aurora caelus or helbitaljanken, are occurrences
so rare that they deserve the audience.
## Changelog
🆑 Rhials
qol: Observers now recieve an alert when a powersink is activated/about
to explode.
qol: His Grace being awoken now alerts observers, to give you a
headstart on your murderbone ghost ring.
qol: Ascension Rituals being completed will also alert observers, for
basically the same reason.
qol: Arming a hot potato will now alert observers. Catch!
qol: Eyesnatcher victims will now notify observers, and invite them to
laugh at their state of misery and impotence.
qol: Observers will be notified of any acute references to The Simpsons
or other 20th Television America copyright properties.
qol: Wizard Imposter spawns alert observers, much like any other ghost
role event should.
qol: Playing Rock-Paper-Scissors with death will now alert the observers
and invite them to watch. Better not choke!
qol: Observers now get an orbit link for BSA impact sites. Why does it
keep teleporting me to the AI upload??
qol: Spontaneous Appendicitis now alerts deadchat.
qol: The purchasing of a badass syndie balloon now alerts deadchat. You
might not be any more powerful, but at least you have an audience.
qol: When beginning to delaminate, the Supermatter will alert observers
and invite them to watch the fireworks.
/🆑
This tracks the seconds per tick of a subsystem, however note that it is
not completely accurate, as subsystems can be delayed, however it's
useful to have this number as a multiplier or ratio, so that if in
future someone changes the subsystem wait time code correctly adjusts
how fast it applies effects
regexes used
git grep --files-with-matches --name-only 'DT_PROB' | xargs -l sed -i
's/DT_PROB/SPT_PROB/g'
git grep --files-with-matches --name-only 'delta_time' | xargs -l sed -i
's/delta_time/seconds_per_tick/g'
Makes the code compatible with 515.1594+
Few simple changes and one very painful one.
Let's start with the easy:
* puts call behind `LIBCALL` define, so call_ext is properly used in 515
* Adds `NAMEOF_STATIC(_,X)` macro for nameof in static definitions since
src is now invalid there.
* Fixes tgui and devserver. From 515 onward the tmp3333{procid} cache
directory is not appened to base path in browser controls so we don't
check for it in base js and put the dev server dummy window file in
actual directory not the byond root.
* Renames the few things that had /final/ in typepath to ultimate since
final is a new keyword
And the very painful change:
`.proc/whatever` format is no longer valid, so we're replacing it with
new nameof() function. All this wrapped in three new macros.
`PROC_REF(X)`,`TYPE_PROC_REF(TYPE,X)`,`GLOBAL_PROC_REF(X)`. Global is
not actually necessary but if we get nameof that does not allow globals
it would be nice validation.
This is pretty unwieldy but there's no real alternative.
If you notice anything weird in the commits let me know because majority
was done with regex replace.
@tgstation/commit-access Since the .proc/stuff is pretty big change.
Co-authored-by: san7890 <the@san7890.com>
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
Moves singulo and supermatter dmis into obj/engine, renamed from obj/tesla_engine
Moves Halloween, Christmas, and misc holiday items to obj/holiday
Moves lollipops to obj/food
Moves crates, closets, and storage to obj/storage
Moves assemblies to obj/assemblies
Renames decals.dmi to signs.dmi ...because they're signs and not decals
Moves statues, cutouts, instruments, art supplies, and crayons to obj/art
Moves balloons, plushes, toys, cards, dice, the hourglass, and TCG to obj/toys
Moves guns, swords, shields to obj/weapons
Adds a modifier variable which can be used to increase or decrease a given items damage to structures, machinery, vehicles, and robots (including cyborgs, simple-bots, and anything else with the MOB_ROBOTIC biotype)
The toolbox sprites have been moved from the regular icon folder to the goon folder.
Why It's Good For The Game
The toolbox sprites that we currently use originally came from Goon, and were ported over by @dannno (#23938).
Therefore, they belong in the goon folder, where they won't possibly be confused for a CC-BY-SA licensed asset.
I have no clue who made the original toolbox sprites on Goon (If someone who does know happens to read this, please let me know so i can give them proper credit), but i do know that dannno made another PR that modified them to how they look today (#24001).
## About The Pull Request
stop forgetting to include mapload, if you don't include it then every single subtype past it by default doesn't include it
for example, `obj/item` didn't include mapload so every single item by default didn't fill in mapload

## Regex used:
procs without args, not even regex
`/Initialize()`
procs with args
`\/Initialize\((?!mapload)((.)*\w)?`
cleanup of things i didn't want to mapload:
`\/datum\/(.)*\/Initialize\(mapload`
Converts most spans into span procs. Mostly used regex for this and sorted out any compile time errors afterwards so there could be some bugs.
Was initially going to do defines, but ninja said to make it into a proc, and if there's any overhead, they can easily be changed to defines.
Makes it easier to control the formatting and prevents typos when creating spans as it'll runtime if you misspell instead of silently failing.
Reduces the code you need to write when writing spans, as you don't need to close the span as that's automatically handled by the proc.
(Note from Lemon: This should be converted to defines once we update the minimum version to 514. Didn't do it now because byond pain and such)
Replaces GLOB.poi_list |= src and GLOB.poi_list -= src with an element that handles it directly.
More consistent code, especially when a lot of code couldn't decide how to add/remove (some |=, some -=, some .Remove, etc).
* Process procs now properly use deltatime when implementing rates, timers and probabilities
* Review fixes
* Geiger counters cleanup
Made hardsuit geiger code more similar to geiger counter code
Geiger counters are more responsive now
* Moved SS*_DT defines to subsystems.dm
* Rebase fix
* Redefined the SS*_DT defines to use the subsystem wait vars
* Implemented suggested changes by @AnturK
* Commented /datum/proc/process about the deltatime stuff
* Send delta_time as a process parameter instead of the defines
Also DTfied acid_processing
* Dtfied new acid component
Adds SIGNAL_HANDLER, a macro that sets SHOULD_NOT_SLEEP(TRUE). This should ideally be required on all new signal callbacks.
Adds BLOCKING_SIGNAL_HANDLER, a macro that does nothing except symbolize "this is an older signal that didn't necessitate a code rewrite". It should not be allowed for new work.
This comes from discussion around #52735, which yields by calling input, and (though it sets the return type beforehand) will not properly return the flag to prevent attack from slapping.
To fix 60% of the yielding cases, WrapAdminProcCall no longer waits for another admin's proc call to finish. I'm not an admin, so I don't know how many behinds this has saved, but if this is problematic for admins I can just make it so that it lets you do it anyway. I'm not sure what the point of this babysitting was anyway.
Requested by @optimumtact.
Changelog
cl
admin: Calling a proc while another admin is calling one will no longer wait for the first to finish. You will simply just have to call it again.
/cl
* Renames a few variables. Also reorders fallback order again.
Renames item_state to inhand_icon_state
Renames mob_overlay_icon to worn_icon
Renames mob_overlay_state to worn_icon_state
worn_icon_state/mob_overlay_state now never gets used for inhands.
* Fixes some comments
* Fixes map issue
* Restart lints
* Properly resolves conflicts
About The Pull Request
Converts every single usage of playsound's vary parameter to use the boolean define instead of 1 or 0. I'm tired of people copypasting the incorrect usage.
Also changes a couple of places where a list was picked from instead of using get_sfx internal calls
This was done via regex:
(playsound\(.+,.+,.+, ?)1( ?\)| ?,.+\)) to match 1
(playsound\(.+,.+,.+, ?)0( ?\)| ?,.+\)) to match 0
full sed commands:
/(playsound\(.+,.+,.+, ?)1( ?\)| ?,.+\))/\1TRUE\2/ 1 to TRUE
/(playsound\(.+,.+,.+, ?)0( ?\)| ?,.+\))/\1FALSE\2/ 0 to FALSE
I'm not very good with regex and these could probably be optimized, but they worked.
Why It's Good For The Game
Code usability
* 1/4 done? maybe?
* more
* stuff
* incremental stuff
* stuff
* stuff & things
* mostly done but not yet
* stuffing
* stuffing 2: electric boogaloo
* Git Commit and the Kingdom of the Crystal Skull
* make it actually compile
* found more stuff
* fixes
* fix AI laws appearing out of order
* fix windows
* should be the remaining stuff
* this time for real
* i guess it should compile too
* fix sechuds
* Refactors NODROP flag into TRAIT_NODROP
🆑 coiax
fix: Anti-drop implants can no longer be used to drop objects that they
were not responsible for sticking to a person's hand.
fix: Backfiring with a Barnyard spellbook will now play a spooky horse sound.
refactor: Refactors the way that "NODROP" items work to a new system,
there should be no change in functionality.
/🆑
Various items in the codebase were doing weird hoop jumps in order to
preserve the nodrop flag's state when it also wanted to change it, so I
moved it to a trait system.
I may have gone overboard with the type of unique trait sources, but
those can be changed later. My long term plan is make a general "CURSED"
nodrop origin, which means you can unlock cursed items by being hit with
a bolt of door opening or something. But that's for another PR, this has
no functionality changes, apart from some slightly modified descriptions
on cursed masks.
- Removed a bunch of redundant voice changing code for all the voice
changing animal masks, used two new clothing flags for this purpose.
- Also refactored a bit the animal masks, making new cursed subtypes that play
the sound when created.
* Drop location
Aiming to implement the framework oranges has detailed in https://tgstation13.org/phpBB/viewtopic.php?f=10&t=19102
Moves canmove to a bitflag in a new variable called mobility_flags, that will allow finer grain control of what someone can do codewise, for example, letting them move but not stand up, or stand up but not move.
Adds Immobilize()d status effect that freezes movement but does not prevent anything else.
Adds Paralyze()d which is oldstun "You can't do anything at all and knock down).
Stun() will now prevent any item/UI usage and movement (which is similar to before).
Knockdown() will now only knockdown without preventing item usage/movement.
People knocked down will be able to crawl at softcrit-speeds
Refactors some /mob variables and procs to /mob/living.
update_canmove() refactored to update_mobility() and will handle mobility_flags instead of the removed canmove
cl
rscadd: Crawling is now possible if you are down but not stunned. Obviously, you will be slower.
/cl
Refactors are done. I'd rather get this merged faster than try to fine tune stuff like slips. The most obvious gameplay effect this pr has will be crawling, and I believe I made tiny tweaks but I can't find it Anything I missed or weird behavior should be reported.
* Revert "all this wrapping and it's not even christmas (#33035)"
This reverts commit faaf151580.
* Revert "fuck me for forgetting to graph this one"
This reverts commit 45d7acea2f.
* Revert "defines math"
This reverts commit 2817a1737b.