diff --git a/code/__defines/MC.dm b/code/__defines/MC.dm index 5620f51b3b..1d41a31209 100644 --- a/code/__defines/MC.dm +++ b/code/__defines/MC.dm @@ -27,6 +27,10 @@ if(current_step == this_step || (initial_step && !resumed)) /* So we start at st #define MC_AVERAGE_FAST(average, current) (0.7 * (average) + 0.3 * (current)) #define MC_AVERAGE(average, current) (0.8 * (average) + 0.2 * (current)) #define MC_AVERAGE_SLOW(average, current) (0.9 * (average) + 0.1 * (current)) + +#define MC_AVG_FAST_UP_SLOW_DOWN(average, current) (average > current ? MC_AVERAGE_SLOW(average, current) : MC_AVERAGE_FAST(average, current)) +#define MC_AVG_SLOW_UP_FAST_DOWN(average, current) (average < current ? MC_AVERAGE_SLOW(average, current) : MC_AVERAGE_FAST(average, current)) + #define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;} #define START_PROCESSING(Processor, Datum) if (!Datum.isprocessing) {Datum.isprocessing = 1;Processor.processing += Datum} diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 961f657b2d..6cfd051727 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -428,7 +428,7 @@ var/datum/controller/master/Master = new() // in those cases, so we just let them run) if (queue_node_flags & SS_NO_TICK_CHECK) if (queue_node.tick_usage > TICK_LIMIT_RUNNING - TICK_USAGE && ran_non_ticker) - queue_node.queued_priority += queue_priority_count * 0.10 + queue_node.queued_priority += queue_priority_count * 0.1 queue_priority_count -= queue_node_priority queue_priority_count += queue_node.queued_priority current_tick_budget -= queue_node_priority @@ -446,26 +446,32 @@ var/datum/controller/master/Master = new() else tick_precentage = tick_remaining - current_ticklimit = TICK_USAGE + tick_precentage + // Reduce tick allocation for subsystems that overran on their last tick. + tick_precentage = max(tick_precentage*0.5, tick_precentage-queue_node.tick_overrun) + + current_ticklimit = round(TICK_USAGE + tick_precentage) if (!(queue_node_flags & SS_TICKER)) ran_non_ticker = TRUE ran = TRUE - tick_usage = TICK_USAGE + queue_node_paused = (queue_node.state == SS_PAUSED || queue_node.state == SS_PAUSING) last_type_processed = queue_node queue_node.state = SS_RUNNING + tick_usage = TICK_USAGE var/state = queue_node.ignite(queue_node_paused) + tick_usage = TICK_USAGE - tick_usage + if (state == SS_RUNNING) state = SS_IDLE current_tick_budget -= queue_node_priority - tick_usage = TICK_USAGE - tick_usage + if (tick_usage < 0) 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.state = state if (state == SS_PAUSED) @@ -494,11 +500,11 @@ var/datum/controller/master/Master = new() if (queue_node_flags & SS_TICKER) queue_node.next_fire = world.time + (world.tick_lag * queue_node.wait) else if (queue_node_flags & SS_POST_FIRE_TIMING) - queue_node.next_fire = world.time + queue_node.wait + 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 else - queue_node.next_fire = queue_node.queued_time + queue_node.wait + queue_node.next_fire = queue_node.queued_time + queue_node.wait + (world.tick_lag * (queue_node.tick_overrun/100)) queue_node.queued_time = 0 diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm index 437c10424b..3d37e9ba7d 100644 --- a/code/controllers/subsystem.dm +++ b/code/controllers/subsystem.dm @@ -17,6 +17,7 @@ var/next_fire = 0 //scheduled world.time for next fire() var/cost = 0 //average time to execute var/tick_usage = 0 //average tick usage + var/tick_overrun = 0 //average tick overrun var/state = SS_IDLE //tracks the current state of the ss, running, paused, etc. var/paused_ticks = 0 //ticks this ss is taking to run right now. var/paused_tick_usage //total tick_usage of all of our runs while pausing this run @@ -167,7 +168,7 @@ if(can_fire && !(SS_NO_FIRE & flags)) - msg = "[round(cost,1)]ms|[round(tick_usage,1)]%|[round(ticks,0.1)]\t[msg]" + msg = "[round(cost,1)]ms|[round(tick_usage,1)]%([round(tick_overrun,1)]%)|[round(ticks,0.1)]\t[msg]" else msg = "OFFLINE\t[msg]"