From b478367fd913b9760985761a914e8c9c97acb861 Mon Sep 17 00:00:00 2001 From: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Date: Thu, 15 Dec 2022 22:55:32 -0800 Subject: [PATCH] Saves on average 10 seconds from roundstart times (#71730) ## About The Pull Request When runlevels change mid work, subsystems running behind have their next_fire updated. It's offset by a sum of random numbers, so things don't bunch up, especially KEEPTIME SSs The trouble is we have so many subsystems that get added at roundstart that this offset gets LARGE, like 10 seconds on average. So instead of randomly offsetting, why not "fill" a set of time slots? Only 1 keeptime subsystem a tick, and 4 others. Then we just fill up those buckets and get to it (also don't offset things that are already processing) I've talked to mso a bit about this. What he reccomended was sampling a random time withing a 2 second window. I'm not totally sure why, kinda waiting for him to tell me off, if he does I'll fix things up. This pattern takes the max possible delay from 16 (76 * 5 / 20)) seconds to 0.7 (56 / 4 / 20) It obviously scales with subsystem count, but I like this scaling a bit better I've applied the same pattern to the offsetting we do at the start of Loop(), for ticker subsystems. I am less confident in this, it does take last fire times from at worst 3.75 seconds (15 * 5 / 20) to a static 0.75 (15 / 20) As stated I'm less sure of this, hoping to get mso'd so I can clean things up ## Why It's Good For The Game Makes roundstart snappier ## Changelog :cl: code: Roundstart "starting" should be much snappier now /:cl: Co-authored-by: Kyle Spier-Swenson --- code/controllers/master.dm | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/code/controllers/master.dm b/code/controllers/master.dm index b6fb14a695..e695b0fd0b 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -292,7 +292,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new SS.state = SS_IDLE if (SS.flags & SS_TICKER) tickersubsystems += SS - timer += world.tick_lag * rand(1, 5) + // Timer subsystems aren't allowed to bunch up, so we offset them a bit + timer += world.tick_lag * rand(0, 1) SS.next_fire = timer continue @@ -371,14 +372,16 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/checking_runlevel = current_runlevel if(cached_runlevel != checking_runlevel) //resechedule subsystems + var/list/old_subsystems = current_runlevel_subsystems cached_runlevel = checking_runlevel current_runlevel_subsystems = runlevel_sorted_subsystems[cached_runlevel] - var/stagger = world.time - for(var/I in current_runlevel_subsystems) - var/datum/controller/subsystem/SS = I - if(SS.next_fire <= world.time) - stagger += world.tick_lag * rand(1, 5) - SS.next_fire = stagger + + //now we'll go through all the subsystems we want to offset and give them a next_fire + for(var/datum/controller/subsystem/SS as anything in current_runlevel_subsystems) + //we only want to offset it if it's new and also behind + if(SS.next_fire > world.time || (SS in old_subsystems)) + continue + SS.next_fire = world.time + world.tick_lag * rand(0, DS2TICKS(min(SS.wait, 2 SECONDS))) subsystems_to_check = current_runlevel_subsystems else