ID:2421230
 
(See the best response by Nadrew.)
Given the intense size of my map, world.Repop() can lag out my entire server for multiple seconds. I have many different types of mobs in game that I would like to be affected by the magic of world.Repop(), but without the CPU-draining process of scanning the map. My idea was to, when the server boots, run through a list of every mob and get their paths, then never touch this list again as it should serve the basis of what mobs need to exist. Done like so:

The Initial Loop:
var/list/RepopMobs = list()
. . .
world
New()
. . .
spawn(20) for(var/mob/M in world) if(!M.client && /*misc checks to make sure it is the type of mob I want*/) RepopMobs.Add(M.type)


Then using this probably-functioning list, I attempt the repop in the way of creating a new mob of each path, matching it to an existing mob, then copying over the variables. Like so:

The Repop, in another proc:
. . .
for(var/mob/Monster/M in world)if(M)
if(M.NODELETEME)continue
for(var/X in RepopMobs)
if(M.type == X) // recall that X is a type path
var/mob/NEW = new X
for(var/S in M.vars)
if(S == "type" || S == "parent_type" || S == "client" || S == "key" || S == "verbs")
continue
NEW.vars[S] = M.vars[S]
break
del(M)
. . .


Problem description:
The issue with this is every time I run it, I get a new runtime error when this proc is called, on the line containing "NEW.vars[S] = M.vars[S]" -- always stating either "Cannot write to datum.(whatever)" or "Cannot write to atom.(whatever)". The first few times I simply added that variable to that little blacklist, though I fear I will have to do this infinitely at this rate because something is probably horribly wrong. This looks like the wrong way to go about this, but the lack of a mob-specific Repop() kills me. If I could simply do this, or a general equivalent, I would be happy:

for(var/mob/Monster/M in world)
M.Repop()
Instead of creating a brand new mob and trying to make it identical to the one that was removed, simply save the first one and reuse it in the same position over and over.

Destroying and creating things at runtime, especially on larger games can be very taxing (especially using del() which will have to check everything that exists for references to itself and wipe them, bigger games should never use del() unless Del() is doing something non-standard). It's usually always a better idea to recycle instead of rebuild.

A combination of a list that's smaller than 'world' and properly managing a recycling pool system will go a long way, and not just for mobs, objs too.
Now, define "save the first one and reuse it" -- that does sound lovely, though how could I easily tell a mob to reset to its original location and variables? Is the only way to make a specific proc for my mobs, which would manually reset all their variables, including starting location, to their initial values? Or is there some magic way Repop() does it where I can just say "M.ReInit()" or something to reset it to its DM state?
Best response
Doing it manually is probably the best route either way, you usually want finer control over what's kept and what isn't.

There's no built-in method, no, but it's rare to actually need to fully reset them, a few key variables like their location and your user-defined stuff is enough. The initial() proc is about as close to a baked in method as you get.
Ah I was entirely unaware of this inital() proc, that is perfect! Exactly what I can use. Thank you kindly.