Files
VMSolidus 1423fcd04e Various Delta Time Fixes (#21871)
Organs were being given ~3 seconds of DT per ~2 seconds of real time,
because they were being hit by Process() TWICE, once during processing
for the "Set of all objects", and again during processing for the "Set
of all mobs". No species was hit harder than this but IPCs, who suffered
from having wildly inconsistent temperature mechanics that seemingly
never matched the expected numbers.

I have actually tested this PR to verify that it works. I even went the
extra mile to more extensively test IPC temperature mechanics to find a
separate bug unrelated to DTs that was causing suit coolers to just
straight up not work at all (space suit or otherwise) on a majority of
all IPC subspecies. I then tested the numbers in the PR for IPC cooling
to verify that things work as intended.

<img width="969" height="623" alt="image"
src="https://github.com/user-attachments/assets/01c3aca7-b436-4e52-86f7-aed847dcba5e"
/>

I also tweaked all the subsystems to have a small performance
improvement.

---------

Signed-off-by: VMSolidus <evilexecutive@gmail.com>
2026-02-27 01:28:20 +00:00

57 lines
2.6 KiB
Plaintext

//Used to process objects. Fires once every two seconds.
SUBSYSTEM_DEF(processing)
name = "Processing"
priority = FIRE_PRIORITY_PROCESS
flags = SS_BACKGROUND|SS_POST_FIRE_TIMING|SS_NO_INIT
wait = 1 SECONDS
var/stat_tag = "P" //Used for logging
var/list/processing = list()
var/list/currentrun = list()
/datum/controller/subsystem/processing/stat_entry(msg)
msg = "[stat_tag]:[processing.len]"
return ..()
/datum/controller/subsystem/processing/fire(resumed = 0)
if (!resumed)
currentrun = processing.Copy()
//cache for sanic speed (lists are references anyways)
var/list/current_run = currentrun
var/seconds_per_tick = wait * 0.1
while(current_run.len)
var/datum/thing = current_run[current_run.len]
current_run.len--
if(QDELETED(thing))
processing -= thing
else if(thing.process(seconds_per_tick) == PROCESS_KILL)
// fully stop so that a future START_PROCESSING will work
STOP_PROCESSING(src, thing)
if (MC_TICK_CHECK)
return
/**
* This proc is called on a datum on every "cycle" if it is being processed by a subsystem. The time between each cycle is determined by the subsystem's "wait" setting.
* You can start and stop processing a datum using the START_PROCESSING and STOP_PROCESSING defines.
*
* Since the wait setting of a subsystem can be changed at any time, it is important that any rate-of-change that you implement in this proc is multiplied by the seconds_per_tick that is sent as a parameter,
* Additionally, any "prob" you use in this proc should instead use the SPT_PROB define to make sure that the final probability per second stays the same even if the subsystem's wait is altered.
* Examples where this must be considered:
* - Implementing a cooldown timer, use `mytimer -= seconds_per_tick`, not `mytimer -= 1`. This way, `mytimer` will always have the unit of seconds
* - Damaging a mob, do `L.adjustFireLoss(20 * seconds_per_tick)`, not `L.adjustFireLoss(20)`. This way, the damage per second stays constant even if the wait of the subsystem is changed
* - Probability of something happening, do `if(SPT_PROB(25, seconds_per_tick))`, not `if(prob(25))`. This way, if the subsystem wait is e.g. lowered, there won't be a higher chance of this event happening per second
*
* If you override this do not call parent, as it will return PROCESS_KILL. This is done to prevent objects that dont override process() from staying in the processing list
*/
/datum/proc/process(seconds_per_tick)
set waitfor = FALSE
return PROCESS_KILL
/datum/controller/subsystem/processing/ExplosionStart()
can_fire = FALSE
/datum/controller/subsystem/processing/ExplosionEnd()
can_fire = TRUE