No excuse, just dumb. Random layer is the randomly generated parallax
layer, which is null 30% of the time, so this would runtime in SSstation
setup in 30% of rounds
Also another thing where I added extra params and didn't add them to the
proc, fucking parallax for some roundstart clients and latejoins
🆑
fix: fixes a runtime in SSstation setup
fix: fixes parallax not rendering correctly for latejoins
/🆑

## About The Pull Request
We already have nyctophobia, so why not have its inverse?
Adds the photophobia quirk which causes you to get a negative moodlet
while in light and increases flash sensitivity (makes regular eyes as
sensitive to flashes as moth eyes and makes moth eyes as sensitive to
flashes as maint-adapted chaplain eyes)
Sunglasses, welding masks, and things of that nature will negate the
negative moodlet
Thanks to _distrilul, Eton, and Hardly for helping me with this agony.
## Why It's Good For The Game
It's good for quirk variety and adds to roleplay potential.
## Changelog
🆑
add: Photophobia as a negative quirk.
/🆑
---------
Co-authored-by: Jacquerel <hnevard@gmail.com>
## About The Pull Request
Adds a new station trait: Radioactive Nebula!
The station is located inside a radioactive nebula. Space background and
lighting is different shades of green. Objects in space will also glow
green. (This is kinda lying, since the glowing stuff isn't radioactive,
you just get an element that slowly irradiates you, though people and
certain objects that get the 'IRRADIATED' status may still double-whammy
you)
Do not go into space without rad-protected gear, or you will get very
sick very fast. RAD-protection MODsuit modules spawn in robotics and are
also immediately researched.
The nebula does protect against external threats, like pirates, ninja's
and nukies. They can still get to the station pretty well, but they
can't stay in space for extended periods of time
To make it more livable, public rad protection gear will spawn in
lockers around the station. Everyone will also spawn with potassium
iodide pills in their emergency box. Dynamics threat is also reduced by
30, so there's a proclivity towards more lower threat rounds when the
radioactive nebula is present. Radioactive resonance virus cannot be
generated though, since it kinda obliterates any and all challenge and
threat

**Shielding**

In order to protect the station from radiation, nebula shielding units
need to be constructed. Five spawn ready-to-built in engineering, and
more can be bought pretty cheap from cargo. (Normal radstorms are
disabled)
The gravity generator has 20 minutes of innate shielding, where every
nebula shielding unit adds another 20 minutes. 5 are needed to
completely block all radiation even when the gravity gen is down, but
constructing more is recommended in-case of sabotage/destructions/power
outtages.
Active nebula shielding will passively generate tritium. You can either
vent/ignore this, or use it for something. I'm not an atmos tech but I'm
sure you can do something with it
_What happens when no shielding units are constructed/they all fail?_
The station will suffer a 5 minute long radiation storm, with only
shuttles being excempt. The storm is nerfed strongly, and you can tank
the 5 minutes, but you'll be pretty sick. After the 5 minutes are over,
central command will send an emergency shielding unit which will block
the radiation for 10 minutes and warn the station to set up nebula
shielding.
## Why It's Good For The Game
The station being inside a radioactive nebula shakes up a pretty major
aspect of the game (that being the 'space' in space station 13). Hallway
decals are colored green, display screens will display radiation
markings, carps blend with the nebula, etc. Putting the station inside a
radioactive nebula shakes up the rules of the game and what people can
expect. Suddenly, you can no longer just go outside without taking meds
or getting proper radiation protection, encouraging people to stay cozy
and inside.

Inside, the crew gets the goal to set-up radiation shielding to defend
themselves against the nebula, rewarding a creative engineering
department with passive resource income and protecting the station
against massive radiation storms. I think it's nice to give engineering
something to set up. Even if they don't care, they can just plop it down
somewhere in a closed room and be done with it.
The radiation storm is pretty aggressive, but very survivable if you use
your potassium iodide pills, the extra radiation suits or whatever
chemistry has whipped up.
Most importantly, it gives the entire station a common enemy: the
nebula. Everyone is encouraged to prepare against the mechanics.
Chemistry can make meds, viro can make protective virusses, robotics
gets encouraged to make radprotected MODsuits, engineering gets to
set-up radiation shielding, assistants can look at space or whatever
assistants do.
<details>
<summary>Cool images</summary>




