mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 23:27:34 +01:00
ok-behavior-trees
8
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0716e3fff4 |
Atmos refactor & speedup by utilizing BYOND 516 vector functions (#96448)
## About The Pull Request ### Summary This PR changes internal structure of `/datum/gas_mixture`: `gases[gas_id][MOLES]` refactored into `moles[gas_id]`, `gases[gas_id][ARCHIVE]` into `moles_archive[gas_id]` and `gases[gas_id][GAS_META]` into `gas_meta` static variable. This allows us to use BYOND 516 vector functions for calculating total moles and heat capacity. Also it simplifies some parts of the code, allowing us to get rid of macros `ADD_GAS` and `ASSERT_GAS`. According to the profiler `/turf/open/process_cell` time is reduced by ~20%. ### Details `gas_mixture.gases` was a nested 2d-list with MOLES, ARCHIVE and GAS_META for each gas_id. For example, to get gas moles you had to do `gases[gas_id][MOLES]`. I've changed this structure to be as follows: `moles[gas_id]` - moles for the gas, `moles_archive[gas_id]` - archived version of moles, `gas_meta[KEY][gas_id]` - static var with meta information for the gas. Since I removed key GAS_META from the gases, `gas_meta` was moved to the static variable and the order of keys in the array was changed from `gas_meta[gas_id][META_KEY]' to 'gas_meta[META_KEY][gas_id]`. This was done to allow using it in vector calculations (for example heat capacity or fusion power). Static variable access is very fast and it is considered as accessing a global in the bytecode. Byond 516 introduced new vector functions: `values_sum`, `values_dot` and others. These functions are very fast, but operate only on associative lists. This allows us to change the way we calculate total_moles and heat_capacity - very hot and heavily used functions. `total_moles()` became just `values_sum(moles)`, and `heat_capacity` is just a dot product: `values_dot(moles, gas_meta[META_GAS_SPECIFIC_HEAT])`. As a side bonus, since `moles` is just an associative list, you don't really need old macros `ADD_GAS` and `ASSERT_GAS` - all they did was to make a copy of a list[3] with default value [0, 0, gas_meta] for specific gas. Now when you're adding gas you can just use `moles[gas_id] += amount` and when you query amount of gas you can just query the key (for example `moles[/datum/gas/oxygen]`) if the key does not exist, it returns null and works as 0 for all arithmetic and logic operations. For example, old code would be `if (!air.gases[/datum/gas/oxygen] || air.gases[/datum/gas/oxygen][MOLES] < 1)` and now it is `if (moles[/datum/gas/oxygen] < 1)`. This simplifies some parts of the code and also speeds things up. For the performance comparison I used Tracy profiler. I've done many different tests, and they all show slightly different numbers, but overall speedup for `process_cell` is about 20%. (-20% to average time per call from ). My testing setup was as follows: Load Icebox, drop 30/60/90 radius bomb in the middle of the bridge, set code to blue, wait 10 minutes until the round ends. Also I fixed random seed in the master controller and in the planetary gas randomization so generated maps are the same between tests. Althought it's not very realistic, it generates a lot of samples for the `process_cell` (around ~3.5M per 10 minutes). Another test I did was a plasmafire in an 8x8 space, on runtime station, it showed (-24% time on process_cell). Another test was a emagged holodeck burn test, it showed (-13% time) As for other functions of gas_mixture: `total_moles`: -50%(2x speedup), `heat_capacity`: -65%(3x speedup), `share`: -30%, `react`: -20%. Timings of all those functions is in microseconds range and they are very hot (call count is in the same order as process_cell) <details><summary>Some pictures from profiler</summary> <img width="569" height="642" alt="process_cell" src="https://github.com/user-attachments/assets/76fa0c27-719d-485d-9bfc-859fef788999" /> <img width="572" height="315" alt="image" src="https://github.com/user-attachments/assets/f68497e9-4db8-4a9c-b43f-ad04e6dc5cac" /> <img width="569" height="317" alt="image" src="https://github.com/user-attachments/assets/d7249e7b-f344-47a6-8b39-1bab0521182d" /> <img width="541" height="316" alt="image" src="https://github.com/user-attachments/assets/1bef71fd-533d-40fa-a85e-7a803ad322f7" /> <img width="519" height="409" alt="image" src="https://github.com/user-attachments/assets/51165289-174e-403d-a09c-787dd9af136a" /> <img width="523" height="318" alt="image" src="https://github.com/user-attachments/assets/fe4b1db0-17d8-47f9-8fd0-e2ecef2ee66a" /> </details> <details><summary>Setting up a profiler</summary> If you wanna to reproduce my results here is a list of steps 1. download: https://github.com/goonstation/byond-tracy-writer (this one has offsets for my version 1677) 2. build the dll, drop in the tgstation/ folder 3. download rtracy https://github.com/Dimach/rtracy 4. download Tracy profiler (0.13.1) https://github.com/wolfpld/tracy 5. uncomment `#define USE_BYOND_TRACY` in `_compile_options.dm` 6. build tgstation 7. open dream daemon, run the desired test, after round end dream daemon closes 8. navigate to tgstation/data/profiler, find the `123412341234.utracy` file 9. run `rtracty 123412341234.utracy` 10. open tracy-profiler.exe, press Connect, save the profiler data 11. repeat steps 5-10 with another branch, save another profiler data 12. open tracy-profiler, open first data, press compare, open second data </details> ## Why It's Good For The Game ## Changelog 🆑 refactor: Atmos refactor & speedup by utilizing BYOND 516 vector functions /🆑 --------- Co-authored-by: san7890 <the@san7890.com> |
||
|
|
265ceb3eb2 |
Fixes Flakey Ashwalker Lung Unit Test Failures on gateway_test (#94821)
## About The Pull Request
Closes #94794
Both of these unit tests were using the outdated way of changing the gas
mix on a turf, probably because they were more than a few years old
apiece. The modern way is using the `/datum/gas_mixture` and
`parse_gas_string()` to either retrieve the gas mix from cache or
generate it on-demand. Neither of these tests were doing that, and they
worked well enough until they got mutated in #94771
(
|
||
|
|
f9fe79a307 |
Organ Unit Tests & Bugfixes (#73026)
## About The Pull Request This PR adds a new unit test for all organs, a new unit test for lungs, and includes improvements for the existing breath and organ_set_bonus tests. Using the tests, I was able to root out bugs in the organs. This PR includes an advanced refactor of several developer-facing functions. This PR certainly represents a "quality pass" for organs which will make them easier to develop from now on. ### Synopsis of changes: 1. Fixed many fundamental bugs in organ code, especially in `Insert()`/`Remove()` and their overrides. 2. Added two new procs to `/obj/item/organ` named `on_insert` and `on_remove`, each being called after `Insert()`/`Remove()`. 3. Added `organ_effects` lazylist to `/obj/item/organ`. Converted `organ_traits` to lazylist. 2x less empty lists per organ. 4. Adding `SHOULD_CALL_PARENT(TRUE)` to `Insert()`/`Remove()` was very beneficial to stability and overall code health. 5. Created unit test `organ_sanity` for all usable organs in the game. Tests insertion and removal. 6. Created unit test `lungs_sanity` for `/obj/item/organ/internal/lungs`. 7. Improved `breath_sanity` unit tests with additional tests and conditions. 8. Improved `organ_set_bonus_sanity` unit tests with better documentation and maintainable code. --- ### Granular bug/fix list: - A lot of organs are overriding `Insert()` to apply unique side-effects, but aren't checking the return value of the parent proc which causes the activation of side-effects even if the insertion technically fails. I noticed the use-case of applying "unique side-effects" is repeated across a lot of organs in the game, and by overriding `Insert()` the potential for bugs is very high; I solved this problem with inversion-of-control by adding two new procs to `/obj/item/organ` named `on_insert` and `on_remove`, each being called after `Insert()` and `Remove()` succeed. - Many organs, such as abductor "glands", cursed heart, demon heart, alien hive-node, alien plasma-vessel, etc, were not returning their parent's `Insert()` proc return value at all, and as a result those organs `Insert()`s were always returning `null`. I have been mopping those bugs up in my last few PRs, and now the unit test reveals it all. Functions such as those in surgery expect a truthy value to be returned from `Insert()` to represent insertion success, and otherwise it force-moves the organ out of the mob. - Fixed abductor "glands" which had a hard-del bug due to their `Remove()` not calling the parent proc. - Fixed cybernetic arm implants which had a hard-del bug due to `Remove()` not resetting their `hand` variable to `null`. - Fixed lungs gas exchange implementation, which was allowing exhaled gases to feedback into the inhaled gases, which caused Humans to inhale much more gas than intended and not exhale expected gases. ### Overview of the `organ_sanity` unit test: - The new `organ_sanity` unit test gathers all "usable" organs in the game and tests to see if their `Insert()` and `Remove()` functions behave as we expect them to. - Some organs, such as the Nightmare Brain, cause the mob's species to change which subsequently swaps out all of their organs; the unit test accounts for these organs via the typecache `species_changing_organs`. - Some organs are not usable in-game and can't be unit tested, so the unit test accounts for them via the typecache `test_organ_blacklist`. ### Overview of the `lungs_sanity` unit test: - This unit test focuses on `/obj/item/organ/internal/lungs` including Plasmaman and Ashwalker lungs. The test focuses on testing the lungs' `check_breath()` proc. - The tests are composed of calling `check_breath` with different gas mixes to test breathing and suffocation. - Includes gas exchange test for inhaled/exhaled gases, such as O2 to CO2. ### Improvements to the `breath_sanity` unit tests: - Added additional tests for suffocation with empty internals, pure Nitrogen internals, and a gas-less turf. - Includes slightly more reliable tests for internals tanks. ## Why It's Good For The Game **Organs and Lungs were mostly untested. Too many refactors have been submitted without the addition of unit tests to prove the code works at all.** Time to stop. _Time to get some help_. Due to how bad the code health is in organs, any time we've tried to work with them some sort of bug caused them to blow up in our faces. I am trying to fix some of that by establishing some standard testing for organs. These tests have revealed and allowed me to fix lot of basic developer errors/oversights, as well as a few severe bugs.  ## Changelog 🆑 A.C.M.O. fix: Fixed lungs gas exchange implementation, so you always inhale and exhale the correct gases. fix: Fixed a large quantity of hard-deletes which were being caused by organs and cybernetic organs. fix: Fixed many organs which were applying side-effects regardless of whether or not the insertion failed. code: Added unit tests for Organs. code: Added unit tests for Lungs. code: Improved unit tests for breathing. code: Improved unit tests for DNA Infuser organs. /🆑 |
||
|
|
1900eb9484 |
Unit Tests use a consistent human subtype (#71515)
title |
||
|
|
dff635b7f6 |
Atmos init speedup, saves 4 seconds (#69697)
* Micro optimizes ssair's turf init, saving 2 seconds Most of this is making existing operations do more legwork, or cheaper. I did add cycle checking to ONLY init turf linking, which required creating a new proc. Did some horrible horrible things in said proc to save like 0.8 seconds. I think it was worth it. |
||
|
|
234d4c1217 | makes most alerts, defines (#65086) | ||
|
|
1663f3efcb |
Changes Plasmamen belt tanks volume and the rate that their lungs consume plasma to 1/4 of the previous value. (#62081)
Plasmamen belt tank volume is 24, the extended engineering one is 6 and the emergency internals are 3. The issue balance wise is that all of those have the same pocket size and can be printed at the same Research tier, this results on smart atmos/engineers printing a plasmamen belt tank and filling it with O2 so their internals can last for almost 2 hours instead of the 24 minutes of the extended O2. Now they have the same volume but plasmamen lungs were rebalanced to consume plasma at a lower rate. To be clear, it will have no effect on how long the internal last for a plasmamen. Removes a no skill trick that gives you internals that will last for all shift, you can still make those but it will take a tiny bit of effort now. Also a small step to make internals balanced. |
||
|
|
99cd00f5fe |
Makes gas actually dissipate (#57634)
* Raises the quantize threshold from 1E-7 to 1E-4. This makes gas dissipate as expected, and should help with the amount of useless gas floating around the station at highpop Adds a garbage_collect() call to the portion of pipeline code where all gasmixes are in one place, this should clean things up properly. Changes BREATH_VOLUME from 2 to 1.99. This is imperative Documents a FUCKING HELLBUG in quantize/breathcode that can lead to breaths just not working sometimes. I'm not sure how to fix this totally, so I'll document it and pray. See <https://www.desmos.com/calculator/5icdlnktus> Adds a unit test to check for this sort of failure. Addendum for people tweaking this value in the future. Because o2 tank release values/human o2 requirements are very strictly set to the same pressure, small errors can cause breakage This comes from QUANTIZE being used in /datum/gas_mixture.remove(), forming a slight sawtooth pattern of the added/removed gas, centered on the actual pressure Changing BREATH_VOLUME can set us on the lower half of this sawtooth, making humans unable to breath at standard pressure. There's no good way I can come up with to hardcode a fix for this. So if you're going to change this variable graph the functions that describe how it is used/how it interacts with breath code, and pick something on the upper half of the sawtooth NOTE: I've made this change with a focus on o2 requirements. Changing this will effect other settings, but most all of them can be ignored, as none will notice. * Thank you moth man Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com> * Docs the purpose of the breath unit test, and better explains partial pressure Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com> |