diff --git a/code/__DEFINES/logging.dm b/code/__DEFINES/logging.dm
index 854b10bad48..9dae5569556 100644
--- a/code/__DEFINES/logging.dm
+++ b/code/__DEFINES/logging.dm
@@ -50,3 +50,15 @@
#define LOGSRC_CKEY "Ckey"
#define LOGSRC_MOB "Mob"
+
+//wrapper macros for easier grepping
+#define DIRECT_OUTPUT(A, B) A << B
+#define DIRECT_INPUT(A, B) A >> B
+#define SEND_IMAGE(target, image) DIRECT_OUTPUT(target, image)
+#define SEND_SOUND(target, sound) DIRECT_OUTPUT(target, sound)
+#define SEND_TEXT(target, text) DIRECT_OUTPUT(target, text)
+#define WRITE_FILE(file, text) DIRECT_OUTPUT(file, text)
+#define READ_FILE(file, text) DIRECT_INPUT(file, text)
+//This is an external call, "true" and "false" are how rust parses out booleans
+#define WRITE_LOG(log, text) rustg_log_write(log, text, "true")
+#define WRITE_LOG_NO_FORMAT(log, text) rustg_log_write(log, text, "false")
diff --git a/code/__HELPERS/logging/_logging.dm b/code/__HELPERS/logging/_logging.dm
new file mode 100644
index 00000000000..9f0070c7247
--- /dev/null
+++ b/code/__HELPERS/logging/_logging.dm
@@ -0,0 +1,244 @@
+//print a warning message to world.log
+#define WARNING(MSG) warning("[MSG] in [__FILE__] at line [__LINE__] src: [UNLINT(src)] usr: [usr].")
+/proc/warning(msg)
+ msg = "## WARNING: [msg]"
+ log_world(msg)
+
+//not an error or a warning, but worth to mention on the world log, just in case.
+#define NOTICE(MSG) notice(MSG)
+/proc/notice(msg)
+ msg = "## NOTICE: [msg]"
+ log_world(msg)
+
+//print a testing-mode debug message to world.log and world
+#ifdef TESTING
+#define testing(msg) log_world("## TESTING: [msg]"); to_chat(world, "## TESTING: [msg]")
+
+GLOBAL_LIST_INIT(testing_global_profiler, list("_PROFILE_NAME" = "Global"))
+// we don't really check if a word or name is used twice, be aware of that
+#define testing_profile_start(NAME, LIST) LIST[NAME] = world.timeofday
+#define testing_profile_current(NAME, LIST) round((world.timeofday - LIST[NAME])/10,0.1)
+#define testing_profile_output(NAME, LIST) testing("[LIST["_PROFILE_NAME"]] profile of [NAME] is [testing_profile_current(NAME,LIST)]s")
+#define testing_profile_output_all(LIST) { for(var/_NAME in LIST) { testing_profile_current(,_NAME,LIST); }; };
+#else
+#define testing(msg)
+#define testing_profile_start(NAME, LIST)
+#define testing_profile_current(NAME, LIST)
+#define testing_profile_output(NAME, LIST)
+#define testing_profile_output_all(LIST)
+#endif
+
+#define testing_profile_global_start(NAME) testing_profile_start(NAME,GLOB.testing_global_profiler)
+#define testing_profile_global_current(NAME) testing_profile_current(NAME, GLOB.testing_global_profiler)
+#define testing_profile_global_output(NAME) testing_profile_output(NAME, GLOB.testing_global_profiler)
+#define testing_profile_global_output_all testing_profile_output_all(GLOB.testing_global_profiler)
+
+#define testing_profile_local_init(PROFILE_NAME) var/list/_timer_system = list( "_PROFILE_NAME" = PROFILE_NAME, "_start_of_proc" = world.timeofday )
+#define testing_profile_local_start(NAME) testing_profile_start(NAME, _timer_system)
+#define testing_profile_local_current(NAME) testing_profile_current(NAME, _timer_system)
+#define testing_profile_local_output(NAME) testing_profile_output(NAME, _timer_system)
+#define testing_profile_local_output_all testing_profile_output_all(_timer_system)
+
+#if defined(UNIT_TESTS) || defined(SPACEMAN_DMM)
+/proc/log_test(text)
+ WRITE_LOG(GLOB.test_log, text)
+ SEND_TEXT(world.log, text)
+#endif
+
+#if defined(REFERENCE_DOING_IT_LIVE)
+#define log_reftracker(msg) log_harddel("## REF SEARCH [msg]")
+
+/proc/log_harddel(text)
+ WRITE_LOG(GLOB.harddel_log, text)
+
+#elif defined(REFERENCE_TRACKING) // Doing it locally
+#define log_reftracker(msg) log_world("## REF SEARCH [msg]")
+
+#else //Not tracking at all
+#define log_reftracker(msg)
+#endif
+
+/**
+ * Generic logging helper
+ *
+ * reads the type of the log
+ * and writes it to the respective log file
+ * unless log_globally is FALSE
+ * Arguments:
+ * * message - The message being logged
+ * * message_type - the type of log the message is(ATTACK, SAY, etc)
+ * * color - color of the log text
+ * * log_globally - boolean checking whether or not we write this log to the log file
+ */
+/atom/proc/log_message(message, message_type, color = null, log_globally = TRUE)
+ if(!log_globally)
+ return
+ //SKYRAT EDIT ADDITION BEGIN
+ #ifndef SPACEMAN_DMM
+ if(CONFIG_GET(flag/sql_game_log) && CONFIG_GET(flag/sql_enabled))
+ var/datum/db_query/query_sql_log_messages = SSdbcore.NewQuery({"
+ INSERT INTO [format_table_name("game_log")] (datetime, round_id, ckey, loc, type, message)
+ VALUES (:time, :round_id, :ckey, :loc, :type, :message)
+ "}, list("time" = SQLtime(), "round_id" = "[GLOB.round_id]", "ckey" = key_name(src), "loc" = loc_name(src), type = message_type, "message" = message))
+ if(!query_sql_log_messages.warn_execute())
+ qdel(query_sql_log_messages)
+ return
+ qdel(query_sql_log_messages)
+ if(!CONFIG_GET(flag/file_game_log))
+ return
+ #endif
+ //SKYRAT EDIT ADDITION END
+ var/log_text = "[key_name(src)] [message] [loc_name(src)]"
+ switch(message_type)
+ if(LOG_ATTACK)
+ log_attack(log_text)
+ if(LOG_SAY)
+ log_say(log_text)
+ if(LOG_WHISPER)
+ log_whisper(log_text)
+ if(LOG_EMOTE)
+ log_emote(log_text)
+ //SKYRAT EDIT ADDITION BEGIN
+ if(LOG_SUBTLER)
+ log_subtler(log_text)
+ //SKYRAT EDIT ADDITION END
+ if(LOG_RADIO_EMOTE)
+ log_radio_emote(log_text)
+ if(LOG_DSAY)
+ log_dsay(log_text)
+ if(LOG_PDA)
+ log_pda(log_text)
+ if(LOG_CHAT)
+ log_chat(log_text)
+ if(LOG_COMMENT)
+ log_comment(log_text)
+ if(LOG_TELECOMMS)
+ log_telecomms(log_text)
+ if(LOG_ECON)
+ log_econ(log_text)
+ if(LOG_OOC)
+ log_ooc(log_text)
+ if(LOG_ADMIN)
+ log_admin(log_text)
+ if(LOG_ADMIN_PRIVATE)
+ log_admin_private(log_text)
+ if(LOG_ASAY)
+ log_adminsay(log_text)
+ if(LOG_OWNERSHIP)
+ log_game(log_text)
+ if(LOG_GAME)
+ log_game(log_text)
+ if(LOG_MECHA)
+ log_mecha(log_text)
+ if(LOG_SHUTTLE)
+ log_shuttle(log_text)
+ else
+ stack_trace("Invalid individual logging type: [message_type]. Defaulting to [LOG_GAME] (LOG_GAME).")
+ log_game(log_text)
+
+/* For logging round startup. */
+/proc/start_log(log)
+ WRITE_LOG(log, "Starting up round ID [GLOB.round_id].\n-------------------------")
+
+/* Close open log handles. This should be called as late as possible, and no logging should hapen after. */
+/proc/shutdown_logging()
+ rustg_log_close_all()
+
+/* Helper procs for building detailed log lines */
+/proc/key_name(whom, include_link = null, include_name = TRUE)
+ var/mob/M
+ var/client/C
+ var/key
+ var/ckey
+ var/fallback_name
+
+ if(!whom)
+ return "*null*"
+ if(istype(whom, /client))
+ C = whom
+ M = C.mob
+ key = C.key
+ ckey = C.ckey
+ else if(ismob(whom))
+ M = whom
+ C = M.client
+ key = M.key
+ ckey = M.ckey
+ else if(istext(whom))
+ key = whom
+ ckey = ckey(whom)
+ C = GLOB.directory[ckey]
+ if(C)
+ M = C.mob
+ else if(istype(whom,/datum/mind))
+ var/datum/mind/mind = whom
+ key = mind.key
+ ckey = ckey(key)
+ if(mind.current)
+ M = mind.current
+ if(M.client)
+ C = M.client
+ else
+ fallback_name = mind.name
+ else // Catch-all cases if none of the types above match
+ var/swhom = null
+
+ if(istype(whom, /atom))
+ var/atom/A = whom
+ swhom = "[A.name]"
+ else if(istype(whom, /datum))
+ swhom = "[whom]"
+
+ if(!swhom)
+ swhom = "*invalid*"
+
+ return "\[[swhom]\]"
+
+ . = ""
+
+ if(!ckey)
+ include_link = FALSE
+
+ if(key)
+ if(C?.holder && C.holder.fakekey && !include_name)
+ if(include_link)
+ . += ""
+ . += "Administrator"
+ else
+ if(include_link)
+ . += ""
+ . += key
+ if(!C)
+ . += "\[DC\]"
+
+ if(include_link)
+ . += ""
+ else
+ . += "*no key*"
+
+ if(include_name)
+ if(M)
+ if(M.real_name)
+ . += "/([M.real_name])"
+ else if(M.name)
+ . += "/([M.name])"
+ else if(fallback_name)
+ . += "/([fallback_name])"
+
+ return .
+
+/proc/key_name_admin(whom, include_name = TRUE)
+ return key_name(whom, TRUE, include_name)
+
+/proc/loc_name(atom/A)
+ if(!istype(A))
+ return "(INVALID LOCATION)"
+
+ var/turf/T = A
+ if (!istype(T))
+ T = get_turf(A)
+
+ if(istype(T))
+ return "([AREACOORD(T)])"
+ else if(A.loc)
+ return "(UNKNOWN (?, ?, ?))"
diff --git a/code/__HELPERS/logging/admin.dm b/code/__HELPERS/logging/admin.dm
new file mode 100644
index 00000000000..5e35d35d09f
--- /dev/null
+++ b/code/__HELPERS/logging/admin.dm
@@ -0,0 +1,43 @@
+/* Items with ADMINPRIVATE prefixed are stripped from public logs. */
+
+/// General logging for admin actions
+/proc/log_admin(text)
+ GLOB.admin_log.Add(text)
+ if (CONFIG_GET(flag/log_admin))
+ WRITE_LOG(GLOB.world_game_log, "ADMIN: [text]")
+
+/// Logging for admin actions on or with circuits
+/proc/log_admin_circuit(text)
+ GLOB.admin_log.Add(text)
+ if(CONFIG_GET(flag/log_admin))
+ WRITE_LOG(GLOB.world_game_log, "ADMIN: CIRCUIT: [text]")
+
+/// General logging for admin actions
+/proc/log_admin_private(text)
+ GLOB.admin_log.Add(text)
+ if (CONFIG_GET(flag/log_admin))
+ WRITE_LOG(GLOB.world_game_log, "ADMINPRIVATE: [text]")
+
+/// Logging for AdminSay (ASAY) messages
+/proc/log_adminsay(text)
+ GLOB.admin_log.Add(text)
+ if (CONFIG_GET(flag/log_adminchat))
+ WRITE_LOG(GLOB.world_game_log, "ADMINPRIVATE: ASAY: [text]")
+
+/// Logging for DeachatSay (DSAY) messages
+/proc/log_dsay(text)
+ if (CONFIG_GET(flag/log_adminchat))
+ WRITE_LOG(GLOB.world_game_log, "ADMIN: DSAY: [text]")
+
+/**
+ * Writes to a special log file if the log_suspicious_login config flag is set,
+ * which is intended to contain all logins that failed under suspicious circumstances.
+ *
+ * Mirrors this log entry to log_access when access_log_mirror is TRUE, so this proc
+ * doesn't need to be used alongside log_access and can replace it where appropriate.
+ */
+/proc/log_suspicious_login(text, access_log_mirror = TRUE)
+ if (CONFIG_GET(flag/log_suspicious_login))
+ WRITE_LOG(GLOB.world_suspicious_login_log, "SUSPICIOUS_ACCESS: [text]")
+ if(access_log_mirror)
+ log_access(text)
diff --git a/code/__HELPERS/logging/antagonists.dm b/code/__HELPERS/logging/antagonists.dm
new file mode 100644
index 00000000000..c66fc8437e1
--- /dev/null
+++ b/code/__HELPERS/logging/antagonists.dm
@@ -0,0 +1,24 @@
+/// Logging for traitor objectives
+/proc/log_traitor(text)
+ if (CONFIG_GET(flag/log_traitor))
+ WRITE_LOG(GLOB.world_game_log, "TRAITOR: [text]")
+
+/// Logging for items purchased from a traitor uplink
+/proc/log_uplink(text)
+ if (CONFIG_GET(flag/log_uplink))
+ WRITE_LOG(GLOB.world_uplink_log, "UPLINK: [text]")
+
+/// Logging for changeling powers purchased
+/proc/log_changeling_power(text)
+ if (CONFIG_GET(flag/log_uplink))
+ WRITE_LOG(GLOB.world_uplink_log, "CHANGELING: [text]")
+
+/// Logging for heretic powers learned
+/proc/log_heretic_knowledge(text)
+ if (CONFIG_GET(flag/log_uplink))
+ WRITE_LOG(GLOB.world_uplink_log, "HERETIC RESEARCH: [text]")
+
+/// Logging for wizard powers learned
+/proc/log_spellbook(text)
+ if (CONFIG_GET(flag/log_uplink))
+ WRITE_LOG(GLOB.world_uplink_log, "SPELLBOOK: [text]")
diff --git a/code/__HELPERS/logging/atmos.dm b/code/__HELPERS/logging/atmos.dm
new file mode 100644
index 00000000000..a5a13e61a71
--- /dev/null
+++ b/code/__HELPERS/logging/atmos.dm
@@ -0,0 +1,8 @@
+/// Logs the contents of the gasmix to the game log, prefixed by text
+/proc/log_atmos(text, datum/gas_mixture/mix)
+ var/message = text
+ message += "TEMP=[mix.temperature],MOL=[mix.total_moles()],VOL=[mix.volume]"
+ for(var/key in mix.gases)
+ var/list/gaslist = mix.gases[key]
+ message += "[gaslist[GAS_META][META_GAS_ID]]=[gaslist[MOLES]];"
+ log_game(message)
diff --git a/code/__HELPERS/logging/attack.dm b/code/__HELPERS/logging/attack.dm
new file mode 100644
index 00000000000..6b03bc1fdf4
--- /dev/null
+++ b/code/__HELPERS/logging/attack.dm
@@ -0,0 +1,85 @@
+/// Generic attack logging
+/proc/log_attack(text)
+ if (CONFIG_GET(flag/log_attack))
+ WRITE_LOG(GLOB.world_attack_log, "ATTACK: [text]")
+
+/**
+ * Log a combat message in the attack log
+ *
+ * Arguments:
+ * * atom/user - argument is the actor performing the action
+ * * atom/target - argument is the target of the action
+ * * what_done - is a verb describing the action (e.g. punched, throwed, kicked, etc.)
+ * * atom/object - is a tool with which the action was made (usually an item)
+ * * addition - is any additional text, which will be appended to the rest of the log line
+ */
+/proc/log_combat(atom/user, atom/target, what_done, atom/object=null, addition=null)
+ var/ssource = key_name(user)
+ var/starget = key_name(target)
+
+ var/mob/living/living_target = target
+ var/hp = istype(living_target) ? " (NEWHP: [living_target.health]) " : ""
+
+ var/sobject = ""
+ if(object)
+ sobject = " with [object]"
+ var/saddition = ""
+ if(addition)
+ saddition = " [addition]"
+
+ var/postfix = "[sobject][saddition][hp]"
+
+ var/message = "has [what_done] [starget][postfix]"
+ user.log_message(message, LOG_ATTACK, color="red")
+
+ if(user != target)
+ var/reverse_message = "has been [what_done] by [ssource][postfix]"
+ target.log_message(reverse_message, LOG_VICTIM, color="orange", log_globally=FALSE)
+
+/**
+ * log_wound() is for when someone is *attacked* and suffers a wound. Note that this only captures wounds from damage, so smites/forced wounds aren't logged, as well as demotions like cuts scabbing over
+ *
+ * Note that this has no info on the attack that dealt the wound: information about where damage came from isn't passed to the bodypart's damaged proc. When in doubt, check the attack log for attacks at that same time
+ * TODO later: Add logging for healed wounds, though that will require some rewriting of healing code to prevent admin heals from spamming the logs. Not high priority
+ *
+ * Arguments:
+ * * victim- The guy who got wounded
+ * * suffered_wound- The wound, already applied, that we're logging. It has to already be attached so we can get the limb from it
+ * * dealt_damage- How much damage is associated with the attack that dealt with this wound.
+ * * dealt_wound_bonus- The wound_bonus, if one was specified, of the wounding attack
+ * * dealt_bare_wound_bonus- The bare_wound_bonus, if one was specified *and applied*, of the wounding attack. Not shown if armor was present
+ * * base_roll- Base wounding ability of an attack is a random number from 1 to (dealt_damage ** WOUND_DAMAGE_EXPONENT). This is the number that was rolled in there, before mods
+ */
+/proc/log_wound(atom/victim, datum/wound/suffered_wound, dealt_damage, dealt_wound_bonus, dealt_bare_wound_bonus, base_roll)
+ if(QDELETED(victim) || !suffered_wound)
+ return
+ var/message = "has suffered: [suffered_wound][suffered_wound.limb ? " to [suffered_wound.limb.name]" : null]"// maybe indicate if it's a promote/demote?
+
+ if(dealt_damage)
+ message += " | Damage: [dealt_damage]"
+ // The base roll is useful since it can show how lucky someone got with the given attack. For example, dealing a cut
+ if(base_roll)
+ message += " (rolled [base_roll]/[dealt_damage ** WOUND_DAMAGE_EXPONENT])"
+
+ if(dealt_wound_bonus)
+ message += " | WB: [dealt_wound_bonus]"
+
+ if(dealt_bare_wound_bonus)
+ message += " | BWB: [dealt_bare_wound_bonus]"
+
+ victim.log_message(message, LOG_ATTACK, color="blue")
+
+/// Logging for bombs detonating
+/proc/log_bomber(atom/user, details, atom/bomb, additional_details, message_admins = TRUE)
+ var/bomb_message = "[details][bomb ? " [bomb.name] at [AREACOORD(bomb)]": ""][additional_details ? " [additional_details]" : ""]."
+
+ if(user)
+ user.log_message(bomb_message, LOG_ATTACK) //let it go to individual logs as well as the game log
+ bomb_message = "[key_name(user)] at [AREACOORD(user)] [bomb_message]"
+ else
+ log_game(bomb_message)
+
+ GLOB.bombers += bomb_message
+
+ if(message_admins)
+ message_admins("[user ? "[ADMIN_LOOKUPFLW(user)] at [ADMIN_VERBOSEJMP(user)] " : ""][details][bomb ? " [bomb.name] at [ADMIN_VERBOSEJMP(bomb)]": ""][additional_details ? " [additional_details]" : ""].")
diff --git a/code/__HELPERS/logging/debug.dm b/code/__HELPERS/logging/debug.dm
new file mode 100644
index 00000000000..513f9e0471a
--- /dev/null
+++ b/code/__HELPERS/logging/debug.dm
@@ -0,0 +1,57 @@
+/// Logging for loading and caching assets
+/proc/log_asset(text)
+ if(CONFIG_GET(flag/log_asset))
+ WRITE_LOG(GLOB.world_asset_log, "ASSET: [text]")
+
+/// Logging for config errors
+/// Rarely gets called; just here in case the config breaks.
+/proc/log_config(text)
+ WRITE_LOG(GLOB.config_error_log, text)
+ SEND_TEXT(world.log, text)
+
+/proc/log_filter_raw(text)
+ WRITE_LOG(GLOB.filter_log, "FILTER: [text]")
+
+/// Logging for job slot changes
+/proc/log_job_debug(text)
+ if (CONFIG_GET(flag/log_job_debug))
+ WRITE_LOG(GLOB.world_job_debug_log, "JOB: [text]")
+
+/// Logging for mapping errors
+/proc/log_mapping(text, skip_world_log)
+ WRITE_LOG(GLOB.world_map_error_log, text)
+ if(skip_world_log)
+ return
+ SEND_TEXT(world.log, text)
+
+/// Logging for game performance
+/proc/log_perf(list/perf_info)
+ . = "[perf_info.Join(",")]\n"
+ WRITE_LOG_NO_FORMAT(GLOB.perf_log, .)
+
+/// Logging for hard deletes
+/proc/log_qdel(text)
+ WRITE_LOG(GLOB.world_qdel_log, "QDEL: [text]")
+
+/// Logging for SQL errors
+/proc/log_query_debug(text)
+ WRITE_LOG(GLOB.query_debug_log, "SQL: [text]")
+
+/// Logging for DB errors
+/proc/log_sql(text)
+ WRITE_LOG(GLOB.sql_error_log, "SQL: [text]")
+
+/// Logging for world/Topic
+/proc/log_topic(text)
+ WRITE_LOG(GLOB.world_game_log, "TOPIC: [text]")
+
+/* Log to the logfile only. */
+/proc/log_runtime(text)
+ WRITE_LOG(GLOB.world_runtime_log, text)
+
+/// Log to both DD and the logfile.
+/proc/log_world(text)
+#ifdef USE_CUSTOM_ERROR_HANDLER
+ WRITE_LOG(GLOB.world_runtime_log, text)
+#endif
+ SEND_TEXT(world.log, text)
diff --git a/code/__HELPERS/logging/economy.dm b/code/__HELPERS/logging/economy.dm
new file mode 100644
index 00000000000..8f190cb934c
--- /dev/null
+++ b/code/__HELPERS/logging/economy.dm
@@ -0,0 +1,3 @@
+/proc/log_econ(text)
+ if (CONFIG_GET(flag/log_econ))
+ WRITE_LOG(GLOB.world_econ_log, "MONEY: [text]")
diff --git a/code/__HELPERS/logging/game.dm b/code/__HELPERS/logging/game.dm
new file mode 100644
index 00000000000..ed3318fe8b4
--- /dev/null
+++ b/code/__HELPERS/logging/game.dm
@@ -0,0 +1,34 @@
+/// Logging for generic/unsorted game messages
+/proc/log_game(text)
+ if (CONFIG_GET(flag/log_game))
+ WRITE_LOG(GLOB.world_game_log, "GAME: [text]")
+
+/// Logging for emotes
+/proc/log_emote(text)
+ if (CONFIG_GET(flag/log_emote))
+ WRITE_LOG(GLOB.world_game_log, "EMOTE: [text]")
+
+/// Logging for emotes sent over the radio
+/proc/log_radio_emote(text)
+ if (CONFIG_GET(flag/log_emote))
+ WRITE_LOG(GLOB.world_game_log, "RADIOEMOTE: [text]")
+
+/// Logging for messages sent in OOC
+/proc/log_ooc(text)
+ if (CONFIG_GET(flag/log_ooc))
+ WRITE_LOG(GLOB.world_game_log, "OOC: [text]")
+
+/// Logging for prayed messages
+/proc/log_prayer(text)
+ if (CONFIG_GET(flag/log_prayer))
+ WRITE_LOG(GLOB.world_game_log, "PRAY: [text]")
+
+/// Logging for changes to ID card access
+/proc/log_access(text)
+ if (CONFIG_GET(flag/log_access))
+ WRITE_LOG(GLOB.world_game_log, "ACCESS: [text]")
+
+/// Logging for OOC votes
+/proc/log_vote(text)
+ if (CONFIG_GET(flag/log_vote))
+ WRITE_LOG(GLOB.world_game_log, "VOTE: [text]")
diff --git a/code/__HELPERS/logging/manifest.dm b/code/__HELPERS/logging/manifest.dm
new file mode 100644
index 00000000000..7275b1cc73d
--- /dev/null
+++ b/code/__HELPERS/logging/manifest.dm
@@ -0,0 +1,4 @@
+/// Logging for player manifest (ckey, name, job, special role, roundstart/latejoin)
+/proc/log_manifest(ckey, datum/mind/mind, mob/body, latejoin = FALSE)
+ if (CONFIG_GET(flag/log_manifest))
+ WRITE_LOG(GLOB.world_manifest_log, "[ckey] \\ [body.real_name] \\ [mind.assigned_role.title] \\ [mind.special_role ? mind.special_role : "NONE"] \\ [latejoin ? "LATEJOIN":"ROUNDSTART"]")
diff --git a/code/__HELPERS/logging/mecha.dm b/code/__HELPERS/logging/mecha.dm
new file mode 100644
index 00000000000..45c6a445dd2
--- /dev/null
+++ b/code/__HELPERS/logging/mecha.dm
@@ -0,0 +1,10 @@
+/// Logging for mech actions
+/proc/log_mecha(text)
+ if (CONFIG_GET(flag/log_mecha))
+ WRITE_LOG(GLOB.world_mecha_log, "MECHA: [text]")
+
+/// Logging for equipment installed in a mecha
+/obj/item/mecha_parts/mecha_equipment/log_message(message, message_type = LOG_MECHA, color = null, log_globally)
+ if(chassis)
+ return chassis.log_message("ATTACHMENT: [src] [message]", message_type, color)
+ return ..()
diff --git a/code/__HELPERS/logging/mob.dm b/code/__HELPERS/logging/mob.dm
new file mode 100644
index 00000000000..7d752c1eb6b
--- /dev/null
+++ b/code/__HELPERS/logging/mob.dm
@@ -0,0 +1,56 @@
+/proc/log_mob_tag(text)
+ WRITE_LOG(GLOB.world_mob_tag_log, "TAG: [text]")
+
+/proc/log_silicon(text)
+ if (CONFIG_GET(flag/log_silicon))
+ WRITE_LOG(GLOB.world_silicon_log, "SILICON: [text]")
+
+
+/// Logs a message in a mob's individual log, and in the global logs as well if log_globally is true
+/mob/log_message(message, message_type, color = null, log_globally = TRUE)
+ if(!LAZYLEN(message))
+ stack_trace("Empty message")
+ return
+
+ // Cannot use the list as a map if the key is a number, so we stringify it (thank you BYOND)
+ var/smessage_type = num2text(message_type, MAX_BITFLAG_DIGITS)
+
+ if(client)
+ if(!islist(client.player_details.logging[smessage_type]))
+ client.player_details.logging[smessage_type] = list()
+
+ if(!islist(logging[smessage_type]))
+ logging[smessage_type] = list()
+
+ var/colored_message = message
+ if(color)
+ if(color[1] == "#")
+ colored_message = "[message]"
+ else
+ colored_message = "[message]"
+
+ //This makes readability a bit better for admins.
+ switch(message_type)
+ if(LOG_WHISPER)
+ colored_message = "(WHISPER) [colored_message]"
+ if(LOG_OOC)
+ colored_message = "(OOC) [colored_message]"
+ if(LOG_ASAY)
+ colored_message = "(ASAY) [colored_message]"
+ if(LOG_EMOTE)
+ colored_message = "(EMOTE) [colored_message]"
+ //SKYRAT EDIT ADDITION BEGIN
+ if(LOG_SUBTLER)
+ colored_message = "(EMOTE) (SUBTLER) [colored_message]"
+ //SKYRAT EDIT ADDITION END
+ if(LOG_RADIO_EMOTE)
+ colored_message = "(RADIOEMOTE) [colored_message]"
+
+ var/list/timestamped_message = list("\[[time_stamp(format = "YYYY-MM-DD hh:mm:ss")]\] [key_name(src)] [loc_name(src)] (Event #[LAZYLEN(logging[smessage_type])])" = colored_message)
+
+ logging[smessage_type] += timestamped_message
+
+ if(client)
+ client.player_details.logging[smessage_type] += timestamped_message
+
+ ..()
diff --git a/code/__HELPERS/logging/paper.dm b/code/__HELPERS/logging/paper.dm
new file mode 100644
index 00000000000..b748faf217e
--- /dev/null
+++ b/code/__HELPERS/logging/paper.dm
@@ -0,0 +1,3 @@
+/// Logging for writing made on paper
+/proc/log_paper(text)
+ WRITE_LOG(GLOB.world_paper_log, "PAPER: [text]")
diff --git a/code/__HELPERS/logging/pda.dm b/code/__HELPERS/logging/pda.dm
new file mode 100644
index 00000000000..01c8d98d95a
--- /dev/null
+++ b/code/__HELPERS/logging/pda.dm
@@ -0,0 +1,16 @@
+/// Logging for PDA messages sent
+/proc/log_pda(text)
+ if (CONFIG_GET(flag/log_pda))
+ WRITE_LOG(GLOB.world_pda_log, "PDA: [text]")
+
+/// Logging for newscaster comments
+/proc/log_comment(text)
+ //reusing the PDA option because I really don't think news comments are worth a config option
+ if (CONFIG_GET(flag/log_pda))
+ WRITE_LOG(GLOB.world_pda_log, "COMMENT: [text]")
+
+/// Logging for chatting on modular computer channels
+/proc/log_chat(text)
+ //same thing here
+ if (CONFIG_GET(flag/log_pda))
+ WRITE_LOG(GLOB.world_pda_log, "CHAT: [text]")
diff --git a/code/__HELPERS/logging/shuttle.dm b/code/__HELPERS/logging/shuttle.dm
new file mode 100644
index 00000000000..62a5fcd3e6e
--- /dev/null
+++ b/code/__HELPERS/logging/shuttle.dm
@@ -0,0 +1,4 @@
+/// Logging for shuttle actions
+/proc/log_shuttle(text)
+ if (CONFIG_GET(flag/log_shuttle))
+ WRITE_LOG(GLOB.world_shuttle_log, "SHUTTLE: [text]")
diff --git a/code/__HELPERS/logging/talk.dm b/code/__HELPERS/logging/talk.dm
new file mode 100644
index 00000000000..86382f6a339
--- /dev/null
+++ b/code/__HELPERS/logging/talk.dm
@@ -0,0 +1,42 @@
+/**
+ * Helper for logging chat messages or other logs with arbitrary inputs (e.g. announcements)
+ *
+ * This proc compiles a log string by prefixing the tag to the message
+ * and suffixing what it was forced_by if anything
+ * if the message lacks a tag and suffix then it is logged on its own
+ * Arguments:
+ * * message - The message being logged
+ * * message_type - the type of log the message is(ATTACK, SAY, etc)
+ * * tag - tag that indicates the type of text(announcement, telepathy, etc)
+ * * log_globally - boolean checking whether or not we write this log to the log file
+ * * forced_by - source that forced the dialogue if any
+ */
+/atom/proc/log_talk(message, message_type, tag = null, log_globally = TRUE, forced_by = null, custom_say_emote = null)
+ var/prefix = tag ? "([tag]) " : ""
+ var/suffix = forced_by ? " FORCED by [forced_by]" : ""
+ log_message("[prefix][custom_say_emote ? "*[custom_say_emote]*, " : ""]\"[message]\"[suffix]", message_type, log_globally = log_globally)
+
+/// Logging for generic spoken messages
+/proc/log_say(text)
+ if (CONFIG_GET(flag/log_say))
+ WRITE_LOG(GLOB.world_game_log, "SAY: [text]")
+
+/// Logging for whispered messages
+/proc/log_whisper(text)
+ if (CONFIG_GET(flag/log_whisper))
+ WRITE_LOG(GLOB.world_game_log, "WHISPER: [text]")
+
+/// Helper for logging of messages with only one sender and receiver (i.e. mind links)
+/proc/log_directed_talk(atom/source, atom/target, message, message_type, tag)
+ if(!tag)
+ stack_trace("Unspecified tag for private message")
+ tag = "UNKNOWN"
+
+ source.log_talk(message, message_type, tag = "[tag] to [key_name(target)]")
+ if(source != target)
+ target.log_talk(message, LOG_VICTIM, tag = "[tag] from [key_name(source)]", log_globally = FALSE)
+
+/// Logging for speech taking place over comms, as well as tcomms equipment
+/proc/log_telecomms(text)
+ if (CONFIG_GET(flag/log_telecomms))
+ WRITE_LOG(GLOB.world_telecomms_log, "TCOMMS: [text]")
diff --git a/code/__HELPERS/logging/tool.dm b/code/__HELPERS/logging/tool.dm
new file mode 100644
index 00000000000..4fd354eb58d
--- /dev/null
+++ b/code/__HELPERS/logging/tool.dm
@@ -0,0 +1,4 @@
+/// Logging for tool usage
+/proc/log_tool(text, mob/initiator)
+ if(CONFIG_GET(flag/log_tools))
+ WRITE_LOG(GLOB.world_tool_log, "TOOL: [text]")
diff --git a/code/__HELPERS/logging/tools.dm b/code/__HELPERS/logging/tools.dm
new file mode 100644
index 00000000000..4c5f2d3e655
--- /dev/null
+++ b/code/__HELPERS/logging/tools.dm
@@ -0,0 +1,3 @@
+/proc/log_tool(text, mob/initiator)
+ if(CONFIG_GET(flag/log_tools))
+ WRITE_LOG(GLOB.world_tool_log, "TOOL: [text]")
diff --git a/code/__HELPERS/logging/ui.dm b/code/__HELPERS/logging/ui.dm
new file mode 100644
index 00000000000..3a0432d35f7
--- /dev/null
+++ b/code/__HELPERS/logging/ui.dm
@@ -0,0 +1,34 @@
+/proc/log_href(text)
+ WRITE_LOG(GLOB.world_href_log, "HREF: [text]")
+
+/**
+ * Appends a tgui-related log entry. All arguments are optional.
+ */
+/proc/log_tgui(user, message, context,
+ datum/tgui_window/window,
+ datum/src_object)
+ var/entry = ""
+ // Insert user info
+ if(!user)
+ entry += ""
+ else if(istype(user, /mob))
+ var/mob/mob = user
+ entry += "[mob.ckey] (as [mob] at [mob.x],[mob.y],[mob.z])"
+ else if(istype(user, /client))
+ var/client/client = user
+ entry += "[client.ckey]"
+ // Insert context
+ if(context)
+ entry += " in [context]"
+ else if(window)
+ entry += " in [window.id]"
+ // Resolve src_object
+ if(!src_object && window?.locked_by)
+ src_object = window.locked_by.src_object
+ // Insert src_object info
+ if(src_object)
+ entry += "\nUsing: [src_object.type] [REF(src_object)]"
+ // Insert message
+ if(message)
+ entry += "\n[message]"
+ WRITE_LOG(GLOB.tgui_log, entry)
diff --git a/code/__HELPERS/logging/virus.dm b/code/__HELPERS/logging/virus.dm
new file mode 100644
index 00000000000..6ec03af8e17
--- /dev/null
+++ b/code/__HELPERS/logging/virus.dm
@@ -0,0 +1,15 @@
+/// Logging for the creation and contraction of viruses
+/proc/log_virus(text)
+ if (CONFIG_GET(flag/log_virus))
+ WRITE_LOG(GLOB.world_virus_log, "VIRUS: [text]")
+
+/// Returns a string for admin logging uses, should describe the disease in detail
+/datum/disease/proc/admin_details()
+ return "[src.name] : [src.type]"
+
+/// Describes this disease to an admin in detail (for logging)
+/datum/disease/advance/admin_details()
+ var/list/name_symptoms = list()
+ for(var/datum/symptom/S in symptoms)
+ name_symptoms += S.name
+ return "[name] sym:[english_list(name_symptoms)] r:[totalResistance()] s:[totalStealth()] ss:[totalStageSpeed()] t:[totalTransmittable()]"
diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm
index f767ef7d747..f85b0a4ca89 100644
--- a/code/datums/diseases/_disease.dm
+++ b/code/datums/diseases/_disease.dm
@@ -61,10 +61,6 @@
var/turf/source_turf = get_turf(infectee)
log_virus("[key_name(infectee)] was infected by virus: [src.admin_details()] at [loc_name(source_turf)]")
-//Return a string for admin logging uses, should describe the disease in detail
-/datum/disease/proc/admin_details()
- return "[src.name] : [src.type]"
-
///Proc to process the disease and decide on whether to advance, cure or make the sympthoms appear. Returns a boolean on whether to continue acting on the symptoms or not.
/datum/disease/proc/stage_act(delta_time, times_fired)
diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm
index 4638cc01fbd..265ed0e5620 100644
--- a/code/datums/diseases/advance/advance.dm
+++ b/code/datums/diseases/advance/advance.dm
@@ -155,19 +155,6 @@
//this is a new disease starting over at stage 1, so processing is not copied
return A
-//Describe this disease to an admin in detail (for logging)
-/datum/disease/advance/admin_details()
- var/list/name_symptoms = list()
- for(var/datum/symptom/S in symptoms)
- name_symptoms += S.name
- return "[name] sym:[english_list(name_symptoms)] r:[totalResistance()] s:[totalStealth()] ss:[totalStageSpeed()] t:[totalTransmittable()]"
-
-/*
-
- NEW PROCS
-
- */
-
// Mix the symptoms of two diseases (the src and the argument)
/datum/disease/advance/proc/Mix(datum/disease/advance/D)
if(!(IsSame(D)))
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index b4ddb1d4709..6e235f70096 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -1576,178 +1576,6 @@
/atom/proc/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock)
return
-/**
- * Generic logging helper
- *
- * reads the type of the log
- * and writes it to the respective log file
- * unless log_globally is FALSE
- * Arguments:
- * * message - The message being logged
- * * message_type - the type of log the message is(ATTACK, SAY, etc)
- * * color - color of the log text
- * * log_globally - boolean checking whether or not we write this log to the log file
- */
-/atom/proc/log_message(message, message_type, color=null, log_globally=TRUE)
- if(!log_globally)
- return
- //SKYRAT EDIT ADDITION BEGIN
- #ifndef SPACEMAN_DMM
- if(CONFIG_GET(flag/sql_game_log) && CONFIG_GET(flag/sql_enabled))
- var/datum/db_query/query_sql_log_messages = SSdbcore.NewQuery({"
- INSERT INTO [format_table_name("game_log")] (datetime, round_id, ckey, loc, type, message)
- VALUES (:time, :round_id, :ckey, :loc, :type, :message)
- "}, list("time" = SQLtime(), "round_id" = "[GLOB.round_id]", "ckey" = key_name(src), "loc" = loc_name(src), type = message_type, "message" = message))
- if(!query_sql_log_messages.warn_execute())
- qdel(query_sql_log_messages)
- return
- qdel(query_sql_log_messages)
- if(!CONFIG_GET(flag/file_game_log))
- return
- #endif
- //SKYRAT EDIT ADDITION END
- var/log_text = "[key_name(src)] [message] [loc_name(src)]"
- switch(message_type)
- if(LOG_ATTACK)
- log_attack(log_text)
- if(LOG_SAY)
- log_say(log_text)
- if(LOG_WHISPER)
- log_whisper(log_text)
- if(LOG_EMOTE)
- log_emote(log_text)
- //SKYRAT EDIT ADDITION BEGIN
- if(LOG_SUBTLER)
- log_subtler(log_text)
- //SKYRAT EDIT ADDITION END
- if(LOG_RADIO_EMOTE)
- log_radio_emote(log_text)
- if(LOG_DSAY)
- log_dsay(log_text)
- if(LOG_PDA)
- log_pda(log_text)
- if(LOG_CHAT)
- log_chat(log_text)
- if(LOG_COMMENT)
- log_comment(log_text)
- if(LOG_TELECOMMS)
- log_telecomms(log_text)
- if(LOG_ECON)
- log_econ(log_text)
- if(LOG_OOC)
- log_ooc(log_text)
- if(LOG_ADMIN)
- log_admin(log_text)
- if(LOG_ADMIN_PRIVATE)
- log_admin_private(log_text)
- if(LOG_ASAY)
- log_adminsay(log_text)
- if(LOG_OWNERSHIP)
- log_game(log_text)
- if(LOG_GAME)
- log_game(log_text)
- if(LOG_MECHA)
- log_mecha(log_text)
- if(LOG_SHUTTLE)
- log_shuttle(log_text)
- else
- stack_trace("Invalid individual logging type: [message_type]. Defaulting to [LOG_GAME] (LOG_GAME).")
- log_game(log_text)
-
-/**
- * Helper for logging chat messages or other logs with arbitrary inputs(e.g. announcements)
- *
- * This proc compiles a log string by prefixing the tag to the message
- * and suffixing what it was forced_by if anything
- * if the message lacks a tag and suffix then it is logged on its own
- * Arguments:
- * * message - The message being logged
- * * message_type - the type of log the message is(ATTACK, SAY, etc)
- * * tag - tag that indicates the type of text(announcement, telepathy, etc)
- * * log_globally - boolean checking whether or not we write this log to the log file
- * * forced_by - source that forced the dialogue if any
- */
-/atom/proc/log_talk(message, message_type, tag = null, log_globally = TRUE, forced_by = null, custom_say_emote = null)
- var/prefix = tag ? "([tag]) " : ""
- var/suffix = forced_by ? " FORCED by [forced_by]" : ""
- log_message("[prefix][custom_say_emote ? "*[custom_say_emote]*, " : ""]\"[message]\"[suffix]", message_type, log_globally=log_globally)
-
-/// Helper for logging of messages with only one sender and receiver
-/proc/log_directed_talk(atom/source, atom/target, message, message_type, tag)
- if(!tag)
- stack_trace("Unspecified tag for private message")
- tag = "UNKNOWN"
-
- source.log_talk(message, message_type, tag="[tag] to [key_name(target)]")
- if(source != target)
- target.log_talk(message, LOG_VICTIM, tag="[tag] from [key_name(source)]", log_globally=FALSE)
-
-/**
- * Log a combat message in the attack log
- *
- * Arguments:
- * * atom/user - argument is the actor performing the action
- * * atom/target - argument is the target of the action
- * * what_done - is a verb describing the action (e.g. punched, throwed, kicked, etc.)
- * * atom/object - is a tool with which the action was made (usually an item)
- * * addition - is any additional text, which will be appended to the rest of the log line
- */
-/proc/log_combat(atom/user, atom/target, what_done, atom/object=null, addition=null)
- var/ssource = key_name(user)
- var/starget = key_name(target)
-
- var/mob/living/living_target = target
- var/hp = istype(living_target) ? " (NEWHP: [living_target.health]) " : ""
-
- var/sobject = ""
- if(object)
- sobject = " with [object]"
- var/saddition = ""
- if(addition)
- saddition = " [addition]"
-
- var/postfix = "[sobject][saddition][hp]"
-
- var/message = "has [what_done] [starget][postfix]"
- user.log_message(message, LOG_ATTACK, color="red")
-
- if(user != target)
- var/reverse_message = "has been [what_done] by [ssource][postfix]"
- target.log_message(reverse_message, LOG_VICTIM, color="orange", log_globally=FALSE)
-
-/**
- * log_wound() is for when someone is *attacked* and suffers a wound. Note that this only captures wounds from damage, so smites/forced wounds aren't logged, as well as demotions like cuts scabbing over
- *
- * Note that this has no info on the attack that dealt the wound: information about where damage came from isn't passed to the bodypart's damaged proc. When in doubt, check the attack log for attacks at that same time
- * TODO later: Add logging for healed wounds, though that will require some rewriting of healing code to prevent admin heals from spamming the logs. Not high priority
- *
- * Arguments:
- * * victim- The guy who got wounded
- * * suffered_wound- The wound, already applied, that we're logging. It has to already be attached so we can get the limb from it
- * * dealt_damage- How much damage is associated with the attack that dealt with this wound.
- * * dealt_wound_bonus- The wound_bonus, if one was specified, of the wounding attack
- * * dealt_bare_wound_bonus- The bare_wound_bonus, if one was specified *and applied*, of the wounding attack. Not shown if armor was present
- * * base_roll- Base wounding ability of an attack is a random number from 1 to (dealt_damage ** WOUND_DAMAGE_EXPONENT). This is the number that was rolled in there, before mods
- */
-/proc/log_wound(atom/victim, datum/wound/suffered_wound, dealt_damage, dealt_wound_bonus, dealt_bare_wound_bonus, base_roll)
- if(QDELETED(victim) || !suffered_wound)
- return
- var/message = "has suffered: [suffered_wound][suffered_wound.limb ? " to [suffered_wound.limb.name]" : null]"// maybe indicate if it's a promote/demote?
-
- if(dealt_damage)
- message += " | Damage: [dealt_damage]"
- // The base roll is useful since it can show how lucky someone got with the given attack. For example, dealing a cut
- if(base_roll)
- message += " (rolled [base_roll]/[dealt_damage ** WOUND_DAMAGE_EXPONENT])"
-
- if(dealt_wound_bonus)
- message += " | WB: [dealt_wound_bonus]"
-
- if(dealt_bare_wound_bonus)
- message += " | BWB: [dealt_bare_wound_bonus]"
-
- victim.log_message(message, LOG_ATTACK, color="blue")
-
/atom/proc/add_filter(name,priority,list/params)
LAZYINITLIST(filter_data)
var/list/copied_parameters = params.Copy()
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 6d47732c2ad..c9933421b94 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -1779,7 +1779,7 @@
var/answer = href_list["slowquery"]
if(answer == "yes")
log_query_debug("[usr.key] | Reported a server hang")
- if(tgui_alert(usr, "Had you just press any admin buttons?", "Query server hang report", list("Yes", "No")) == "Yes")
+ if(tgui_alert(usr, "Did you just press any admin buttons?", "Query server hang report", list("Yes", "No")) == "Yes")
var/response = input(usr,"What were you just doing?","Query server hang report") as null|text
if(response)
log_query_debug("[usr.key] | [response]")
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 55d81b09007..ee419d70677 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -341,55 +341,6 @@
var/mob/living/T = pick(nearby_mobs)
ClickOn(T)
-/// Logs a message in a mob's individual log, and in the global logs as well if log_globally is true
-/mob/log_message(message, message_type, color=null, log_globally = TRUE)
- if(!LAZYLEN(message))
- stack_trace("Empty message")
- return
-
- // Cannot use the list as a map if the key is a number, so we stringify it (thank you BYOND)
- var/smessage_type = num2text(message_type, MAX_BITFLAG_DIGITS)
-
- if(client)
- if(!islist(client.player_details.logging[smessage_type]))
- client.player_details.logging[smessage_type] = list()
-
- if(!islist(logging[smessage_type]))
- logging[smessage_type] = list()
-
- var/colored_message = message
- if(color)
- if(color[1] == "#")
- colored_message = "[message]"
- else
- colored_message = "[message]"
-
- //This makes readability a bit better for admins.
- switch(message_type)
- if(LOG_WHISPER)
- colored_message = "(WHISPER) [colored_message]"
- if(LOG_OOC)
- colored_message = "(OOC) [colored_message]"
- if(LOG_ASAY)
- colored_message = "(ASAY) [colored_message]"
- if(LOG_EMOTE)
- colored_message = "(EMOTE) [colored_message]"
- //SKYRAT EDIT ADDITION BEGIN
- if(LOG_SUBTLER)
- colored_message = "(EMOTE) (SUBTLER) [colored_message]"
- //SKYRAT EDIT ADDITION END
- if(LOG_RADIO_EMOTE)
- colored_message = "(RADIOEMOTE) [colored_message]"
-
- var/list/timestamped_message = list("\[[time_stamp(format = "YYYY-MM-DD hh:mm:ss")]\] [key_name(src)] [loc_name(src)] (Event #[LAZYLEN(logging[smessage_type])])" = colored_message)
-
- logging[smessage_type] += timestamped_message
-
- if(client)
- client.player_details.logging[smessage_type] += timestamped_message
-
- ..()
-
///Can the mob hear
/mob/proc/can_hear()
. = TRUE
diff --git a/tgstation.dme b/tgstation.dme
index 730bd8f710f..326d7ec5792 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -328,7 +328,6 @@
#include "code\__DEFINES\~skyrat_defines\_globalvars\lists\mapping.dm"
#include "code\__DEFINES\~skyrat_defines\_HELPERS\lighting.dm"
#include "code\__HELPERS\_lists.dm"
-#include "code\__HELPERS\_logging.dm"
#include "code\__HELPERS\_string_lists.dm"
#include "code\__HELPERS\admin.dm"
#include "code\__HELPERS\ai.dm"
@@ -400,6 +399,24 @@
#include "code\__HELPERS\verbs.dm"
#include "code\__HELPERS\view.dm"
#include "code\__HELPERS\weakref.dm"
+#include "code\__HELPERS\logging\_logging.dm"
+#include "code\__HELPERS\logging\admin.dm"
+#include "code\__HELPERS\logging\antagonists.dm"
+#include "code\__HELPERS\logging\atmos.dm"
+#include "code\__HELPERS\logging\attack.dm"
+#include "code\__HELPERS\logging\debug.dm"
+#include "code\__HELPERS\logging\economy.dm"
+#include "code\__HELPERS\logging\game.dm"
+#include "code\__HELPERS\logging\manifest.dm"
+#include "code\__HELPERS\logging\mecha.dm"
+#include "code\__HELPERS\logging\mob.dm"
+#include "code\__HELPERS\logging\paper.dm"
+#include "code\__HELPERS\logging\pda.dm"
+#include "code\__HELPERS\logging\shuttle.dm"
+#include "code\__HELPERS\logging\talk.dm"
+#include "code\__HELPERS\logging\tool.dm"
+#include "code\__HELPERS\logging\ui.dm"
+#include "code\__HELPERS\logging\virus.dm"
#include "code\__HELPERS\sorts\__main.dm"
#include "code\__HELPERS\sorts\InsertSort.dm"
#include "code\__HELPERS\sorts\MergeSort.dm"