diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 4ed03713e6a..4a51b132b3f 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -474,3 +474,4 @@ var/global/list/ghost_others_options = list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define debug_world_log(msg) if (Debug2) world.log << "DEBUG: [msg]"
#define COORD(A) "([A.x],[A.y],[A.z])"
+#define INCREMENT_TALLY(L, stat) if(L[stat]){L[stat]++}else{L[stat] = 1}
diff --git a/code/controllers/subsystem/pool.dm b/code/controllers/subsystem/pool.dm
new file mode 100644
index 00000000000..245e733e984
--- /dev/null
+++ b/code/controllers/subsystem/pool.dm
@@ -0,0 +1,48 @@
+var/datum/subsystem/pool/SSpool
+
+/datum/subsystem/pool
+ name = "Pool"
+ init_order = 20
+ flags = SS_BACKGROUND | SS_FIRE_IN_LOBBY
+ var/list/global_pool
+ var/list/pool_levels = list()
+ var/sum = 0
+
+ var/list/maintained_types = list(
+ /obj/item/stack/tile/plasteel = 100
+ )
+
+ var/list/stats_placed_in_pool = list()
+ var/list/stats_pooled_or_newed = list()
+ var/list/stats_reused = list()
+ var/list/stats_created_new = list()
+
+/datum/subsystem/pool/New()
+ NEW_SS_GLOBAL(SSpool)
+
+/datum/subsystem/pool/Initialize(timeofday)
+ global_pool = GlobalPool
+
+/datum/subsystem/pool/stat_entry(msg)
+ if(global_pool)
+ msg += "Types: [global_pool.len]|Total Pooled Objects: [sum]"
+ else
+ msg += "NULL POOL"
+ ..(msg)
+
+/datum/subsystem/pool/fire()
+ sum = 0
+ for(var/type in global_pool + maintained_types)
+ var/list/L = global_pool[type]
+ var/required_number = maintained_types[type] || 0
+
+ // Update pool levels and tracker
+ var/amount = 0
+ if(L)
+ amount = L.len
+ sum += amount
+
+ // why yes, just inflate the pool at one item per tick
+ if(amount < required_number)
+ var/diver = new type
+ qdel(diver)
diff --git a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm
index 1e7ed6c4bce..b1420d8cb03 100644
--- a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm
+++ b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm
@@ -250,8 +250,8 @@
PoolOrNew(/obj/effect/overlay/temp/revenant, T)
if(!istype(T, /turf/open/floor/plating) && !istype(T, /turf/open/floor/engine/cult) && istype(T, /turf/open/floor) && prob(15))
var/turf/open/floor/floor = T
- if(floor.intact)
- floor.builtin_tile.loc = floor
+ if(floor.intact && floor.floor_tile)
+ PoolOrNew(floor.floor_tile, floor)
floor.broken = 0
floor.burnt = 0
floor.make_plating(1)
diff --git a/code/game/objects/items/stacks/sheets/light.dm b/code/game/objects/items/stacks/sheets/light.dm
index bddd8c2f251..fc6b74dabb9 100644
--- a/code/game/objects/items/stacks/sheets/light.dm
+++ b/code/game/objects/items/stacks/sheets/light.dm
@@ -29,7 +29,7 @@
var/obj/item/stack/sheet/metal/M = O
if (M.use(1))
use(1)
- var/obj/item/stack/tile/light/L = new (user.loc)
+ var/obj/item/L = PoolOrNew(/obj/item/stack/tile/light, user.loc)
user << "You make a light tile."
L.add_fingerprint(user)
else
diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm
index 10607785a4e..8d8b89760fe 100644
--- a/code/game/objects/items/stacks/tiles/tile_types.dm
+++ b/code/game/objects/items/stacks/tiles/tile_types.dm
@@ -18,6 +18,10 @@
pixel_x = rand(-3, 3)
pixel_y = rand(-3, 3) //randomize a little
+/obj/item/stack/tile/Destroy()
+ ..()
+ return QDEL_HINT_PUTINPOOL
+
/obj/item/stack/tile/attackby(obj/item/W, mob/user, params)
if (istype(W, /obj/item/weapon/weldingtool))
diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm
index ec8b97b9099..4626db9cbbe 100644
--- a/code/game/objects/items/weapons/storage/backpack.dm
+++ b/code/game/objects/items/weapons/storage/backpack.dm
@@ -285,7 +285,7 @@
/obj/item/weapon/storage/backpack/satchel_flat/New()
..()
- new /obj/item/stack/tile/plasteel(src)
+ PoolOrNew(/obj/item/stack/tile/plasteel, src)
new /obj/item/weapon/crowbar(src)
/obj/item/weapon/storage/backpack/dufflebag
diff --git a/code/game/pooling/pool.dm b/code/game/pooling/pool.dm
index ebbcebeb959..e99df9c5b0b 100644
--- a/code/game/pooling/pool.dm
+++ b/code/game/pooling/pool.dm
@@ -40,14 +40,22 @@ var/global/list/GlobalPool = list()
if(!get_type)
return
+ if(SSpool)
+ INCREMENT_TALLY(SSpool.stats_pooled_or_newed, get_type)
+
. = GetFromPool(get_type,second_arg)
if(!.)
+ if(SSpool)
+ INCREMENT_TALLY(SSpool.stats_created_new, get_type)
if(ispath(get_type))
if(islist(second_arg))
. = new get_type (arglist(second_arg))
else
. = new get_type (second_arg)
+ else
+ if(SSpool)
+ INCREMENT_TALLY(SSpool.stats_reused, get_type)
/proc/GetFromPool(get_type,second_arg)
@@ -88,6 +96,9 @@ var/global/list/GlobalPool = list()
if(diver in GlobalPool[diver.type])
return
+ if(SSpool)
+ INCREMENT_TALLY(SSpool.stats_placed_in_pool, diver.type)
+
if(!GlobalPool[diver.type])
GlobalPool[diver.type] = list()
diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm
index 1fb959a7fc6..b41861c5448 100644
--- a/code/game/turfs/simulated/floor.dm
+++ b/code/game/turfs/simulated/floor.dm
@@ -19,7 +19,6 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
//NOTE: Floor code has been refactored, many procs were removed and refactored
//- you should use istype() if you want to find out whether a floor has a certain type
//- floor_tile is now a path, and not a tile obj
- //- builtin_tile should be dropped if needed for performance reasons (eg singularity_act())
name = "floor"
icon = 'icons/turf/floors.dmi'
@@ -31,7 +30,6 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
var/broken = 0
var/burnt = 0
var/floor_tile = null //tile that this floor drops
- var/obj/item/stack/tile/builtin_tile = null //needed for performance reasons when the singularity rips off floor tiles
var/list/broken_states = list("damaged1", "damaged2", "damaged3", "damaged4", "damaged5")
var/list/burnt_states = list()
@@ -41,14 +39,6 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
icon_regular_floor = "floor"
else
icon_regular_floor = icon_state
- if(floor_tile)
- builtin_tile = new floor_tile
-
-/turf/open/floor/Destroy()
- if(builtin_tile)
- qdel(builtin_tile)
- builtin_tile = null
- . = ..()
/turf/open/floor/ex_act(severity, target)
var/shielded = is_shielded()
@@ -150,7 +140,8 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
user << "You forcefully pry off the planks, destroying them in the process."
else
user << "You remove the floor tile."
- builtin_tile.loc = src
+ if(floor_tile)
+ PoolOrNew(floor_tile, src)
make_plating()
playsound(src, 'sound/items/Crowbar.ogg', 80, 1)
return 1
@@ -159,18 +150,18 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
/turf/open/floor/singularity_pull(S, current_size)
if(current_size == STAGE_THREE)
if(prob(30))
- if(builtin_tile)
- builtin_tile.loc = src
+ if(floor_tile)
+ PoolOrNew(floor_tile, src)
make_plating()
else if(current_size == STAGE_FOUR)
if(prob(50))
- if(builtin_tile)
- builtin_tile.loc = src
+ if(floor_tile)
+ PoolOrNew(floor_tile, src)
make_plating()
else if(current_size >= STAGE_FIVE)
- if(builtin_tile)
+ if(floor_tile)
if(prob(70))
- builtin_tile.loc = src
+ PoolOrNew(floor_tile, src)
make_plating()
else if(prob(50))
ReplaceWithLattice()
diff --git a/code/game/turfs/simulated/floor/light_floor.dm b/code/game/turfs/simulated/floor/light_floor.dm
index 62b64373140..e4895097777 100644
--- a/code/game/turfs/simulated/floor/light_floor.dm
+++ b/code/game/turfs/simulated/floor/light_floor.dm
@@ -12,10 +12,6 @@
/turf/open/floor/light/New()
..()
- spawn(5) //needed because when placing a light floor tile it will take a short while before setting state
- if(istype(builtin_tile, /obj/item/stack/tile/light))
- var/obj/item/stack/tile/light/L = builtin_tile
- L.state = state
update_icon()
/turf/open/floor/light/update_icon()
diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm
index f177df2d679..3a540a57857 100644
--- a/code/game/turfs/simulated/floor/plating.dm
+++ b/code/game/turfs/simulated/floor/plating.dm
@@ -168,9 +168,9 @@
/turf/open/floor/engine/singularity_pull(S, current_size)
if(current_size >= STAGE_FIVE)
- if(builtin_tile)
+ if(floor_tile)
if(prob(30))
- builtin_tile.loc = src
+ PoolOrNew(floor_tile, src)
make_plating()
else if(prob(30))
ReplaceWithLattice()
diff --git a/code/modules/recycling/disposal-structures.dm b/code/modules/recycling/disposal-structures.dm
index 5e116c89d7d..e31ecf4beff 100644
--- a/code/modules/recycling/disposal-structures.dm
+++ b/code/modules/recycling/disposal-structures.dm
@@ -258,9 +258,8 @@
if(istype(T, /turf/open/floor)) //intact floor, pop the tile
var/turf/open/floor/myturf = T
- if(myturf.builtin_tile)
- myturf.builtin_tile.loc = T
- myturf.builtin_tile = null
+ if(myturf.floor_tile)
+ PoolOrNew(myturf.floor_tile, T)
myturf.make_plating()
if(direction) // direction is specified
diff --git a/code/world.dm b/code/world.dm
index 0d1c298e64c..2b70a86cea8 100644
--- a/code/world.dm
+++ b/code/world.dm
@@ -11,6 +11,7 @@ var/global/list/map_transition_config = MAP_TRANSITION_CONFIG
/world/New()
check_for_cleanbot_bug()
map_ready = 1
+ world.log << "Map is ready."
#if (PRELOAD_RSC == 0)
external_rsc_urls = file2list("config/external_rsc_urls.txt","\n")
diff --git a/tgstation.dme b/tgstation.dme
index 8d1afe94f43..9d1cd853a76 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -148,6 +148,7 @@
#include "code\controllers\subsystem\npcpool.dm"
#include "code\controllers\subsystem\objects.dm"
#include "code\controllers\subsystem\pai.dm"
+#include "code\controllers\subsystem\pool.dm"
#include "code\controllers\subsystem\radio.dm"
#include "code\controllers\subsystem\server_maintenance.dm"
#include "code\controllers\subsystem\shuttles.dm"
diff --git a/tools/linux_build.py b/tools/linux_build.py
index 13fc1a5dd3f..bf23b2c531e 100755
--- a/tools/linux_build.py
+++ b/tools/linux_build.py
@@ -4,6 +4,7 @@ import subprocess
import os
import sys
import argparse
+import time
from subprocess import PIPE, STDOUT
null = open("/dev/null", "wb")
@@ -36,7 +37,8 @@ def stage2(map):
p = subprocess.Popen(args, shell=True)
wait(p)
-def stage3():
+def stage3(profile_mode=False):
+ start_time = time.time()
play("sound/misc/compiler-stage2.ogg")
logfile = open('server.log~','w')
p = subprocess.Popen(
@@ -45,9 +47,15 @@ def stage3():
try:
while p.returncode is None:
stdout = p.stdout.readline()
- t = "Initializations complete."
- if t in stdout:
+ if "Initializations complete." in stdout:
play("sound/misc/server-ready.ogg")
+ time_taken = time.time() - start_time
+ print("{} seconds taken to fully start".format(time_taken))
+ if "Map is ready." in stdout:
+ time_taken = time.time() - start_time
+ print("{} seconds for initial map loading".format(time_taken))
+ if profile_mode:
+ return time_taken
sys.stdout.write(stdout)
sys.stdout.flush()
logfile.write(stdout)
@@ -63,6 +71,7 @@ def main():
parser.add_argument('-s','---stage',default=1,type=int)
parser.add_argument('--only',action='store_true')
parser.add_argument('-m','--map',type=str)
+ parser.add_argument('--profile-mode',action='store_true')
args = parser.parse_args()
stage = args.stage
assert stage in (1,2,3)
@@ -75,7 +84,9 @@ def main():
if not args.only:
stage = 3
if stage == 3:
- stage3()
+ value = stage3(profile_mode=args.profile_mode)
+ with open('profile~', 'a') as f:
+ f.write("{}\n".format(value))
if __name__=='__main__':
try: