## About The Pull Request
Re-adds nanites, balance changes pending.
No plans to do mapping/role changes
Based on https://github.com/tgstation/tgstation/pull/60473 with a lot of
work on modularizing
## Why It's Good For The Game
Nanites are a rather interesting system, my hope is to port it in a more
balanced format.
## Proof Of Testing
Works, thoroughly tested
## Changelog
🆑
add: Re-adds nanites
/🆑
TODO:
- [x] Add techweb linking for nanites
- [x] Prevent stacking of armor mods (fortitude + dna vault + nanite
armor)
- [x] Rebalance damage regeneration programs
- [x] Remove force speak program by @StrangeWeirdKitten request
- [x] Convert UI's to TSX
- [x] Fix Nanite program uhb and programmer overlays not working
---------
Co-authored-by: Waterpig <49160555+Majkl-J@users.noreply.github.com>
## About The Pull Request
This PR should fix the problem of small previews in TGUI once and for
all (I hope).
What was causing it? Because TGUI takes a long time to open, that's why
previews were generated broken (small).
On Byond 515 this problem was not so noticeable as the interfaces opened
faster, but with the release of 516 it became much worse.
Previews were generated inside a window that was not yet open, so the
scale was broken, sometimes the window would open before the preview was
done and sent, usually with small interfaces, or when reopening.
I'm not very good at working with signals, and to tell the truth this is
my second experience with them, so I hope I did it right.
## Why It's Good For The Game
No more small map previews
<details> <summary> Video </summary>
https://github.com/user-attachments/assets/834f3820-cc6a-4f65-90e5-d6bb2a118bcf
</details>
## Changelog
🆑
fix: Fixed small character preview, color matrix preview, mech preview,
and other previews with uses ByondUI map
/🆑
---------
Co-authored-by: Gaxeer <44334376+Gaxeer@users.noreply.github.com>
Replaces the asset subsystem's spritesheet generator with a rust-based
implementation (https://github.com/tgstation/rust-g/pull/160).
This is a rough port of
https://github.com/BeeStation/BeeStation-Hornet/pull/10404, but it
includes fixes for some cases I didn't catch that apply on TG.
(FWIW we've been using this system on prod for over a year and
encountered no major issues.)

`/datum/asset/spritesheet_batched`: A version of the spritesheet system
that collects a list of `/datum/universal_icon`s and sends them off to
rustg asynchronously, and the generation also runs on another thread, so
the game doesn't block during realize_spritesheet. The rust generation
is about 10x faster when it comes to actual icon generation, but the
biggest perk of the batched spritesheets is the caching system.
This PR notably does not convert a few things to the new spritesheet
generator.
- Species and antagonist icons in the preferences view because they use
getFlatIcon ~~which can't be converted to universal icons~~.
- Yes, this is still a *massive* cost to init, unfortunately. On Bee, I
actually enabled the 'legacy' cache on prod and development, which you
can see in my PR. That's why I added the 'clear cache' verb and the
`unregister()` procs, because it can force a regeneration at runtime. I
decided not to port this, since I think it would be detrimental to the
large amount of contributors here.
- It is *technically* possible to port parts of this to the uni_icon
system by making a uni_icon version of getFlatIcon. However, some
overlays use runtime-generated icons which are ~~completely unparseable
to IconForge, since they're stored in the RSC and don't exist as files
anywhere~~. This is most noticeable with things like hair (which blend
additively with the hair mask on the server, thus making them invisible
to `get_flat_uni_icon`). It also doesn't help that species and antag
icons will still need to generate a bunch of dummies and delete them to
even verify cache validity.
- It is actually possible to write the RSC icons to the filesystem
(using fcopy) and reference them in IconForge. However, I'm going to
wait on doing this until I port my GAGS implementation because it
requires GAGS to exist on the filesystem as well.
IconForge generates a cache based on the set of icons used, all
transform operations applied, and the source DMIs of each icon used
within the spritesheet. It can compare the hashes and invalidate the
cache automatically if any of these change. This means we can enable
caching on development, and have absolutely no downsides, because if
anything changes, the cache invalidates itself.
The caching has a mean cost of ~5ms and saves a lot of time compared to
generating the spritesheet, even with rust's faster generation. The main
downside is that the cache still requires building the list of icons and
their transforms, then json encoding it to send to rustg.
Here's an abbreviated example of a cache JSON. All of these need to
match for the cache to be valid. `input_hash` contains the transform
definitions for all the sprites in the spritesheet, so if the input to
iconforge changes, that hash catches it. The `sizes` and `sprites` are
loaded into DM.
```json
{
"input_hash": "99f1bc67d590e000",
"dmi_hashes": {
"icons/ui/achievements/achievements.dmi": "771200c75da11c62"
},
"sizes": [
"76x76"
],
"sprites": {
"achievement-rustascend": {
"size_id": "76x76",
"position": 1
}
},
"rustg_version": "3.6.0",
"dm_version": 1
}
```
Universal icons are just a collection of DMI, Icon State, and any icon
transformation procs you apply (blends, crops, scales). They can be
convered to DM icons via `to_icon()`. I've included an implementation of
GAGS that produces universal icons, allowing GAGS items to be converted
into them. IconForge can read universal icons and add them to
spritesheets. It's basically just a wrapper that reimplements BYOND icon
procs.
Converts some uses of md5asfile within legacy spritesheets to use
rustg_hash_file instead, improving the performance of their generation.
Fixes lizard body markings not showing in previews, and re-adds eyes to
the ethereal color preview. This is a side effect of IconForge having
*much* better error handling than DM icon procs. Invalid stuff that gets
passed around will error instead of silently doing nothing.
Changes the CSS used in legacy spritesheet generation to split
`background: url(...) no-repeat` into separate props. This is necessary
for WebView2, as IE treats these properties differently - adding
`background-color` to an icon object (as seen in the R&D console) won't
work if you don't split these out.
Deletes unused spritesheets and their associated icons (condiments
spritesheet, old PDA spritesheet)
If you press "Character Setup", the 10-13sec of lag is now approximately
0.5-2 seconds.
Tracy profile showing the time spent on get_asset_datum. I pressed the
preferences button during init on both branches. Do note that this was
ran with a smart cache HIT, so no generation occurred.

Much lower worst-case for /datum/asset/New (which includes
`create_spritesheets()` and `register()`)

Here's a look at the internal costs from rustg - as you can see
`generate_spritesheet()` is very fast:

**Before**

**After**

🆑
fix: Fixed lizard body markings and ethereal feature previews in the
preference menu missing some overlays.
refactor: Optimized spritesheet asset generation greatly using rustg
IconForge, greatly reducing post-initialization lag as well as reducing
init times and saving server computation.
config: Added 'smart' asset caching, for batched rustg IconForge
spritesheets. It is persistent and suitable for use on local, with
automatic invalidation.
add: Added admin verbs - Debug -> Clear Smart/Legacy Asset Cache for
spritesheets.
fix: Fixed R&D console icons breaking on WebView2/516
/🆑
## About The Pull Request
Port of a fix from
https://github.com/Monkestation/Monkestation2.0/pull/4995
Due to how modular computers worked with the nested tgui stuff, the
SecurEye app wouldn't properly autoupdate whenever a camera it was
watching moved (when there's not any tracking going on)
This "fixes" that issue by adding a new var, `always_update_ui`, to
modular computer programs, which will make the modpc call the active
program's `ui_interact` even after the UI is opened.
## Why It's Good For The Game
bugfix good. if the whole "watch broadcast camera streams on PDA" thing
ever gets ported here, this is a needed fix for that.
## Changelog
🆑
fix: SecurEye now properly follows moving cameras.
/🆑
I standardized stuff in AASs code, and all current reference to it. Also
added interactions for bounty cubes, weather reports and request
consoles, all of it can be changed from AASs UI.
Also it's easier now to add new config entries for AAS to proceed, and
it's now downstream friendly.
Well, because kind of order in code and because it's funny to make
custom messages for... Almost everything?
BTW any entry can be blocked from ingame changes, by default you can't
change Broken Arrival shuttle and Security Officer arrival
announcements, how it was before. But may be we should allow it - it's
an open question.
🆑
add: Many things now handles via AAS: Bounty Cubes, Request Consoles,
Brig Cells, Vending Machines and Orion Trails alerts, Weather Reports,
Cargo Order Console
code: Now anyone can make their own entry for AAS
refactor: AAS internals, also cleanup
/🆑
## About The Pull Request
Closes#89329
Also added a balloon_alert
## Changelog
🆑
qol: SiliConnect now informs you that you're successfully downloading
logs
fix: Fixes SiliConnect not being able to download logs
/🆑
## About The Pull Request
-Creates a new button in the "Secrets" menu that can override the
cooldown for ordering items from department consoles. It can be used to
make the cooldown longer, shorter or non-existent.
-Creates a new global var to manage this override on every console in
dept_order.dm
## Why It's Good For The Game
This tool assists in finding and fixing bugs related to cargo orders and
cargo crates. The wait time for these cooldowns can be ten minutes or
longer, and this speeds up the process significantly.
It could also be used by admins during play to make the cooldown lower,
or cause absolute mayhem on cargo by setting the cooldown duration to 0.
## Changelog
🆑
add: Added a button in the "Secrets" menu to alter the department
console order delay.
qol: Button makes it easier to find cargo related bugs.
code: Changed code in department_order.dm to allow for overriding the
order cooldown duration.
admin: Created an admin button in the "Secrets" panel.
/🆑
---------
Co-authored-by: Zephyr <12817816+ZephyrTFA@users.noreply.github.com>
## About The Pull Request

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.
/🆑
## About The Pull Request
Adds a new NTOS application to the game: "Plexagon Punch Clock", which
functions similarly to the time clock in cryo.
Using the app, crew members can clock out wherever they want. This will
also create a locked briefcase containing certain job-related items;
this can be unlocked by the player once they return to the shift, or by
a relevant Command member.
For later changes I'd like to be able to have this app be able to clock
in/out a user via their DNA imprint.
## Why It's Good For The Game
- It's easier to clock out before going for RP/ERP when done with work.
- Placing job items in an easily-accessible box means that it's less
annoying to return to work after finishing RP/ERP
- Convenience
## Proof Of Testing
<details>
<summary>Screenshots/Videos</summary>

</details>
## Changelog
🆑 ArrisFairburne, LT3
add: Added a new app to clock in and out from any NT OS-compatible
device (Plexagon Punch Clock)
qol: Your job items are now locked into a box instead of warped to cryo,
when clocking out
/🆑
---------
Co-authored-by: lessthanthree <83487515+lessthnthree@users.noreply.github.com>
Co-authored-by: The Sharkening <95130227+StrangeWeirdKitten@users.noreply.github.com>
## About The Pull Request
fix image display in `NT IRN` PDA app
<details>
<summary>
Images present!
</summary>

</details>
## Why It's Good For The Game
Bug fixes good
## Changelog
🆑
fix: fix image display in `NT IRN` PDA app for preview and contents
/🆑
## About The Pull Request
PDAs no longer go white when the virtual pet app is opened
## Why It's Good For The Game
fixes virtual pet app changing PDA's colors when open
## Changelog
🆑
fix: fixes virtual pet app changing PDA's colors when open
/🆑
## About The Pull Request
Fixes#89272
- Adds an argument to `is_wire_tool` to fail if the item is secured,
which assemblies are by default. (They must be screwdriver'd to attach
to things)
Makes cyborg use item interaction
- Cleaner, non-deprecated attack chain.
- Also changes to chats to balloon alerts.
## Changelog
🆑 Melbert
qol: Using items on cyborgs now use balloon alerts instead of chat
messages.
fix: You can flash cyborgs again
refactor: Refactored item interaction on cyborgs.
/🆑
## About The Pull Request
Replace bubble sort with timsort for cameralist
Move cameralist related global procs to `cameranet` datum
Other minor code cleanup things
## Why It's Good For The Game
Cameralist reads for UIs are now more performant
## Changelog
🆑
refactor: replace bubble sort with timsort for cameralist, move global
procs to `cameranet` datum
/🆑
## About The Pull Request
This PR makes the reward and cooldown for departmental orders scale with
crate cost using a logarithmic scaling, instead of comparing the price
to preset thresholds for time, or awarding the same amount as the
crate's cost.
Previously, to calculate the cooldown time, the code was calculated via
the following manner:
```
credits = clamp(credits, min, max)
time_y = 10 MINUTES * ((credits - min)/(max - min) + 1)
```
Minimum was 320 credits, max was 3000, thus, all crates slid around
between 10 minutes to 20 minutes.
The reward for delivering the crates was the same as the crate's value.
This meant ordering egregiously expensive crates, far beyond 3000 was
way too desirable.
This PR changes both to use logarithmic scaling.
Cooldown time uses `60* log(price)^2.2`, and reward uses `140 *
log(price)^1.4`.
**Cooldown analysis**
At 320 it's 7.54 minutes, at 1400 it's 12.44 minutes, at 3000 (around
gun crates) it's 15.5 minutes, at 8000 (hat crate) 20 minutes, at 9000
(expensive atmos cans) it's 20.58 minutes, and at the 20k crate it's
24.76 minutes.
**Crate rewards analysis**
At 320 it's 475 credits, at 1400 it's 669 credits, at 3000 (around gun
crates) its 778, at 8000 (hat crate) it's 925 credits, at 9000
(expensive atmos cans) it's 943 credits, and at the 20k crate it's 1070
credits.
Up to 540 credits, you are actually getting a higher reward than what
the crate costs, but this is okay, as its a reward for delivering
simpler orders. A little surplus for you.
For the console UI, I have made items costing 3000 or more display
Moderate, and items costing 8000 or more, Long cooldowns.
## Why It's Good For The Game
Ordering really expensive crates should be a luxury, not a way to
generate money. The money is supposed to be a bonus, in addition to the
free crate to sell. Using a logarithmic scale, the credit bonus is
reigned in more evenly, making it more predictable for economy tweaking,
and avoids players double dipping credits in their free purchase.
Decreasing the rewards also give space for other new ways to generate
rewards in relation to departmental orders, such as stamping the
manifest with the correct head's stamp being worth more money and such.
<details>
<summary>Old PR Text, which was using a price cap instead</summary>
## About The Pull Request
Departmental orders are a neat feature, but some of the available packs
had problems economywise. The cooldown of range from 10 to 20 minutes,
with 10 minutes being the base for anything costing less than 320
credits, and 20 minutes at 3000 credits. I have no problem with the
lower cap, but the upper cap has issues, as recently, a 20k crate was
added to cargo, which means it is possible to dump quite a large amount
of funds into cargo every 20 minutes.
Departmental orders probably need a bigger overhaul, and this solution
is imperfect, but I have talked with @ArcaneMusic about this as an
interim stop gap measure.
This PR also autodocs a proc, and moves some values to global defines,
for ease of balancing.
This PR affects the following crates, with the uncapped crate values in
brackets.
Armoury
- Combat Shotguns (3500 credits)
- Energy Guns (3600 credits)
- NT BR-38 Crate (20,000 credits)
Engineering
- BSA parts (6000 credits)
- DNA Vault Parts (4800 credits)
Engine Construction
- HFR Crate (4800)
- Supermatter Shard Crate (4000)
Materials
- BZ Crate (9000 credits)
- Nitrous Oxide (9000 credits)
- Water Vapor Crate (3010 credits)
Toys
- Collectible Hats Crate (8000 credits)
## Why It's Good For The Game
Instantly awarding 20k to cargo every 20 minute, in addition to 27k from
the other consoles (if both engineering and science orders BZ, service
orders collectible hats, and medical orders something around 1000), is a
bit too much. The money gained should be along a much more predictable
and expected value. With this chance, the most they can get is 13k every
20 minutes across all departments.
</details>
## Changelog
🆑
balance: Rewards from departmental orders use a logarithmic scale,
resulting in less rewards for high tier crates. The cooldown time is
also logarithmic now, which has slightly decreased cooldown values on
cheaper crates.
/🆑
## About The Pull Request
when you summon a virtual pet's hologram, itll automatically follow you
on release rather than u having to give it the command
## Why It's Good For The Game
adds some minor convenience to the minigame.
## Changelog
🆑
qol: virtual pet holograms now automatically follow you when released
rather than having to give it the command post summon
/🆑
Renames all uses of caller, as they (currently) shadow the new byond var
and will in future error
Ups our "wan if compiled after" experiement compile version to 516
Adds an alternate 516 unit test
## About The Pull Request
Was just scrolling through the Paradise github since they seem to have
more work done for 516 to see if there's anything I can port over, found
this and thought why not.
Ports parts of https://github.com/ParadiseSS13/Paradise/pull/25105
Specifically, updaing all hrefs to use the internal ``byond://``, and
adding it to grep.
## Why It's Good For The Game
More work towards 516.
## Changelog
Nothing player-facing.
## About The Pull Request
<!-- Describe The Pull Request. Please be sure every change is
documented or this can delay review and even discourage maintainers from
merging your PR! -->
Modular computer laptops can now be interacted with RMB when open, or
opened with RMB when closed.
Also screentips for this added.
It was inteded for laptops to be interactable when open. but didn't work
because old code was not adjusted for attack chains.
## Why It's Good For The Game
Laptop usage is more user friendly :D
<details>
<summary>Demonstration :D</summary>

</details>
## Changelog
🆑
fix: modular computer laptops can now be interacted with RMB, instead of
picked up
qol: modular computer laptops can now be interacted with RMB when open,
or opened with RMB when closed. Also screentips for this added
/🆑
---------
Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
## About The Pull Request
Add a missing period to the PDA typing message.
## Changelog
🆑
spellcheck: Added a missing period to the PDA typing message.
/🆑
## About The Pull Request
Lil cleanup/tweak I couldn't do in the main PR because it conflicted
before and i forgot after. Yes this works with overrides that don't have
the arg, yes I tested it.
## Why It's Good For The Game
Don't run armor code thrice please thank you
## Changelog
🆑
code: Projectile impacts no longer fetch mobs' armor values thrice
/🆑
## About The Pull Request
Fixes issues with var typing and proc arguments, discovered using
OpenDream's WIP TypeMaker feature (using improvements I haven't PR'd
upstream yet).
## Why It's Good For The Game
Codebase maintenance.
## About The Pull Request
See name, if a dummy somehow gets hold of a PDA with the camera app
installed (This just so happens to be a default PDA program in the case
on Nova, Skyrat, and Bubber), and the delete_equipment proc is called,
the camera inside the PDA gets sent to the wardrobe because of
`/datum/outfit/job/assistant/gimmick/hall_monitor` having one, and then
qdelled with the PDA, leaving a hanging ref
This causes a harddel during tests that has caused me great pains to
locate. Turns out a single example holodisk with the clown holds a
magical key to trigger all this: a single PDA
## Why It's Good For The Game
Fixes a harddel. There might be other similar ones hiding in the dark
like cameras in other objects.
## Changelog
🆑
fix: Fixes SSWardrobe stealing a camera from the camera app when on a
dummy, causing a harddel
/🆑
## About The Pull Request
As before, more fiddling with NTNRC, more bugs.
This time, the same user sending the same message within the same second
would cause this message to spawn a new copy each time the channel was
opened, until the UI was closed and re-opened.
Looking into it, this seemed to be because we would set the `Box`'s
`key` value to the message contents:
<b0d71024c0/tgui/packages/tgui/interfaces/NtosNetChat.jsx (L156)>
Which isn't actually unique.
To fix this, we instead make each channel keep track of an incrementing
`id` number to assign to each message, and convert the `messages` list
to an associative list using those numerical ids stringified.
We don't just use the list index as a key, as we later may want to
target specific messages, so a consistent unique key is important.
This fixes our primary issue.
In the process of making the rest of the code account for this, I
noticed that the NTNRC program header that's supposed to show new
messages in the active channel when the program is idle didn't actually
work.
Just at all.
So I rewrote the entire thing, and it now tracks the last read message's
id rather than the full message, and sets this when you actually
background the program. The rest still runs on process tick, where it
updates the header if there's a new message with a different id on top.
Finally, the header part of the UI wasn't actually updating if there
were no headers, so now it forwards a lack of headers change as well.
## Why It's Good For The Game
Reduces more NTNRC jank.
Good if shit like, actually works.
## Changelog
🆑
fix: NTNRC no longer endlessly duplicates messages with duplicate
contents upon switching channels.
fix: The new message header you get when NTNRC runs in the background
actually works.
fix: NtOS header actually updates if there are no program headers.
/🆑
---------
Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com>
## About The Pull Request
- SiliConnect is no longer a default app for cyborgs.
- RoboTact, the borg self-status app now has a Network tab, which lists
other borgs' status.
- The Network tab will only list borgs connected to the same AI as you.
If your AI goes down, you lose connection to other borgs' status info.
- Your AI is also listed on the Network tab, with their own status in a
very binary good/bad form.
- Syndicate borgs are able to see other syndicate borgs on the Network
list, even though they lack an AI.
## Why It's Good For The Game
SiliConnect was recently added to the default borg apps list. But it has
a lot of features that borgs can't actually use, and so feels rather
messy. It was added with the goal of letting borgs see eachother's
status, and so I've ported that functionality into RoboTact. SiliConnect
is no longer a default borg app (though it *can* be installed if a borg
and human really want it to be).
Showing the AI's status is certainly a balance choice. But it's not
really that much of a secret when the AI dying already adjusts the
monitors across the station to a BSOD image. On the flip side, we get to
shut off borg status sharing when the AI goes offline, which is neat.
## Changelog
🆑
del: SiliConnect, a tool meant for Roboticists, is no longer included by
default on borgs.
add: RoboTact, the borg self-status app, now shows the status of other
borgs synced to the same AI. Syndicate borgs can likewise see
eachother's status, even without an AI.
balance: RoboTact also shows their synced AI's very basic status of
functional or offline.
/🆑
UI Pictures:

Dead AI:

Syndicate borgs do not see station borg status, but can see eachother's

~~Drafting because I need to do edge-case testing, and the AI box isn't
quite functioning correctly when the borg has no AI master.~~
## About The Pull Request
Massive cleanup/pseudo-refactor of projectile and projectile-adjacent
code. One letter variables, weird logic, some runtimes, all of that.
Atomized in a separate PR from the actual refactor so we don't end up
with a 5k line PR.
## Why It's Good For The Game
Makes the code possible to work with before I nuke pixel_move and kevinz
units™️
## About The Pull Request
During all that fiddling with NTNRC I noticed that sometimes the
download percentage would shoot above 100%.
Looking into it, it seems that that's just because it isn't actually
capped at the downloaded file size.
So we cap it to the file size after adding our next download chunk, but
parallel to before don't complete it immediately so that we stay on 100%
for another cycle before finishing. For style reasons.
Then I noticed files with a size of 0 would sometimes display NaN% or
Infinite%, presumably because both of the progress percentage
calculations in the ui would be dividing by zero.
So to avoid this, we just skip the downloading cycle entirely for 0 size
programs, and go to download completion immediately on clicking.
This fixes our issues.
## Why It's Good For The Game
Fixes some jank.
## Changelog
🆑
fix: NT Software Hub no longer displays >100% completion on downloads
sometimes.
fix: NT Software Hub no longer displays NaN% or Infinite% completion on
files with a size of 0 sometimes.
/🆑
---------
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com>
## About The Pull Request
While looking into getting the NTNRC username list sorted, I found out
that it was _already_ supposed to be sorted by status, but just got
broken in a pr that removes the program status variable forwarded for
this reason.
In this pr we simply add a `get_numerical_status()` proc that converts
the new logic into a number we can sort by, then make the tgui sort
account for this.
Additionally, we make it sort alphabetically in its subcategories, for
sanity's sake.
It now sorts by operator perms first, then
online>away(background)>offline, then alphabetically.
While I dislike operators being at the top regardless of their status,
it seems like that is how it was intended to work, and doing so sanely
would requite rethinking how names are coloured entirely. On the other
end, I think it's potentially good to have operators be at the top and
thus easily pingable at all times.
## Why It's Good For The Game
Fixes broken status sorting.
Alphabetical sorting makes finding a specific user to mute or ping them
less of a pain.
## Changelog
🆑
fix: NTNRC channel user list is sorted by status again. It goes
operator>online>away>offline.
qol: NTNRC channel user list is now alphabetically sorted under its
status subcategories.
/🆑
## About The Pull Request
When fiddling around with NTNRC, I noticed that muted clients... can
still talk.
While the input bar is reddened and displays a mute message, it isn't
actually disabled- even more so, there's no sanity checks for being
muted on the `ui_act(...)`.
In this pr we just make it so the input gets disabled, and add a sanity
check to avoid people bypassing it.
## Why It's Good For The Game
...good if the app's muting feature like, actually works.
## Changelog
🆑
fix: NTNRC muting actually works again.
/🆑
## About The Pull Request
Closes#87592
You could pass additional args into emotes with zero sanitization if you
got yourself a way to call TGUI acts
## Changelog
🆑
fix: Fixed HTML injections via pet tricks
/🆑
## About The Pull Request
Does as title says. Doesn't take effect if the ID has no job listed.
## Why It's Good For The Game
Gives a bit more context about who is sending a message.
## Changelog
🆑
add: Borgs now get the job title of someone sending them a message
through SiliConnect.
/🆑
## About The Pull Request
- Removes the restriction from borgs and AIs opening PDA interfaces.
- Adds a restriction on Messenger if the PDA is being viewed by an AI or
Cyborg *and* the PDA is not a silicon-type PDA. Messenger is completely
unusable in this case.
- The AI's own PDA is unaffected, due to it being a silicon-type PDA.
Downstreams that give Borg PDAs the Messenger app should likewise be
unaffected. Though mainly unrelated to the PR, pAIs were also tested and
have not been affected.
## Why It's Good For The Game
Back before tablets and PDAs were squished together, silicons could
access tablets freely. TGUI PDAs were restricted from Silicons mainly to
keep parity with the old PDAs, of which Messenger is the major feature
that was ported over. Thus, I'm blocking Messenger specifically while
allowing the rest of a PDA's features to be unblocked.
As an aside, the old fluff text `It doesn't feel right to snoop around
like that...` was kinda terrible, since there are many times you do, in
fact, want to snoop. The AI trying to track down a known killer's
accomplice would want to snoop. The Malf AI that's trying to trick the
Captain would want to snoop. The prior owner of the PDA before they were
borged wouldn't even feel like it's snooping. So now it's a connection
refused thing, not an AI's feelings thing.
## Changelog
🆑
balance: Borgs and AIs can now access dropped PDAs. The Messenger app
does not work over a remote connection, however.
/🆑
Messenger interface when accessed remotely, by the by;

## About The Pull Request
This makes it so receiving a PDA message will give the holder a balloon
alert with their ringtone.
## Why It's Good For The Game
PDA messages are often ignored due to not being noticed, as many players
are more often focused on the main game screen (which runechat has
somewhat normalized) than the chat window. This makes things more
obvious that there's a PDA message.
## Changelog
🆑
add: PDA ringtones now show a balloon alert to the PDA holder.
/🆑
3591 individual conflicts
Update build.js
Update install_node.sh
Update byond.js
oh my fucking god
hat
slow
huh
holy shit
we all fall down
2 more I missed
2900 individual conflicts
2700 Individual conflicts
replaces yarn file with tg version, bumping us down to 2200-ish
Down to 2000 individual conflicts
140 down
mmm
aaaaaaaaaaaaaaaaaaa
not yt
575
soon
900 individual conflicts
600 individual conflicts, 121 file conflicts
im not okay
160 across 19 files
29 in 4 files
0 conflicts, compiletime fix time
some minor incap stuff
missed ticks
weird dupe definition stuff
missed ticks 2
incap fixes
undefs and pie fix
Radio update and some extra minor stuff
returns a single override
no more dupe definitions, 175 compiletime errors
Unticked file fix
sound and emote stuff
honk and more radio stuff
## About The Pull Request
Just adds the NTNRC client to the pAI digital messenger software's
starting programs.
To avoid also giving this to the AI, creates a new silicon PDA subtype
for pAIs and applies it similarly to borgs.
## Why It's Good For The Game
It's already barely ever used, and I just think it'd be fun to let pAIs
talk to the never-checked department consoles or open chatrooms with
each other or their hosts.
Currently you can do this by being in your host's PDA, but this means
they couldn't use their PDA at the same time as you just... chatting.
Nor could you share a chatroom with them, due to sharing the same
account.
Also the pAI cabal using the bootleg IRC client to plot their next move
is just incredibly funny to me.
## Changelog
🆑
balance: The pAI digital messenger software now includes the NTNRC
client.
/🆑
## About The Pull Request
<details>
- renamed ai folder to announcer
-- announcer --
- moved vox_fem to announcer
- moved approachingTG to announcer
- separated the ambience folder into ambience and instrumental
-- ambience --
- created holy folder moved all related sounds there
- created engineering folder and moved all related sounds there
- created security folder and moved ambidet there
- created general folder and moved ambigen there
- created icemoon folder and moved all icebox-related ambience there
- created medical folder and moved all medbay-related ambi there
- created ruin folder and moves all ruins ambi there
- created beach folder and moved seag and shore there
- created lavaland folder and moved related ambi there
- created aurora_caelus folder and placed its ambi there
- created misc folder and moved the rest of the files that don't have a
specific category into it
-- instrumental --
- moved traitor folder here
- created lobby_music folder and placed our songs there (title0 not used
anywhere? - server-side modification?)
-- items --
- moved secdeath to hailer
- moved surgery to handling
-- effects --
- moved chemistry into effects
- moved hallucinations into effects
- moved health into effects
- moved magic into effects
-- vehicles --
- moved mecha into vehicles
created mobs folder
-- mobs --
- moved creatures folder into mobs
- moved voice into mobs
renamed creatures to non-humanoids
renamed voice to humanoids
-- non-humanoids--
created cyborg folder
created hiss folder
moved harmalarm.ogg to cyborg
-- humanoids --
-- misc --
moved ghostwhisper to misc
moved insane_low_laugh to misc
I give up trying to document this.
</details>
- [X] ambience
- [x] announcer
- [x] effects
- [X] instrumental
- [x] items
- [x] machines
- [x] misc
- [X] mobs
- [X] runtime
- [X] vehicles
- [ ] attributions
## Why It's Good For The Game
This folder is so disorganized that it's vomit inducing, will make it
easier to find and add new sounds, providng a minor structure to the
sound folder.
## Changelog
🆑 grungussuss
refactor: the sound folder in the source code has been reorganized,
please report any oddities with sounds playing or not playing
server: lobby music has been repathed to sound/music/lobby_music
/🆑
## About The Pull Request
So, do you remember orbies, those cutesy virtual PDA pets from that PR
that Ben made roughly six months ago before moving on his next project,
leaving them to be probably forgotten in a near future/present/past?
Yeah, personally I never played around, however I recalled that they do
have customizable virtual hats, which can be selected from a dropdown in
the UI, and I thought that it would be a perfect target for some
achievement-related content, as they're totally cosmetic that provides
no gameplay advantage nor affects balance in no way whatsoever. I cannot
sit well with cheevos being purely an end to itself, that's the reason
this PR exists.
The new additions to orbies hats, and their respective required
achievements are:
- The fishing hat (Legendary Fisher)
- A huge-ass rollie (Unhealthy Snacks) (yeah, it isn't exactly a hat but
the code in no way assume that the item has to be a hat, beside vars
named like that for the sake of convenience)
- A tape wizard hat (Archmage)
- An energy cakehat (Very Important Piscis)
- A bounty hunter cowboy hat (Hot Damn!)
- A fancy crown (Outdebted)
The huge-ass rollie (called fat dart) in the game, is a new cigarette,
rarely found in hacked cigarette vending machines. It's obviously a
reference to that Ralsei meme from 3 years ago or so but I personally
don't care, I just wanted to give an excessively big cigarette to orbies
to symbolize the proposterous accomplishment of eating 500 cigarettes in
a single round without dying from nicotine OD less than halfway through,
but since orbie hats use actual items are references for their
appearance, I found myself obliged to add one to the code. Overall, the
fat dart comes from an old PR on Citadel, though I had to resprite it
myself.
Here's a lazy collage of the hats. For some reason unbeknownst to me,
the hats are horizontally squished. I need to ask Ben why he did them
this way when Orbies' heads are as wide as a rugby ball.

## Why It's Good For The Game
Simple, extra cosmetic stuff for a simple feature that's as relevant as
playing around with plushes.
## Changelog
🆑
add: Added more customizable options to PDA virtual pets, which can be
unlocked by completing achievements.
add: Added a fat dart that can be rarely found in hacked cigarette
vending machines.
/🆑