</details>
## Changelog
🆑
add: Adds a new rare radioactive nebula station trait! Get ready and
PREPARE, before it gets in...
tweak: Nearstation space area lighting may look slightly different
/🆑
---------
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
Co-authored-by: Jacquerel <hnevard@gmail.com>
## About The Pull Request
Adds a new 7 point positive quirk, "Spacer Born". Totally not inspired
by The Expanse, don't look at the branch name.
You were born in space, rather than on a planet, so your physiology has
adapted differently.
You are more comfortable in space, and way less comfortable on a planet.
Benefits:
- You are slightly taller. (No mechanical effect)
- You take 20% less damage from pressure damage.
- You take 20% less damage from cold environments.
- You move 10% faster while floating (NOT drifting, this is zero gravity
movement while beside a wall).
- You drift 20% faster (Drifting through zero gravity, untethered to
anything)
- While in space (z-level-wise, not turf wise), you lose some disgust
overtime.
- While experiencing no-gravity for an extended period of time, you will
start regenerating stamina and reduce stuns at a very low rate.
- If you are assigned to shaft miner (or the map is Icebox), you are
awarded with a 25% wage bonus (hazard pay).
Downsides:
- While on a planet (Yes, this includes Icebox and planetary maps), you
gain gravity sickness:
- Passive accrue disgust (slightly lessened on Icebox) (Capped at low
levels)
- Choking, after extended periods (disabled on Icebox)
- Slower movement
- Weaker stamina (disabled on Icebox)
- Suffocation from extended periods (disabled on Icebox) (Lungs aren't
adapted)
- Mood debuff
(Effects not final)
## Why It's Good For The Game
I'd figure I throw my hat in with the Positive Quirk Curse.
This is a quirk that improves your ability in a niche circumstance (low
gravity / dangerous pressure), with some downsides that are only
generally in effect if you play a few roles (or it's Icebox).
Because of this I think it'll provide an interesting niche, where Spacer
Born engineers are slightly better than their counterparts due to their
origin (moving faster in space without a jetpack, withstanding
pressure). However, at the same time, if the mining outpost sustains
damage and needs repairs... suddenly your buff over your cohorts
disappears, and you have to brave somewhere hostile to your body.
Ultimately, the goal of the quirk is to encourage people to approach
situations a bit differently.
Or take it as a challenge and play shaft miner.
## Changelog
🆑 Melbert
add: Adds a new 7 point positive quirk, "Spacer Born". You were born in
space, and as a result your body's adapted to life in artificial
gravity, making you much more effective and comfortable in lower
gravity. However, travelling planet-side is quite a chore, especially if
you're assigned to work there.
add: Adds a chemical: Ondansetron, created by Oil + Nitrogen + Oxygen +
Ethanol catalyst. A powerful Antiemetic (lowers disgust).
/🆑
## About The Pull Request
Basically, the organ equivalents of prosthetic limb and quadruple
amputee.
These replace your organs with absolutely terrible cybernetic
counterparts which also have absolutely no resistance against EMPs.

### ADDITIONAL FUN
Surplus organs are so awful that if surgically removed while not EMPed
nor failing, they *explode*!
## Why It's Good For The Game
More character customization, and more suffering for hardcore random
players.
## Changelog
🆑
add: Added two new quirks, prosthetic organ and tin man. Essentially,
they replace organs with bad bad not good cybernetic counterparts.
/🆑
---------
Co-authored-by: Jacquerel <hnevard@gmail.com>
Co-authored-by: carlarctg <53100513+carlarctg@users.noreply.github.com>
## About The Pull Request
This was one of the tradeoffs for removing other, more consistent
sources of languages, and was requested by Melbert among many others.
This does go against my wanted goal of decreasing the risk of
eavesdropping by other players through just magically knowing a
language, but it is an expensive quirk and it is in their medical
records, which makes it better than language encryption keys or silicon
just innately knowing them.
This also limits Bilingual to only roundstart languages (+Uncommon),
rather than being randomly selected from a list (that had very useless
ones like monkey, podpeople, and beachbum). This is mostly just for
modularity, I didn't want to make it look terrible code-wise and thought
this may be the optimal way to handle it.
This is also me going back on
https://github.com/tgstation/tgstation/pull/71773 - which I had closed
myself.
## Why It's Good For The Game
If we're gonna keep the Bilingual quirk, it might as well be something
players can choose the language of, it's their character and they should
be allowed to decide how their character is, and it is my fault that
this stupid compromise of "getting a random language" was made in the
first place. It never should've happened.
It now actually limits it to roundstart-only languages, so there's no
way you can spy on people who prepare in advance through becoming
podpeople, or monkeys, etc.
## Changelog
🆑
balance: Bilingual quirk now lets you choose your language between ones
given to roundstart species.
balance: Foreigner and Bilingual are now mutually exclusive languages.
/🆑
## About The Pull Request
Adds a few new quirks so allow for some more individuality from players!
~~They're set to 0 right now for TM purposes.~~ No TM, thus spoke
Melbert.
To-do:
- [x] Bilingual - Random extra language
- [x] ~~Mutated - Random mutation~~
- [x] Big Hands (fetish content???) - Big hands trait (can't use guns)
- [x] Soft-Spoken - Whisper permanently
- [x] Clumsy (not a packet dropper) - Clumsy trait (clown shit)
- [x] ~~Paroled Convict - Spawn with a tracking implant + prisoner
armband.~~
- [x] ~~Fashionista (headmins made me do it) - Lets you pick a scarf
roundstart.~~
- [x] The more the merrier.
## Why It's Good For The Game
Small changes at the cost of a negative quirk or two are a fun way to
develop the story. It's fun! These aren't game breaking and might lead
way to some interesting interactions!
## Changelog
🆑 Chadley
add: Adds some new quirks!!
add: Adds the bilingual quirk, which gives a new random language.
add: Adds the big hand quirk which stops the usage of most guns.
add: Adds the soft spoken quirk which forces you to whisper.
add: Adds the clumsy quirk enabling the clumsy trait.
/🆑
---------
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
## About The Pull Request
quirk called social anxiety is no longer compatible with mute as mute is
a more severe option of that quirk
## Why It's Good For The Game
free points are bad
## Changelog
🆑
fix: social anxiety is incompatible with mute
/🆑
## About The Pull Request
Generally cleans up code on both components.
Moves burn proc back to /obj level, I'm not sure why I moved it to /atom
level, it was unnecessary.
Acid component generalized so it can be used on any atom that uses
atom_integrity.
Fixes a bug where objects that stopped burning didn't update their burn
overlay properly due to bad removal logic and leftover code.
Standardizes examine messages on burning items by just slapping an
examine signal registration on the component.
Adds fire particles to items thanks to Lemon's PR:
https://github.com/tgstation/tgstation/pull/74524
## Why It's Good For The Game
Particles look cool


Bugfixes are good
Code improvements are good
## Changelog
🆑
add: Burning items now get (small) smoke particles. Sick.
fix: Burning objects now clear their burning overlay properly.
qol: Examining burning objects will always tell you that they are
burning.
/🆑
---------
Co-authored-by: san7890 <the@san7890.com>
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'
# MAINTAINER - USE THE BUTTON THAT SAYS "MERGE MASTER" THEN SET THE PR
TO AUTO-MERGE! IT'S MUCH EASIER FOR ME TO FIX THINGS BEFORE THEY SKEW
RATHER THAN AFTER THE FACT.
## About The Pull Request
Hey there,
This took a while to do, but here's the gist:
Python file now regexes every file in `/code` except for those that have
some valid reason to be tacking on more global defines. Some of those
reasons are simply just that I don't have the time right now (doing what
you see in this PR took a few hours) to refactor and parse what should
belong and what should be thrown out. For the time being though, this PR
will at least _halt_ people making the mistake of not `#undef`ing any
files they `#define` "locally", or within the scope of a file.
Most people forget to do this and this leads to a lot of mess later on
due to how many variables can be unmanaged on the global level. I've
made this mistake, you've made this mistake, it's a common thing. Let's
automatically check for it so it can be fixed no-stress.
Scenarios this PR corrects:
* Forgetting to undef a define but undeffing others.
* Not undeffing any defines in your file.
* Earmarking a define as a "file local" define, but not defining it.
* Having a define be a "file local" define, but having it be used
elsewhere.
* Having a "local" define not even be in the file that it only shows up
in.
* Having a completely unused define*
(* I kept some of these because they seemed important... Others were
junked.)
## Why It's Good For The Game
If you wanna use it across multiple files, no reason to not make it a
global define (maybe there's a few reasons but let's assume that this is
the 95% case).
Let me know if you don't like how I re-arranged some of the defines and
how you'd rather see it be implemented, and I'd be happy to do that.
This was mostly just "eh does it need it or not" sorta stuff.
I used a pretty cool way to detect if we should use the standardized
GitHub "error" output, you can see the results of that here
https://github.com/san7890/bruhstation/actions/runs/4549766579/jobs/8022186846#step:7:792
## Changelog
Nothing that really concerns players.
(I fixed up all this stuff using vscode, no regexes beyond what you see
in the python script. sorry downstreams)
## About The Pull Request
This is a continuation of
https://github.com/tgstation/tgstation/pull/74085 - I announced in the
comments there that this would be my next PR, and this is it.
Removes SSnetwork, ``/datum/ntnet``,
``/datum/component/ntnet_interface``, ``var/network_root_id``, the
network unit test, and a lot of other things related to networks.
- NTNet circuits now check for an Ntnet relay, and uses signals to
operate.
- Logs in Wirecarp is now only for PDA and Ntnet Relay things, so you
can no longer see what ruins exist using it (why should Wirecarp know
that Oldstation spawned? The flavor is that they dont know its there).
- Removed it from MULEbots entirely, I don't think it even did anything
for them? Botkeeper seems to work without it, so it's possibly there
from pre-tgui PDAs.
- Moves assigning random names to a base proc instead of being tied to
network, this is things like random-naming scrubbers/vents. The behavior
hasn't changed at all.
- Makes Ntos work for consoles when relays are down, as the comments
said they're supposed to (because they're wired). I think this was an
accidental change on my part, so this is a revert of that.
## Why It's Good For The Game
Ntnet is ancient code that hasn't given us much that we can't do with
already existing alternatives, we've been slowly moving away from it for
init times, and though a large portion of that was limited to airlocks,
I still don't think this is a system worth keeping around.
It's way too complex to expect feature coders to do anything with it,
and too old with better alternatives for anyone to want to improve any
of it.
## Changelog
🆑
fix: Computers are now properly connected to Ethernet, and can use Ntos
when Relays are down.
refactor: Removes Ntnet and Ntnet interfaces, which was only used by
Ntnet circuits (which now directly checks for a Relay to work) and
MULEbots, which did nothing with it.
balance: Wirecarp no longer tells you what ruins spawned in a round,
instead it's limited to PDA logs, and tells you the source too. This
means the RD can catch someone running illegal programs if they don't
make any attempt at hiding it.
qol: Wirecarp logs is now set to save 300 at once, instead of 100 and
being increased to 300 by the RD during the round. This is pretty
insignificant, since there's no reason to NOT want as many logs as
possible.
/🆑
---------
Co-authored-by: Zephyr <12817816+ZephyrTFA@users.noreply.github.com>
## About The Pull Request
Removes NtNet softwaredownload/communication because they did nothing,
so this also removes the feature to shut them off from Wirecarp
I removed tablets from being added to networks, Tablets already generate
logs for actions they do, which is already enough for the effects it has
in-game (just being visible to Wirecarp), once NtNet is deleted from
everything else then we can move it to ModPCs and limit logging to only
ModPC actions.
Fixes shutting off ntnet relays from Wirecarp, now you can properly shut
off Ntnet, and the warning that it kicks you out of the program is now
true.
Gives the Holodeck it's own network root define and fixes Syndicate
network showing up on Wirecarp
Wirecarp's PDA logs now shows the source of an action
## Why It's Good For The Game
Moves ModPCs further from NTNet so we can move towards deleting it
entirely
Makes Wirecarp more responsible and trustworthy
Removes useless stuff that never gets used, simplifying a overthought
overcomplicated system.
## Changelog
🆑
balance: Wirecarp now properly shuts off NtNet remotely.
balance: Wirecarp now shows the source of a PDA that does an action.
fix: Wirecarp can no longer be used to see if Nukies exist through their
networks.
del: Removes Software downloading and communication Ntnet networks, as
they were pretty worthless.
/🆑
## About The Pull Request
Current blacklist makes it so you cannot be both frail and paraplegic,
but it's intended to exclude quad amputees from taking those.
## Why It's Good For The Game
Who says a paraplegic can't also have weak bones?
## Changelog
🆑
fix: frail and paraplegia quirks can once again be taken together.
/🆑
## About The Pull Request
Station traits can't roll twice in the same round.
They currently have blacklist for traits that can't roll together, this
makes them not roll with themselves too.
## Why It's Good For The Game
Closes https://github.com/tgstation/tgstation/issues/61873
Station traits are not made with rolling twice in the same round in
mind, and is just a waste of trait points, or will just be annoying
(like in the issue report's case)
## Changelog
🆑
fix: There will no longer have 2 of the same station trait roll twice in
the same round.
/🆑
## 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
Closes#72141
Roundstart humans weren't in control of their mob by the time
`AssignQuirks` was called.
The call chain for roundstart goes `create_characters` ->
`equip_characters` -> `AssignQuirks` -> `transfer_characters`.
For latejoin, `create_character` -> `transfer_character` ->
`AssignQuirks`.
I could simply move around the call chain, but that feels much more
fragile and more liable to cause other issues to me. So instead, I
simply allowed add quirk to be passed a client, so that a client's
quirks can be applied to a mob they are not currently inhabiting.
In doing this, it became possible to show visual quirks on the prefs
dummy, like nearsighted glasses and heterochromia. So I put in a little
work to accomplish that as well.

Along side, some refactoring and documentation for quirk datums.
## Why It's Good For The Game
People get what they expect on roundstart.
## Changelog
🆑 Melbert
qol: The preview dummy in the preferences menu now shows some visual
quirks, like Heterochromia or nearsighted.
fix: Fixed some quirks which read a preference roundstart not applying
the preference.
refactor: Refactored some bits of quirk datums and the quirk application
process.
/🆑
Co-authored-by: Time-Green <timkoster1@hotmail.com>
## About The Pull Request
Neutral pride pin quirk added. Pride pins can be infinitely reskinned
now. Changes "sexuality" to "pride" in description of pin.
## Why It's Good For The Game
Pride pins are cute and having to buy them every round is a chore. Pride
pins are purely cosmetic and have no reason to be locked into only being
reskinned once.
## Changelog
🆑
add: Pride pin quirk! Start the shift off with a pride pin in-hand.
qol: Pride pins can be infinitely reskinned now.
/🆑
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
## About The Pull Request
Adds the modular computer subsystem which is meant to replace mod PC's
reliance on networks and radios, specifically the network subsystem, the
ntnet interface, and /datum/ntnet. This PR removes station_root ntnets
entirely, but I tried to keep it small.
This PR also removes a ton of unused vars and defines, such as NTNet
channels that were unused (peer2peer and systemcontrol), atmos networks
(as they were removed a while ago) and NTNet var on relays (its stated
purpose is so admins can see it through varedits, but that's useless now
that it's a subsystem)
I also removed ``setting_disabled`` as a thing the RD can do, it turned
off ALL ntnet systems. However, this was when there were 4 different
ones, now that there's only 2 I thought it was redundant and he could
just click 2 buttons to close them.
## Why It's Good For The Game
``/datum/ntnet``, ``/datum/component/ntnet_interface``, and
``/datum/controller/subsystem/networks`` are all old-code messes that
depend on eachother and is hard for people to understand what exactly it
adds to the game. 90% of its features is allowing the Wirecarp app to
see all the ruins that spawned in-game, which I don't think is something
that we even WANT (why does the RD need to know that oldstation spawned?
Why should they know this anyway??)
This hopefully starts to simplify networks/ntnet to make it easier to
remove in the future, because surely there are better alternatives than
**this**
## Changelog
🆑
refactor: Modular computers NTnet and applications run on its own
subsystem, please report any new bugs you may find.
/🆑
## About The Pull Request
Adds a new station trait, the Cybernetic Revolution
It causes every crewmember to spawn with a cybernetic implant/organ (it
depends on their job).
For example. the bartender has an upgraded cybernetic liver, security
officers have extendable flashes, prisoners have flash shielded eyes.
For AIs, they get the surveillance upgrade.
The trait also lowers research costs for the cybernetic designs, triples
the price of EMP kits and EMP flashlights, doubles price of EMP bombs,
and allows traitors to buy autosurgeons, so they can implant themselves
with whatever they ripped out of the crew.
If you do not wish to partake, you can also take the Body Purist quirk,
which prevents you from getting a cybernetic, but everytime you have a
mechanical limb/organ from some other source, you will take a severe
mood penalty.
## Why It's Good For The Game
This could be a cool modifier to rounds once in a while, slightly
modifying the gameplay of all the crew.
Also our implant system is very barely used, so why not?

## Changelog
🆑
add: New Station Trait: Cybernetic Revolution
add: Body Purist Quirk
/🆑
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
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>
## About The Pull Request
Area contents isn't a real list, instead it involves filtering
everything in world
This is slow, and something we should have better support for.
So instead, lets manage a list of turfs inside our area. This is simple,
since we already move turfs by area contents anyway
This should speed up the uses I've found, and opens us up to using this
pattern more often, which should make dev work easier.
By nature this is a tad fragile, so I've added a unit test to double
check my work
Rather then instantly removing turfs from the contained_turfs list, we
enter them into a list of turfs to pull out, later.
Then we just use a getter for contained_turfs rather then a var read
This means we don't need to generate a lot of usage off removing turf by
turf from space, and can instead do it only when we need to
I've added a subsystem to manage this process as well, to ensure we
don't get any out of memory errors. It goes entry by entry, ensuring we
get no overtime.
This allows me to keep things like space clean, while keeping high
amounts of usage on a sepearate subsystem when convienient
As a part of this goal of keeping space's churn as low as possible, I've
setup code to ensure we do not add turfs to areas during a z level
increment adjacent mapload. this saves a LOT of time, but is a tad
messy
I've expanded where we use contained_turfs, including into some cases
that filter for objects in areas. need to see if this is sane or not.
Builds sortedAreas on demand, caching until we mark the cache as
violated
It's faster, and it also has the same behavior
I'm not posting speed changes cause frankly they're gonna be a bit
scattered and I'm scared to.
@Mothblocks if you'd like I can look into it. I think it'll pay for
itself just off `reg_in_areas_in_z` (I looked into it. it's really hard
to tell, sometimes it's a bit slower (0.7), sometimes it's 2 seconds
(0.5 if you use the old master figure) faster. life is pain.)
## Why It's Good For The Game
Less stupid, more flexible, more speed
Co-authored-by: san7890 <the@san7890.com>
* Object Window Niceties
Alright. I got bored and polished up the object/alt click window.
It had a few issues:
First, we generated all our images in bulk, as soon as requested
Second, the caching was global, despite only working on a client to
client basis
Third, we only generated up to 10 images. This could be fine, but the
javascript code will continuiously rerender assuming unrendered images
will come eventually, and they well, weren't. This caused MASSIVE
clientside lag
Fourth and finally, I did not like how moving away from the viewed turf
lagged behind, in sync with the stat tab update. Looked bad.
I've resolved all these.
I solved the first three issues by reworking how obj images were
generatated and managed.
Rather then storing a basic cache on the subsystem, and doing all the
image generation at once, we queue up image generation as we like, and
generate images inside a new processing subsystem fire.
This isn't the best solution, since it still eats cpu somewhat, but it's
a whole lot better then the other options, outside either removing the
need to getflat, or somehow predicting what items a client will want to
see
I've started storing three bits of info. First, a list of all the
objects we currently want to display.
Second, a list of atom -> image html
Third, a list of atoms to imageify.
This information is stored on a datum on /client, since I want this to
have a lifetime linked to well, clients.
I've used this datum to solve that fourth bit, using a component I made
for parallax a bit back. This lets me react to our client's mob, and
update the tab linked to that, rather then on a subsystem call by call
basis.
That's about it.
Co-authored-by: san7890 <the@san7890.com>
ever see the tram take 10 milliseconds per movement to move 2100 objects? now you have
https://user-images.githubusercontent.com/15794172/166198184-8bab93bd-f584-4269-9ed1-6aee746f8f3c.mp4
About The Pull Request
fixes#66887
done for the code bounty posted by @MMMiracles to optimize the tram so that it can be sped up. the tram is now twice as fast, firing every tick instead of every 2 ticks. and is now around 10x cheaper to move. also adds support for multiz trams, as in trams that span multiple z levels.
the tram on master takes around 10-15 milliseconds per movement with nothing on it other than its starting contents. why is this? because the tram is the canary in the coal mines when it comes to movement code, which is normally expensive as fuck. the tram does way more work than it needs to, and even finds new ways to slow the game down. I'll walk you through a few of the dumber things the tram currently does and how i fixed them.
the tram, at absolute minimum, has to move 55 separate industrial_lift platforms once per movement. this means that the tram has to unregister its entered/exited signals 55 times when "the tram" as a singular object is only entering 5 new turfs and exiting 5 old turfs every movement, this means that each of the 55 platforms calculates their own destination turfs and checks their contents every movement. The biggest single optimization in this pr was that I made the tram into a single 5x11 multitile object and made it only do entering/exiting checks on the 5 new and 5 old turfs in each movement.
way too many of the default tram contents are expensive to move for something that has to move a lot. fun fact, did you know that the walls on the tram have opacity? do you know what opacity does for movables? it makes them recalculate static lighting every time they move. did you know that the tram, this entire time, was taking JUST as much time spamming SSlighting updates as it was spending time in SStramprocess? well it is! now it doesnt do that, the walls are transparent. also, every window and every grille on the tram had the atmos_sensitive element applied to them which then added connect_loc to them, causing them to update signals every movement. that is also dumb and i got rid of that with snowflake overrides. Now we must take care to not add things that sneakily register to Moved() or the moved signal to the roundstart tram, because that is dumb, and the relative utility of simulating objects that should normally shatter due to heat and conduct heat from the atmosphere is far less than the cost of moving them, for this one object.
all tram contents physically Entered() and Exited() their destination and old turfs every movement, even though because they are on a tram they literally do not interact with the turf, the tram does. also, any objects that use connect_loc or connect_loc behalf that are on the same point on the tram also interact with each other because of this. now all contents of the tram act as if theyre being abstract_move()'d to their destination so that (almost) nothing thats in the destination turf or the exit turf can react to the event of "something laying on the tram is moving over you". the rare things that DO need to know what is physically entering or exiting their turf regardless of whether theyre interacting with the ground can register to the abstract entered and exited signals which are now always sent.
many of the things hooked into Moved(), whether it be overrides of Moved() itself, or handlers for the moved signal, add up to a LOT of processing time. especially for humans. now ive gotten rid of a lot of it, mostly for the tram but also for normal movement. i made footsteps (a significant portion of human movement cost) not do any work if the human themselves didnt do the movement. i optimized has_gravity() a fair amount, and then realized that since everything on the tram isnt changing momentum, i didnt actually need to check gravity for the purposes of drifting (newtonian_move() was taking a significant portion of the cost of movement at some points along the development process). so now it simply doesnt call newtonian_move() for movements that dont represent a change in momentum (by default all movements do).
also i put effort into 1. better organizing tram/lift code so that most of it is inside of a dedicated modules folder instead of scattered around 5 generic folders and 2. moved a lot of behavior from lift platforms themselves into their lift_master_datum since ideally the platforms would just handle moving themselves, while any behavior involving the entire lift such as "move to destination" and "blow up" would be handled by the lift_master_datum.
also
https://user-images.githubusercontent.com/15794172/166220129-ff2ea344-442f-4e3e-94f0-ec58ab438563.mp4
multiz tram (this just adds the capability to map it like this, no tram does this)
Actual Performance Differences
to benchmark this, i added a world.Profile(PROFILER_START) and world.Profile(PROFILER_START) to the tram moving, so that it generates a profiler output of all tram movement without any unrelated procs being recorded (except for world.Profile() overhead). this made it a lot easier to quantify what was slowing down both the tram and movement in general. and i did 3 types of tests on both master and my branch.
also i should note that i sped up the "master" tram test to move once per tick as well, simply because the normal movement speed seems unbearably slow now. so all recorded videos are done at twice the speed of the real tram on master. this doesnt affect the main thing i was trying to measure: cost for each movement.
the first test was the base tram, containing only my player mob and the movables starting on the tram roundstart. on master, this takes around 13 milliseconds or so on my computer (which is pretty close to what it takes on the servers), on this branch, it takes between 0.9-1.3 milliseconds.
ALSO in these benchmarks youll see that tram/proc/travel() will vary significantly between the master and optimized branches. this is 100% because there are 55 times more platforms moving on master compared to the master branch, and thus 55x more calls to this proc. every test was recorded with the exact same amount of distance moved
here are the master and optimized benchmark text files:
master
master base tram.txt
https://user-images.githubusercontent.com/15794172/166210149-f118683d-6f6d-4dfb-b9e4-14f17b26aad8.mp4
also this shows the increased SSlighting usage resulting from the tram on master spamming updates, which doesnt happen on the optimized branch
optimized
optimization base tram.txt
https://user-images.githubusercontent.com/15794172/166206280-cd849aaa-ed3b-4e2f-b741-b8a5726091a9.mp4
the second test is meant to benchmark the best case scaling cost of moving objects, where nothing extra is registered to movement besides the bare minimum stuff on the /atom/movable level. Each of the open tiles of the tram had 1 bluespace rped filled with parts dumped onto it, to the point that the tram in total was moving 2100 objects. the vast majority of these objects did nothing special in movement so they serve as a good base case. only slightly off due to the rped's registering to movement.
on master, this test takes over 100 milliseconds per movement
master 2000 obj's.txt
https://user-images.githubusercontent.com/15794172/166210560-f4de620d-7dc6-4dbd-8b61-4a48149af707.mp4
when optimized, about 10 milliseconds per movement
https://user-images.githubusercontent.com/15794172/166208654-bc10086b-bbfc-49fa-9987-d7558109cc1d.mp4
optimization 2000 obj's.txt
the third test is 300 humans spawned onto the tram, meant to test all the shit added on to movement cost for humans/carbons. in retrospect this test is actually way too biased in favor of my optimizations since the humans are all in only 3 tiles, so all 100 humans on a tile are reacting to the other 99 humans movements, which wouldnt be as bad if they were distributed across 20 tiles like in the second test. so dont read into this one too hard.
on master, this test takes 200 milliseconds
master 300 catgirls.txt
when optimized, this takes about 13-14 milliseconds.
optimization 300 catgirls on ram ranch.txt
Why It's Good For The Game
the tram is literally 10x cheaper to move. and the code is better organized.
currently on master the tram is as fast as running speed, meaning it has no real relative utility compared to just running the tracks (except for the added safety of not having to risk being ran over by the tram). now the tram of which we have an entire map based around can be used to its full potential.
also, has some fixes to things on the tram reacting to movement. for example on master if you are standing on a tram tile that contains a banana and the TRAM moves, you will slip if the banana was in that spot before you (not if you were there first however). this is because the banana has no concept of relative movement, you and it are in the same reference frame but the banana, which failed highschool physics, believes you to have moved onto it and thus subjected you to the humiliation of an unjust slipping. now since tram contents that dont register to abstract entered/exited cannot know about other tram contents on the same tile during a movement, this cannot happen.
also, you no longer make footstep sounds when the tram moves you over a floor
TODO
mainly opened it now so i can create a stopping point and attend to my other now staling prs, we're at a state of functionality far enough to start testmerging it anyways.
add a better way for admins to be notified of the tram overloading the server if someone purposefully stuffs it with as much shit as they can, and for admins to clear said shit.
automatically slow down the tram if SStramprocess takes over like, 10 milliseconds complete. the tram still cant really check tick and yield without introducing logic holes, so making sure it doesnt take half of the tick every tick is important
go over my code to catch dumb shit i forgot about, there always is for these kinds of refactors because im very messy
remove the area based forced_gravity optimization its not worth figuring out why it doesnt work
fix the inevitable merge conflict with master lol
create an icon for the tram_tunnel area type i made so that objects on the tram dont have to enter and exit areas twice in a cross-station traversal
add an easy way to vv tram lethality for mobs/things being hit by it. its an easy target in another thing i already wanted to do: a reinforced concept of shared variables from any particular tram platform and the entire tram itself. admins should be able to slow down the tram by vv'ing one platform and have it apply to the entire tram for example.
Changelog
cl
balance: the tram is now twice as fast, pray it doesnt get any faster (it cant without raising world fps)
performance: the tram is now about 10 times cheaper to move for the server
add: mappers can now create trams with multiple z levels
code: industrial_lift's now have more of their behavior pertaining to "the entire lift" being handled by their lift_master_datum as opposed to belonging to a random platform on the lift.
/cl
This PR rewrites almost all messages related to cascade events. Some messages felt kinda clunky to read or could have been written better. Overall, the new messages add to the experience as a cascade being a terrifying event in a way that I felt the old ones missed, and they make the event feel overall a lot sharper.
While looking at the resonance cascade code, I noticed that there a lot of stuff about cascades in the air which was not touched on. So, as I do, this PR evolved into a polish and roundup PR for cascades. There was a lot of stuff still hanging out relating to the event, and although the big backend of it sits, there was still a bit left to be completed. Therefore this PR deserves more the title of the "Resonance cascade POLISHENING" instead of the "REFLAVAHRING". But yeah, you ever go on a massive tangent before?
Changes the cascade walls from turfs to objects to improve the performances of the roundending cascade.
The issue was that ChangeTurf() was a pretty expensive proc to be called that many times so i moved the cascade wall into an object. It doesn't delete anything other than living mobs and the portal to prevent edge case runtimes.
Plus remove a span_bold() from the announcement text since it wasn't making the text bold but was leaving behind
Cascade walls were processing on object subsystem, they are now in their own subsystem that ticks once per second and should be more reliable even in case of high td
better description for the walls to be more interesting
Have you ever noticed that the chemical smoke and chemical foam reactions are a lot less effective in confined spaces? This is because they currently attempt to spread to all tiles within n steps of their origin. If they can't expand onto a tile they get blocked and the expanding cloud/flood misses out on all the tiles that would be in range, but that can't be reached.
Obviously smoke and foam getting blocked by walls and the like makes intuitive sense, but it seemed a bit nonsensical that walls would basically delete a significant chunk of an expanding, amoebic mass. The solution I came up with is making smoke and foam expand until they cover a certain area, with a shared tracker for the target size and total size of the flood. The flood will simply expand as normal until it covers the desired target area. Blocked expansions just don't count and will be made up for with expansion elsewhere.
Attendant to these changes are a whole bunch of minor code improvement to smoke, foam, and one for wizard spells because I was already in the area and :pain:.
There have been some minor balance changes to the chemical smoke and foam reactions:
I converted them over to passing the desired area of the resulting smoke cloud/foam flood. The old equation for the resulting area was along the lines of 2sqrt(x)(sqrt(x) + 1) + 1 given reaction volume x and given unobstructed expansion. I've made them just pass around 2x instead. This is actually less than they used to try for, but now they're guaranteed to reach that unless the flood is fully contained. Not entirely certain if buff or nerf. Probably buff on the station.
Also, foam dilution is now based on covered area instead of target expansion range. Since this scales faster than it used to foam has been effectively nerfed at high volumes. To compensate for this I removed the jank 6/7 effect multiplier and increased the base reagent scaling a bit. Again, not certain if buff or nerf.
Adds the navigate verb, it makes a holographic path to any navigation beacon on station
Video here: https://streamable.com/2uy76l
removes wayfiding pinpointers and the associated quirk, as theyre kinda redundant with it
needs #65665 before merge
partially inspired by goon
Adds a basic bucketing system to move loops.
This should hopefully save a lot of cpu time, and allow for more load while gaining better smoothness.
The idea is very similar to SStimer, but my implementation is much more simple, since I have to worry less about long delays and redundant buckets.
Insertion needs to be cheaper too, since I'm making a system that by design holds a lot of looping things
It comes with some minor tradeoffs, we can't have constant rechecking of loops if a move "fails", not that we really want that anyway
We also lose direct control over the timer var, but I think that's better, don't want people manipulating that directly
Not that it even really worked very well back when we did have it
Removes the sleep from singularity code
Rather then using sleep to store the state of our iteration, we instead queue the iteration in a list.
We then use a custom singulo processing subsystem to call our "digest" proc several times per full eat, with the hope of staying on top of
our queue
This rarely happens because the queue is too large, god why is a sm powered singulo 24x24 tiles.
I've also A: cached our dist checks, and B: Added dist checks to prevent attempting to pull things out of range
This might look a bit worse, but it saves a lot of work
Oh right and I made the singulo unable to eat while it still has tiles to digest. The hope is to prevent
overwork and list explosion.
Hopefully this will prevent singulo server stoppage, though I've seen some other worrying things in testing.
Adds a /datum/autowiki template which can be derived in order to create wiki pages and queue file uploads. This is then kickstarted by the new tgs target autowiki (using the AUTOWIKI define) in order to upload these pages.
The pages generated are, in a best case scenario, raw data. This means that wiki editors can decide what the actual theme is without ever having to touch the repository. In the future, MSO will hopefully sandbox the wiki and install Scribunto to let us separate data and style even more.
These will, when done, upload to templates, such as Template:Autowiki/VendingMachines. The actual pages (in this case "Vending Machines") will include this, and thus can write down their own prose and whatnot without ever having to touch repo.
This will also be run on a daily GitHub action, with some secrets setup to link to the account. Currently this is on a bot password (my forum account will not be leaked in the event of a collapse), but at some point I would like to create a dedicated bot account.
This PR adds a Techweb and Vending Machine autowiki. You can look at the Vending Machines one here and the Techweb one here.
I have absolutely no idea what to label this PR (other than note the unit tests I've added). Feel free to add whatever gives GBP 😉
makes most updating stat panel tabs update once every 4 seconds instead of 4 deciseconds, but switching tabs instantly updates statpanel data for you. also makes examining a turf make flat icons for a maximum of 10 contents instead of 30 because its ridiculous to call getFuckingFlatIcon() wrappers that many times. also makes SSfluids not have SS_TICKER and updates its wait accordingly because theres no reason for it to be a ticker subsystem
the mc tab updates every 2 seconds unless someone has the pref enabled to refresh it quickly because SOME UNILLUMINATED LEMONS absolutely must watch overtime spikes in real time
statpanels can take between 1-3% of masters total processing time at very high pop, which is silly considering theres no need for someone to know any of the data updated accurate to less than half of a second. The only reason it needed to update so fast was because it looked awful when switching tabs, which will only be updated on the next fire. now switching tabs updates data instantly so theres no need to update the rest of the data quickly.
also makes each stat tab update into its own proc so we can tell how much each tab update costs
* Adds a subsystem to handle automated directional movement, replaces all instances of walk_towards with it. Makes meteors and immovable rods not drift in space, and makes immovable rods more destructive. Note, I've opted not to use byond's method of moving towards something, which is effectively Move(src, get_step(src, get_dir(src, target))) as it's cringe and doesn't make a smooth line. I've replaced it with a autoupdating rise over run setup, read the code for more details
* woop forgot the subsystem
* Documentation, contributing.md entry, and some cleanup
* Makes the moveloop datum more oop friendly, sets us up for a lot of conversions
* Converts the curseblob and walk_away() to the subsystem
* Changes the default for override from FALSE to TRUE
* converts walk() over, still need to add a replacement proc for it, but we didn't actually have anything that used the raw proc
* converts the rest of walk_to() over, nearing the end now
* cleans up some errors
* Fully documents everything, fills in some missing movement types, uses the power of oop to make things cleaner, and typepaths longer
* Finishes the contributing.md stuff
* Done
* Fefaults -> Defaults, can you tell I wrote this at 1AM?
* resolves bubblegum issues
* Roh's suggestions
Co-authored-by: Rohesie <rohesie@gmail.com>
* Cleanup
* Hey lemon, did you know that Destroy() lives on datums? ahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
* Converts over the discrepencies created in my absense
* HAHA FUCK YOU I PAY MY DUES
* Whoops lost some stuff in the merge
* Converts the system from seconds to deciseconds to make dealing with the api more sane
* Some stuff I missed
* Makes movement an inheritable subsystem type, splits the moveloop file into two, one for the subsystem, and one for the datums
* Makes a subsystem that handles directing movers out to other subsystems. It's a bit bad right now, but it's a
good first step. I think I'll move the move loop datum to a lazy var on mobs instead of an assoc list, don't
like lists.
Also makes the movement procs global, I'll move em to the /movement subsystem at some point or something like
that
* Converts the existing uses of the procs over to the new format
* Adds support for subsystem precedence, so a type of A can override type B.
General cleanup, still kinda in debug mode but it's getting better
* I'll admit I'm not too familiar with this, but I think it will work
* Adds starting logic so movement types "pausing" makes any sense
Redoes how waiting is handled to make it based on world.time directly. I don't remember why. I think it's better
this way.
Adds a drifting movement type, moves space drift over to it.
Needs severe work before it's ready, too much info stored and modified on the moving object, see comment
Starts work on making drifting smooth
* Moves almost all space drifting vars over to signals on the movement datum
Properly implements glide size stuff for both the subsystem and the loops. Space drift will be smoother now.
It's not perfect, but it'll work just fine for now
Adds a way to override a client'd mob's glide size mid move, uses it to make entering a spacedrift look right
Adds a way to delay a client move outside of just move_delay, meant to be used for long periods, and setup such
that it doesn't make inputs persist
Adds flags to movement loops, alongside MOVELOOP_OVERRIDE_CLIENT_CONTROL, which blocks client movements while
the loop is firing, and for it's visual delay after
This means you can't exit a space drift until you hit the actual wall. This feels a lot better
Some general logic stuff, move() will return true/false if it succeeded or failed
Adds a stop_loop() proc that's called when a move loop is no longer active
Suck my nuts
* Moves precedence to the loop instead of the subsystem
* Moves drifting into a component, this lets me explictly block input after the move loop ends, so people can't
move the moment they functionally move onto a new tile
This is a bit underdeveloped currently, but that's a problem for another day
Cleans up some uses of move procs, fixes runtimes in metoer and curseblob code
Adds signals for stopping/starting a move loop, sending one for destroy is redundant.
Moves existing event signals from the movable being acted on to the loop itself, makes more sense this way
Makes the move handler return the created loop up the chain so we can register to it
Fixes a logic error in loop contesting code that lead to loops never actually being removed from subsystems
because they didn't know they should be.
Properly changes lifetime from a time to stop, to functionally an amount of moves to complete before stopping
Adds some new signals for pre/post loop process. This is to better tie into components.
I decided I didn't like the idea of tying all functionality to the loops themselves
The loop decides functionally how to move, components or just tied in signals can decide when/when not to move
and can modify properties of the loop
Making a new loop for things like atmos drift, something I'm interested in tackling in the future, seemed silly
* Moves movement procs directly to the subsystem for better namespacing or whatever
* Moves movement packets onto /atom/movable, no longer need the debugging
I've decided to not just put their contents fully onto atom movable, since it makes debugging on live much
harder, can't sdql for them anymore.
Fixes a runtime in meteor code, properly this time
Fixes a logic error in stop_looping
Makes move manager NO_INIT, because well, it doesn't init
* Commits human sin, makes Recover() work properly for movement subsystems
* Fixes immovable rod orbits not always working, they were returning too early in moved and fucking up the var we use to track move count, and thus not sending a signal properly
* Reworks the curseblob to use signals more, and to not use override
* Missed this in the movement ss commit
* Removes override, makes having a higher or equal precedence take its place
* Updates documentation
* Cleans up some unused defines
* Nukes the unused flags option
* Whoops forgot to qdel check
* Removes an unused var I had for client move prevention before I started using a component
* Let's do this properly
* Modernizes meteor code to better match how explosions actually work currently
* Some more cleanup
* Cleans up effect code a little bit
Nukes the effect system's sleep loop, we use movement loops instead
As a part of that, instead of 1 timer per effect spawned, we react to loop failure and make it 1 timer per
effect system
This should reduce the amoumt of slowdown we see after mass lighting break
It's not everything, we're still making a timer per spark effect, but it cuts things down significantly
* Updates explosions to not sleep
* Adds support for modifying a loops delay post process, makes extinguisher code suck less then it does currently, nukes some more sleeps and timer loops
* Converts water tank resin over to move loops rather then sleeps, minor behavior change mind, the cooldown starts on fire rather then on land, but I think that makes more sense anyway
* compile and runtime fix
* Fixes some runtimes, cleans up some code, ensures feature parity when it comes to logging
* Prevents resin foam from space drifting
* Adds support for flags back into the system, I need it for reasons
* Updates move_towards to fix some bugs and resolve some inconsistent behavior, implements a flag that makes a loop's first move start instantly
* Fixes extinguishers not actually transfering any reagents
* Converts sprays to the new system. This does actually minorly change behavior, in that I've changed the order of spray actions from step -> sleep -> wash to step -> wash -> sleep, but I'm not terribly torn up about it because frankly I think it feels better
* Converts grav catapults over to the new system
* Converts trays over to moveloops
* Converts robot streaking to move loops, the other two coming soon
* Compile you won't. Also fixes a behavior issue with oil streaks
* Does directional step_to properly, cleans up the other two streaking types
* Converts step_trigger over, not that it's actually used anywhere. Changes how stoping a move works, you need to explicitly qdel, other the step is just considered to be ignored. This will make life easier later
* Adds a jps movement loop. It's a bit bloaty, id is stupid, but it'll work just fine
* Makes the system support passing in a datum that's just used as extra context for the move. The hope is this makes signalizing things less of an absolute headache
* Begins the conversion of ai movement datums to movement loops
* These two are reasonably simple, only weird thing I'm doing is A: Not allowing target hotswapping, which I hope none is doing, and B: passing the controller into the move loop as extra context so things work properly
* JPS is a bit more complex, partially because the old implementation was a bit weird. 2 major things. 1: I'm dropping what I think was a redundant behavior minimum distance check from the premove bit of logic, since I'm pretty sure it didn't do anything. 2, instead of just stoping the step in an error state like being pulled, we count it against our max move total
* Audit
* Moves most forced movement to the framework, adds some components to make things nicer
* Implements a flag that makes the loop always operate, regardless of precedence and without impacting any other loops
* Moves movement subsystems into the right folder
* Hey potato what if you had two procs that did the same thing and one called the other? Wow it's useless
* Merges slipping and force movement
* Converys conveyors over to the system. It's a bit fragile, but I think it's totally worth it to save the sleep loop
* Precedence -> Priority, cleans up some logic errors, makes priority highest to lowest instead of lowest to highest, straight cleans some code up
* Makes poly and bubbles ignore spacedrift, now that precedence actually functions properly. I'm likely missing cases of this, will deal with it later
* Depression, thy name is linter
* Fixes linter, and hopefully fixes the runtimes in ci too
* Wew
* Sets sprays and extinguishers back to legacy, since people do actually seem to have noticed
* Spelling errors my beloved
Co-authored-by: Kylerace <kylerlumpkin1@gmail.com>
* More detail, moves return descriptions
* Converts transit tubes to the system?
* Adds the glide size modifier. Not honestly sure that this should be default, considering how crummy it makes things look for normal walking, but it's useful as hell here
* Adds a force move in dir template, actual support for fast initial steps (wtf old me) and a helper proc for setting delay
* Cleans up displosal code a bit, I thought about adding it to the system but it would functionally be just 'disposal loops'. Maybe I'll make a template subtype? not sure how I want to handle stuff like this
* Cleans up mob movement a bit
* Let's use the controller's visual delay
* Makes the resin thrower nicer, cries
* Cleans up some comments, replaces an implicit world.icon_size with an explicit one, fixes up a typecheck
* typecache instead of double istype. Can't do much about the !atom/movable, list would be too big I feel
* hhh
* bro wtf
* Documents the why of SS_TICKER
* Puts SSmovement on SS_TICKER. Lets us support tick steps
* Cleans up the charge action. Makes it use moveloops
* Fixes CI? kinda worried that this just got dropped
* Converts disposal pipes to move loops. They stutter a bit more then usual as of now, hoping that's a me thing, if it's not I'ma look at uping the priority of the base subsystem
* Moves the move subsystems off background, puts some on ssticker
* Prevents some things that shouldn't move in space from moving in space
* Documents the general form and usage of the system
* Virgin one vs chad once
Co-authored-by: Kylerace <kylerlumpkin1@gmail.com>
* Removes unneeded check
* Moves appropriate movement subsystems into SS_BACKGROUND. Removes redundant SS_KEEP_TIMINGs
I do want the behavior of SS_TICKER, which at this point is tick based waits, and ignoring overtime when
calculating next fire.
Since honestly, these subsystems should ignore overtime in regards to next fire, the cost of moving A may be
nothing compared to the cost of moving B.
* Makes the MODULUS macro use floor. I knew our coders would never let me down, glad this exists, thanks ninja
Fixes teleporting caused by shitty round() behavior, adds a "you hit your target" case to homing loops
* Converts blood splatters to move loops, that'll do it
Co-authored-by: Rohesie <rohesie@gmail.com>
Co-authored-by: Kylerace <kylerlumpkin1@gmail.com>
I'm refactoring proximity monitors and fields, removing lots of bloat from both that's hardly even used. Proximity monitors no longer generate effect objects to track the surrounding area, should be less cpu expensive and easier to maintain (or phase out), read and use.
This PR also adds a couple components which may be needed for future stuff (for starters, the mirror reflection PR #62638 could use the connect_range comp)
Improving old old, ugly old code and adding some useful backend components. Tested and working.
About The Pull Request
A circuit and shell components have been added to Synthesizers (headphones and spacepods included, though with a reduced capacity because of their size), so they can now be used for wiremod. Just like for instant cameras, no shell design here. They are meant to be found in dorms or maybe ordered from cargo.
Why It's Good For The Game
The station outside the sci department has plenty of USB ports stuff but is lacking when it comes to circuits shell. This is another small step toward a better and more applicable wiremod.
Changelog
cl
expansion: Synthesizers and headphones can now have circuits installed.
/cl
Renames conveyor2.dm to conveyor.dm, and removes the historical comment about "new conveyor belts". As a reminder, comments should be about what the code is now, not what it used to be. (Muh history -Lemon)
Moves conveyor belts to their own SS with an identical wait. It is very common, as an admin, for me to want to adjust conveyor belt processing, either to make it faster (for laughs) or to disable it when it is causing heavy lag. It is very difficult to do this (especially the former) because it just uses fast process.