diff --git a/code/__DEFINES/MC.dm b/code/__DEFINES/MC.dm index 4e6bfc0d83bf..0cfbf865dd76 100644 --- a/code/__DEFINES/MC.dm +++ b/code/__DEFINES/MC.dm @@ -45,10 +45,16 @@ /// (implies all runlevels because of how it works) /// (overrides SS_BACKGROUND) /// This is designed for basically anything that works as a mini-mc (like SStimer) +/// +/// * Ticker is its own priority bucket. The highest one. Be careful. +/// * Ticker disables tick overrun punishment. #define SS_TICKER (1<<4) /** keep the subsystem's timing on point by firing early if it fired late last fire because of lag */ /// ie: if a 20ds subsystem fires say 5 ds late due to lag or what not, its next fire would be in 15ds, not 20ds. +/// +/// * This will only keep timing past the last 10 seconds, it will not attempt to catch the subsystem up without bounds. +/// * This disables tick overrun punishment. #define SS_KEEP_TIMING (1<<5) /** Calculate its next fire after its fired. */ diff --git a/code/__DEFINES/controllers/_subsystems.dm b/code/__DEFINES/controllers/_subsystems.dm index 7a9ae5d608d2..feec5c5f2dc8 100644 --- a/code/__DEFINES/controllers/_subsystems.dm +++ b/code/__DEFINES/controllers/_subsystems.dm @@ -155,14 +155,15 @@ DEFINE_BITFIELD(runlevels, list( // Any ../subsystem/.. is here unless it doesn't have SS_BACKGROUND in subsystem_flags! // This means by default, ../subsystem/processing/.. is here! -#define FIRE_PRIORITY_RADIATION 10 //! laggy as hell, bottom barrel until optimizations are done. -#define FIRE_PRIORITY_GARBAGE 15 -#define FIRE_PRIORITY_CHARACTERS 25 -#define FIRE_PRIORITY_PARALLAX 30 -#define FIRE_PRIORITY_AIR 35 -#define FIRE_PRIORITY_PROCESS 45 -// DEFAULT PRIORITY IS HERE -#define FIRE_PRIORITY_PLANETS 75 +#define FIRE_PRIORITY_RADIATION 10 //! laggy as hell, bottom barrel until optimizations are done. +#define FIRE_PRIORITY_GARBAGE 15 +#define FIRE_PRIORITY_CHARACTERS 20 +#define FIRE_PRIORITY_PARALLAX 20 +#define FIRE_PRIORITY_AIR 25 +#define FIRE_PRIORITY_ASSET_LOADING 25 +#define FIRE_PRIORITY_PLANETS 25 +#define FIRE_PRIORITY_PROCESS 50 +// DEFAULT PRIORITY IS HERE (50) //? Normal Subsystems - Above background, below ticker // Any ../subsystem/.. without SS_TICKER or SS_BACKGROUND in subsystem_flags is here! @@ -176,27 +177,27 @@ DEFINE_BITFIELD(runlevels, list( #define FIRE_PRIORITY_SERVER_MAINT 10 #define FIRE_PRIORITY_ZMIMIC 10 #define FIRE_PRIORITY_ALARMS 20 +#define FIRE_PRIORITY_AIRFLOW 20 #define FIRE_PRIORITY_SPACEDRIFT 25 -#define FIRE_PRIORITY_AIRFLOW 30 #define FIRE_PRIORITY_OBJ 40 -// DEFAULT PRIORITY IS HERE +// DEFAULT PRIORITY IS HERE (50) #define FIRE_PRIORITY_LIGHTING 50 -#define FIRE_PRIORITY_INSTRUMENTS 90 -#define FIRE_PRIORITY_ASSET_LOADING 100 -#define FIRE_PRIORITY_MACHINES 100 -#define FIRE_PRIORITY_AI_MOVEMENT 150 -#define FIRE_PRIORITY_AI_SCHEDULING 150 -#define FIRE_PRIORITY_AI_HOLDERS 150 -#define FIRE_PRIORITY_NANO 150 -#define FIRE_PRIORITY_AI 200 -#define FIRE_PRIORITY_TGUI 200 -#define FIRE_PRIORITY_PROJECTILES 200 -#define FIRE_PRIORITY_THROWING 200 -#define FIRE_PRIORITY_STATPANELS 400 -#define FIRE_PRIORITY_OVERLAYS 500 -#define FIRE_PRIORITY_SMOOTHING 500 -#define FIRE_PRIORITY_CHAT 500 -#define FIRE_PRIORITY_INPUT 1000 +#define FIRE_PRIORITY_INSTRUMENTS 50 +#define FIRE_PRIORITY_MACHINES 50 +#define FIRE_PRIORITY_AI 65 +#define FIRE_PRIORITY_AI_HOLDERS 65 +#define FIRE_PRIORITY_AI_MOVEMENT 75 +#define FIRE_PRIORITY_AI_SCHEDULING 75 +#define FIRE_PRIORITY_NANO 80 +#define FIRE_PRIORITY_TGUI 80 +#define FIRE_PRIORITY_OVERMAP_PHYSICS 90 +#define FIRE_PRIORITY_PROJECTILES 90 +#define FIRE_PRIORITY_THROWING 90 +#define FIRE_PRIORITY_STATPANELS 100 +#define FIRE_PRIORITY_OVERLAYS 100 +#define FIRE_PRIORITY_SMOOTHING 100 +#define FIRE_PRIORITY_CHAT 100 +#define FIRE_PRIORITY_INPUT 100 //? Ticker Subsystems - Highest priority // Any subsystem flagged with SS_TICKER is here! @@ -204,9 +205,9 @@ DEFINE_BITFIELD(runlevels, list( // Is your feature as important as movement, chat, or timers? // Probably not! Go to normal bracket instead! -// DEFAULT PRIORITY IS HERE -#define FIRE_PRIORITY_DPC 700 -#define FIRE_PRIORITY_TIMER 700 +// DEFAULT PRIORITY IS HERE (50) +#define FIRE_PRIORITY_DPC 100 +#define FIRE_PRIORITY_TIMER 100 //? Special diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 746bb2544cc9..71dc99baf347 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -52,18 +52,6 @@ GLOBAL_REAL(Master, /datum/controller/master) = new /// The type of the last subsystem to be process()'d. var/last_type_processed - /// Start of queue linked list. - var/datum/controller/subsystem/queue_head - - /// End of queue linked list (used for appending to the list). - var/datum/controller/subsystem/queue_tail - - /// Running total so that we don't have to loop thru the queue each run to split up the tick. - var/queue_priority_count = 0 - - /// Total background subsystems in the queue. - var/queue_priority_count_bg = 0 - /// For scheduling different subsystems for different stages of the round. var/current_runlevel @@ -75,13 +63,24 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/static/random_seed + //* Processing Variables *// + + /// total fire_priority of all non-background subsystems in the queue + var/queue_priority_count = 0 + /// total fire_priority of all background subsystems in the queue + var/queue_priority_count_bg = 0 + + /// Start of queue linked list. + var/datum/controller/subsystem/queue_head + /// End of queue linked list (used for appending to the list). + var/datum/controller/subsystem/queue_tail + /** * current tick limit, assigned before running a subsystem. * used by CHECK_TICK as well so that the procs subsystems call can obey that SS's tick limits. */ var/static/current_ticklimit = TICK_LIMIT_RUNNING - /datum/controller/master/New() //# 1. load configs if(!config_legacy) @@ -302,7 +301,6 @@ GLOBAL_REAL(Master, /datum/controller/master) = new if(current_runlevel < 1) CRASH("Attempted to set invalid runlevel: [new_runlevel]") - /** * Starts the mc, and sticks around to restart it if the loop ever ends. */ @@ -349,6 +347,10 @@ GLOBAL_REAL(Master, /datum/controller/master) = new SS.queue_next = null SS.queue_prev = null SS.state = SS_IDLE + + // Set precomputed variables + SS.recompute_wait_dt() + if (SS.subsystem_flags & SS_TICKER) SStickersubsystems += SS // Timer subsystems aren't allowed to bunch up, so we offset them a bit. @@ -390,7 +392,6 @@ GLOBAL_REAL(Master, /datum/controller/master) = new iteration = 1 var/error_level = 0 var/sleep_delta = 1 - var/list/subsystems_to_check //# The actual loop. while (1) @@ -433,28 +434,24 @@ GLOBAL_REAL(Master, /datum/controller/master) = new new/datum/controller/failsafe() // (re)Start the failsafe. //# Now do the actual stuff. - if (!queue_head || !(iteration % 3)) - 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] - - // 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))) + //* **Experimental**: Check every tick. + if(cached_runlevel != current_runlevel) + // Resechedule subsystems. + var/list/old_subsystems = current_runlevel_subsystems + cached_runlevel = current_runlevel + current_runlevel_subsystems = runlevel_sorted_subsystems[cached_runlevel] + + // 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 - subsystems_to_check = current_runlevel_subsystems + SS.next_fire = world.time + world.tick_lag * rand(0, DS2TICKS(min(SS.wait, 2 SECONDS))) - else - subsystems_to_check = SStickersubsystems - - if (CheckQueue(subsystems_to_check) <= 0) + //* **Experimental**: Check every queue, every tick. + if (CheckQueue(current_runlevel_subsystems) <= 0 || CheckQueue(SStickersubsystems) <= 0) if (!SoftReset(SStickersubsystems, runlevel_sorted_subsystems)) log_world("MC: SoftReset() failed, crashing") return @@ -550,7 +547,9 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/ran = TRUE // This is right. var/ran_non_SSticker = FALSE var/bg_calc // Have we swtiched current_tick_budget to background mode yet? - var/tick_usage + + // the % of tick used by the current running subsystem + var/queue_node_tick_usage /** * Keep running while we have stuff to run and we haven't gone over a tick @@ -609,9 +608,10 @@ GLOBAL_REAL(Master, /datum/controller/master) = new queue_node.state = SS_RUNNING - tick_usage = TICK_USAGE + // ignite / fire the head node + queue_node_tick_usage = TICK_USAGE var/state = queue_node.ignite(queue_node_paused) - tick_usage = TICK_USAGE - tick_usage + queue_node_tick_usage = TICK_USAGE - queue_node_tick_usage if (state == SS_RUNNING) state = SS_IDLE @@ -619,53 +619,58 @@ GLOBAL_REAL(Master, /datum/controller/master) = new current_tick_budget -= queue_node_priority - if (tick_usage < 0) - tick_usage = 0 + if (queue_node_tick_usage < 0) + queue_node_tick_usage = 0 - queue_node.tick_overrun = max(0, MC_AVG_FAST_UP_SLOW_DOWN(queue_node.tick_overrun, tick_usage-tick_precentage)) + queue_node.tick_overrun = max(0, MC_AVG_FAST_UP_SLOW_DOWN(queue_node.tick_overrun, queue_node_tick_usage-tick_precentage)) queue_node.state = state + // if it paused mid-run, track that if (state == SS_PAUSED) queue_node.paused_ticks++ - queue_node.paused_tick_usage += tick_usage + queue_node.paused_tick_usage += queue_node_tick_usage queue_node = queue_node.queue_next continue + // it did not pause; this is a complete run + queue_node.ticks = MC_AVERAGE(queue_node.ticks, queue_node.paused_ticks) - tick_usage += queue_node.paused_tick_usage + queue_node_tick_usage += queue_node.paused_tick_usage - queue_node.tick_usage = MC_AVERAGE_FAST(queue_node.tick_usage, tick_usage) + queue_node.tick_usage = MC_AVERAGE_FAST(queue_node.tick_usage, queue_node_tick_usage) - queue_node.cost = MC_AVERAGE_FAST(queue_node.cost, TICK_DELTA_TO_MS(tick_usage)) + queue_node.cost = MC_AVERAGE_FAST(queue_node.cost, TICK_DELTA_TO_MS(queue_node_tick_usage)) queue_node.paused_ticks = 0 queue_node.paused_tick_usage = 0 if (queue_node_flags & SS_BACKGROUND) // Update our running total. queue_priority_count_bg -= queue_node_priority - else queue_priority_count -= queue_node_priority queue_node.last_fire = world.time queue_node.times_fired++ + // schedule next run if (queue_node_flags & SS_TICKER) + // ticker: run this many ticks after always queue_node.next_fire = world.time + (world.tick_lag * queue_node.wait) - else if (queue_node_flags & SS_POST_FIRE_TIMING) + // post fire timing: fire this much wait after current time, with tick overrun punishment queue_node.next_fire = world.time + queue_node.wait + (world.tick_lag * (queue_node.tick_overrun/100)) - else if (queue_node_flags & SS_KEEP_TIMING) - queue_node.next_fire += queue_node.wait - + // keep timing: fire this much wait after *the last time we should have fired*, without tick overrun punishment + // **experimental**: do not keep timing past last 10 seconds, if something is running behind that much don't permanently accelerate it. + queue_node.next_fire = max(world.time - 10 SECONDS, queue_node.next_fire + queue_node.wait) else + // normal: fire this much wait after when we were queued, with tick overrun punishment queue_node.next_fire = queue_node.queued_time + queue_node.wait + (world.tick_lag * (queue_node.tick_overrun/100)) queue_node.queued_time = 0 // Remove from queue. queue_node.dequeue() - + // move to next queue_node = queue_node.queue_next . = TRUE diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm index 1e700a8b91dc..0ef79b8d0584 100644 --- a/code/controllers/subsystem.dm +++ b/code/controllers/subsystem.dm @@ -67,10 +67,15 @@ //# The following variables are managed by the MC and should not be modified directly. - /// Last world.time the subsystem completed a run (as in wasn't paused by [MC_TICK_CHECK]). + /// Last world.time we did a full ignite()/fire() without pausing + /// + /// * this is set by the MC's processing loop + /// * this is a heuristic; subsystems that have weird pausing behaviors won't work right with this. + /// * this is why it's crucial subsystems call pause() if they didn't finish a run! var/last_fire = 0 - - /// Scheduled world.time for next fire(). + /// Scheduled world.time for next ignite(). + /// + /// * this is set by the MC's processing loop var/next_fire = 0 /// Running average of the amount of milliseconds it takes the subsystem to complete a run (including all resumes but not the time spent paused). @@ -82,12 +87,6 @@ /// Running average of the amount of tick usage (in percents of a game tick) the subsystem has spent past its allocated time without pausing. var/tick_overrun = 0 - /// How much of a tick (in percents of a tick) were we allocated last fire. - var/tick_allocation_last = 0 - - /// How much of a tick (in percents of a tick) do we get allocated by the mc on avg. - var/tick_allocation_avg = 0 - /// Tracks the current execution state of the subsystem. Used to handle subsystems that sleep in fire so the mc doesn't run them again while they are sleeping. var/state = SS_IDLE @@ -103,9 +102,6 @@ /// Tracks the amount of completed runs for the subsystem. var/times_fired = 0 - /// How many fires have we been requested to postpone. - var/postponed_fires = 0 - /// Time the subsystem entered the queue, (for timing and priority reasons). var/queued_time = 0 @@ -122,11 +118,33 @@ var/static/list/failure_strikes /// Next subsystem in the queue of subsystems to run this tick. + /// + /// * the queue is a doubly-linked non-circular linked list var/datum/controller/subsystem/queue_next - /// Previous subsystem in the queue of subsystems to run this tick. + /// + /// * the queue is a doubly-linked non-circular linked list var/datum/controller/subsystem/queue_prev + //* Recomputed at start of Loop(), as well as on changes *// + + /// The **nominal** world.time in deciseconds, before runs + var/nominal_dt_ds + /// The **nominal** world.time in seconds, before runs + var/nominal_dt_s + + //* Tracked by ignite() *// + + /// running average of our 'personal' tick drift + /// + /// * this is pretty much time dilation for this subsystem + /// * this is based on wait time; e.g. 100% means we're running twice as slow, etc + var/tick_dilation_avg = 0 + /// How much of a tick (in percents of a tick) were we allocated last fire. + var/tick_allocation_last = 0 + /// How much of a tick (in percents of a tick) do we get allocated by the mc on avg. + var/tick_allocation_avg = 0 + /** * # Do not blindly add vars here to the bottom, put it where it goes above. * # If your var only has two values, put it in as a flag. @@ -185,6 +203,12 @@ enqueue() state = SS_PAUSED queued_time = QT + else + // track time between runs + var/full_run_took = world.time - last_fire + var/new_tick_dilation = (full_run_took / nominal_dt_ds) * 100 - 100 + tick_dilation_avg = max(0, MC_AVERAGE_SLOW(tick_dilation_avg, new_tick_dilation)) + last_fire = world.time /** * previously, this would have been named 'process()' but that name is used everywhere for different things! @@ -195,7 +219,6 @@ subsystem_flags |= SS_NO_FIRE CRASH("Subsystem [src]([type]) does not fire() but did not set the SS_NO_FIRE flag. Please add the SS_NO_FIRE flag to any subsystem that doesn't fire so it doesn't get added to the processing list and waste cpu.") - /datum/controller/subsystem/Destroy() dequeue() can_fire = 0 @@ -205,7 +228,6 @@ return ..() - /** * Queue it to run. * (we loop thru a linked list until we get to the end or find the right point) @@ -249,7 +271,9 @@ queued_time = world.time queued_priority = SS_priority state = SS_QUEUED - if (SS_flags & SS_BACKGROUND) // Update our running total. + + /// update the running total of priorities in the queue of the MC + if (SS_flags & SS_BACKGROUND) Master.queue_priority_count_bg += SS_priority else Master.queue_priority_count += SS_priority @@ -276,15 +300,14 @@ queue_node.queue_prev = src /datum/controller/subsystem/proc/dequeue() + // eject from doubly linked list if (queue_next) queue_next.queue_prev = queue_prev - if (queue_prev) queue_prev.queue_next = queue_next - + // ensure MC's references aren't us if (src == Master.queue_tail) Master.queue_tail = queue_prev - if (src == Master.queue_head) Master.queue_head = queue_next @@ -323,7 +346,7 @@ */ /datum/controller/subsystem/stat_entry() if(can_fire && !(SS_NO_FIRE & subsystem_flags)) - . = "[round(cost,1)]ms|[round(tick_usage,1)]%([round(tick_overrun,1)]%)|[round(ticks,0.1)] " + . = "[round(cost,1)]ms | D:[round(tick_dilation_avg,1)]% | U:[round(tick_usage,1)]% | O:[round(tick_overrun,1)]% | T:[round(ticks,0.1)] " else . = "OFFLINE " @@ -351,7 +374,6 @@ if(next_fire - world.time < wait) next_fire += (wait*cycles) - /** * Usually called via datum/controller/subsystem/New() when replacing a subsystem (i.e. due to a recurring crash). * Should attempt to salvage what it can from the old instance of subsystem. @@ -366,9 +388,10 @@ // This is so the subsystem doesn't rapid fire to make up missed ticks causing more lag if (var_value) next_fire = world.time + wait - if (NAMEOF(src, queued_priority)) // Editing this breaks things. return FALSE + if (NAMEOF(src, wait)) + return set_wait(var_value) . = ..() @@ -420,3 +443,15 @@ */ /datum/controller/subsystem/proc/on_sql_reconnect() return + +//* Wait *// + +/datum/controller/subsystem/proc/set_wait(new_wait) + ASSERT(isnum(new_wait)) + src.wait = new_wait + recompute_wait_dt() + return TRUE + +/datum/controller/subsystem/proc/recompute_wait_dt() + nominal_dt_ds = max(world.tick_lag, (subsystem_flags & SS_TICKER)? (wait * world.tick_lag) : (wait)) + nominal_dt_s = nominal_dt_ds * 0.1 diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm index 062341b700c8..8609e1f99b1a 100644 --- a/code/controllers/subsystem/air.dm +++ b/code/controllers/subsystem/air.dm @@ -249,7 +249,7 @@ SUBSYSTEM_DEF(air) src.currentrun = active_hotspots.Copy() //cache for sanic speed (lists are references anyways) var/list/currentrun = src.currentrun - var/dt = (subsystem_flags & SS_TICKER)? (wait * world.tick_lag * 0.1) : (wait * 0.1) + var/dt = nominal_dt_s while(currentrun.len) var/atom/movable/fire/fire = currentrun[currentrun.len] currentrun.len-- diff --git a/code/controllers/subsystem/asset_loading.dm b/code/controllers/subsystem/asset_loading.dm index 27400cf89f5d..c69e81c6eaaf 100644 --- a/code/controllers/subsystem/asset_loading.dm +++ b/code/controllers/subsystem/asset_loading.dm @@ -7,7 +7,7 @@ SUBSYSTEM_DEF(asset_loading) name = "Asset Loading" priority = FIRE_PRIORITY_ASSET_LOADING // todo: hibernation - subsystem_flags = SS_NO_INIT + subsystem_flags = SS_NO_INIT | SS_BACKGROUND runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT /// things waiting to be loaded diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index a598989f32e4..f846f197e125 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -41,7 +41,7 @@ SUBSYSTEM_DEF(events) //cache for sanic speed (lists are references anyways) var/list/currentrun = src.currentrun - var/dt = (subsystem_flags & SS_TICKER)? (wait * world.tick_lag * 0.1) : (wait * 0.1) + var/dt = nominal_dt_s while (currentrun.len) var/datum/event/E = currentrun[currentrun.len] currentrun.len-- diff --git a/code/controllers/subsystem/input.dm b/code/controllers/subsystem/input.dm index 6f848ba04ce3..31d921504741 100644 --- a/code/controllers/subsystem/input.dm +++ b/code/controllers/subsystem/input.dm @@ -18,6 +18,9 @@ SUBSYSTEM_DEF(input) /// Macro set for classic. var/list/input_mode_macros + /// currentrun list of clients + var/list/client/currentrun + /datum/controller/subsystem/input/Initialize() setup_macrosets() // set init early so refresh macrosets works @@ -110,11 +113,18 @@ SUBSYSTEM_DEF(input) user.set_macros() user.update_movement_keys() -/datum/controller/subsystem/input/fire() - for(var/client/C as anything in GLOB.clients) +/datum/controller/subsystem/input/fire(resumed) + if(!resumed) + currentrun = GLOB.clients.Copy() + var/i + for(i in length(currentrun) to 1 step -1) + var/client/C = currentrun[i] if(!C.initialized) continue C.keyLoop() + if(MC_TICK_CHECK) + break + currentrun.len -= length(currentrun) - i + 1 /// *sigh /client/verb/NONSENSICAL_VERB_THAT_DOES_NOTHING() diff --git a/code/controllers/subsystem/machines.dm b/code/controllers/subsystem/machines.dm index 8411930bdb67..d0fa25883a7f 100644 --- a/code/controllers/subsystem/machines.dm +++ b/code/controllers/subsystem/machines.dm @@ -94,7 +94,7 @@ SUBSYSTEM_DEF(machines) src.current_run = global.pipe_networks.Copy() //cache for sanic speed (lists are references anyways) var/list/current_run = src.current_run - var/dt = (subsystem_flags & SS_TICKER)? (wait * world.tick_lag) : max(world.tick_lag, wait * 0.1) + var/dt = nominal_dt_s while(current_run.len) var/datum/pipe_network/PN = current_run[current_run.len] current_run.len-- @@ -112,7 +112,7 @@ SUBSYSTEM_DEF(machines) src.current_run = global.processing_machines.Copy() var/list/current_run = src.current_run - var/dt = (subsystem_flags & SS_TICKER)? (wait * world.tick_lag) : max(world.tick_lag, wait * 0.1) + var/dt = nominal_dt_s while(current_run.len) var/obj/machinery/M = current_run[current_run.len] current_run.len-- diff --git a/code/controllers/subsystem/materials.dm b/code/controllers/subsystem/materials.dm index a4adda3d45d9..85e4869c4f36 100644 --- a/code/controllers/subsystem/materials.dm +++ b/code/controllers/subsystem/materials.dm @@ -63,7 +63,7 @@ SUBSYSTEM_DEF(materials) src.currentrun = ticking.Copy() var/list/currentrun = src.currentrun var/atom/A - var/dt = (subsystem_flags & SS_TICKER)? (wait * world.tick_lag) : max(world.tick_lag, wait * 0.1) + var/dt = nominal_dt_s var/i var/datum/material_trait/trait for(i in length(currentrun) to 1 step -1) diff --git a/code/controllers/subsystem/mobs.dm b/code/controllers/subsystem/mobs.dm index 3c4692649b97..1d7cf7eed2f7 100644 --- a/code/controllers/subsystem/mobs.dm +++ b/code/controllers/subsystem/mobs.dm @@ -36,7 +36,7 @@ SUBSYSTEM_DEF(mobs) //cache for sanic speed (lists are references anyways) var/list/currentrun = src.currentrun var/times_fired = src.times_fired - var/dt = (subsystem_flags & SS_TICKER)? (world.tick_lag * wait) : max(world.tick_lag, wait * 0.1) + var/dt = nominal_dt_s while(currentrun.len) var/mob/M = currentrun[currentrun.len] currentrun.len-- diff --git a/code/controllers/subsystem/overmap_physics.dm b/code/controllers/subsystem/overmap_physics.dm index 8f981b805fec..afe4be8b9508 100644 --- a/code/controllers/subsystem/overmap_physics.dm +++ b/code/controllers/subsystem/overmap_physics.dm @@ -1,5 +1,6 @@ SUBSYSTEM_DEF(overmap_physics) name = "Overmap Physics" + priority = FIRE_PRIORITY_OVERMAP_PHYSICS subsystem_flags = SS_NO_INIT wait = 0.25 diff --git a/code/controllers/subsystem/planets.dm b/code/controllers/subsystem/planets.dm index cf113153c443..b01d171eff85 100644 --- a/code/controllers/subsystem/planets.dm +++ b/code/controllers/subsystem/planets.dm @@ -159,7 +159,7 @@ SUBSYSTEM_DEF(planets) return var/list/currentrun = src.currentrun - var/dt = (subsystem_flags & SS_TICKER)? (wait * world.tick_lag * 0.1) : (wait * 0.1) + var/dt = nominal_dt_s while(currentrun.len) var/datum/planet/P = currentrun[currentrun.len] currentrun.len-- diff --git a/code/controllers/subsystem/radiation.dm b/code/controllers/subsystem/radiation.dm index 88484652331c..c2b79d92ef6c 100644 --- a/code/controllers/subsystem/radiation.dm +++ b/code/controllers/subsystem/radiation.dm @@ -50,7 +50,7 @@ SUBSYSTEM_DEF(radiation) if(length(currentrun)) var/i var/datum/component/radioactive/source - var/dt = (subsystem_flags & SS_TICKER)? (world.tick_lag * wait) : (wait) + var/dt = nominal_dt_s for(i in 1 to length(currentrun)) source = currentrun[i] source.emit(dt) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 00a7fca8b7c7..badb7450553b 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -499,7 +499,7 @@ SUBSYSTEM_DEF(ticker) if(current_state != GAME_STATE_PLAYING) return 0 - var/dt = (subsystem_flags & SS_TICKER)? (wait * world.tick_lag * 0.1) : (wait * 0.1) + var/dt = nominal_dt_s mode.process(dt) var/game_finished = 0 diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 95e3a0e8c74c..69a9cbe4ee0b 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -467,6 +467,9 @@ //* logout mob?.pre_logout(src) + //* cleanup from SSinput + SSinput.currentrun -= src + . = ..() //Even though we're going to be hard deleted there are still some things that want to know the destroy is happening return QDEL_HINT_HARDDEL_NOW