84 Commits

Author SHA1 Message Date
MrMelbert 79cdde5b4e Head revs get codewords, rev antag info panel (#96425) 2026-06-17 22:37:58 +10:00
Wisemonster 370a529ace Changes slaughter/laughter demons to use sentient mob pref (#96342) 2026-06-05 11:55:34 -04:00
MrMelbert 6b631cb2c2 Roundstart nuke ops now spawn on an elevator to wait while the base loads in (#96178) 2026-06-02 20:59:42 +10:00
Leland Kemble 41ce7bf46c fixes second-choice headrevs having their preferences ignored (#95751)
## About The Pull Request

Second-choice headrevs after a first choice became indisposed did not
check client preferences.
Also, moves `ROLE_HEAD_REV` define into roundstart section of defines
because it is a roundstart ruleset

## Why It's Good For The Game

fixes #95742
2026-04-13 12:37:10 -05:00
MrMelbert fbfacd2792 Let's make sure solo rulesets work too (#95694) 2026-04-10 00:53:11 +02:00
MrMelbert a3bfe66765 Fixes wizard, cult, nukies, revs, and malf from unable to be be rolled roundstart (#95609)
## About The Pull Request

#94899 did not fix all instances where `pick_roundstart_rulesets` added
rulesets to the list

## Changelog

🆑 Melbert
fix: Fixes wizard, cult, nukies, revs, and malf being unable to be
selected for roundstart antag (yes, you read that right)
/🆑
2026-04-02 23:30:43 -04:00
MrMelbert f94302188b Admins can actually ban from recovered crew, blood worm, fugitive(/hunter), paradox clone, monkey helmet, glitch (#95522)
## About The Pull Request

`ROLE_RECOVERED_CREW` jobban flag was used for recovered crew,
experimental cloner, and now Thantorenasia, but it was never actually an
option in the banning panel. Now it is.

While investigating this, I noticed there was several polls that checked
for an role that you couldn't ban from, so they were either added or
folded into a different preference. (Blood worms, fugitive, fugitive
hunter, paradox clone, glitch, monkey helmet)

## Changelog
🆑 Melbert
admin: Admins can ban from "recovered crew", "blood worm", "fugitive" /
"fugitive hunter", "glitch", and "paradox clone"
admin: Mind Magnification Monkeys are now affected by a sentience ban
(previously unbannable)
/🆑
2026-03-29 17:10:39 +01:00
LemonInTheDark f2360d64fd Gives subsystem controllers a bitfield def to make vv easier, renames their flags var (#95439) 2026-03-22 19:06:30 -04:00
theOOZ 5464a0225b [NO GBP] Fixes queue'ing of roundstart ruleset (#94899)
## About The Pull Request

https://github.com/tgstation/tgstation/pull/94843 broke the queue'ing of
roundstart rulesets by handing the proc which processes this instances
while it expected typepaths.

## Why It's Good For The Game

Sorry!
2026-01-19 12:20:42 -06:00
RikuTheKiller c7e4e90004 Adds a new antag, the Blood Worm (#93787)
## LTS Document

Check this document before making any significant future changes to
blood worms, please.

https://hackmd.io/@RikuTheKiller/H1AHQSKNZx

## About The Pull Request

THIS PR SHOULD ABSOLUTELY BE TM'D FIRST

Blood worms are a new progression antag. When the event runs, 2
candidates are picked from ghosts and spawned in as blood worm
hatchlings, which then have to grow up, do a couple objectives and take
over the station.

Hatchlings are weak outside of a host, while juveniles can stand their
own reasonably well. Adults have high offensive power and can only be
dealt with using the right gear or a lot of luck and robustness. They're
meant to be a moment of glory for achieving maximum progression and they
can bootstrap the next hatchlings by gathering corpses before cocooning.

Each growth stage requires 30 seconds in a cocoon, which can only be
created after consuming a lot of blood. There's a falloff curve on a
per-blood-type basis, meaning you can't drain the same person over and
over again to reach adulthood. The medbay freezer is a priority target
for the blood worms and can get one of them to the juvenile stage if
fully ransacked.

It takes 500 blood to mature from hatchling to juvenile, and 1500 blood
to mature from juvenile to adult. You can only get up to 1000 blood from
synthetic sources like monkeys, and consuming synthetic blood is 30%
less efficient. Blood worms can also examine living targets to see how
much blood a target has, and how much growth the blood worm would gain
for consuming that blood.

Blood worms spawn in vents and have night vision for maneuvering in
maintenance. Hatchlings can ventcrawl, while juveniles can move around
by breaking things. Optionally, you can take over a host with a lot of
access like the Captain to go basically anywhere, especially if nobody
knows you killed the captain.

Behind the scenes, host-taking kicks the host's original mind to a
backseat mob. This needs the most testing in practice, but it's
confirmed that it returns the host's mind back to their body, at least
in testing.

All mob, ability and action sprites are made by INFRARED_BARON. Legal
rights were transferred to me after I paid for the commission.

Note, I've been working on this massive PR for quite a while, so
documenting every small change is really hard! Apologies for anything
I've missed. There's a lot.

Final note, admins can spawn these by either:
A. Trigger the midround event via the dynamic-panel verb, under the
Rulesets tab.
B. Giving someone the Blood Worm antag datum via the Traitor Panel in
the Player Panel for the target player. This will transform their mob
into a valid Blood Worm, with all of the associated objectives and such.

### Active Abilities
1. Leech Blood (No Host) - Lets the blood worm drain blood from living
targets and reagent containers. Uses an aggressive grab to restrain
living targets until leeching is over, which takes around a second to
initiate. Causes oxyloss during the leeching. NPC monkeys can't escape
from this and it floors targets as well.
2. Spit Blood (Both) - Multi-function ability, lets the blood worm fire
ranged corrosive blood spit at targets, melt restraints on their hosts
by right-clicking, and as an adult, shoot a burst of blood spit at a
target by right-clicking. Note of the right-click abilities, shooting
bursts can't be done while in a host. (to avoid unfair stealth kills)
Shooting a burst has a much longer cooldown than shooting normally. All
spit types cost blood to use.
3. Invade Corpse (No Host) - Lets the blood worm take a host for
themselves, consuming all of the host's blood and in essence, "becoming"
the host. Any bloodloss inflicted on the host is taken as damage to the
blood worm, and the blood worm retains its weakness to fire even in this
state. Burn damage itself no longer has any extra damage, though.
4. Leave Host (Host) - Title, literally just leaves the host after a
delay. Notably works even while the host is moving, dead, incapacitated
or otherwise fucked up in any way, shape or form.
5. Inject Blood (Host) - Lets the blood worm heal its host. The potency
of this increases as the worm grows up, but so does the cooldown and
blood consumption. This works on organ damage, injuries, etc.
6. Mature (No Host) - Makes the blood worm enter a cocoon for 30
seconds, emerging as the next growth stage. Requires an increasing
amount of consumed blood / growth as the blood worm uses it.
7. Reproduce (No Host, Adult Only) - Makes the blood worm enter a cocoon
for 30 seconds, with 4 hatchlings emerging out of it, including the
original blood worm, now reverted back into a hatchling as well.
8. Revive Host (Host) - If the host is in a viable state to be revived,
revives them after an animation sequence plays out.

### Passive Abilities
1. Space Immunity - Blood worms are immune to the cold, low pressures
and a lack of oxygen. Only the immunity to a lack of oxygen carries on
to hosts from this.
2. Organ Insertion - Blood worms can insert organs into their hosts by
right-clicking on them with the organ in-hand. This mainly exists to
deal with hosts that lack organs, and avoids the gotcha where an adult
blood worm ends up gutting their host by hitting them too hard, as they
can simply fix it on the spot.
3. Life Support - Blood worm hosts don't need a heart, lungs or a liver
to survive. Lungs are useful for speaking, and a liver is necessary to
process reagents.
4. Regeneration - Blood worms slowly heal over time. This is nowhere
near enough to overcome bleeding or heat damage, since it's 0.3 hp/s for
a hatchling, 0.4 hp/s for a juvenile and 0.5 hp/s for an adult.
5. Night Vision - Blood worms can see in the dark. This doesn't extend
to hosts.
6. Ventcrawling - Hatchling blood worms can ventcrawl.
7. Doorcrawling - Hatchling and juvenile blood worms can slide under
doors. Doing so takes 3 seconds for a hatchling and 5 seconds for a
juvenile.
8. HUD - Blood worms can tell how much blood targets have at a glance,
via a blood HUD bar exclusive to them. They can also tell apart other
blood worm hosts from normal people via an antag HUD. There's also an
examine message they can use on living targets for even more info.

### Weaknesses
1. Heat and Fire - Blood worms quickly die to heat, their bodies are
flammable and their blood will burn up if their host's core temperature
is too high. The main counter to this is getting a host with
flame-resistant gear.
2. Bleeding - While in a host, bleeding wounds will directly damage the
blood worm itself. How much a host needs to bleed before the worm dies
depends on their growth stage. Blood worm hosts keep bleeding even while
dead, so just keep hitting them and they'll die. Blood worms
automatically leave their hosts when they hit 10% health or lower, and
their hosts bleed 50% faster than normal people.
3. Stuns - Blood worms have no way of dealing with a stunned host other
than getting out. They can deal with any restraints by melting them,
though.
4. Testing - Security can order a blood worm testing crate from cargo,
either for a 20 minute cooldown via the security cargo interface
console, or for 10000 credits via the supply console. It contains 4
single-use testers that hurt a bit when applied, but are instant to use
and 100% accurate. The stopgap is that they're really fucking expensive
and only work once per item.

### Screenshot
<img width="280" height="132" alt="image"
src="https://github.com/user-attachments/assets/00d22361-997e-4347-a0bf-aa240de40727"
/>

## Why It's Good For The Game

Antagonist variety, mainly. This is basically Cortical Borers 2:
Electric Boogaloo.

Currently, we lack any antagonists with mind control abilities. That
really sucks!

I've also gotten a lot of positive feedback about the antagonist while
working on it.

This antagonist also has great potential for roleplay, as they can take
over hosts, surprise attack people by getting out of a dead corpse, talk
to each other using Wormspeak, etc.

I think we're also itching for variety on "pest" antagonists. Right now
we just have spiders and xenos. Everybody knows these two, so why not
mix it up a bit?

And as for balance? Blood worms are relatively easy to dispatch when you
know their weaknesses, which are extremely clear. Bleeding for hosts,
fire for either one, lasers for the worms themselves. As long as you get
the host in crit and keep hitting, you've pretty much won, and they
can't keep spamming Inject Blood forever since they'll quickly run out
of blood to use.
## Changelog
🆑
add: Added a new heavy roundstart/midround antagonist, the Blood Worm.
Credit to INFRARED_BARON for the sprites!
fix: Removing traits based on a source no longer causes issues with
trait signals.
fix: High-priority effects no longer double-trigger due to subsystem
issues.
fix: Weighted averaging in reagent merging code has been band-aid fixed.
It's not the best, but it works.
/🆑
2026-01-14 23:30:35 -06:00
theOOZ fdd96d7d23 queued_rulesets list uses proc to unqueue (#94843)
## About The Pull Request

Makes unqueue'ing rulesets use a `unqueue_ruleset()` proc, just like
`queue_ruleset()`
Takes singletons instead of type paths.

## Why It's Good For The Game

Consistently uses these procs when adding or removing rulesets from the
queue. There was already a proc for adding, so having one for removing
suits. This PR removes any case of directly editing the
`queued_rulesets` list. This should make the code cleaner, among other
things.

## Changelog

🆑
code: Adding or removing rulesets from the queue list is done by procs
instead of directly editing the list.
/🆑
2026-01-15 03:44:38 +01:00
SmArtKar 0dcf70d9ec Adds a warning for invalid dynamic config weights (#94517)
## About The Pull Request

Warns admins and clamps values for dynamic weights/pops to ensure that
invalid values don't get stored in the list
Should prevent errors like
https://github.com/tgstation-operations/server-config/commit/e3c44eebf3de8f6b99a7ddc18268e87b33d793cb
from slipping under our radar in the future

## Changelog
🆑
admin: Added a warning for invalid dynamic config weights
/🆑
2025-12-19 10:17:15 -05:00
MrMelbert 9e3d50a162 Heretic latejoin cleanup (#94003)
## About The Pull Request

Dead path 
Closes #93757
2025-11-19 02:59:03 +01:00
Roxy d84a87f668 Rewrites to fix compiler errors on 516.1670+ (#93801)
## About The Pull Request

Fixes all instances of numbers being used as assoc list keys in things
that aren't alists, either by turning them into alists or changing the
keys to something else. Also adds new macros to support creating global
alists, as a few global lists became alists. Most of these are pretty
simple and self-explanatory but
- The GLOB.huds one necessitated rewriting because code depended on it
being a non-assoc list, which it technically was because the defines it
used as keys were numbers so BYOND turned it into a regular list, most
of this was for loops through all the subtypes of
`/datum/atom_hud/data/diagnostic` of which there's only one, so I just
changed it to get that type directly by key
- NT Frontier used number indexes which it looped through for some
reason and also passed to TGUI, changed these to strings and adjusted
the TGUI to match, I tested this and it works fine

## Why It's Good For The Game

Makes the code compile, I couldn't test everything but I tried to check
all usages of affected vars to make sure they wouldn't break from being
switched to alists, a TM might be in order just to be sure nothing's
fucked

## Changelog
🆑
refactor: rewrote all cases of numbers being used as keys in non-alist
associative lists
/🆑
2025-11-08 14:19:55 -08:00
MrMelbert 8b8bcfd674 Adds two heavy midround rulesets, mass traitors and mass changelings (#93447)
## About The Pull Request

- [ ] I tested this pr

Adds "Midround Mass Traitors" and "Midround Mass Changelings" heavy
rulesets

Midround Mass Traitors will turn a number of the crew into sleeper
agents

Midround Mass Lings will spawn a number of changeling meteors 

BY DEFAULT:
- Traitors will spawn 2-4 sleeper agents
- Lings will spawn 2-3 changeling meteors
- They won't run without >=2 candidates
- They have no config blacklist (so the HoP can roll mass midround
traitor, despite not being able to roll normal midround traitor. However
default blacklisted roles like security officers are still blocked)
- They're weighted impossible on tier 0, same weight as most midrounds
on tier 1, and fairly high on tiers 2 and 3
- They're repeatable but very unlikely to repeat
- Significantly higher min pop brackets than their solo counter part

## Why It's Good For The Game

Adds more options for lategame antags than big midrounds

## Changelog

🆑 Melbert
add: Two new heavy dynamic rulesets: "Midround Mass Traitors" and
"Midround Mass Changelings"
/🆑
2025-10-18 19:06:29 +02:00
EnterTheJake a2c7c8e57b Heretic Antagonist Full Overhaul. (#92119)
## About The Pull Request

Heretic has received a complete overhaul. This PR touches nearly every
aspect of the antagonist. For readability's sake, not every change is
going to be listed in this pull request.

For the full list of changes please refer to the design doc:
https://hackmd.io/@BiST8PJVRjiwVPY86U3bLQ/B11HyChz1g.

Code by Me, @Xander3359 and @Arturlang 

TGUI by @Arturlang 

Sprites by OrcaCora and GregorDM

Writing bits by @necromanceranne 

### Core changes

- Cross-pathing has been removed. Main knowledge spells are now
exclusive to their path (for the most part).

- For every main knowledge unlocked (save for the robes and the blade
upgrade), Heretics can choose one option from a draft of 3 random side
knowledges (this is a free point).

- Heretics can now purchase side knowledges from a new tab, the
"Knowledge Shop". Side-knowledges have been divided by tier (Stealth,
Defense, Summons, Combat and Main). Tiers are unlocked as you progress
toward your main path.

- Heretics now gain the grasp and mark upgrade immediately, but their
main knowledge choices cost twice as much (except for the first spell,
the robes and the blade upgrade).

- Path specific robes have been introduced! They come with their own set
of quirks.

- Each Path has received a passive ability. This passive is upgraded
when you first create your robes, and again when you complete the Ritual
of Knowledge.

- Paths have been rebalanced as a result of the removal of cross-path
progression. Cosmic and Moon paths have received soft reworks.

- Upon unlocking the path 2nd level or reaching a total of 8 points
worth of knowledge, Heretics will lose the ability to blade break (and
the limit on blades all together).

- Ascension now automatically calls the shuttle with no possibility of a
recall.

- Late join Heretic has been removed.

### New UI 
<img width="750" height="635" alt="moon path ui"
src="https://github.com/user-attachments/assets/184ef783-5c9c-48a1-a2f7-4807ca93e990"
/>


### Knowledge shop

<img width="787" height="669" alt="Knowledge shop"
src="https://github.com/user-attachments/assets/3dc89b84-8c70-4d47-b612-54396e3ea6e7"
/>




### Quality of life //General balance changes

- Heretics will now gain X-ray vision for a few seconds when nearby an
eldritch essence (this effect has a cooldown).

- Ritual of knowledge now requires 1 uncommon item instead of 2. You may
now use a stunprod instead of a baton to complete the ritual. Beartraps
have been removed from the list of possible reagents.

- The maximum number of possible sacrifices required to ascend has been
reduced from 6 to 5 while the minimum has been upped to 4.

- Codex Cicatrix no longer requires a special pen to be made.

### Passive abilities

- Heretics now start with a passive ability. You can find what it does
on the path info tab after a path has been selected, and what they gain
when upgraded.

- Crafting your first set of Eldritch robes will bump your passive to
level 2.

- Unlocking the 2nd level will subsequently unlock your "Ritual Of
Knowledge"

- Completing the ritual of knowledge or ascending will net you the final
level.

### Path Specific Robes

- Armorer's Ritual is no longer a side knowledge. Each path will have
their own unique version of the ritual. This is placed after the 2nd
spell in the tree.

- Robes can no longer be destroyed by fire and acid, grant t4 flash
protection (Moth Heretics stay winning) and protection against basic
syringes, to bring them on par with other antagonist's armor sets.

- The recipe to craft the robes is now a set of armor/vest, a mask (any
mask will do now, not just gas masks), plus the unique reagent required
for the blades (Plasma for Cosmic, Trash For Rust, match for Ash and so
on)

- Wearing the robes as a non-heretic may yield some unfortunate
side-effects.

### Moon Path Rework

Moon path  rework.

Moon Heretics gain immunity to brain traumas and slowly regenerate brain
health. Equipping the moon amulette channels its effects through the
moon blade; making it unblockable and cause sanity damage instead of
brute. Ring leader's Rise now summons an army of harmless clones that
explode when attacked; the explosion briefly stuns non-heretics and
cause sanity and brain damage to them. Moon blade can also now be used
when pacified and Moon spells are no longer blocked by regular anti
magic, only mind magic protection.


**Cosmic Path Rework**

Cosmic path has received the biggest batch of changes alongside Moon.
The path has been dead last in ascension and pickrate (less than 5%) for
almost 2 years. It did gain some popularity over the last few months,
reaching the highest ascension rate in the game (12%) while mantaining a
relatively low pickrate.

Cosmic sits in a weird spot, where pretty much every knowledge
surrounding the path is either mediocre or, in the case of the
ascension, dysfunctional. Yet it has maintained a smidge of relevancy
due to how quickly Cosmic heretics can capture and sacrifice targets
thanks to Star Touch.

As a result, the best course of action would be to rebalance the
entirety of the kit; granting the heretic more tools to manipulate space
and dictate the flow of a fight, while lessening their ability to end a
confrontation by instantly sleeping their opponents.

lastly The Star Gazer is now ghost controlled ; And they shoot lazers!

<img width="636" height="451" alt="gazer gag 3"
src="https://github.com/user-attachments/assets/601d6881-c042-4e42-8ce6-ac90cd27848b"
/>


## Why It's Good For The Game


### Ok...but why do we want this?

Again, if you want my full reasoning, please check my doc
https://hackmd.io/@BiST8PJVRjiwVPY86U3bLQ/B11HyChz1g.

To keep it short and concise; Heretic is too complex and unintuitive for
its own good. Too impenetrable for new players and too abusable for
experienced players. This can be chalked up to a lot of poor design
decisions. But ultimately, what I believe being the biggest contributor
to the current status of Heretic is the ability to move into different
paths, also known as "Cross-Pathing".

### Cross Pathing my beloathed.

Cross-pathing, while cool in theory, overcomplicates the antagonist and
overloads them with power. Players dealing with the heretic are
incapable of working out what a given heretic can do. This also leads to
late game heretics having 3 rows Worth of action buttons and virtually
no weakness.

Over the last year, I've often received the understandable but also kind
of unfair accusations of making Heretic too powerful without a clear aim
or purpose.

My goal with the paths I've reworked over the last year (Rust,Void and
Blade) wasn't necessarily to just make them stronger (although that was
also part of the goal, as they were paths that were underperforming),
but for them to have more interactions with the sandbox and to better
live up to the fantasy presented to the player.

If an harbringer of frost gets countered by a cup of coffee, we probably
messed something up.


Unfortunately, the current incarnation of Heretic doesn't really allow
for surgical balance changes to specific paths. Every time a knowledge
gets buffed, we make every path that can easily tap onto that knowledge
stronger by default. It doesn't take a genius to understand why this
system is ultimately unsustainable.

### Blade Breaking

I feel that after a heretic has reached the near peak of their power,
they no longer need the ability to instantly escape any encounter. Check
my doc for my full reasoning.

## Less versatile, more specialized paths.

By removing cross-pathing, we remove a huge maintainability burden from
the antagonist. Paths can now be designed around clearer strengths and
weaknesses. They become easier to balance and less of an headache to
understand for everyone.

It also means we can give paths some needed quality of life quirks
without having to worry how such a change might have a knock-on effect
for other paths.

Ash heretics can finally let loose without dying by their own flames.
Cosmic Heretic can go to space without having to carry a modsuit. Moon
Heretic can use their abilities without fear of one random trauma
ruining their day, and so on.

### What a horrible night to have a curse...., wait how do I curse
people again?

As of right now the heretic tree has quite a hefty amount of trinkets
that pretty much never see use.

Partly because the tree itself is a nightmare to navigate. And partly
because why would anyone set up an elaborate plan or scheme when they
can unleash 2 rows of spell in the span of bunch of seconds.

Heretics mostly gravitate towards powers that push them towards greater,
more potent combat strength. If it doesn't contribute to killing people
quicker, it isn't worth doing for most. And given the opportunity cost
associated for taking those powers, they will remain that way so long as
there are better choices to be poached.

The new draft system encourages Heretics to play more with the tools at
their disposal. If you want to go for a specific combo from the side
path options, you may now do so by tapping into the knowledge shop.

Yes, the shop does include a few knowledges from the other paths. But
these are limited to 1 per path, are very expensive and can only be
unlocked very late into the shift.

## Drip Of the Mansus

The iconic heretic robe is actually sequestered to a side path that is
most easily access by only two paths at a time. Since heretic paths are
being made to be much more specialized, the most obvious way in which
this can be showcased is through an easily
identifiable outfit.

By using the robes, we can both telegraph WHAT heretic you are looking
at, and just how much power they've accumulated and when it is
reasonable to take the kid gloves off and treat them as a genuine
threat. If a heretic is in their
robes, that heretic is now a significantly more prominent danger to the
station.

It also serves as a useful means for gating some of the more powerful
effects of a heretic's path behind the robes, AND enable options for
disarming them of that power should they be captured without making it
something endemic to their mob.

A major problem with heretics is a lack of certainty as to how powerful
they have become. A heretics robes is one of the milestones to help
players dealing with heretics identify that.

### Will this be 100% fair and balanced?

This is a massive overhaul to a pretty complex and bloated antagonist.
I've done my best to show the changes to several maintainers and other
members of the community for their feedback. But at some point we'll
have to see how this behave in the environment to get a feel if
something is over or undertuned. (that's my way of saying, yes this is
likely gonna require a testmerge or two).

What I will say is that I'm not trying to change the core identity of
Heretic.

Heretics should have the upperhand in single encounters early on, be
able to joust a small group of players after they unlock their final
spell, and end the round when they ascend. They're a progression
antagonist. They should retain their payoff as well as pose a danger as
they grow stronger.

But if more players feel like they are more reliably able to play the
antagonist in more varied and interesting ways, rather than the
antagonist largely existing as a measuring stick for 'robustness' due to
its elitist design philosophy, then the rework has been a success. There
should be something for
everyone in the antagonist, as is true for all of our antagonist roles.
2025-10-15 22:34:51 +00:00
Roxy f3848f1ef2 Renames flatten_list proc to assoc_to_values (#93453)
## About The Pull Request

`/proc/flatten_list()` -> `/proc/assoc_to_values()`, also changes the
code doc to mirror the language of `assoc_to_keys()`'s code doc

## Why It's Good For The Game

Having a proc called `assoc_to_keys` that takes an associative list and
returns a list of the keys, and also having a proc that takes an
associative list and returns a list of the values, and the latter not
being called `assoc_to_values` is very funny

## Changelog
🆑
code: renamed flatten_list proc to assoc_to_values
/🆑

---------

Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
2025-10-14 21:01:09 +00:00
MrMelbert de0393e642 Dynamic Tester differentiates lights and heavies (#93089) 2025-10-06 13:25:45 +02:00
Bloop a7b1f8f77a Adds more detailed logging data to dynamic (#93060)
## About The Pull Request

Tin. It annoyed me how useless the logging was for forcing a dynamic
ruleset. "but preparation failed!" (ok, but why?)

So this just adds more detailed explanations for why the preparation
failed.

<img width="640" height="47" alt="image"
src="https://github.com/user-attachments/assets/cc1f9e94-293e-422d-bd16-0ae5f28fd1eb"
/>

## Why It's Good For The Game

Better logging and clearer admin messages.

## Changelog

🆑
qol: improves admin logging of forced dynamic events.
/🆑
2025-10-02 20:51:13 +02:00
SimplyLogan 721428c65a Status Display Automation & NT Logo Change (#93088)
## About The Pull Request

- Status Displays update automatically for emergency alerts and show
round start logos by default instead of a blank screen.
- Tested in game with manual graphics and with triggered events.
- There is also a priority system, some emergencies will display
temporarily if a higher priority (shuttle call) is in progress.
- It also has checks on when something ends, i.e if radiation storm
happens, the alert for that goes away after the storm passes instead of
staying on the display.
- The manual buttons on the comms console to update the screens are
still there and work with this.
- BLOB file tweaks - All blob features works but with non blocking
cleanup as Linter threw errors.
- Also found a nicer sprite from AI core to use for the NT logo on the
displays since we'll be seeing it on more, the current one is just a bit
too bright

| Default logo | Alert Level Auto Switch | Events "can" interrupt
shuttle call display but only for 30 seconds |
|--------|--------|--------|
| <img width="443" height="182" alt="image"
src="https://github.com/user-attachments/assets/4027d8cc-041a-4e26-8120-742bf38f9c8a"
/>| <img width="444" height="181" alt="image"
src="https://github.com/user-attachments/assets/267363be-7f3a-4b63-a412-ea74c9d23c60"
/> | <img width="432" height="172" alt="image"
src="https://github.com/user-attachments/assets/842b9bfd-6e32-4833-8c06-42518dd8c0d2"
/> |

**Nanotrasen Logo Replacement - Left is original - Right is new**

<img width="181" height="82" alt="image"
src="https://github.com/user-attachments/assets/ac78d1c2-059b-4ab5-9d2c-3e59bec87620"
/>


## Why It's Good For The Game

- Status displays leave an empty void on the walls in rounds, this adds
a bit more value to them
- Should make the screens feel busier/more dynamic and the game a little
more engaging
## Changelog
🆑
add: Status displays now show logo at round start - Status displays now
change more often for alerts and other key events
fix: Blob non blocking cleanup - Should have no change in player
experience
image: Replaces bright blue NT logo with the more subtle slightly
animated sprite from AI core, fits nicer.
/🆑

---------

Co-authored-by: loganuk <falseemail@aol.com>
2025-09-30 19:50:24 +02:00
MrMelbert da9eb945fc Adds a 1/5 chance for Paradox Clone to spawn two for the price of one (#92855)
## About The Pull Request

Paradox Clone ruleset has a 1/5 chance of spawning an additional clone
of the same target. This chance is configurable (so server operators can
disable it), but the amount of clones it adds is not.

The second clone is *not* on a team with the first. Paradox Clone's
primary objective has been updated to `Be the only [x] alive`, rather
than `Kill [x]`.

- [ ] I tested this pr

## Why It's Good For The Game

A while back someone suggested "What if Paradox Clone spawned a third
clone with the objective to protect the guy instead of kill them"

I thought this sounded pretty neat but the idea of spawning an antag
that worked against antags seemed to be grounds for problems. So I stole
half the idea.

This adds a little more variety in Paradox Clone happenings:
- Clones have no idea or indication if there are other clones (unless
you spawn together - which is not guaranteed), so each clone is less
sure of things and has to improvise more
- Neither the clones nor the crew can be fully complacent after dealing
with one "clone"
- More plausible deniability for Genetics or Changelings to mess with
people
- And yes, even the clones aren't 100% sure if the *other* clone is real
or fake, so now they're roped in on the fun

## Changelog

🆑 Melbert
add: There's a 1/5 chance that Paradox Clone spawns a second clone if
there are enough candidates. Neither clone is aware of or on a team with
the other - There can only be one.
add: Paradox Clones are now tasked to `Be the only [x] alive`, meaning
means of identity cloning (such as Genetics or Changelings) may throw a
wrench in your plan.
/🆑
2025-09-12 16:44:11 +02:00
Bloop a029668e56 Makes the dynamic tester tiers / population caps start at 1 (#92870)
## About The Pull Request

No antags are spawned at 0 anyway, and it causes some runtimes. 

## Why It's Good For The Game

## Changelog

Not player-facing
2025-09-07 11:12:38 +02:00
MrMelbert 80069f4830 Increase repo default max number of traitors spawned roundstart (#92478)
## About The Pull Request

Repo default max traitors upped from

1 per 38 players (up to 2 traitors at 50 pop, up to 3 traitors at 80
pop)

to

1 per 24 players (up to 3 traitors at 50 pop, up to 4 traitors at 80
pop)

Note: The ruleset can be executed twice or even thrice depending on RNG,
meaning a particularly chaotic round may spawn with up to 6/9 traitors
at 50 pop (and more may be added via midrounds and latejoins).

## Why It's Good For The Game

#67823 changed this number

This was done because dynamic would force spawn midround traitor IF any
midround ruleset failed to execute. But dynamic no longer does that. So
this value should be reverted.
2025-08-30 12:49:27 -05:00
Rhials 822a1d3d55 Fugitive Hunters spawn again (#92761)
## About The Pull Request

Fugitive hunters no longer runtime on their timer check. 

The `check_spawn_hunters` proc was getting passed the fugitive hunters'
backstory (not needed in the proc) instead of the time until their
expected spawn.
## Why It's Good For The Game

The fugitive hunters are a pretty important part of the fugitive antag.
It's like playing hide and seek without any seekers. It sucks.

Closes the unresolved part of #92618.
2025-08-29 15:15:08 -05:00
Rhials 8476ac925e Solo fugitives spawn with a toolbox, like group fugitives do (#92685)
## About The Pull Request

Solo fugitives weren't getting their toolbox because
`equip_fugitive_leader()` doesn't get called. While this makes sense,
seeing as there isn't a "leader" to equip, there isn't actually a reason
not to call this for single fugitives.

So, `equip_fugitive_leader()` now runs for all fugitive quantities. If
someone wants to add more essential equipment for newly spawned
fugitives, it should go there alongside the toolbox.
## Why It's Good For The Game

Partially handles #92618.
## Changelog
🆑 Rhials
fix: Solo fugitives now spawn with a mechanical toolbox, as intended.
/🆑
2025-08-24 07:29:58 +02:00
MrMelbert 5cddf64930 Fixes some cases of dynamic reading defined values over config values (#92126)
## About The Pull Request

Fixes #92125

Very simple, when working without an instantiated datum we would read
from the config manually, but some places neglected to do that.

So I added a macro to help in the future.

## Changelog

🆑 Melbert
fix: Fixes some places where dynamic configs were not being read
correctly
/🆑
2025-07-14 16:46:28 -06:00
Time-Green 39a2434c06 Voidwalker Rework | Basic Mob Edition + Bonus Antag (#91646)
## About The Pull Request

Reworks the Voidwalker into a basic mob, including a lot of the balance
and mechanics!

Old (left), new (right)

![image](https://github.com/user-attachments/assets/5583db66-6025-4874-95dd-938aa828634c)![image](https://github.com/user-attachments/assets/2785c5cc-ccda-4ffd-bc1c-5bb278873d9b)


https://github.com/user-attachments/assets/22d6138f-11aa-4f7a-8600-2565e6578bcf

(little outdated)
https://youtu.be/cp1E3qPJGX4 (high res mirror)

**🟨Voidwalker mob changes🟨**
No longer a human species and no more void eater. Instead deals damage
by simple unarmed attacks.
Instead of dealing brute, the voidwalker does oxygen damage (4-5 hits to
knock out) with left-click, and slight brute on right click. Non-human
mobs automatically take brute damage instead of oxygen damage.

150 HP
33% burn armor

Yes it has hands, but it can only pick up and drop stuff

**🟨Window phase🟨**

![image](https://github.com/user-attachments/assets/82a330ee-16f8-46e4-a325-c894fc8931d6)
Instead of needing to smash a window with the void eater, moving through
windows simply leaves them passable for 5 seconds. Makes kidnapping a
lot easier, but also makes it easier for people to chase you

People who used the voided skull also leave windows passable for a short
bit.

**🟩Cosmic Charge🟩**
Standard charge ability, but only lets you charge towards space and
works while dragging people

**🟩The Vomitwalker🟩**
People you kidnapped now occasionally do the nebula vomit, which
voidwalkers can use to dive from and into

![image](https://github.com/user-attachments/assets/e483a0d2-a418-479e-89e5-1dcd71165140)
Diving into it is very fast but also removes the nebula vomit. You can
also kidnap people into the vomit (this doesn't remove the vomit).

There is also a little UI for tracking this. Clicking it while in space
dive teleports you to the next nebula vomit, if there are any.


![image](https://github.com/user-attachments/assets/8907f261-6395-44fb-86ea-0ed548aca3ab)

**🟨Voided people changes🟨**
Kidnapped people and people that used the cosmic skull are no longer
muted, but take 10% extra brute and occasionally leave behind glass
shards when taking a lot of damage.

Are no longer obliterated on a second encounter with voidwalkers.
Voidwalkers can't hurt people they've already voided (unless they really
want to), but instead just knock them out for 30s

Also the kidnapped do space vomit as I said earlier.

**🟩Sunwalker🟩**
Voidwalker variant made for pure murderbone. Has no camo and kindap
mechanics, but has a fiery charge, loads of damage and area igniting and
people ignition. It's admin, but I might change this later once I've had
some more time to think about it.

![image](https://github.com/user-attachments/assets/2383dc6e-2173-4449-b71b-367e81c55f88)

Other changes: 
- Voidwindows no longer need to be space adjacent
- Unsettle works faster but can't be used in combat anymore
- Space camo now grants complete space invisibility
- Makes a lot of aspects easily moddable, so we can easily mod it into a
moistwalker in-game
- Taking a cosmic skull when you already used one gives you the old
voidwalker void eater arm. Additional uses just gives you more void
eater arms until you run out of hands
- I definitely forgot a lot more
- I made a cool voidwalker hud! It even has a unique space camo toggle
## Why It's Good For The Game

<details>
  <summary>Lot of text</summary>
  
Voidwalker was basically a snowflaked toghether human species because I
didn't know how to sprite, but I was able to work with species and
visual effects. Then I realized I can just commission sprites!

This also let me just cut out a lot of the snowflake code, because it's
no longer a human so half the things I didn't want them to be able to
do, they just literally cannot do.

Voidwalkers were in a bit of strange spot with kidnapping? There was
essentially no incentive, other than "smash spaceman = funny". They also
had issues doing, anything? There's surprisingly little space on a space
station, especially maps such as tram. Making the voided victims have
nebula vomit gives the voidwalker a reason to WANT to kidnap, by giving
them a way to appear basically anywhere on the station. I don't think
it's too overpowered. Voided people don't vomit that much, it's easily
cleanable and diving into it removes them, so they're limited usability.

Replacing the brute damage with oxygen damage also kinda... just makes
sense? I seriously contemplated letting them do stamina damage for the
first iteration, but opted not to do it because stamina damage has so
many hooks attached. Oxygen damage doesn't! It's also just incredibly
thematic, let's them bypass most armor and makes them more suited to
non-letha kidnappings.

Space camo making them completely invisible was also long overdue. It
was literally just urging people to turn up their gamma and turn down
their parallax settings. I thought it was an interesting mechanic, but
it's just straight up unfair and doesn't belong in a multiplayer game.
They now more frequently leave behind little glass shards, leave
particles from nebula vomit they leave from and have more unique sound
effects, so attentive (and lucky) people can still deduce if an area is
safe-ish.

I removed being able to shatter voided people because the mechanic was
deeply misunderstood. It was intended to give them a means of removing
people if they kept incessently bothering the voidwalker, but people
went out of their way to use this to roundremove people they had already
voided. The 30s sleep conveys my intention a lot better, and fits better
now that the voidwalker benefits from having as many voided people
vomitting all over the place.

The cosmic charge gives them some much needed survivability. My
experiences (in observing voidwalkers, I can never get the roll ;_;) is
that they're constantly one mistake away from complete obliteration. The
cosmic charge let's them get out quick despite their slow movement speed
in gravity. It also makes them stronger when fighting in space.

They got 33% burn armor so it's a tiny bit harder to wipe them away in a
single laser salvo, while still giving people ample opportunity to fight
them off . Also they're like glass or something so it fits thematically.

I gave them hands because I thought it was cool, might be a mistake idk
  
</details>

## Changelog

🆑 Time-Green, INFRARED_BACON
add: Voidwalker has been throughly reworked! Now you are even less safe!
admin: Adds admin-only Sunwalker mob
fix: Unsettle doesnt work on yourself anymore
fix: Space camo doesnt stop bobbing anymore
fix: Voidwalker windows now recharge on kidnap 
runtime: Fixes healthanalyzers runtiming when scanning mobs without
reagent holders
/🆑
2025-07-01 12:55:31 +01:00
MrMelbert 421204a281 Fix high impact rulesets being disregarded for roundstart selection (#91883)
## About The Pull Request

Fixes #91882 

`RULESET_HIGH_IMPACT` is checked in `get_weight`, but by the time
`get_weight` is called for roundstart rulesets, no rulesets are
selected.

So we need to add logic in `pick_roundstart_rulesets`

Not super big fan of this fix - I think it'd be a lot cleaner if all the
rulesets recalculated their weights, but this is a needed temp fix.

## Changelog

🆑 Melbert
fix: Multiple high impact rulesets will no longer roll simultaneously
unless dynamic picks "high chaos"
/🆑
2025-06-30 02:16:15 +03:00
MrMelbert 4c277dc572 Dynamic Rework (#91290)
## About The Pull Request

Implements https://hackmd.io/@tgstation/SkeUS7lSp , rewriting Dynamic
from the ground-up

- Dynamic configuration is now vastly streamlined, making it far far far
easier to understand and edit

- Threat is gone entirely; round chaos is now determined by dynamic
tiers
   - There's 5 dynamic tiers, 0 to 4.
      - 0 is a pure greenshift.
- Tiers are just picked via weight - "16% chance of getting a high chaos
round".
- Tiers have min pop ranges. "Tier 4 (high chaos) requires 25 pop to be
selected".
- Tier determines how much of every ruleset is picked. "Tier 4 (High
Chaos) will pick 3-4 roundstart[1], 1-2 light, 1-2 heavy, and 2-3
latejoins".
- The number of rulesets picked depends on how many people are in the
server - this is also configurable[2]. As an example, a tier that
demands "1-3" rulesets will not spawn 3 rulesets if population <= 40 and
will not spawn 2 rulesets if population <= 25.
- Tiers also determine time before light, heavy, and latejoin rulesets
are picked, as well as the cooldown range between spawns. More chaotic
tiers may send midrounds sooner or wait less time between sending them.

- On the ruleset side of things, "requirements", "scaling", and
"enemies" is gone.
- You can configure a ruleset's min pop and weight flat, or per tier.
- For example a ruleset like Obsession is weighted higher for tiers 1-2
and lower for tiers 3-4.
- Rather than scaling up, roundstart rulesets can just be selected
multiple times.
- Rulesets also have `min_antag_cap` and `max_antag_cap`.
`min_antag_cap` determines how many candidates are needed for it to run,
and `max_antag_cap` determines how many candidates are selected.

- Rulesets attempt to run every 2.5 minutes. [3]

- Light rulesets will ALWAYS be picked before heavy rulesets. [4]

- Light injection chance is no longer 100%, heavy injection chance
formula has been simplified.
- Chance simply scales based on number of dead players / total number
off players, with a flag 50% chance if no antags exist. [5]

[1] This does not guarantee you will actually GET 3-4 roundstart
rulesets. If a roundstart ruleset is picked, and it ends up being unable
to execute (such as "not enough candidates", that slot is effectively a
wash.) This might be revisited.

[2] Currently, this is a hard limit - below X pop, you WILL get a
quarter or a half of the rulesets. This might be revisited to just be
weighted - you are just MORE LIKELY to get a quarter or a half.

[3] Little worried about accidentally frontloading everything so we'll
see about this

[4] This may be revisited but in most contexts it seems sensible. 

[5] This may also be revisited, I'm not 100% sure what the best / most
simple way to tackle midround chances is.

Other implementation details

- The process of making rulesets has been streamlined as well. Many
rulesets only amount to a definition and `assign_role`.

- Dynamic.json -> Dynamic.toml

- Dynamic event hijacked was ripped out entirely.
- Most midround antag random events are now dynamic rulesets. Fugitives,
Morphs, Slaughter Demons, etc.
      - The 1 weight slaughter demon event is gone. RIP in peace. 
- There is now a hidden midround event that simply adds +1 latejoin, +1
light, or +1 heavy ruleset.

- `mind.special_role` is dead. Minds have a lazylist of special roles
now but it's essentially only used for traitor panel.

- Revs refactored almost entirely. Revs can now exist without a dynamic
ruleset.

- Cult refactored a tiny bit. 

- Antag datums cleaned up.

- Pre round setup is less centralized on Dynamic.

- Admins have a whole panel for interfacing with dynamic. It's pretty
slapdash I'm sure someone could make a nicer looking one.


![image](https://github.com/user-attachments/assets/e99ca607-20b0-4d30-ab4a-f602babe7ac7)


![image](https://github.com/user-attachments/assets/470c3c20-c354-4ee6-b63b-a8f36dda4b5c)

- Maybe some other things.

## Why It's Good For The Game

See readme for more info.

Will you see a massive change in how rounds play out? My hunch says
rounds will spawn less rulesets on average, but it's ultimately to how
it's configured

## Changelog

🆑 Melbert
refactor: Dynamic rewritten entirely, report any strange rounds
config: Dynamic config reworked, it's now a TOML file
refactor: Refactored antag roles somewhat, report any oddities
refactor: Refactored Revolution entirely, report any oddities
del: Deleted most midround events that spawn antags - they use dynamic
rulesets now
add: Dynamic rulesets can now be false alarms
add: Adds a random event that gives dynamic the ability to run another
ruleset later
admin: Adds a panel for messing around with dynamic
admin: Adds a panel for chance for every dynamic ruleset to be selected
admin: You can spawn revs without using dynamic now
fix: Nuke team leaders get their fun title back
/🆑
2025-06-25 17:36:10 -07:00
Jeremiah 9db2f6916b Sets prettier to run on the repo (#91379)
## About The Pull Request
Prettier (an auto formatter) is set to only run within the tgui folder
currently. This removes that limitation, allowing it to automatically
format all supported files in the repo (.js, .html, .yml
[etc](https://prettier.io/docs/))

I made a few exceptions for bundled and generated files
## Why It's Good For The Game
I'm of the opinion that code should look uniform and am lazy enough to
want CTRL-S to format files without having to think beyond that
## Changelog
2025-05-29 21:23:59 -07:00
Lucy 37ec7f8054 Changes all uses of notify_ghosts to use the real names of mobs (#90919)
## About The Pull Request

Quite simple - this changes every direct mention of a mob in a
`notify_ghosts` message to use `[mob.real_name]` instead of just `[mob]`

## Why It's Good For The Game

makes things less confusing - ghosts can see easily their actual
identity anyways, so it's not like there's much of a reason _not_ to do
this.

## Changelog
🆑
qol: Ghost notifications will now use the real names of mobs when
something happens (i.e no more "Unknown has completed an ascension
ritual!")
/🆑
2025-05-08 00:48:52 +00:00
SmArtKar 963ca5b1ee Cult Master title is now granted to the most experienced cult player, improvements and fixes (#90824)
## About The Pull Request

When the cult roundstart ruleset is picked, the most experienced cult
player is granted the cult Master title instead of it being determined
by voting. They can pass the role onto another willing cultist by using
an action once. Fixed cult masters not receiving their large speech
(instead not having any text spans whatsoever) and the Eldritch Pulse
spell being not usable whatsoever. Mark Target now displays an arrow
similar to heretic's living hearbeat to all cultists upon being cast.
This is a commission by Improvedname, but I do stand by the ideas
myself.

## Why It's Good For The Game

Cult Master, since its very inception, has been used for one thing and
one thing only - casting Final Reckoning on the summon rune by whoever
got to the area first and quickly used the vote that the cult reserved
for the finale. This results in other spells almost never being used, as
can be seen by the fact that one of them has been broken for the past 2
years. This change should make cult master more of a commander role akin
to how nuclear operative leader works, and make them a valuable target
for non-cultists to hunt down as they'll be present since roundstart.

## Changelog
🆑
add: Cult Master is now assigned to the player with most hours as a
cultist upon roundstart, instead of being votable.
add: Cult Masters can transfer their role once.
balance: Mark Target now gives all cultists a noticable directional
indicator, similar to heretics' living hearbeat
fix: Fixed cult master's broken speech spans
fix: Fixed Eldritch Pulse not working
/🆑
2025-05-05 00:30:34 +10:00
TiviPlus 88c2213f1e Force UTC±0 for time2text logging and IC times (#90347)
## About The Pull Request
This won't actually do anything on live, since those are all set to
UTC±0 currently

Pins logging and IC uses of time2text to UTC±0 instead of using the
system timezone (byond default)
Timezones not being set to utc0 caused issues before (and is again)

All timezones are now passed explicitly to make it more likely it's
cargo culted properly at least

Deletes worldtime2text cus it was gameTimestamp default args

## Why It's Good For The Game
Server timezone changes probably shouldn't affect logging, round times,
file hashes, IC time, when you caught fish, etc

## Changelog
🆑
refactor: Logging and IC timestamps will now always use UTC±0 and not be
affected by server system timezone changes
fix: Station and round times will not longer be incorrect if the system
timezone is not UTC±0
/🆑

---------

Co-authored-by: TiviPlus <572233640+TiviPlus@users.noreply.com>
2025-04-01 22:08:15 +02:00
Joshua Kidder cd7da5b684 Heretic is now considered an equal threat level to changeling (#90146)
## About The Pull Request

This adjusts the threat level for Heretic for the dynamic game mode to
have them cost as much as a changeling to be chosen. As well, it adjusts
the weighting for heretic latejoin from 8 to 4.
## Why It's Good For The Game

Heretic threat, as it is, is stupendously under-valued in relation to
our other antagonist threats. Heretic is regularly a round-ending threat
and their current threat level is totally inaccurate.
## Changelog
N/A
2025-03-20 12:47:49 +01:00
Kashargul dfa7f2bb62 some more 516 compat fixes (#89766)
Ports the helpers from
https://github.com/BeeStation/BeeStation-Hornet/pull/12240

This should fix some more of the 516 issues that I've seen while giving
a quick check through the code

The remaining browse should work now.

Also fixing another sass warning while being on it.

## About The Pull Request
## Why It's Good For The Game
## Changelog
🆑
fix: tgui say 516 will no longer change channels when the button is used
to drag it
fix: tgui say 516 will no longer leak radio messages into the wrong
channel
fix: runechat flickering when faded up messages fade out
/🆑
2025-03-03 15:15:07 +01:00
Kapu1178 a0e862d575 Base implementation of /datum/persistent_client (#89449)
## About The Pull Request
Converts `/datum/player_details` into `/datum/persistent_client`.
Persistent Clients persist across connections. The only time a mob's
persistent client will change is if the ckey it's bound to logs into a
different mob, or the mob is deleted (duh).

Also adds PossessByPlayer() so that transfering mob control is cleaner
and makes more immediate sense if you don't know byond-fu.

## Why It's Good For The Game
Clients are an abstract representation of a connection that can be
dropped at almost any moment so putting things that should be stable to
access at any time onto an undying object is ideal. This allows for
future expansions like abstracting away client.screen and managing
everything cleanly.
2025-02-25 13:52:24 -06:00
Jacquerel 23ac16411d Removes Secondary & Final Objectives from Traitors (#89466)
## About The Pull Request


![image](https://github.com/user-attachments/assets/cb0bffb3-33be-4fb1-baec-a4d0f4a4cd57)
Pre-discussed with @Watermelon914, this PR removes Secondary & Final
Objectives from all Traitors, rather than just midround ones. It also
removes all of the surrounding supporting code.
Randomly assigned Primary Objectives still exist, I just used the
ability to rewrite mine to take the screenshot.

In terms of final objectives, the surrounding items that were available
still exist but don't necessarily have sources.
If anyone has good ideas for readding these in some other form it can be
done in future PRs.

It also allows all traitors to buy the Contractor kit, previously
limited to midround traitors which lacked secondary objectives, because
now all traitors lack secondary objectives.

This essentially limits all traitors to a maximum of 20 TC (16 if they
spawn with an uplink implant). Currently I don't foresee that they
strictly need any additional way of gaining TC during a round as 20 is
quite sufficient, but it may take some time to adjust and get used to it
after such a long time of having access to more. If we need to adjust
the starting value or add a slow drip of more points over time or
something, that can be done in followup PRs.

This also removes the ability to recreate your uplink added by my
beautiful wife in #74315
This was part of the progression traitor design document, but ultimately
probably a bad idea as it essentially made traitors impossible to
properly disarm. You will once more just need to carefully protect your
uplink.

**This does not remove the threat/progression system**. 
Like midround traitors, all Reputation requirements on gear are now
simple timelocks, most of which will have elapsed by the time 30 minutes
have passed.

**Finally** this PR also adds Romerol to the traitor uplink for 25 TC
and 30 minutes of reputation, as a treat (and because I removed the
final objective that previously granted it).

## Why It's Good For The Game

We've tried this system for a long time (3 years last month!) and while
I think it had a lot of promise, enabled some cool moments, and also
solved several of the problems it set out to solve, overall I think some
of the behaviours it has encouraged in players have been overall
negative for the game.
While the _game systems_ are fine, even quite fun and cool (especially
final objectives) I am of the opinion that having them in the game
creates a net negative purely in the way that they react with players'
_brains_, creating incentives towards behaviour we don't actually want
people to pursue.

While it's hard-to-impossible to prove any of this with hard data, there
has been a prevailing feeling for some time among many (though certainly
not all) people that the simple fact of _having_ a constant drip-feed of
objective available to players leads directly to less interesting
antagonist play. While certainly nobody is _forced_ to do secondary
objectives you are directly and quite strongly rewarded for doing so,
doing so efficiently, and doing so in a way which makes sure that nobody
(alive) sees you do it. This leads to a tendency to play defensively and
try to maximise the number of tasks you can complete in one round, which
also has a knock-on effect of generally minimising the number of people
you attempt to interact with in a round (unless you are killing them).

Even people who _intend_ on doing some more interesting gimmick can fall
into this trap, as "having more tools" is always useful for anyone who
is intending on any kind of plan at all, but then executing on the
secondary objectives again incentivises you to lay low, not interact
with anyone, be efficient, and then reduces the time you are spending
doing the thing that's your actual plan for the round. Removing the
ever-present temptation to fish for extra TC leaves "doing whatever your
actual plan is" as the sole thing to optimise.

Final Objectives too have created unfortunate psychological effects
between crewsided players and other antagonists. Because of the _threat_
(no matter how remote, Final Objectives have always been tuned to be
appropriately rare) that leaving any antagonist alone will cause them to
snowball by acquiring more power, it starts to feel foolish to respond
to any threat with less than the maximum possible level of force even if
they seem relatively innocuous in the moment. This even has an effect on
other non-progression antagonists, as traitors are the most common
antagonist type and how people treat them is going to be their default
level of reaction to most other station threats.

While there has always been the promise of expanding the system with
novel and exciting objectives that leverage appearing mid-round to do
something unique, we've taken very little advantage of that over time.
Most objectives we have added that didn't boil down to "kill someone,
with a twist" have been somewhat unsuccessful, serving either as ways to
get yourself arrested and killed for no reason or ways to get free
telecrystals by doing something the crew don't really care about
stopping you from doing. The option still exists to add more roundstart
objectives to traitors, if someone suddenly has a great idea that would
fit in this space.

The ideal outcome of making this change is a slight relaxation of crew
attitude towards feeling like their only option after catching an
antagonist that isn't sandbagging is to permanently remove them from the
round (although it's fine to do this still in many scenarios), and a
broadening of traitorous activity which is not purely focused on
collecting as many checkboxes as possible and might give people more
time to roleplay with other players, not worrying that this time could
have been more efficiently spent pursuing a different secondary goal.
I don't anticipate or desire that this will prevent traitors from
killing anyone (or even stop them from killing people they don't have a
specific objective to kill), I just want to remove the FOMO from
people's minds.

Also this gives us something to talk about at the coder townhall meeting
on the 22nd.

## Changelog

🆑
del: Misplaced or stolen traitor uplinks can no longer be recreated
using a radio code and special device, guard yours carefully or buy a
backup implant.
del: Roundstart traitors can no longer take on additional objectives in
order to earn additional Telecrystals and fast-forward any unlock timers
on items. They also cannot earn the ability to complete a Final
Objective.
balance: Roundstart traitors can now buy the Contractor Kit from their
traitor uplink, rather than only midround traitors.
add: Traitors can buy Romerol for 25 TC, after 30 minutes of time has
passed in a round.
/🆑
2025-02-14 12:46:56 +00:00
SmArtKar 6f082544e8 You can wear voidwalker's skull on your head + void curse no longer colors stars in your skin color (#89270)
## About The Pull Request


![image](https://github.com/user-attachments/assets/071d4cb3-1c8b-45a5-a91e-87fef3d4ea08)

Voided curse now randomizes your limb's color override while its
applied, resulting in fancier stars that aren't skin colored


![image](https://github.com/user-attachments/assets/a31f4d29-32e9-413d-b256-0999cc108c30)

## Why Is This Good For The Game

Neat feature + pretty

## Changelog
🆑
add: You can wear voidwalker's skull on your head now
fix: Void curse no longer colors stars in your skin color
/🆑
2025-01-30 09:50:23 +01:00
jimmyl 92a585cb3a new icebox ruin: outpost 31 + megafauna (technically???) (#88714)
## About The Pull Request
<details>
<summary> expand to spoil the fun of exploring something for yourself
</summary>

firstly, the new ruin: outpost 31
its layout is vaguely based off an official map of the Outpost 31 from
the Thing movie but i ran out of space halfway


![image](https://github.com/user-attachments/assets/6db1aa9f-40d3-4693-897b-01e32b3ee1d2)

the boss drops a keycard for the storage room that you cant get in
otherwise, containing its own special item, and other stuff probably
useful for crew
crusher loot: trophy that heals you on each hit

the ruin is guarded by like 3 flesh blobs, very resilient (and slow)
masses of flesh that deal 3 brute damage, not harmful in melee but WILL
attempt to grab and devour/assimilate you which is FAR more lethal



https://github.com/user-attachments/assets/542cc6d0-f4ee-4598-9677-a03170c6c1c3



Boss: The Thing (with creative liberties otherwise this thing would
instakill you if it was true to source material)
difficulty: medium apparently idk mining jesus beat it with 400ms or so
HP: 1800
It is a much higher ranking changeling than those infiltrating SS13
It has 3 phases, 600hp each. Depleting its phase health will turn it
invincible and it will heal back half in 10 seconds. In order to prevent
this, the two Molecular Accelerators must be overloaded by interacting
with them to blast the changeling with deadly scifi magic or whatever
they do, forcing it to shed its form further and go to the next phase.
Not necessary for phase 3 because it literally just dies then

it focuses mostly on meleeing you and making certain tiles impassable
for you with 1hp tendrils, all attacks are telegraphed so theres no dumb
instakills here

it alternates between aoe abilities and abilities 

melee behavior:
- if too far, charge at target (charges twice on phase 3)
- too close, shriek (unavailable in phase 1) (technically AOE but its
more like a melee ability you know??)
- otherwise just try to melee

Shriek: if the player is too close emit a confusing shriek that makes
them confused and drop items

aoe behavior (phase 2, 3 only):
1: Puts 4 tendrils in a line cardinally
2: Puts tendrils around itself
3. Puts a patch of tendrils around and under the target, 3x3 in phase 3
4. Phase 3 only - spits patches of acid into the air that hurt when
stepped on

_(crusher is hard ok)_


https://github.com/user-attachments/assets/cbb98209-d3f0-470d-b0e8-4e310c5b709c



unique megafauna loot for this boss is like 1 AI-Uplink brain
its like a BORIS module but for humans i think you can figure out what
that means
while in a human shell they cannot roll non-malf midrounds and cannot be
converted, and cannot be mindswapped
the human MUST have all robotic organs (minus tongue because its not in
the exosuit fab and that kinda sucks to get)
will undeploy if polymorphed



https://github.com/user-attachments/assets/abcc277a-995a-4fa7-b980-0549b6b7cf52



</details>

## Why It's Good For The Game

icebox is severely lacking in actual good ruins (fuck that one fountain
ruin)
i feel that the loot given by megafauna has been and still apparently is
exclusively to make the victor more powerful, which kinda sucks because
thats just powergaming???? the loot of this boss is more crewsided,
specifically aiding the AI in a VERY limited quantity (1), so its not
anything good for powergamers, good for crew if the AI is not rogue

## Changelog
🆑
add: outpost 31, the icebox ruin. Also its associated mobs, and
megafauna, and loot. Im not spoiling anything, find it yourself.
/🆑

---------

Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com>
2025-01-23 18:33:05 +01:00
Vekter 83e179ee21 Drastically simplifies the roundstart report (#89150)
## About The Pull Request

The roundstart report has been changed in the following ways:

- There are now only four alert levels: Yellow Star (0-65 Threat), Red
Star (66-79 Threat), Black Orbit (80-99 Threat), and Midnight Sun (100
Threat).
- The roundstart report is now 100% accurate.
- Extended rounds will still show the "No credible threat" alerts, but
this should only happen if an admin sets the round to Extended.

## Why It's Good For The Game

The current roundstart report system is too granular as it is now, which
leads to situations where players will suicide 5-10 minutes into the
round due to the threat level being too low. Making it potentially
random was meaningless, because players would just act on whatever it
said without actually giving the round a chance to do anything.

I also feel like this brings back a fair bit of paranoia to the round,
as low threat levels would often just result in people expecting nothing
to happen. That can be fun when the report is lying, but it doesn't
happen often enough to really make it worth keeping.

We tested this a few months ago and the results seemed positive. We also
had a lot of discussion about the matter and, while I'm open to changing
implementation in some ways, I'm pretty set on this being a beneficial
change, at least in the short term until we can make Dynamic more
interesting.

I kept the high threat level stuff because it's fun to know some crazy
shit might happen. I might bring back the random threat level thing to
differentiate between those but I don't really care tbh; the targeted
behavior here is people bailing on low threat rounds, not people knowing
it's a high threat round.
## Changelog
🆑 Vekter
balance: The roundstart report will now display a more broad, less
specific message about threat levels when between 0 and 80 threat.
/🆑
2025-01-21 21:45:45 -08:00
Aylong 1795c18aea Fix a bunch of html UI's for 516 (#88917)
## About The Pull Request
Moved broken on 516 UI's to browser datum
They now work and have a dark theme
Most of them are admin ones (All except 1)

I tried to check all the raw HTML UI's by typing `<< browse(` into the
VSC search and going through each element, but I might have missed
something.

What worked as it was, I didn't touch, except for the Dynamic control
UI's

## Why It's Good For The Game
Admin can do their things on 516
Coders/Mappers can debug some stuff on 516


![image](https://github.com/user-attachments/assets/013508d1-18cc-4001-92e4-0bc554960f86)

## Changelog

🆑
fix: Admin/Debug UI's (Especially the Game Panel) now work properly on
Byond 516, instead of showing raw HTML
/🆑
2025-01-06 18:13:48 -08:00
John Willard 2e4d70afe5 Updates href uses for 516 (#88699)
## 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.
2024-12-24 11:42:20 -08:00
MrMelbert 75696ab873 Fixes random stuff spilling into ooc tab (#88221)
## 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
/🆑
2024-11-27 17:41:52 +01:00
Penelope Haze b67a0901f2 Fix issues discovered via TypeMaker (#87596)
## 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.
2024-11-19 15:24:52 -05:00
harryob 30345725d2 fixes some dynamic rulesets purging their candidate pools (#87760)
## About The Pull Request
autotator, malf and blob's candidates would all get wiped out by this,
as `can_roll_midround()` returns TRUE if they can roll midround

## Why It's Good For The Game
seems like we want candidates in these roles, given the game is trying
to get some

## Changelog
🆑
fix: dynamic rulesets can get candidates for their roles
/🆑
fixes #87535
2024-11-09 16:57:45 +01:00
Jerry 314217b5cf Separate forced injection between latejoin and midround (#87557)
## About The Pull Request

Fixes an issue mentioned in
https://github.com/tgstation/tgstation/issues/72526, where pressing
"Now!" in the game panel for injecting a latejoin, caused midround one
to occur as well. This was because the same boolean was used for forcing
both, which caused both to happen.

* Closes https://github.com/tgstation/tgstation/issues/72526
## Why It's Good For The Game

Improves admin tools by fixing a bug.
## Changelog
🆑
admin: doing a latejoin injection no longer causes a midround one as
well
/🆑
2024-11-01 13:47:06 +01:00
Ghom 778ed9f1ab The death or internal/external organ pathing (ft. fixed fox ears and recoloring bodypart overlays with dye sprays) (#87434)
## 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):

![immagine](https://github.com/user-attachments/assets/2bb625c9-9233-42eb-b9b8-e0bd6909ce89)

## 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.
/🆑
2024-10-30 08:03:02 +01:00
Time-Green d170a410d4 Recovered Crew | Medical+Cargo Respawns (#87072)
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: _0Steven <42909981+00-Steven@users.noreply.github.com>
Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com>
2024-10-26 09:36:57 +02:00
grungussuss 58501dce77 Reorganizes the sound folder (#86726)
## 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
/🆑
2024-09-23 22:24:50 -07:00
Timberpoes 6808a082eb Assorted changes to job assignment code and logging. Runtime free, guaranteed or your money back. Price: $£0. (#85947)
## About The Previous Pull Request

#85308 reverted by #85929


![image](https://github.com/user-attachments/assets/e7518dcb-a60a-4bf1-a3d4-a5a8966d8633)

~~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
https://github.com/tgstation/tgstation/pull/85947/commits/e0e9f2f430079d4ab7097abe12e75f934131a638)

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.
/🆑
2024-09-13 13:58:35 +02:00