diff --git a/code/__defines/dcs/signals/signals_subsystem.dm b/code/__defines/dcs/signals/signals_subsystem.dm new file mode 100644 index 0000000000..26daf58e1a --- /dev/null +++ b/code/__defines/dcs/signals/signals_subsystem.dm @@ -0,0 +1,7 @@ +// Subsystem signals. Format: +// When the signal is called: (signal arguments) +// All signals send the source datum of the signal as the first argument + +///Subsystem signals +///From base of datum/controller/subsystem/Initialize +#define COMSIG_SUBSYSTEM_POST_INITIALIZE "subsystem_post_initialize" diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index 4d80021c0f..eb813b0d1a 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -202,3 +202,6 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G * * timer_subsystem the subsystem to insert this timer into */ #define addtimer(args...) _addtimer(args, file = __FILE__, line = __LINE__) + +/// The timer key used to know how long subsystem initialization takes +#define SS_INIT_TIMER_KEY "ss_init" diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 35145d5a62..ec7f0a61e4 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -19,44 +19,66 @@ GLOBAL_REAL(Master, /datum/controller/master) = new /// Stack end detector to detect stack overflows that kill the mc's main loop var/datum/stack_end_detector/stack_end_detector - // world.time of last fire, for tracking lag outside of the mc + /// world.time of last fire, for tracking lag outside of the mc var/last_run - // List of subsystems to process(). + /// List of subsystems to process(). var/list/subsystems // Vars for keeping track of tick drift. var/init_timeofday var/init_time var/tickdrift = 0 + /// Tickdrift as of last tick, w no averaging going on + var/olddrift = 0 + /// How long is the MC sleeping between runs, read only (set by Loop() based off of anti-tick-contention heuristics) var/sleep_delta = 1 - var/make_runtime = 0 + /// Only run ticker subsystems for the next n ticks. + var/skip_ticks = 0 + + /// makes the mc main loop runtime + var/make_runtime = FALSE var/initializations_finished_with_no_players_logged_in //I wonder what this could be? // The type of the last subsystem to be process()'d. var/last_type_processed - var/datum/controller/subsystem/queue_head //Start of queue linked list - var/datum/controller/subsystem/queue_tail //End of queue linked list (used for appending to the list) + var/datum/controller/subsystem/queue_head //!Start of queue linked list + var/datum/controller/subsystem/queue_tail //!End of queue linked list (used for appending to the list) var/queue_priority_count = 0 //Running total so that we don't have to loop thru the queue each run to split up the tick var/queue_priority_count_bg = 0 //Same, but for background subsystems - var/map_loading = FALSE //Are we loading in a new map? + var/map_loading = FALSE //!Are we loading in a new map? - var/current_runlevel //for scheduling different subsystems for different stages of the round + var/current_runlevel //!for scheduling different subsystems for different stages of the round + + /// During initialization, will be the instanced subsytem that is currently initializing. + /// Outside of initialization, returns null. + var/current_initializing_subsystem = null var/static/restart_clear = 0 var/static/restart_timeout = 0 var/static/restart_count = 0 - //current tick limit, assigned by the queue controller 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/random_seed + + ///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 /datum/controller/master/New() // Highlander-style: there can only be one! Kill off the old and replace it with the new. + + if(!random_seed) + #ifdef UNIT_TESTS + random_seed = 29051994 // How about 22475? + #else + random_seed = rand(1, 1e9) + #endif + rand_seed(random_seed) + var/list/_subsystems = list() subsystems = _subsystems if (Master != src) @@ -84,6 +106,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new reverseRange(subsystems) for(var/datum/controller/subsystem/ss in subsystems) log_world("Shutting down [ss.name] subsystem...") + if (ss.slept_count > 0) + log_world("Warning: Subsystem `[ss.name]` slept [ss.slept_count] times.") ss.Shutdown() log_world("Shutdown complete") @@ -178,8 +202,9 @@ GLOBAL_REAL(Master, /datum/controller/master) = new for (var/datum/controller/subsystem/SS in subsystems) if (SS.flags & SS_NO_INIT) continue - SS.Initialize(REALTIMEOFDAY) + init_subsystem(SS) CHECK_TICK + current_initializing_subsystem = null current_ticklimit = TICK_LIMIT_RUNNING var/time = (REALTIMEOFDAY - start_timeofday) / 10 @@ -187,6 +212,10 @@ GLOBAL_REAL(Master, /datum/controller/master) = new to_chat(world, span_boldannounce("[msg]")) log_world(msg) + + // FIXME: TGS <-> Discord communication; sending message to a TGS chat channel + // send2chat("Server Initialization completed! - Took [time] second[time == 1 ? "" : "s"].", "bot announce") + if (!current_runlevel) SetRunLevel(RUNLEVEL_LOBBY) @@ -207,6 +236,80 @@ GLOBAL_REAL(Master, /datum/controller/master) = new // Loop. Master.StartProcessing(0) +/** + * Initialize a given subsystem and handle the results. + * + * Arguments: + * * subsystem - the subsystem to initialize. + */ +/datum/controller/master/proc/init_subsystem(datum/controller/subsystem/subsystem) + var/static/list/valid_results = list( + SS_INIT_FAILURE, + SS_INIT_NONE, + SS_INIT_SUCCESS, + SS_INIT_NO_NEED, + ) + + if (subsystem.flags & SS_NO_INIT || subsystem.subsystem_initialized) //Don't init SSs with the corresponding flag or if they already are initialized + return + + current_initializing_subsystem = subsystem + rustg_time_reset(SS_INIT_TIMER_KEY) + + var/result = subsystem.Initialize() + + // Capture end time + var/time = rustg_time_milliseconds(SS_INIT_TIMER_KEY) + var/seconds = round(time / 1000, 0.01) + + // Always update the blackbox tally regardless. + // SSblackbox.record_feedback("tally", "subsystem_initialize", time, subsystem.name) + feedback_set_details("subsystem_initialize", "[time] [subsystem.name]") + + // Gave invalid return value. + if(result && !(result in valid_results)) + warning("[subsystem.name] subsystem initialized, returning invalid result [result]. This is a bug.") + + // just returned ..() or didn't implement Initialize() at all + if(result == SS_INIT_NONE) + warning("[subsystem.name] subsystem does not implement Initialize() or it returns ..(). If the former is true, the SS_NO_INIT flag should be set for this subsystem.") + + if(result != SS_INIT_FAILURE) + // Some form of success, implicit failure, or the SS in unused. + subsystem.subsystem_initialized = TRUE + + SEND_SIGNAL(subsystem, COMSIG_SUBSYSTEM_POST_INITIALIZE) + else + // The subsystem officially reports that it failed to init and wishes to be treated as such. + subsystem.subsystem_initialized = FALSE + subsystem.can_fire = FALSE + + // The rest of this proc is printing the world log and chat message. + var/message_prefix + + // If true, print the chat message with boldwarning text. + var/chat_warning = FALSE + + switch(result) + if(SS_INIT_FAILURE) + message_prefix = "Failed to initialize [subsystem.name] subsystem after" + chat_warning = TRUE + if(SS_INIT_SUCCESS) + message_prefix = "Initialized [subsystem.name] subsystem within" + if(SS_INIT_NO_NEED) + // This SS is disabled or is otherwise shy. + return + else + // SS_INIT_NONE or an invalid value. + message_prefix = "Initialized [subsystem.name] subsystem with errors within" + chat_warning = TRUE + + var/message = "[message_prefix] [seconds] second[seconds == 1 ? "" : "s"]!" + var/chat_message = chat_warning ? span_boldwarning(message) : span_boldannounce(message) + + to_chat(world, chat_message) + log_world(message) + /datum/controller/master/proc/SetRunLevel(new_runlevel) var/old_runlevel = isnull(current_runlevel) ? "NULL" : runlevel_flags[current_runlevel] testing("MC: Runlevel changed from [old_runlevel] to [new_runlevel]") diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm index 3cd8af77fe..3e5e269057 100644 --- a/code/controllers/subsystem.dm +++ b/code/controllers/subsystem.dm @@ -1,36 +1,99 @@ +/** + * # Subsystem base class + * + * Defines a subsystem to be managed by the [Master Controller][/datum/controller/master] + * + * Simply define a child of this subsystem, using the [SUBSYSTEM_DEF] macro, and the MC will handle registration. + * Changing the name is required +**/ + /datum/controller/subsystem // Metadata; you should define these. - name = "fire coderbus" //name of the subsystem - var/init_order = INIT_ORDER_DEFAULT //order of initialization. Higher numbers are initialized first, lower numbers later. Can be decimal and negative values. - var/wait = 20 //time to wait (in deciseconds) between each call to fire(). Must be a positive integer. - var/priority = FIRE_PRIORITY_DEFAULT //When mutiple subsystems need to run in the same tick, higher priority subsystems will run first and be given a higher share of the tick before MC_TICK_CHECK triggers a sleep - var/flags = 0 //see MC.dm in __DEFINES Most flags must be set on world start to take full effect. (You can also restart the mc to force them to process again) - var/subsystem_initialized = FALSE //set to TRUE after it has been initialized, will obviously never be set if the subsystem doesn't initialize - var/runlevels = RUNLEVELS_DEFAULT //points of the game at which the SS can fire + /// Name of the subsystem - you must change this + name = "fire coderbus" - //set to 0 to prevent fire() calls, mostly for admin use or subsystems that may be resumed later - // use the SS_NO_FIRE flag instead for systems that never fire to keep it from even being added to the list + /// Order of initialization. Higher numbers are initialized first, lower numbers later. Use or create defines such as [INIT_ORDER_DEFAULT] so we can see the order in one file. + var/init_order = INIT_ORDER_DEFAULT + + /// Time to wait (in deciseconds) between each call to fire(). Must be a positive integer. + var/wait = 20 + + /// Priority Weight: When mutiple subsystems need to run in the same tick, higher priority subsystems will be given a higher share of the tick before MC_TICK_CHECK triggers a sleep, higher priority subsystems also run before lower priority subsystems. + var/priority = FIRE_PRIORITY_DEFAULT + + /// [Subsystem Flags][SS_NO_INIT] to control binary behavior. Flags must be set at compile time or before preinit finishes to take full effect. (You can also restart the mc to force them to process again) + var/flags = NONE + + /// This var is set to TRUE after the subsystem has been initialized. + var/subsystem_initialized = FALSE + + /// Set to 0 to prevent fire() calls, mostly for admin use or subsystems that may be resumed later + /// use the [SS_NO_FIRE] flag instead for systems that never fire to keep it from even being added to list that is checked every tick var/can_fire = TRUE - // Bookkeeping variables; probably shouldn't mess with these. - var/last_fire = 0 //last world.time we called fire() - 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 - var/ticks = 1 //how many ticks does this ss take to run on avg. - var/times_fired = 0 //number of times we have called fire() - var/queued_time = 0 //time we entered the queue, (for timing and priority reasons) - var/queued_priority //we keep a running total to make the math easier, if priority changes mid-fire that would break our running total, so we store it here - //linked list stuff for the queue + ///Bitmap of what game states can this subsystem fire at. See [RUNLEVELS_DEFAULT] for more details. + var/runlevels = RUNLEVELS_DEFAULT + + /* + * 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]) + var/last_fire = 0 + + /// Scheduled world.time for next fire() + 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) + var/cost = 0 + + /// Running average of the amount of tick usage in percents of a tick it takes the subsystem to complete a run + var/tick_usage = 0 + + /// 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 + + /// Tracks how many times a subsystem has ever slept in fire(). + var/slept_count = 0 + + /// Tracks how many fires the subsystem has consecutively paused on in the current run + var/paused_ticks = 0 + + /// Tracks how much of a tick the subsystem has consumed in the current run + var/paused_tick_usage + + /// Tracks how many fires the subsystem takes to complete a run on average. + var/ticks = 1 + + /// Tracks the amount of completed runs for the subsystem + var/times_fired = 0 + + /// Time the subsystem entered the queue, (for timing and priority reasons) + var/queued_time = 0 + + /// Priority at the time the subsystem entered the queue. Needed to avoid changes in priority (by admins and the like) from breaking things. + var/queued_priority + + /// How many times we suspect a subsystem type has crashed the MC, 3 strikes and you're out! + var/static/list/failure_strikes + + /// Next subsystem in the queue of subsystems to run this tick var/datum/controller/subsystem/queue_next + /// Previous subsystem in the queue of subsystems to run this tick var/datum/controller/subsystem/queue_prev - var/static/list/failure_strikes //How many times we suspect a subsystem type has crashed the MC, 3 strikes and you're out! + //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. //Do not override ///datum/controller/subsystem/New() @@ -41,24 +104,32 @@ /datum/controller/subsystem/proc/PreInit() return -//This is used so the mc knows when the subsystem sleeps. do not override. -/datum/controller/subsystem/proc/ignite(resumed = 0) +///This is used so the mc knows when the subsystem sleeps. do not override. +/datum/controller/subsystem/proc/ignite(resumed = FALSE) + SHOULD_NOT_OVERRIDE(TRUE) set waitfor = 0 + . = SS_IDLE + + tick_allocation_last = Master.current_ticklimit-(TICK_USAGE) + tick_allocation_avg = MC_AVERAGE(tick_allocation_avg, tick_allocation_last) + . = SS_SLEEPING fire(resumed) . = state if (state == SS_SLEEPING) + slept_count++ state = SS_IDLE if (state == SS_PAUSING) + slept_count++ var/QT = queued_time enqueue() state = SS_PAUSED queued_time = QT -//previously, this would have been named 'process()' but that name is used everywhere for different things! -//fire() seems more suitable. This is the procedure that gets called every 'wait' deciseconds. -//Sleeping in here prevents future fires until returned. -/datum/controller/subsystem/proc/fire(resumed = 0) +///previously, this would have been named 'process()' but that name is used everywhere for different things! +///fire() seems more suitable. This is the procedure that gets called every 'wait' deciseconds. +///Sleeping in here prevents future fires until returned. +/datum/controller/subsystem/proc/fire(resumed = FALSE) flags |= SS_NO_FIRE throw EXCEPTION("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.") @@ -66,12 +137,13 @@ dequeue() can_fire = 0 flags |= SS_NO_FIRE - Master.subsystems -= src + if (Master) + Master.subsystems -= src return ..() -//Queue it to run. -// (we loop thru a linked list until we get to the end or find the right point) -// (this lets us sort our run order correctly without having to re-sort the entire already sorted list) +///Queue it to run. +/// (we loop thru a linked list until we get to the end or find the right point) +/// (this lets us sort our run order correctly without having to re-sort the entire already sorted list) /datum/controller/subsystem/proc/enqueue() var/SS_priority = priority var/SS_flags = flags @@ -155,14 +227,11 @@ /// Called after the config has been loaded or reloaded. /datum/controller/subsystem/proc/OnConfigLoad() -//used to initialize the subsystem AFTER the map has loaded -/datum/controller/subsystem/Initialize(start_timeofday) - subsystem_initialized = TRUE - var/time = (REALTIMEOFDAY - start_timeofday) / 10 - var/msg = "Initialized [name] subsystem within [time] second[time == 1 ? "" : "s"]!" - to_chat(world, span_boldannounce("[msg]")) - log_world(msg) - return time +/** + * Used to initialize the subsystem. This is expected to be overriden by subtypes. + */ +/datum/controller/subsystem/Initialize() + return SS_INIT_NONE //hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc. /datum/controller/subsystem/stat_entry(msg) @@ -221,3 +290,9 @@ var/msg = "[name] subsystem received final blame for MC failure" log_world(msg) log_game(msg) + +/datum/controller/subsystem/vv_edit_var(var_name, var_value) + switch (var_name) + if (NAMEOF(src, queued_priority)) //editing this breaks things. + return FALSE + . = ..() diff --git a/code/controllers/subsystems/air.dm b/code/controllers/subsystems/air.dm index e008086d04..68183655fa 100644 --- a/code/controllers/subsystems/air.dm +++ b/code/controllers/subsystems/air.dm @@ -101,7 +101,8 @@ SUBSYSTEM_DEF(air) var/current_cycle = 0 var/next_id = 1 //Used to keep track of zone UIDs. -/datum/controller/subsystem/air/Initialize(timeofday) +/datum/controller/subsystem/air/Initialize() + var/start_timeofday = REALTIMEOFDAY report_progress("Processing Geometry...") current_cycle = 0 @@ -111,7 +112,7 @@ SUBSYSTEM_DEF(air) S.update_air_properties() CHECK_TICK - admin_notice(span_danger("Geometry initialized in [round(0.1*(REALTIMEOFDAY-timeofday),0.1)] seconds.") + \ + admin_notice(span_danger("Geometry initialized in [round(0.1*(REALTIMEOFDAY-start_timeofday),0.1)] seconds.") + \ span_info("
\ Total Simulated Turfs: [simulated_turf_count]
\ Total Zones: [zones.len]
\ @@ -166,7 +167,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun log_debug("Active Edges on ZAS Startup\n" + edge_log.Join("\n")) startup_active_edge_log = edge_log.Copy() - ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/air/fire(resumed = 0) var/timer diff --git a/code/controllers/subsystems/alarm.dm b/code/controllers/subsystems/alarm.dm index e3507a34e4..25a28ca59e 100644 --- a/code/controllers/subsystems/alarm.dm +++ b/code/controllers/subsystems/alarm.dm @@ -18,7 +18,7 @@ SUBSYSTEM_DEF(alarm) /datum/controller/subsystem/alarm/Initialize() all_handlers = list(atmosphere_alarm, camera_alarm, fire_alarm, motion_alarm, power_alarm) - . = ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/alarm/fire(resumed = FALSE) if(!resumed) diff --git a/code/controllers/subsystems/atoms.dm b/code/controllers/subsystems/atoms.dm index 5968fe1fe3..81e4d217a5 100644 --- a/code/controllers/subsystems/atoms.dm +++ b/code/controllers/subsystems/atoms.dm @@ -17,13 +17,13 @@ SUBSYSTEM_DEF(atoms) var/list/BadInitializeCalls = list() -/datum/controller/subsystem/atoms/Initialize(timeofday) +/datum/controller/subsystem/atoms/Initialize() setupgenetics() //to set the mutations' place in structural enzymes, so initializers know where to put mutations. initialized = INITIALIZATION_INNEW_MAPLOAD to_world_log("Initializing objects") admin_notice(span_danger("Initializing objects"), R_DEBUG) InitializeAtoms() - return ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms) if(initialized == INITIALIZATION_INSSATOMS) diff --git a/code/controllers/subsystems/character_setup.dm b/code/controllers/subsystems/character_setup.dm index fdad93fbbb..272cd0b8ab 100644 --- a/code/controllers/subsystems/character_setup.dm +++ b/code/controllers/subsystems/character_setup.dm @@ -2,7 +2,7 @@ SUBSYSTEM_DEF(character_setup) name = "Character Setup" init_order = INIT_ORDER_DEFAULT priority = FIRE_PRIORITY_CHARSETUP - flags = SS_BACKGROUND + flags = SS_BACKGROUND | SS_NO_INIT wait = 1 SECOND runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT diff --git a/code/controllers/subsystems/chemistry.dm b/code/controllers/subsystems/chemistry.dm index e31b71dc00..f31441e34c 100644 --- a/code/controllers/subsystems/chemistry.dm +++ b/code/controllers/subsystems/chemistry.dm @@ -18,7 +18,7 @@ SUBSYSTEM_DEF(chemistry) /datum/controller/subsystem/chemistry/Initialize() initialize_chemical_reagents() initialize_chemical_reactions() - ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/chemistry/stat_entry(msg) msg = "C: [chemical_reagents.len] | R: [chemical_reactions.len]" diff --git a/code/controllers/subsystems/circuits.dm b/code/controllers/subsystems/circuits.dm index ca080a3d81..2e555b293d 100644 --- a/code/controllers/subsystems/circuits.dm +++ b/code/controllers/subsystems/circuits.dm @@ -17,9 +17,9 @@ SUBSYSTEM_DEF(circuit) /datum/controller/subsystem/circuit/Recover() flags |= SS_NO_INIT // Make extra sure we don't initialize twice. -/datum/controller/subsystem/circuit/Initialize(timeofday) +/datum/controller/subsystem/circuit/Initialize() circuits_init() - return ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/circuit/proc/circuits_init() //Cached lists for free performance diff --git a/code/controllers/subsystems/events.dm b/code/controllers/subsystems/events.dm index 5bdf83fdec..2e91ad3b15 100644 --- a/code/controllers/subsystems/events.dm +++ b/code/controllers/subsystems/events.dm @@ -21,7 +21,7 @@ SUBSYSTEM_DEF(events) ) if(global.using_map.use_overmap) GLOB.overmap_event_handler.create_events(global.using_map.overmap_z, global.using_map.overmap_size, global.using_map.overmap_event_areas) - return ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/events/fire(resumed) if (!resumed) diff --git a/code/controllers/subsystems/game_master.dm b/code/controllers/subsystems/game_master.dm index 11844b4f98..064c4307e6 100644 --- a/code/controllers/subsystems/game_master.dm +++ b/code/controllers/subsystems/game_master.dm @@ -36,7 +36,7 @@ SUBSYSTEM_DEF(game_master) if(config && !config.enable_game_master) can_fire = FALSE - return ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/game_master/fire(resumed) adjust_staleness(1) diff --git a/code/controllers/subsystems/holomaps.dm b/code/controllers/subsystems/holomaps.dm index 5fcca27480..9275172973 100644 --- a/code/controllers/subsystems/holomaps.dm +++ b/code/controllers/subsystems/holomaps.dm @@ -14,9 +14,9 @@ SUBSYSTEM_DEF(holomaps) /datum/controller/subsystem/holomaps/Recover() flags |= SS_NO_INIT // Make extra sure we don't initialize twice. -/datum/controller/subsystem/holomaps/Initialize(timeofday) +/datum/controller/subsystem/holomaps/Initialize() generateHoloMinimaps() - . = ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/holomaps/stat_entry(msg) if (!Debug2) diff --git a/code/controllers/subsystems/input.dm b/code/controllers/subsystems/input.dm index 62fe0184ff..70d1f9cda6 100644 --- a/code/controllers/subsystems/input.dm +++ b/code/controllers/subsystems/input.dm @@ -2,7 +2,7 @@ SUBSYSTEM_DEF(input) name = "Input" wait = 1 // SS_TICKER means this runs every tick init_order = INIT_ORDER_INPUT - flags = SS_TICKER + flags = SS_TICKER | SS_NO_INIT priority = FIRE_PRIORITY_INPUT runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY diff --git a/code/controllers/subsystems/job.dm b/code/controllers/subsystems/job.dm index d2f7e72bc9..c86d108415 100644 --- a/code/controllers/subsystems/job.dm +++ b/code/controllers/subsystems/job.dm @@ -11,12 +11,12 @@ SUBSYSTEM_DEF(job) var/debug_messages = FALSE -/datum/controller/subsystem/job/Initialize(timeofday) +/datum/controller/subsystem/job/Initialize() if(!department_datums.len) setup_departments() if(!occupations.len) setup_occupations() - return ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/job/proc/setup_occupations(faction = FACTION_STATION) occupations = list() diff --git a/code/controllers/subsystems/lighting.dm b/code/controllers/subsystems/lighting.dm index d9643c15ba..9bc179c278 100644 --- a/code/controllers/subsystems/lighting.dm +++ b/code/controllers/subsystems/lighting.dm @@ -12,7 +12,7 @@ SUBSYSTEM_DEF(lighting) return ..() -/datum/controller/subsystem/lighting/Initialize(timeofday) +/datum/controller/subsystem/lighting/Initialize() if(!subsystem_initialized) if (CONFIG_GET(flag/starlight)) for(var/area/A in world) @@ -24,7 +24,7 @@ SUBSYSTEM_DEF(lighting) fire(FALSE, TRUE) - return ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/lighting/fire(resumed, init_tick_checks) MC_SPLIT_TICK_INIT(3) diff --git a/code/controllers/subsystems/machines.dm b/code/controllers/subsystems/machines.dm index dea5b7ccc3..70f913be52 100644 --- a/code/controllers/subsystems/machines.dm +++ b/code/controllers/subsystems/machines.dm @@ -30,12 +30,12 @@ SUBSYSTEM_DEF(machines) var/list/powernets = list() var/list/powerobjs = list() -/datum/controller/subsystem/machines/Initialize(timeofday) +/datum/controller/subsystem/machines/Initialize() makepowernets() admin_notice(span_danger("Initializing atmos machinery."), R_DEBUG) setup_atmos_machinery(all_machines) fire() - ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/machines/fire(resumed = 0) var/timer = TICK_USAGE diff --git a/code/controllers/subsystems/mapping.dm b/code/controllers/subsystems/mapping.dm index 42e1de651c..4b0beb2485 100644 --- a/code/controllers/subsystems/mapping.dm +++ b/code/controllers/subsystems/mapping.dm @@ -12,7 +12,7 @@ SUBSYSTEM_DEF(mapping) flags |= SS_NO_INIT // Make extra sure we don't initialize twice. shelter_templates = SSmapping.shelter_templates -/datum/controller/subsystem/mapping/Initialize(timeofday) +/datum/controller/subsystem/mapping/Initialize() if(subsystem_initialized) return world.max_z_changed() // This is to set up the player z-level list, maxz hasn't actually changed (probably) @@ -29,7 +29,7 @@ SUBSYSTEM_DEF(mapping) // Lateload Code related to Expedition areas. if(using_map) // VOREStation Edit: Re-enable this. loadLateMaps() - ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/mapping/proc/load_map_templates() for(var/datum/map_template/template as anything in subtypesof(/datum/map_template)) diff --git a/code/controllers/subsystems/media_tracks.dm b/code/controllers/subsystems/media_tracks.dm index 9aa59f95fe..d9b27a3c76 100644 --- a/code/controllers/subsystems/media_tracks.dm +++ b/code/controllers/subsystems/media_tracks.dm @@ -10,10 +10,10 @@ SUBSYSTEM_DEF(media_tracks) /// Lobby music tracks var/list/lobby_tracks = list() -/datum/controller/subsystem/media_tracks/Initialize(timeofday) +/datum/controller/subsystem/media_tracks/Initialize() load_tracks() sort_tracks() - return ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/media_tracks/proc/load_tracks() for(var/filename in CONFIG_GET(str_list/jukebox_track_files)) diff --git a/code/controllers/subsystems/nightshift.dm b/code/controllers/subsystems/nightshift.dm index 4cfddfec0f..882016e081 100644 --- a/code/controllers/subsystems/nightshift.dm +++ b/code/controllers/subsystems/nightshift.dm @@ -17,7 +17,7 @@ SUBSYSTEM_DEF(nightshift) if(config.randomize_shift_time) GLOB.gametime_offset = rand(0, 23) HOURS */ - return ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/nightshift/fire(resumed = FALSE) if(round_duration_in_ds < nightshift_first_check) diff --git a/code/controllers/subsystems/overlays.dm b/code/controllers/subsystems/overlays.dm index 0a953e9782..012b6f10e7 100644 --- a/code/controllers/subsystems/overlays.dm +++ b/code/controllers/subsystems/overlays.dm @@ -28,9 +28,9 @@ SUBSYSTEM_DEF(overlays) CHECK_TICK -/datum/controller/subsystem/overlays/Initialize(timeofday) +/datum/controller/subsystem/overlays/Initialize() fire(FALSE, TRUE) - ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/overlays/stat_entry(msg) msg = "Queued Atoms: [queue.len], Cache Size: [cache_size]" diff --git a/code/controllers/subsystems/overmap_renamer_vr.dm b/code/controllers/subsystems/overmap_renamer_vr.dm index 0180b89355..d82aadbfcb 100644 --- a/code/controllers/subsystems/overmap_renamer_vr.dm +++ b/code/controllers/subsystems/overmap_renamer_vr.dm @@ -10,10 +10,9 @@ SUBSYSTEM_DEF(overmap_renamer) -/datum/controller/subsystem/overmap_renamer/Initialize(timeofday) +/datum/controller/subsystem/overmap_renamer/Initialize() update_names() - - ..() + return SS_INIT_SUCCESS /*Shouldn't be a switch statement. We want ALL of the if(map_template.name in visitable_z_leves_name_list) to fire if we end up with multiple renamable lateload overmap objects.*/ diff --git a/code/controllers/subsystems/persistence.dm b/code/controllers/subsystems/persistence.dm index 1950e90e14..69a92f14e2 100644 --- a/code/controllers/subsystems/persistence.dm +++ b/code/controllers/subsystems/persistence.dm @@ -11,12 +11,12 @@ SUBSYSTEM_DEF(persistence) var/list/unpicked_paintings = list() /datum/controller/subsystem/persistence/Initialize() - . = ..() for(var/datum/persistent/P as anything in subtypesof(/datum/persistent)) if(initial(P.name)) P = new P persistence_datums[P.type] = P P.Initialize() + return SS_INIT_SUCCESS /datum/controller/subsystem/persistence/Shutdown() for(var/thing in persistence_datums) diff --git a/code/controllers/subsystems/planets.dm b/code/controllers/subsystems/planets.dm index 2054d6daa7..fa4cf68068 100644 --- a/code/controllers/subsystems/planets.dm +++ b/code/controllers/subsystems/planets.dm @@ -14,10 +14,10 @@ SUBSYSTEM_DEF(planets) var/static/list/needs_sun_update = list() var/static/list/needs_temp_update = list() -/datum/controller/subsystem/planets/Initialize(timeofday) +/datum/controller/subsystem/planets/Initialize() admin_notice(span_danger("Initializing planetary weather."), R_DEBUG) createPlanets() - ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/planets/proc/createPlanets() var/list/planet_datums = using_map.planet_datums_to_make diff --git a/code/controllers/subsystems/plants.dm b/code/controllers/subsystems/plants.dm index bfa2df55e8..0743f1e262 100644 --- a/code/controllers/subsystems/plants.dm +++ b/code/controllers/subsystems/plants.dm @@ -26,9 +26,9 @@ SUBSYSTEM_DEF(plants) msg = "P:[processing.len]|S:[seeds.len]" return ..() -/datum/controller/subsystem/plants/Initialize(timeofday) +/datum/controller/subsystem/plants/Initialize() setup() - return ..() + return SS_INIT_SUCCESS // Predefined/roundstart varieties use a string key to make it // easier to grab the new variety when mutating. Post-roundstart diff --git a/code/controllers/subsystems/player_tips.dm b/code/controllers/subsystems/player_tips.dm index 7ac58b52bd..8afa6cc5b5 100644 --- a/code/controllers/subsystems/player_tips.dm +++ b/code/controllers/subsystems/player_tips.dm @@ -1,16 +1,12 @@ -/* -Player tips procs and lists are defined under /code/modules/player_tips_vr -*/ +/// Player tips procs and lists are defined under /code/modules/player_tips_vr SUBSYSTEM_DEF(player_tips) name = "Periodic Player Tips" priority = FIRE_PRIORITY_PLAYERTIPS runlevels = RUNLEVEL_GAME - wait = 3000 //We check if it's time to send a tip every 5 minutes (300 seconds) + flags = SS_NO_INIT + var/static/datum/player_tips/player_tips = new - - - /datum/controller/subsystem/player_tips/fire() player_tips.send_tips() diff --git a/code/controllers/subsystems/processing/fastprocess.dm b/code/controllers/subsystems/processing/fastprocess.dm index bda0bb6fb6..407477f9b0 100644 --- a/code/controllers/subsystems/processing/fastprocess.dm +++ b/code/controllers/subsystems/processing/fastprocess.dm @@ -4,6 +4,7 @@ PROCESSING_SUBSYSTEM_DEF(fastprocess) name = "Fast Processing" wait = 2 stat_tag = "FP" + flags = SS_NO_INIT /datum/controller/subsystem/processing/fastprocess/Recover() log_debug("[name] subsystem Recover().") @@ -12,4 +13,4 @@ PROCESSING_SUBSYSTEM_DEF(fastprocess) var/list/old_processing = SSfastprocess.processing.Copy() for(var/datum/D in old_processing) if(CHECK_BITFIELD(D.datum_flags, DF_ISPROCESSING)) - processing |= D \ No newline at end of file + processing |= D diff --git a/code/controllers/subsystems/processing/instruments.dm b/code/controllers/subsystems/processing/instruments.dm index 72770ea39b..e3a4802f11 100644 --- a/code/controllers/subsystems/processing/instruments.dm +++ b/code/controllers/subsystems/processing/instruments.dm @@ -24,7 +24,7 @@ PROCESSING_SUBSYSTEM_DEF(instruments) /datum/controller/subsystem/processing/instruments/Initialize() initialize_instrument_data() synthesizer_instrument_ids = get_allowed_instrument_ids() - return ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/processing/instruments/proc/on_song_new(datum/song/S) songs += S diff --git a/code/controllers/subsystems/processing/turfs.dm b/code/controllers/subsystems/processing/turfs.dm index d28f4b4809..509ec4f17b 100644 --- a/code/controllers/subsystems/processing/turfs.dm +++ b/code/controllers/subsystems/processing/turfs.dm @@ -1,6 +1,7 @@ PROCESSING_SUBSYSTEM_DEF(turfs) name = "Turf Processing" wait = 20 + flags = SS_NO_INIT /datum/controller/subsystem/processing/turfs/Recover() log_debug("[name] subsystem Recover().") @@ -11,4 +12,4 @@ PROCESSING_SUBSYSTEM_DEF(turfs) if(!isturf(D)) log_debug("[name] subsystem Recover() found inappropriate item in list: [D.type]") if(CHECK_BITFIELD(D.datum_flags, DF_ISPROCESSING)) - processing |= D \ No newline at end of file + processing |= D diff --git a/code/controllers/subsystems/robot_sprites.dm b/code/controllers/subsystems/robot_sprites.dm index 88fa331451..d6d38ab50f 100644 --- a/code/controllers/subsystems/robot_sprites.dm +++ b/code/controllers/subsystems/robot_sprites.dm @@ -8,7 +8,7 @@ SUBSYSTEM_DEF(robot_sprites) /datum/controller/subsystem/robot_sprites/Initialize() initialize_borg_sprites() - ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/robot_sprites/proc/initialize_borg_sprites() diff --git a/code/controllers/subsystems/server_maint.dm b/code/controllers/subsystems/server_maint.dm index e8d10d6748..20cd2760db 100644 --- a/code/controllers/subsystems/server_maint.dm +++ b/code/controllers/subsystems/server_maint.dm @@ -18,7 +18,7 @@ SUBSYSTEM_DEF(server_maint) /*/datum/controller/subsystem/server_maint/PreInit() world.hub_password = "" *///quickly! before the hubbies see us. -/datum/controller/subsystem/server_maint/New() +/datum/controller/subsystem/server_maint/Initialize() if (fexists("tmp/")) fdel("tmp/") //if (CONFIG_GET(flag/hub)) diff --git a/code/controllers/subsystems/shuttles.dm b/code/controllers/subsystems/shuttles.dm index 02f9cb91eb..ebd4cdcc5c 100644 --- a/code/controllers/subsystems/shuttles.dm +++ b/code/controllers/subsystems/shuttles.dm @@ -32,7 +32,7 @@ SUBSYSTEM_DEF(shuttles) var/tmp/list/current_run // Shuttles remaining to process this fire() tick -/datum/controller/subsystem/shuttles/Initialize(timeofday) +/datum/controller/subsystem/shuttles/Initialize() last_landmark_registration_time = world.time // Find all declared shuttle datums and initailize them. (Okay, queue them for initialization a few lines further down) for(var/shuttle_type in subtypesof(/datum/shuttle)) // This accounts for most shuttles, though away maps can queue up more. @@ -43,7 +43,7 @@ SUBSYSTEM_DEF(shuttles) LAZYDISTINCTADD(shuttles_to_initialize, shuttle_type) block_init_queue = FALSE process_init_queues() - return ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/shuttles/fire(resumed = 0) if (!resumed) diff --git a/code/controllers/subsystems/skybox.dm b/code/controllers/subsystems/skybox.dm index 52065ad241..a1f6dcf11a 100644 --- a/code/controllers/subsystems/skybox.dm +++ b/code/controllers/subsystems/skybox.dm @@ -28,7 +28,7 @@ SUBSYSTEM_DEF(skybox) normal_space.layer = TURF_LAYER normal_space.icon = 'icons/turf/space.dmi' normal_space.icon_state = "white" - + //Static for (var/i in 0 to 25) var/mutable_appearance/MA = new(normal_space) @@ -36,12 +36,12 @@ SUBSYSTEM_DEF(skybox) im.plane = DUST_PLANE im.alpha = 128 //80 im.blend_mode = BLEND_ADD - + MA.cut_overlays() MA.add_overlay(im) dust_cache["[i]"] = MA - + //Moving for (var/i in 0 to 14) // NORTH/SOUTH @@ -57,12 +57,12 @@ SUBSYSTEM_DEF(skybox) im = image('icons/turf/space_dust_transit.dmi', "speedspace_ew_[i]") im.plane = DUST_PLANE im.blend_mode = BLEND_ADD - + MA.cut_overlays() MA.add_overlay(im) - + speedspace_cache["EW_[i]"] = MA - + //Over-the-edge images for (var/dir in alldirs) var/mutable_appearance/MA = new(normal_space) @@ -90,7 +90,7 @@ SUBSYSTEM_DEF(skybox) . = ..() /datum/controller/subsystem/skybox/Initialize() - . = ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/skybox/proc/get_skybox(z) if(!subsystem_initialized) @@ -101,9 +101,9 @@ SUBSYSTEM_DEF(skybox) /datum/controller/subsystem/skybox/proc/generate_skybox(z) var/datum/skybox_settings/settings = global.using_map.get_skybox_datum(z) - + var/new_overlays = list() - + var/image/res = image(settings.icon) res.appearance_flags = KEEP_TOGETHER @@ -136,7 +136,7 @@ SUBSYSTEM_DEF(skybox) for(var/datum/event/E in SSevents.active_events) if(E.has_skybox_image && E.isRunning && (z in E.affecting_z)) new_overlays += E.get_skybox_image() - + for(var/image/I in new_overlays) I.appearance_flags |= RESET_COLOR @@ -161,7 +161,7 @@ SUBSYSTEM_DEF(skybox) var/icon_state = "dyable" var/color var/random_color = FALSE - + var/use_stars = TRUE var/star_icon = 'icons/skybox/skybox.dmi' var/star_state = "stars" diff --git a/code/controllers/subsystems/sounds.dm b/code/controllers/subsystems/sounds.dm index 7d94a3d21d..9067c077da 100644 --- a/code/controllers/subsystems/sounds.dm +++ b/code/controllers/subsystems/sounds.dm @@ -25,7 +25,7 @@ SUBSYSTEM_DEF(sounds) /datum/controller/subsystem/sounds/Initialize() setup_available_channels() - return ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/sounds/proc/setup_available_channels() channel_list = list() diff --git a/code/controllers/subsystems/sqlite.dm b/code/controllers/subsystems/sqlite.dm index b4074b3355..a2e9b2864a 100644 --- a/code/controllers/subsystems/sqlite.dm +++ b/code/controllers/subsystems/sqlite.dm @@ -7,11 +7,11 @@ SUBSYSTEM_DEF(sqlite) flags = SS_NO_FIRE var/database/sqlite_db = null -/datum/controller/subsystem/sqlite/Initialize(timeofday) +/datum/controller/subsystem/sqlite/Initialize() connect() if(sqlite_db) init_schema(sqlite_db) - return ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/sqlite/proc/connect() if(!CONFIG_GET(flag/sqlite_enabled)) diff --git a/code/controllers/subsystems/sun.dm b/code/controllers/subsystems/sun.dm index 551130a20b..bedb33ed13 100644 --- a/code/controllers/subsystems/sun.dm +++ b/code/controllers/subsystems/sun.dm @@ -1,6 +1,7 @@ SUBSYSTEM_DEF(sun) name = "Sun" wait = 600 + flags = SS_NO_INIT var/static/datum/sun/sun = new /datum/controller/subsystem/sun/fire() diff --git a/code/controllers/subsystems/supply.dm b/code/controllers/subsystems/supply.dm index e7ead3b770..9dbefd3684 100644 --- a/code/controllers/subsystems/supply.dm +++ b/code/controllers/subsystems/supply.dm @@ -33,7 +33,7 @@ SUBSYSTEM_DEF(supply) else qdel(P) - . = ..() + return SS_INIT_SUCCESS // Supply shuttle ticker - handles supply point regeneration. Just add points over time. /datum/controller/subsystem/supply/fire() diff --git a/code/controllers/subsystems/ticker.dm b/code/controllers/subsystems/ticker.dm index 1868f1883f..a28fcbe30e 100644 --- a/code/controllers/subsystems/ticker.dm +++ b/code/controllers/subsystems/ticker.dm @@ -61,7 +61,7 @@ var/global/datum/controller/subsystem/ticker/ticker ) ) GLOB.autospeaker = new (null, null, null, 1) //Set up Global Announcer - return ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/ticker/fire(resumed = FALSE) switch(current_state) diff --git a/code/controllers/subsystems/transcore_vr.dm b/code/controllers/subsystems/transcore_vr.dm index 13a4632b8d..6773e0c1de 100644 --- a/code/controllers/subsystems/transcore_vr.dm +++ b/code/controllers/subsystems/transcore_vr.dm @@ -36,7 +36,7 @@ SUBSYSTEM_DEF(transcore) warning("Instantiated transcore DB without a key: [t]") continue databases[db.key] = db - return ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/transcore/fire(resumed = 0) var/timer = TICK_USAGE diff --git a/code/controllers/subsystems/vis_overlays.dm b/code/controllers/subsystems/vis_overlays.dm index 82a652f00c..61cb58170a 100644 --- a/code/controllers/subsystems/vis_overlays.dm +++ b/code/controllers/subsystems/vis_overlays.dm @@ -9,7 +9,7 @@ SUBSYSTEM_DEF(vis_overlays) /datum/controller/subsystem/vis_overlays/Initialize() vis_overlay_cache = list() - return ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/vis_overlays/fire(resumed = FALSE) if(!resumed) @@ -82,7 +82,7 @@ SUBSYSTEM_DEF(vis_overlays) if(istext(icon)) iconstate = icon icon = src.icon - + return SSvis_overlays.add_vis_overlay(src, icon, iconstate, layer, plane, dir, alpha, add_appearance_flags, add_vis_flags, unique) /atom/proc/remove_vis_overlay(list/overlays) diff --git a/code/controllers/subsystems/webhooks.dm b/code/controllers/subsystems/webhooks.dm index d9b75805af..a47e8933d9 100644 --- a/code/controllers/subsystems/webhooks.dm +++ b/code/controllers/subsystems/webhooks.dm @@ -6,7 +6,7 @@ SUBSYSTEM_DEF(webhooks) /datum/controller/subsystem/webhooks/Initialize() load_webhooks() - . = ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/webhooks/proc/load_webhooks() diff --git a/code/controllers/subsystems/xenoarch.dm b/code/controllers/subsystems/xenoarch.dm index 45a437b966..a0e3991530 100644 --- a/code/controllers/subsystems/xenoarch.dm +++ b/code/controllers/subsystems/xenoarch.dm @@ -14,9 +14,9 @@ SUBSYSTEM_DEF(xenoarch) var/list/artifact_spawning_turfs = list() var/list/digsite_spawning_turfs = list() -/datum/controller/subsystem/xenoarch/Initialize(timeofday) +/datum/controller/subsystem/xenoarch/Initialize() SetupXenoarch() - ..() + return SS_INIT_SUCCESS /datum/controller/subsystem/xenoarch/Recover() if (istype(SSxenoarch.artifact_spawning_turfs)) diff --git a/vorestation.dme b/vorestation.dme index e2be933880..b045f13606 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -165,6 +165,7 @@ #include "code\__defines\dcs\flags.dm" #include "code\__defines\dcs\helpers.dm" #include "code\__defines\dcs\signals.dm" +#include "code\__defines\dcs\signals\signals_subsystem.dm" #include "code\__defines\traits\_traits.dm" #include "code\__defines\traits\declarations.dm" #include "code\__defines\traits\sources.dm"