## About The Pull Request
The map loading function was ignoring JSON values when a map's config
file was custom loaded. (things like - minetype, planetary, etc.)
To resolve this I just made the loadConfig return a json and then use
that json.
## Why It's Good For The Game
Better custom map support!
## Changelog
🆑
fix: Fix custom map loading ignoring JSON values that were ignored
previously. (minetype, planetary, etc.)
/🆑
## 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
Per DarkenedEarth's request on discord, adds a new Fun menu secret which
makes the shuttle go back to the station after a configurable delay with
an announcement (also configurable). After docking at the station it
behaves like BYOS (still requiring to wait for it's arrival despite it
being docked).
## Why It's Good For The Game
Admins want it to hunt early EORGers or make events or something like
that.
## Changelog
🆑
admin: Admins can now return the shuttle back to the station without
ending the round
/🆑
## About The Pull Request
Rewrite ticker `Reboot` proc slightly to use a timer and callback for
the delay before the reboot, tracks this timer in the stat panel for
players to see. Also adds a verb to cancel a pending reboot independent
of the delay round end verb.
## Why It's Good For The Game
It's nice to be able to see exactly how much time is left until the
server restarts, and it's even nicer to see that the round end has been
delayed when the "admin has delayed round end" message gets buried in a
fast moving chat.
## Changelog
🆑
qol: The time until the server reboots is now visible in the status tab.
admin: Added a cancel reboot verb to the server tab.
/🆑
## About The Pull Request
Addition to [#84910](https://github.com/tgstation/tgstation/pull/84910)
Added a "print" button to the request manager. It simply prints at the
centcom station the paper that was faxed to the admins.
Also added "Auto-print Faxes" button to the request manager, which
allows you to enable automatic printing of requests on the admin fax
<details>
<summary>Screenshots</summary>



</details>
## Why It's Good For The Game
The message in the chat may get lost. In this case, it will no longer be
possible to print the paper sent to the CC
Changing the allow_exotic_faxes variable will allow you to fax something
unusual to the station in (very rare) situations. No need to manually
change this variable
## Changelog
🆑
add: added a "print" button to the request manager
add: admin fax can now send exotic items
add: added "Auto-print Faxes" button to the request manager, which
allows you to enable automatic printing of requests on the admin fax
fix: fixed a bug where pressing the print button would cause the receive
animation to appear on all admin faxes.
/🆑
## About The Pull Request
- Fixes#87829
Ensures we can't enter invalid values that actually run timed in this
specific case
## Changelog
🆑
fix: greyscale modify menu has better validation for player entered
colours
/🆑
bounty pr
## About The Pull Request
Lets anyone with permissions verify any admin past 2fa, not just ones
lower than them on the ~totem~ permission pole.
## Why It's Good For The Game

(also fixes an exploit where you could action protected admins who were
deadmined because `D` wouldn't be set by that point.)
Closes#88283
Closes https://github.com/tgstation/tgstation/issues/88320
Fixes a harddel caused by the limp status effect not being properly
deleted
Reduces update-body calls in:
- Initialize from 4 to 1
- On z-level change from 2 to 1
- On move with bloody shoes from 1 to 0
Mostly by just passing along the proper argument and removing seemingly
unnecessary update body calls
## About The Pull Request
`boldannounce` is NOT for use ICly it's only for OOC stuff. `bolddanger`
is identical it just doesn't carry the same baggage
## Changelog
🆑 Melbert
fix: Stuff like the SM exploding will no longer output to your OOC tab
/🆑
## About The Pull Request
~~Kept you waitin huh!~~
The projectile refactor is finally here, 4 years later. This PR (almost)
completely rewrites projectile logic to be more maintainable and
performant.
### Key changes:
* Instead of moving by a fixed amount of pixels, potentially skipping
tile corners and being performance-heavy, projectiles now use
raymarching in order to teleport through tiles and only visually animate
themselves. This allows us to do custom per-projectile animations and
makes the code much more reliable, sane and maintainable. You (did not)
serve us well, pixel_move.
* Speed variable now measures how many tiles (if SSprojectiles has
default values) a projectile passes in a tick instead of being a magical
Kevinz Unit™️ coefficient. pixel_speed_multiplier has been retired
because it never had a right to exist in the first place. __This means
that downstreams will need to set all of their custom projectiles' speed
values to ``pixel_speed_multiplier / speed``__ in order to prevent
projectiles from inverting their speed.
* Hitscans no longer operate with spartial vectors and instead only
store key points in which the projectile impacted something or changed
its angle. This should similarly make the code much easier to work with,
as well as fixing some visual jank due to incorrect calculations.
* Projectiles only delete themselves the ***next*** tick after impacting
something or reaching their maximum range. Doing so allows them to
finish their impact animation and hide themselves between ticks via
animation chains. This means that projectiles no longer disappear ~a
tile before hitting their target, and that we can finally make impact
markers be consistent with where the projectile actually landed instead
of being entirely random.
<details>
<summary>Here is an example of how this affects our slowest-moving
projectile: Magic Missiles.</summary>
Before:
https://github.com/user-attachments/assets/06b3a980-4701-4aeb-aa3e-e21cd056020e
After:
https://github.com/user-attachments/assets/abe8ed5c-4b81-4120-8d2f-cf16ff5be915
</details>
<details>
<summary>And here is a much faster, and currently jankier, disabler
SMG.</summary>
Before:
https://github.com/user-attachments/assets/2d84aef1-0c83-44ef-a698-8ec716587348
After:
https://github.com/user-attachments/assets/2e7c1336-f611-404f-b3ff-87433398d238
</details>
### But how will this affect the ~~trout population~~ gameplay?
Beyond improved visuals, smoother movement and a few minor bugfixes,
this should not have a major gameplay impact. If something changed its
behavior in an unexpected way or started looking odd, please make an
issue report.
Projectile impacts should now be consistent with their visual position,
so hitting and dodging shots should be slightly easier and more
intuitive.
This PR should be testmerged extensively due to the amount of changes it
brings and considerable difficulty in reviewing them. Please contact me
to ensure its good to merge.
Closes#71822Closes#78547Closes#78871Closes#83901Closes#87802Closes#88073
## Why It's Good For The Game
Our core projectile code is an ungodly abomination that nobody except
me, Kapu and Potato dared to poke in the past months (potentially
longer). It is laggy, overcomplicated and absolutely unmaintaineable -
while a lot of decisions made sense 4 years ago when we were attempting
to introduce pixel movement, nowadays they are only acting as major
roadblocks for any contributor who is attempting to make projectile
behavior that differs from normal in any way.
Huge thanks to Kapu and Potato (Lemon) on the discord for providing
insights, ideas and advice throughout the past months regarding
potential improvements to projectile code, almost all of which made it
in.
## Changelog
🆑
qol: Projectiles now visually impact their targets instead of
disappearing about a tile short of it.
fix: Fixed multiple minor issues with projectile behavior
refactor: Completely rewrote almost all of our projectile code - if
anything broke or started looking/behaving oddly, make an issue report!
/🆑
## About The Pull Request
Title. I may have been wrong about how depended on this behaviour was
Also, uh, fixes#87986
## Why It's Good For The Game
trim_reduced no longer needs to exist because trimtext() does it faster,
and there's no reason to have a special proc if trim just calls that
proc anyways. I sincerely doubt the proc overhead is so severe that we
need another proc that will ever only be called directly 3 times in the
code.
Since trimtext() does something we don't expect, it's better to just
have SDQL2 queries use trim() so we're all on the same page.
## Changelog
NO!!!
## About The Pull Request
Fixes issues with var typing and proc arguments, discovered using
OpenDream's WIP TypeMaker feature (using improvements I haven't PR'd
upstream yet).
## Why It's Good For The Game
Codebase maintenance.
## About The Pull Request
Was investigating some stuff downstream related to undeleted SQL
queries, and these two queries were related.
thought it'd be best to make them not block
`/client/proc/set_client_age_from_db`, as the results are never checked
anyways, not even for errors.
I've added a new proc to SSdbcore, `FireAndForget` - takes the same
parameters as NewQuery, but instead of returning the query, it just
asynchronously executes and then deletes it.
## Why It's Good For The Game
less undeleted sql queries, less blocking. yay?
## Changelog
does this count as user-facing? unsure how i'd changelog this tbh
## About The Pull Request
This adds plenty of useful stuff regarding byond-tracy, altho mostly
focused on the [Paradise
fork](https://github.com/ParadiseSS13/byond-tracy).
- Adds two new config options **(THEY ARE DISABLED BY DEFAULT)**
- `ALLOW_TRACY_START` gives admins with +DEBUG the "Run Tracy Now" verb,
which will allow them to start profiling with byond-tracy mid-round.
- `ALLOW_TRACY_QUEUE` gives admins with +DEBUG the "Toggle Tracy Next
Round" verb, which will initialize byond-tracy during world init the
next round (in the same way as passing `-params tracy` or defining
`USE_BYOND_TRACY`)
- If byond-tracy fails to initialize, the error will be logged and
available to view for the whole round.
- If `MC_TAB_TRACY_INFO` is defined, information about byond-tracy now
appears in the MC tab - if it's running or not, if it errored (and what
the error is), why it's running, if its queued for next round, etc.
- byond-tracy is now properly shut down when the world shuts
down/reboots, minimizing the risk of data loss or crashing
- More info regarding byond-tracy init is sent to `world.log`
## Why It's Good For The Game
Profiling is super helpful, and this should make things quite easier
## Changelog
No user-facing changes
## About The Pull Request
existance doesnt exist so i changed it to existence
## Why It's Good For The Game
existance dosent exist
## Changelog
🆑
spellcheck: spellecheck: existence not existance
/🆑
## Why It's Good For The Game
Clarity and consistency regarding DM's systems.
Internally, `eye` is used for anything that controls the client's view.

How `eye` is used in DM is consistent with how we use the term, so I
figured this would add clarity.
Being named mob/camera also makes it unclear exactly what it's doing.
The name implies that it would function similar to how mob/camera/ai_eye
does, but most of the time it's only used as... an eye.
My ulterior reason for this PR is that I want to clean up
mob/camera/ai_eye and it's subtypes after this.
## Changelog
🆑
server: mob/camera has been renamed to mob/eye, which may break
downstreams
/🆑
---------
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
## About The Pull Request
Adds a ternary statement to the logging for adding admin remarks (notes,
messages, watchlists) to specify if a note is secret.
No change to actual administrative functions, just the logging.
## Why It's Good For The Game
Accurately reflects the note added!
## Changelog
🆑
admin: When a secret note is applied, it'll now be logged as a secret
note (instead of appearing like a regular note).
/🆑
## About The Pull Request
Fixed being unable to aghost while corpselocked, via adding another
parameter to ghostize that checks if it's an aghost or not
## Why It's Good For The Game
i wana leave my body when testing as ethereal
## Changelog
🆑
fix: Fixed being unable to aghost while corpselocked
/🆑
## About The Pull Request
This PR kills the abstract internal and external typepaths for organs,
now replaced by an EXTERNAL_ORGAN flag to distinguish the two kinds.
This PR also fixes fox ears (from #87162, no tail is added) and
mushpeople's caps (they should be red, the screenshot is a tad
outdated).
And yes, you can now use a hair dye spray to recolor body parts like
most tails, podpeople hair, mushpeople caps and cat ears. The process
can be reversed by using the spray again.
## Why It's Good For The Game
Time-Green put some effort during the last few months to untie functions
and mechanics from external/internal organ pathing. Now, all that this
pathing is good for are a few typechecks, easily replaceable with
bitflags.
Also podpeople and mushpeople need a way to recolor their "hair". This
kind of applies to fish tails from the fish infusion, which colors can't
be selected right now. The rest is just there if you ever want to
recolor your lizard tail for some reason.
Proof of testing btw (screenshot taken before mushpeople cap fix, right
side has dyed body parts, moth can't be dyed, they're already fabolous):

## Changelog
🆑
code: Removed internal/external pathing from organs in favor of a bit
flag. Hopefully this shouldn't break anything about organs.
fix: Fixed invisible fox ears.
fix: Fixed mushpeople caps not being colored red by default.
add: You can now dye most tails, podpeople hair, mushpeople caps etc.
with a hair dye spray.
/🆑
## About The Pull Request
Previous attempt - https://github.com/tgstation/tgstation/pull/87227
`/atom/proc/singularity_pull(obj/singularity/singularity, current_size)`
has first arg typed, but other procs were just referencing it as a
un-typed variable.
Since args are not standartized AND
`atom/proc/singularity_pull(obj/singularity/singularity, current_size)`
is out-dated, since it can be called by things that has
`/datum/component/singularity` - not just by
`obj/singularity/singularity` - This PR just adds args to every
`proc/singularity_pull()` as follows:
`proc/singularity_pull(atom/singularity, current_size)`
## Why It's Good For The Game
Standartization
## Changelog
No changelog needed
## About The Pull Request
BYOND added a native `trimtext` proc in 515, which as far as I know,
does the same thing as the `trim_reduced` proc - trims whitespace off
both ends of a string, but `trimtext` should be faster, as it's a
builtin rather than implemented in DM.
Also, added a global `_trimtext` proc, for use from SDQL2 or Lua, as
it's a builtin and can't be `call()`'d.
## Why It's Good For The Game
Micro-optimizations my beloved - especially since I imagine this proc is
called quite a lot, even if it doesn't really have a performance impact
anyways, but it can't hurt.
## Changelog
🆑
refactor: Refactored some text helper procs to use BYOND's native text
trimming proc.
admin: Added a _trimtext proc, for use with SDQL2 or Lua scripting.
/🆑
## About The Pull Request
Adds proper law logging to the law panel.
I asked Melbert if he wanted it inside silicon.log, admin.log, or both.
He said admin.log
## Why It's Good For The Game
Logging is good for adminbus and what can be high impact adminbus.
## Changelog
🆑
admin: The Law Panel now properly logs and communicates law edits.
/🆑
## About The Pull Request
This moves all the shuttle related admin verbs into its own category to
make it less cluttered. It was a PIA to debug shuttle related code while
having to hunt down these verbs.
## Why It's Good For The Game
Better UI.

## Changelog
🆑
admin: Organize admin verbs for shuttle events into shuttle category
/🆑
## About The Pull Request
Adds VV header for items, letting quick modification of a few of an
item's combat values..

## Why It's Good For The Game
In testing, I find I tweak these values commonly, to test how effective
an item is vs armor, or how strong a new item should be, etc etc. So
having quick access to these might be cool
I thought about adding a few more like throwforce but I didn't want to
clutter it too much
## Changelog
🆑 Melbert
admin: Items now have a header in VV allowing for quicker editing of
combat properties
/🆑
## About The Pull Request
Before there were two settings for human authority:
`ENFORCE_HUMAN_AUTHORITY` and `ENFORCE_HUMAN_AUTHORITY_ON_EVERYONE`
The first, if enabled, would not let non-humans be heads of staff unless
they had a specific var on their job set to TRUE.
The second, if enabled, would simply ignore that var and reject the
non-human anyways.
This PR replaces both of those settings with a single one,
`HUMAN_AUTHORITY`. You can set it to one of four settings:
* "OFF": human authority will be turned OFF. Non-Humans will be able to
be heads of staff.
* "HUMAN WHITELIST": human authority will be turned OFF, HOWEVER; if a
job has its new `human_authority` variable set to
`JOB_AUTHORITY_HUMANS_ONLY`, then whoever picks that job will be forced
to be human.
* "NON-HUMAN WHITELIST": human authority will be turned ON. However, if
a job has its `human_authority` variable set to
`JOB_AUTHORITY_NON_HUMANS_ALLOWED`, a non-human can become that job.
This is what we have now, it works the same as if
`ENFORCE_HUMAN_AUTHORITY` were turned on. This is also what I've set as
the default value.
* "ENFORCED" human authority will be turned ON. Non-Humans will never be
able to be heads of staff. This is what
`ENFORCE_HUMAN_AUTHORITY_ON_EVERYONE` used to do.
You can also now set the `human_authority` variable through
`jobconfig.toml`!
## Why It's Good For The Game
Allows more configuration options for downstreams, and lets keyholders
and headmins have more options over how to set up human authority.
## Changelog
🆑
config: Both human authority settings were combined into a singular one,
allowing for more flexibility
/🆑
---------
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
## About The Pull Request
Adds the following new general shuttle events:_
**Hitchhiker**
- 1% chance
- A single assistant in an EVA suit and some PBJs in a suitcase
**Assistant Wave**
- 0.1% chance
- Spawns 10 assistants with internals
- For clarity, they don't get sent to the shuttle, but get launched at
it from space. It's a scuffle of 10 assistants trying to get in without
being spaced or succumbing to the cold/pressure
**Intern Wave**
- Admin only
- Unarmed and armed version
- Spawns centcom interns, with a little announcement to warn they're
coming
I've also fixed projectiles bugging out and admin forced shuttle events
not activating if they were added after the shuttle launched
<details>
<summary>Admin only events added</summary>
**Nukie**
Spawns a single nukie, armed with a shotgun, pistol and edagger.
Basically the deathmatch nukie loadout, you dont want to fight this
**Meaty ores**
Meaty-ores meteors. Have a 4% chance to hit the shuttle, posing a
potential hazard
**3 player controlled fire-sharks**
3 fire sharks controlled by players. Not much to talk about here
**Fireball Wave**
Shoots a wave of fireballs at the shuttle. I think it's cool but
apparently shuttle walls and windows deflect fireballs so it's kind of
moot unless you're outside :/
</details>
## Why It's Good For The Game
The assistant and hitchhiker events are some flavoring that I thought up
a while ago. The Hitchhiker is just intentionally a flavor addition, but
the assistant wave and intern wave can be used by admins to repopulate
or retake the emergency shuttle as well.
## Changelog
🆑
add: Adds an assistant and hitchiker shuttle event, replenishing the
crew mid flight!
admin: Adds two intern wave shuttle events
code: You can now supply shuttle events with outfits!
code: You can now shoot projectiles with the shuttle events!
fix: Fixes projectiles bugging out when fired in shuttle transit space
fix: Fixes admin forced shuttle events not activating when added mid
transit
/🆑
## About The Pull Request
Changes map votes to be based on a persistent tally count.
Tallies for maps are cached between rounds and are added to by map
votes.
When a map is chosen, and it wasn't the only valid one, the tallies for
said chosen map will be reset.
Refactors map vote handling and moves it from SSmapping to SSmap_vote.
Rock the Vote has been removed as a result of this refactor.
## Why It's Good For The Game
Makes it more likely that all maps will be played over the course of a
server instead of always being truly random.
Removes some clutter off of SSmapping.
🆑
refactor: Map Votes are now carried over between rounds. When a map vote
is actually a contest, the winning map will have its votes reset.
/🆑
## About The Pull Request
Insert() does not return anything, replace_into relied on that so the
tool ended up just cutting out all the organs it was supposed to insert
after putting them in
## Changelog
🆑
admin: Fixed VV DNA infusion tool
/🆑
## About The Pull Request
123 changed files and multiple crashes after writing broken regex, I
replaced most remains of direct spans with macros. This cleans up the
code and makes it easier to work with in general, see justification for
the original PR. I also fixed a bunch of broken and/or unclosed spans
here too.
I intentionally avoided replacing spans with multiple classes (in most
cases) and spans in the middle of strings as it would impact readability
(in my opinion at least) and could be done later if required.
## Why It's Good For The Game
Cleaner code, actually using our macros, fixes borked HTML in some
places. See original PR.
## Changelog
Nothing player-facing
## 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
/🆑
Fixes#86784
## About The Pull Request
Although some of the issues found were a direct result from #86692
(c698196766), there was still 40% of
length-related issues that wouldn't be covered anyways that are fixed in
this PR. I.E.:
* Name inputs without `MAX_NAME_LEN`
* Desc inputs without `MAX_DESC_LEN`
* Plaque inputs without `MAX_PLAQUE_LEN`
* Some people just screwed up the arguments so it would prefill
something like "40" in the `default` var because they didn't name their
vars.
To help me audit I added a lot of `max_length` named arguments to help
people understand it better. I think it might be kinder to have a
wrapper that handles adding `MAX_MESSAGE_LEN` in a lot of these cases
but I think there is some reason for a coder to be cognitive about input
texts? Let me know what you think. I didn't update anything
admin-related from what I can recall, let me know if anything needs to
be unlimited again.
## Why It's Good For The Game
The change to `INFINITY` notwithstanding, there were still an abundance
of issues that we needed to check up on. A lot of these are filtered on
down the line but it is clear that there needs to be something to catch
these issues. Maybe we could lint to make `max_length` a mandatory
argument? I don't know if that's necessary at all but I think that the
limit should be set by the invoker due to the wide arrangement of cases
that this proc could be used in.
This could all be a big nothingburger if the aforementioned PR is
reverted but a big chunk of cases fixed in this PR need to be fixed
regardless of that since people could put in 1024 character names for
stuff like guardians (or more now with the change). Consider this
"revert agnostic".
## Changelog
🆑
fix: A lot of instances where you could fill in 1024-character names
(normal limit is 42) have been patched out, along with too-long plaque
names, too-long descriptions, and more.
/🆑
## About The Pull Request
GODMODE has a lot of sources that toggle it. From admin-stuff to status
effects, components, actions and mobs which are supposed to be
invincible. It's better off as a trait than a flag, so we can manage
these sources.
## Why It's Good For The Game
See above.
## Changelog
🆑
admin: godmode is now a datum trait instead of a bitflag. This means the
process for toggling it is a little different now.
/🆑
## About The Previous Pull Request
#85308 reverted by #85929

~~Causes the round to not start when a player isn't eligible for any
jobs at a specific priority level due to runtimes trying to `pick()`
from an empty list aborting the entire job assignment stack.~~
(Fixed???? by
e0e9f2f430)
Maybe we should test merge this for a mo just to make sure no more
cheeky runtimes pop up before merging.
## About The Pull Request
This PR does a couple of minor things:
Makes the job debug logging a bit easier to follow.
Minorly brings some SSjob code up to code standards, converting proc
names to snake_case and doing some otherm is cleanup.
Refactored some stuff into different procs, updated some comments.
And some major things:
Changes the job assignment logic.
Old behaviour
> Assign dynamic priority roles
> Force one Head of Staff (if possible)
> Assign all AIs
> Assign overflow roles (bugged in 2 ways)
> Shuffle the available jobs list once, at the start of the random job
assignment loop
> Pick and assign random jobs for random players from High prefs down,
with a priority on Head of Staff roles
> Handle everyone that couldn't be assigned a random job
New behaviour
> Assign dynamic priority roles
> Assign all Head of Staff roles to players with High prefs
> If no Head of Staff was made in the above way, force one Head of Staff
(if possible)
> Assign all AIs
> Assign overflow roles (fixed)
> Prioritise and fill unfilled head roles at each job priority pref
level, from High prefs down.
> Build a list of all jobs that each unassigned player could be eligible
for at the above pref level.
> Pick a job from that list at random and assign it to the player.
> Handle everyone that couldn't be assigned a random job.
In reality there should be little impact on overall job assignment, the
code changes read more as semantics. For example, the priority check for
filling Head slots will have the same candidate pool in both old and new
versions, but in the new version we're more clearly saying that Heads
are important and we want to prioritise filling them for the sake of
round progression even though the outcome in new and old is the same.
A key change will lead to an increase in assistants - Overflow fixes.
Currently the code block to do early assignments to the Overflow role
doesn't work - or works but not as you'd expect. The idea was is that
because enabling the Overflow role in the prefs menu is an On/Off toggle
that sets the job to High priority when enabled and prevents any other
High priority pref, players that have the Overflow role enabled will
**always** get it. It's their highest priority job with infinite slots.
So we do a pass right at the start to give everyone with the Overflow
role enabled that role and save us wasting time later on in random job
code giving them that same role but with more work.
The problem is the code for this only assigns the Overflow role to
people with it set to Low priority in their prefs, resulting in log
readouts like:
```
[2024-07-27 09:49:43.469] DEBUG-JOB: DO, Running Overflow Check 1
[2024-07-27 09:49:43.469] DEBUG-JOB: Running FOC, Job: /datum/job/assistant, Level: Low Priority
[2024-07-27 09:49:43.472] DEBUG-JOB: FOC player job enabled at wrong level, Player: Radioprague, TheirLevel: Medium Priority, ReqLevel: Low Priority
[2024-07-27 09:49:43.472] DEBUG-JOB: FOC player job enabled at wrong level, Player: Caluan, TheirLevel: High Priority, ReqLevel: Low Priority
[2024-07-27 09:49:43.473] DEBUG-JOB: FOC player job enabled at wrong level, Player: Caractaser, TheirLevel: High Priority, ReqLevel: Low Priority
[2024-07-27 09:49:43.473] DEBUG-JOB: FOC player job enabled at wrong level, Player: Apsua, TheirLevel: High Priority, ReqLevel: Low Priority
[2024-07-27 09:49:43.475] DEBUG-JOB: FOC player job enabled at wrong level, Player: Bebrus2, TheirLevel: Medium Priority, ReqLevel: Low Priority
[2024-07-27 09:49:43.475] DEBUG-JOB: AC1, Candidates: 0
```
Where nobody gets pre-assigned the overflow role because their prefs are
all set to the High priority from being toggled... Except wait a second,
some people have it at Medium priority when it should just be a No
Role/High Priority Role toggle?
And herein we meet a problem. My hypothesis is that traits and stuff
that change the overflow have allowed players to set the "ordinary"
overflow role of Assistant to Medium and/or Low priority.
This still shows as enabled in the prefs menu, but leads to an outcome
where a player with assistant enabled is assigned Cook instead.
```
[2024-07-27 09:49:47.775] DEBUG-JOB: DO, Running Overflow Check 1
[2024-07-27 09:49:47.775] DEBUG-JOB: Running FOC, Job: /datum/job/assistant, Level: Low Priority
...
[2024-07-27 09:49:43.475] DEBUG-JOB: FOC player job enabled at wrong level, Player: Bebrus2, TheirLevel: Medium Priority, ReqLevel: Low Priority
...
[2024-07-27 09:49:47.987] DEBUG-JOB: Running AR, Player: Bebrus2, Job: /datum/job/cook, LateJoin: 0
```
So players with the Overflow job pref set to Low (an unexpected state,
should be disabled or High) would be guaranteed to get that role if none
of the higher priority Head of Staff/AI/Dynamic roles took over via the
bugged "force overflow for people with the pref enabled" proc.
Players with the Overflow job pref set to High would be guaranteed to
get that role if none of the higher priority Head of Staff/AI/Dynamic
roles took over via the random job assignment code giving them their
Highest priority role thanks to the infinite job slots of the Overflow.
And players with the Overflow job pref set to Medium (an unexpected
state, should be disabled or High) would get Assistant if the shuffle
step of the available jobs list put Assisstant before any of the other
jobs they had prefs enabled for at Medium that weren't already filled,
otherwise they'd get another random job.
This code is now changed to ignore the priority the player has set when
looking for people to fill the overflow role. As long as it **is**
enabled, the player will get it unless they're forced into a dynamic
ruleset role (AI when malf rolls) or a Head of Staff role due to their
other prefs (they have RD set to med or low, and no other player has a
Head of Staff at high so they get randomly picked and miss the overflow
role).
This will increase the number of assistants in shifts where their pref
state has Assisstant in the bugged Medium priority, but doesn't change
it for bugged Low and not-bugged High/On priority.
On the other side of the coin, we have how the random jobs are picked.
They're kinda not random, and I noticed this reading the logs then
reading the code.
The list of available jobs to pick from is randomly shuffled - but only
**once**. All players pull from a list of jobs in the same order. So you
end up with a log block like this:
```
[2024-07-27 09:49:47.985] DEBUG-JOB: DO pass, Player: Pierow, Level:3, Job:Botanist
[2024-07-27 09:49:47.985] DEBUG-JOB: Running AR, Player: Pierow, Job: /datum/job/botanist, LateJoin: 0
[2024-07-27 09:49:47.985] DEBUG-JOB: Player: Pierow is now Rank: Botanist, JCP:0, JPL:2
[2024-07-27 09:49:47.986] DEBUG-JOB: DO pass, Player: Daddos, Level:3, Job:Botanist
[2024-07-27 09:49:47.986] DEBUG-JOB: Running AR, Player: Daddos, Job: /datum/job/botanist, LateJoin: 0
[2024-07-27 09:49:47.986] DEBUG-JOB: Player: Daddos is now Rank: Botanist, JCP:1, JPL:2
[2024-07-27 09:49:47.986] DEBUG-JOB: FOC job filled and not overflow, Player: Bebrus2, Job: /datum/job/botanist, Current: 2, Limit: 2
[2024-07-27 09:49:47.987] DEBUG-JOB: FOC player job not enabled, Player: Bebrus2
[2024-07-27 09:49:47.987] DEBUG-JOB: DO pass, Player: Bebrus2, Level:3, Job:Cook
[2024-07-27 09:49:47.987] DEBUG-JOB: Running AR, Player: Bebrus2, Job: /datum/job/cook, LateJoin: 0
[2024-07-27 09:49:47.988] DEBUG-JOB: Player: Bebrus2 is now Rank: Cook, JCP:0, JPL:1
[2024-07-27 09:49:47.988] DEBUG-JOB: FOC player job not enabled, Player: Redwizz
[2024-07-27 09:49:47.988] DEBUG-JOB: FOC job filled and not overflow, Player: Redwizz, Job: /datum/job/cook, Current: 1, Limit: 1
```
The list is shuffled into an order of something like `list("Scientist",
"Botanist", "Cook", "Sec Officer", ...)` then iterated over for each
player. So every random job selection goes:
> "Does Player1 have Scientist enabled and at the right priority? No?
Okay, Botanist? Yes? You get botanist."
> "Does Player2 have Scientist enabled and at the right priority? No?
Okay, Botanist? Yes? You get botanist."
> "Does Player3 have Scientist enabled and at the right priority? No?
Okay, Botanist has no slots left so we'll remove it from the list. Okay,
Cook? Yes? You get cook."
> "Does Player4 have Scientist enabled and at the right priority? No?
Okay, Cook has no slots left so we'll remove it from the list. Okay, Sec
Officer? ..."
This can lead to stacked individual departments if it gets randomly
rolled to the start of the list in the shuffle, and completely empty
departments if they end up at the end.
On high pop shifts this is probably less of an issue. Player prefs add
noise to this and as departments at the front fill up, those at the back
pick up some of the lower pref players.
But have you ever had a shift where there's just like... No fucking sec
even though there's tons of players? The logging (before I made changes
in this PR) was a bit ass, but my hypothesis there is that sec officer
was shuffled right at the end of the random job list, so every other
department was filled up before sec officers were picked.
To mitigate this, I made the list shuffle every single time the game
picks a random available job for the player. This should lead to a more
balanced selection of available jobs by avoiding situations where the
code is biased towards packing some departments by accident.
## Why It's Good For The Game
Overflow fixes mean people who go to their prefs and see the Overflow
Role is On will all have the same experience - They will be the Overflow
role.
More random random job selection should prevent individual departments
having a jobs be stacked when it would have otherwise been possible for
a more balanced selection but the code unintentially biased random
departments to be overstaffed and understaffed each shift.
## Changelog
🆑
fix: Having the Overflow Role set to On will properly ensure you get
that role at a High priority as intended by the game code.
fix: Job selection is now a little bit more random. Fixes an
unintentional bias in random job assignment that could lead to
feast-or-famine for roles where everyone is assigned one job and nobody
is assigned another job.
/🆑
## About The Pull Request
Fixes several errors to spelling, grammar, and punctuation.
## Why It's Good For The Game
Improves readability and user experience.
## Changelog
🆑
spellcheck: fixed a few typos
/🆑
## About The Pull Request
Closes#86567
Don't think any of these were found/reported or actually could trigger
in-game
## Why It's Good For The Game
Glory to OpenDream
## Changelog
🆑
code: Fixed multiple minor logic issues with code found by OpenDream's
new pragma
/🆑
## About The Pull Request
Currently, if dreamluau is absent (which it might be on linux instances
that don't automatically download it), every `call_ext` call runtimes,
crashing the calling proc. This fixes that by using a flag that skips
calling `call_ext` if unset.
## Why It's Good For The Game
Apparently this could really bork the garbage collection subsystem, so
fixing it is a really good idea.
## Changelog
Does this even count as a player-facing change?
## About The Pull Request
Fixes several errors to spelling, grammar, and punctuation.
## Why It's Good For The Game
## Changelog
🆑
spellcheck: fixed a few typos
/🆑