## About The Pull Request
[previous PR](https://github.com/tgstation/tgstation/pull/93290)
now command ID (silver & gold IDs) priority remain unchanged
example 1
<img width="435" height="105" alt="Screenshot 2025-10-22 112002"
src="https://github.com/user-attachments/assets/44868d9c-7487-4a9a-b0d9-c94ff4182f92"
/>
before
<img width="87" height="87" alt="Screenshot 2025-10-22 111655"
src="https://github.com/user-attachments/assets/a4223d03-f03f-43f0-bb54-fc8795fd1fab"
/>
^ if you were to remove engi id from the wallet above, it will show
robotics id (instead of secoff)
^ before this PR, engi IDs even took priority over wardens
after
<img width="88" height="90" alt="Screenshot 2025-10-22 112010"
src="https://github.com/user-attachments/assets/a16d508c-4819-4d0a-8316-1372a39a25ff"
/>
example 2
<img width="426" height="111" alt="Screenshot 2025-10-22 111714"
src="https://github.com/user-attachments/assets/fd5b563a-e454-4e0e-be7b-7cfbd9507ca3"
/>
before
<img width="87" height="87" alt="Screenshot 2025-10-22 111655"
src="https://github.com/user-attachments/assets/a4223d03-f03f-43f0-bb54-fc8795fd1fab"
/>
after
<img width="85" height="85" alt="Screenshot 2025-10-22 111646"
src="https://github.com/user-attachments/assets/d6f35891-a29f-4d93-bc4f-899064fa6807"
/>
example 3
before the pr, a geneticist id would take wallet priority over a chemist
id (for instance)
priority used to tally up how many 'command/secure access' areas on the
ID, rather than simply sort order.
for reference, these were the areas:
`ACCESS_AI_UPLOAD, ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_ARMORY,
ACCESS_CHANGE_IDS, ACCESS_COMMAND, ACCESS_EVA, ACCESS_KEYCARD_AUTH,
ACCESS_MINISAT, ACCESS_RC_ANNOUNCE, ACCESS_TCOMMS, ACCESS_TECH_STORAGE,
ACCESS_TELEPORTER, ACCESS_VAULT`
ACCESS_FLAG_COMMAND -> ACCESS_FLAG_PRV_COMMAND
so now it only checks if you have specifically head of staff access
instead
## Why It's Good For The Game
- player friendly
- previously lead to wallet tediousness and unpredictability
- make the core functionality and purpose of wallets simple and easy to
understand
- the previous functionality was more unpredictable and confusing when
considering low pop granting extra access to IDs
## Changelog
🆑 ArchBTW
qol: Changes Wallet Priority: Standard ID cards now go in order
properly: from left to right
/🆑
## About The Pull Request
<img width="491" height="301" alt="image"
src="https://github.com/user-attachments/assets/a3b5b19f-edf5-4de9-9201-9cbfab9e8827"
/>
Mod computers with the access changing software installed have a
secondary ID slot once again. This ID slot doesn't contribute to access.
You can insert IDs into the slot with right click and remove them with
alt-right click.
Also removes the "New IDs and you" memo paper.
Also tweaks PDA on_deconstruct so contents are dropped on when they're
deconstructed with assembly.
Fixes#92151
## Why It's Good For The Game
Changing IDs is very unnecessarily clunky with the one slot. Insert hop
id, log in, remove hop id, insert crew id, change access, remove crew
id, log out.
We had it right back when we had two slots. Insert hop ID, insert crew
id, log in. It just works.
This also allows for mobile HoPs to change access without necessitating
removing their ID from their PDA.
Other changes:
The "New IDs and you" memo is very old. They haven't been new for 4
years now. I don't think anyone reads it and they served their purpose.
I found it odd that, if your PDA was melted or blown up, it would delete
your ID. If this is a hold-over from old PDA behavior feel free to let
me know but otherwise it seems sensible that it'd spit out the contents
as you would expect.
## Changelog
🆑 Melbert
qol: The access changing software (the HoP console) now has ID two slots
again (one for the HoP's id and one for the ID being changed). You can
insert IDs in the secondary slot via the UI or right click, and remove
them via the UI or alt-right click.
qol: If your PDA is destroyed via acid or bombs, your ID (and similar
contents such as disks) are spit out instead of being deleted
del: Deletes the "New IDs and you" memo in the HoP's office. They
haven't been new for 4 years.
fix: Engineering sub-tab in the access changing software no longer looks
messed up
fix: Fix reversed alt-click logic for mod pcs
/🆑
## About The Pull Request
Changes human name to update whenever anything that could result in
their visible name changing occurs, such as changing IDs, equipping
gasmasks, picking potted plants, etc. Currently name updates occur every
``Life()`` tick and in a few "special" cases, which causes a lot of name
changes from sources such as equipment to not apply until the mob ticks,
and makes us waste a tiiiny bit of CPU time on name updates.
I've also slighly cleaned up human /Life() and made species'
``spec_life()`` not run when the mob is dead, as it was causing certain
unintended interactions, such as slimepeople regenerating blood while
dead.
## Why It's Good For The Game
Microoptimization, ensures that correct names are always used (in case
something could update their name but the mob hasn't ticked yet), plus
its just a cleaner implementation
## About The Pull Request
Continuation of #90365
- Formatted some usages of `set_holdable()` to be more readable
- `exception_hold` list now stores its values inside `
GLOB.cached_storage_typecaches`. This means we don't have to manage a
static typecache list per storage but can share the value across all
storages making memory management slightly more efficient
- Monkey cube boxes now cannot hold gorilla cubes cause that would make
gorilla cube boxes obsolete also now gorilla cube boxes can now only
hold gorilla cubes & not general monkey cubes(which gorilla cubes is a
subtype of) cause that would make monkey cube boxes obsolete. We are
specializing each box for that specific use case
## Changelog
🆑
code: further improved storage code
fix: monkey cube boxes can no longer hold gorilla cubes & vice versa
/🆑
## About The Pull Request
Reverts the storage initialization refactor and all subsequent related
PRs.
The original PR is below our standards both for code quality and
testing, and is majorly flawed at its core. This has been discussed with
other maintainers and headcoder(s?) over on discord. A lot of changes
from the PR could be brought over later, but in its current state it
should not have been merged.
- Closes#90322
- Closes#90313
- Closes#90315
- Closes#90320
- Closes#90312
- Closes#90344
## Why It's Good For The Game
This PR causes a series of major issues which cannot be resolved without
either completely rewriting a lot of the original PR, or bad code.
Not matching our standards is grounds for not merging a PR, and the fact
that a PR should not have been merged is a reason for a revert.
## Changelog
🆑
fix: Fixed a series of storage-related bugs caused by a refactor PR.
/🆑
## About The Pull Request
A Huge chunk of changes just comes from moving existing storage code
into new files & seperating `atom_storage` code into its own subtype
under the already existing `storage/subtypes` folder.
With that the changes in this PR can be organized into 3 categories.
**1. Refactors how `/obj/item/storage/PopulateContents()` initializes
storages**
- Fixes#88747 and every other storage item that has a similar variant
of this problem
The problem with `PopulateContents()` is that it allows you to create
atoms directly inside the storage via `new(src)` thus bypassing all the
access restrictions enforced by `/datum/storage/can_insert()` resulting
in storages holding stuff they shouldn't be able to hold.
Now how this proc works has been changed. It must now only return a list
of items(each item in the list can either be a typepath or a solid atom
or a mix of them in any order) that should be inserted into the storage.
Each item is then passed into `can_insert()` to check if it can fit in
the storage.
If your list contains solid atoms they must be first moved
to/Initialized in nullspace so `can_insert()` won't count it as already
inserted. `can_insert()` has now also been refactored to throw stack
traces but explaining exactly why the item could not fit in the storage
thus giving you more debugging details to fix your stuff.
A large majority of changes is refactoring `PopulateContents()` to
return a list instead of simply creating the item in place so simple 1
line changes & with that we have fixed all broken storages(medical
toolbox. electrical toolbox, cruisader armor boxes & many more) that
hold more items they can handle
**2. Organizes initialization of `atom_storage` for storage subtypes.**
All subtypes of `/obj/item/storage` should(not enforced) create their
own `/datum/storage/` subtype under the folder `storage/subtypes` if the
default values are not sufficient. This is the 2nd change done across
all existing storages
Not only does this bring code cleanliness & organization (separating
storage code from item code like how `/datum/wire` code is separated
into its own sub folder) but it also makes storage initialization
slightly faster (because you are not modifying default values after
`atom_storage` is initialized but you are directly setting the default
value in place).
You now cannot & should not modify `atom_storage` values inside
`PopulateContents()`. This will make that proc as pure as possible so
less side effects. Of course this principle is not enforced and you can
still modify the storage value after `Initialize()` but this should not
be encouraged in the future
**3. Adds support for automatic storage computations**
Most people don't understand how `atom_storage` values work. The comment
here clearly states that
https://github.com/tgstation/tgstation/blob/55bbfef0da70d87455ca8d6fd5c95107eb8dbefb/code/game/objects/items/storage/toolbox.dm#L327-L329
Because of that the linked issue occurs not just for medical toolbox but
for a lot of other items as well.
Which is why if you do not know what you doing, `PopulateContents()` now
comes with a new storage parameter i.e. `/datum/storage_config`
This datum allows you to compute storage values that will perfectly fit
with the initial contents of your storage. It allows you to do stuff
like computing `max_slots`, `max_item_weight`, `max_total_weight` etc
based on your storage initial contents so that all the contents can fit
perfectly leaving no space for excess.
## Changelog
🆑
fix: storages are no longer initialized with items that can't be put
back in after taking them out
refactor: storage initialization has been refactored. Please report bugs
on github
/🆑
## About The Pull Request
Currently patches are a subtype of pills, and while they have the
``dissolveable`` var set to FALSE, barely anything checks it (because
people don't expect patches to be pills in disguise) so we end up
patches being dissolveable and implantable, which is far from ideal.
Both have been moved into an ``/obj/item/reagent_containers/applicator``
class, which handles their common logic and helps handling cases where
either one fits. As for gameplay changes:
* Pills no longer dissolve instantly, instead adding their contents to
your stomach after 3 seconds (by default). You can increase the timer by
dropping sugar onto them to thicken their coating, 1s per 1u applied, up
to a full minute. Coating can also be dissolved with water, similarly
-1s per 1u applied. Pills with no coating will work like before.
* Patches now only take half as long to apply (1.5s), but also slowly
trickle in their reagents instead of instantly applying all of them.
This is done via embedding so you could theoretically (if you get lucky)
stick a ranged patch at someone, although they are rather quick to rip
off. The implementation and idea itself are separate, but the idea for
having a visual display has been taken from
https://github.com/Monkestation/Monkestation2.0/pull/2558.

* In order to support the new pill mechanics, stomachs have received
contents. Pills and items that you accidentally swallow now go into your
stomach instead of your chest cavity, and may damage it if they're
sharp, requiring having them surgically cut out (cut the stomach open
with a scalpel, then cauterize it to mend the incision). Or maybe you
can get a bacchus's blessing, or a geneticist hulk to gut punch you,
that may also work. Alien devour ability also uses this system now. If
you get a critical slashing wound on your chest contents of your cut
apart stomach (if a surgeon forgot to mend it, or if you ate too much
glass shard for breakfast) may fall out. However, spacemen with the
strong stomach trait can eat as much glass cereal as they want.
Pill duration can also be chosen in ChemMaster when you have a pill
selected, 0 to 30 seconds.

## Why It's Good For The Game
Patches and pills are extremely similar in their implemenation, former
being a worse version of sprays and pills, with only change being that
pills cannot be applied through helmets while patches and sprays ignore
both. This change makes them useful for separate cases, and allows
reenactment of some classic... movie, scenes, with the pill change. As
for stomach contents, this was probably the sanest way of implementing
pill handling, and everything else (item swallowing and cutting stomachs
open to remove a cyanide pill someone ate before it dissolves) kind of
snowballed from there. I pray to whatever gods that are out there that
this won't have some extremely absurd and cursed interactions (it
probably will).
## Changelog
🆑
add: Instead of dissolving instantly, pills now activate after 4
seconds. This timer can be increased by using a dropper filled with
sugar on them, 1s added per 1u dropped.
add: Patches now stick to you and slowly bleed their reagents, instead
of being strictly inferior to both pills and sprays.
add: Items that you accidentally swallow now go into your stomach
contents.
refactor: Patches are no longer considered pills by the game
refactor: All stomachs now have contents, instead of it being exclusive
to aliens. You can cut open a stomach to empty it with a scalpel, and
mend an existing incision with a cautery.
/🆑
## About The Pull Request
Removes some hard-coded values from wallets, ie name change on
update_label() and overlay icon_state
## Why It's Good For The Game
Easier to add new wallets
## About The Pull Request
Since non-clothing items can also be worn on several slots, there's no
need for cigarettes/vapes to be subtypes of masks anymore, since that
comes with a few oddities like #82870.
## Why It's Good For The Game
This should fix#82870, with about no side-effect aside them no longer
being edible by moths 🤢.
## About The Pull Request
https://github.com/tgstation/tgstation/pull/79843 but working...
So. Turns out the inventory is just a whitelist. Not just 'any tiny
item'.
Whoops.
Also alphabetized the list since I was working on it. Hopefully I did
that right.
Listing the changes, off the top of my head:
- Resprited fishing rods, hooks, and the worm bait!
- Added a new, telescopic fishing rod, that can be bought as a goodie.
The master rod is also telescopic now.
- Added a couple hooks. One that lets you move the bait up and down,
otherwise keeping it in place, and another that stops the fish from
escaping, but slowly kills it. The former from the bepis fishing tech
node, the latter frm the black market.
- Added a fishing skill and relative legendary reward: A fishing hat,
like the one that recites "women fear me, fish fear me"
- You can now stop fishing by activating the fishing rod in your hand,
and stops it from stealing all clicks on other things if it isn't in
your active hand.
- Reworked fishing traits into fish traits, which can apply to fish
after it has been caught.
- Expanded the fish breeding system. Traits may be passed down to
offsprings, and offsprings may evolve (mutate?) into different kind of
fishes if conditions when conditions are met.
- Added half a dozen new fishes, each with its own traits: lubefish,
sludgefish (and its purple variant), slimefish, unmarine bonemass and
unmarine mastodon. Also, holodeck fish, as a joke.
- New traits: lubed skin, parthenogenesis, toxic (new reagent), toxin
immunity, predator, necrophage, no mating, crossbreeder, aggressive and
revival. Converted Emulsijack's ability and Donkfish's yuckiness into
traits as well.
- Added a fish analyzer that you can scan aquariums and fishes with.
- Fish can now be blended if you really want to. The number of reagents
from blending, w_class, and the number of fillets you get from cutting
fish now scale with size and weight.
- fish feed is no longer infinite (but it should still be plenty).
- Implemented temperature requirements for aquarium fish.
- You can now buy (dead) fish from the black market for dirt cheap.
- Last but now least, toilets are now valid fishing spots.
Added the paper biscuits (the ones with the id code) and laser pointers
to the list of things that you can put inside a wallet. If you have
ideas for anything that should also be allowed to be inside wallets,
comment it. I'm sure we have missed some things along the way.
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may
not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull
request process. -->
## About The Pull Request
So they just had list from 6 coins and not random picking of coins, so
now its random.
It will also spawn chococoin because it's a coin too.
But won't spawn `coin/gold/debug` because it's debug and eldritch coin
because comxy asked about it.
Added chococoin to `/obj/effect/spawner/random/entertainment/coin` and
holdables list of wallet.
<!-- Describe The Pull Request. Please be sure every change is
documented or this can delay review and even discourage maintainers from
merging your PR! -->
## Why It's Good For The Game
Random is funny.
<!-- Argue for the merits of your changes and how they benefit the game,
especially if they are controversial and/or far reaching. If you can't
actually explain WHY what you are doing will improve the game, then it
probably isn't good for the game in the first place. -->
## Changelog
<!-- If your PR modifies aspects of the game that can be concretely
observed by players or admins you should add a changelog. If your change
does NOT meet this description, remove this section. Be sure to properly
mark your PRs to prevent unnecessary GBP loss. You can read up on GBP
and it's effects on PRs in the tgstation guides for contributors. Please
note that maintainers freely reserve the right to remove and add tags
should they deem it appropriate. You can attempt to finagle the system
all you want, but it's best to shoot for clear communication right off
the bat. -->
🆑
add: Indusrial Gold and Regenerative Gold extracts now spawn random
coins and not just list of 6 coins. But no mythril as it has miserable
chance to have summoning effect which have even more miserable chance to
spawn something dangerous and not just mice.
add: Chococoin now has a chance to spawn wherever the coins are used to
spawn (wallets, greed ruins, deltastation bar)
/🆑
<!-- Both 🆑's are required for the changelog to work! You can put
your name to the right of the first 🆑 if you want to overwrite your
GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the
icon ingame) and delete the unneeded ones. Despite some of the tags,
changelogs should generally represent how a player might be affected by
the changes rather than a summary of the PR's contents. -->
---------
Co-authored-by: Fikou <23585223+Fikou@users.noreply.github.com>
## About The Pull Request
hey there! as it turns out, the pr that made storage a datum instead of
a component, changed the default value of maximum item size from small
to normal. medkits (and wallets too, but they can only fit some specific
items) didnt override this.
that means they could hold 4 normal sized items (and some small), kind
of invalidating storage space, as you had just a box but better.
its fixed now
edit: candle boxes too
## Why It's Good For The Game
bug bad abuse bad storage bad
## Changelog
🆑
fix: fixes medkits (and wallets, candle boxes) being able to store
normal sized items
/🆑
* Removes overlay queuing, saves 6/7 seconds of initialize. Lightly modifies stat tracking macros
So we have this overlay queuing system right? It's build with the assumption
that the "add to overlay list" operation is real expensive, and is
thus useful to queue removals or additions.
It turns out that it just isn't, at least during init. In my testing the
operation of queuing took LONGER then the actual overlay add/remove did.
That's ignoring the cost of the subsystem's work.
I've also modified part of the stat tracking macro, since it took a good
bit of cpu time, and didn't seem to well, do anything. So far as I can
tell it always evaluates to 1
Currently, storage works as a subtype of /datum/component, utilizing GetComponent() and signals to operate. While this is a pretty good idea in theory, the execution was pretty trash, and we end up with alot of GetComponent() snowflake code (something that shouldn't even need to be used frankly), and a heaping load of scattered procs that lead into one another, and procs that don't get utilized properly.
Instead, this PR adds atom_storage and proc/create_storage(. . .) to every atom, allowing for the possibility of storage on quite frankly anything. Not only does this entirely remove the need for signals, but it heavily squashes down the number of needed procs in total (removing snowflake signal procs that just lead to one another), reducing overall proc overhead and improving performance.
## About The Pull Request
stop forgetting to include mapload, if you don't include it then every single subtype past it by default doesn't include it
for example, `obj/item` didn't include mapload so every single item by default didn't fill in mapload

## Regex used:
procs without args, not even regex
`/Initialize()`
procs with args
`\/Initialize\((?!mapload)((.)*\w)?`
cleanup of things i didn't want to mapload:
`\/datum\/(.)*\/Initialize\(mapload`
First off, I am aware of the Feature Freeze for this month. This PR was initially started in #60401 about a month ago to break the changes into smaller PRs. The end result for this PR is a poor man's attempt at roguelike procedural generation. Enjoy!
Link to the README for how the new spawner system works.
Added the following new random mapping spawners:
pen, crayon, stamp, paper, pamphlet, briefcase, folder, wardrobe closet, wardrobe closet colored, backpack, narcotics, permabrig_weapon, permabrig_gear, prison, material, carpet, ornament, generic decoration, statue, showcase, paint, tool, tool_advanced, tool_rare, material_cheap, material, material_rare, toolbox, flashlight, canister, tank, vending_restock, atmospherics_portable, tracking_beacon, musical_instrument, gambling, coin, money_small, money, money_large, drugs, dice, cigarette_pack, cigarette, cigar, wallet_lighter, lighter, wallet_storage, deck, toy, toy_figure, booze, snack, condiment, cups, minor_healing, injector, surgery_tool, surgery_tool_advanced, surgery_tool_rare, firstaid_rare, firstaid, patient_stretcher, medical supplies, crate, crate_abandoned, girder, grille, lattice, spare_parts, table_or_rack, table, table_fancy, tank_holder, crate_empty, crate_loot, closet_private, closet_hallway, closet_empty, closet_maintencne, chair, chair_maintence, chair_flipped, chair_comfy, barricade, data_disk, graffiti, mopbucket, caution_sign, bucket, soap, box, bin, janitor_supplies, soup, salad, dinner
Removed deprecated wizard trap, vault, and armory spawners.
Add a new simple station trait, that replaces everyone's ID with a
wallet containing said ID, as well as their starting money, and if
they're lucky, a little bonus surprise.
In addition, adds a force variable to station traits, which will
always enable them, rather than having to edit weight and probability
of rolling a trait of that sign (postive, negative).
Co-authored-by: Rohesie <rohesie@gmail.com>
Many moons after I reworked ID cards, I feel the Agent ID card needs a little bit of extra love.
This change adds an option during forging which allows the user to specify whether the agent ID card will force itself to the front-facing/visible ID slot in wallets.
This provides traitors with a way to effectively disguse any special ID cards and accesses they may have without making the agent ID card a must-buy TC tax. If your traitor strategy involves gathering many ID cards, this is a definite buff to an item that took a heavy hit to power in the rework.
Enter(), Entered(), Exit() and Exited() all passed the old loc forward, but everything except a single a case cared about the direction of the movement more than about the specific source.
Since moving multi-tile objects will have multiple sources of movement but a single direction, this change makes it easier to track their movement.
Cleaned up a lot of code around and made proc inputs compatible.
I'll add opacity support for multi-tile objects in a different PR after this is merged, as this has grown large enough and I don't want to compromise the reviewability.
Tested this locally and as expected it didn't impair movement nor produced any runtimes.
Converts most spans into span procs. Mostly used regex for this and sorted out any compile time errors afterwards so there could be some bugs.
Was initially going to do defines, but ninja said to make it into a proc, and if there's any overhead, they can easily be changed to defines.
Makes it easier to control the formatting and prevents typos when creating spans as it'll runtime if you misspell instead of silently failing.
Reduces the code you need to write when writing spans, as you don't need to close the span as that's automatically handled by the proc.
(Note from Lemon: This should be converted to defines once we update the minimum version to 514. Didn't do it now because byond pain and such)
Creates update_name and update_desc
Creates the wrapper proc update_appearance to batch update_name, update_desc, and update_icon together
Less non-icon handling code in update_icon and friends
Signal hooks for things that want to change names and descriptions
99%+ of the changes in this are just from switching everything over to update_appearance from update_icon
* update_icon() improvements
Fixes some update_icon() calls to properly call parent and use update_overlays() and update_icon_state().
The rest of obj/item fuck it
* Suggested fixes, also passes the linter
* I always forget . = ..() is faster than return ..() FOR SOME FUCKING REASON
* Actually this is better
* Signilzes datum/action to update its icon when its connected item does.
* Removes repeated line
* Description change for clothing items that can only store specific items
* Get all children of can_hold listed items.
* can_hold only needs the top most item, child items are dealt automatically
* cant_hold related change
* Text change
* Moves the item check to the line above, and removes the current.
* Same changes, but to belt/wallet code.
* Change to using signals instead
* Generic signal on datum/topic
* Cache typecache, and small signal change
* Small argument tweaks and remove unneeded lists
* Change to proc
* Change call can_holds/cant_holds to use new proc
* initial, and cleaned up display code
* Null check
* Update wallets.dm
* Update pockets.dm
* Apply suggestions from code review
For when people forget how sister code works
Co-Authored-By: Trilbyspaceclone <30435998+Trilbyspaceclone@users.noreply.github.com>
cl XDTM
add: Added credit holochips, a form of semi-physical currency to use in transactions. They can be generated by id cards by drawing from bank accounts and can be used to make payments.
add: There is no limit to the amount of credits that can be stored on a holochip, but being holograms they are vulnerable to electromagnetic pulses, and may disappear if exposed to one!
add: Holochips can be split with alt-click, and can be merged by clicking on another holochip.
/cl
Inserting physical cash into ids and printing it on the go is really jarring, and since we're on a sci-fi universe i think that hard-light hologram chips with encrypted credits sounds more believable.
As a plus, they don't have to deal with messy stack calculations with different denominations, and simply have a credits var that holds their amount. They change color based on the amount of cash for easy recognizability.