ID:1602600
 
Keywords: lag, respawn, usage
(See the best response by Ter13.)
Code:
//ShowEffect(src.loc,'Effects.dmi',"HollowHide")
if(istype(src,/mob/Pets)) src.loc=null
else
src.loc=locate(rand(2,199),rand(2,199),30)
spawn(rand(30,60))//300,600
if(!src.RespawnZ)
for(var/atom/x in src.Cache) del x
del src;return
if(istype(src,/mob/Enemy)) src:LevelShift(initial(src.Level))
src.loc=locate(src.RespawnX+rand(-1,1),src.RespawnY+rand(-1,1),src.RespawnZ)
//ShowEffect(src.loc,'Effects.dmi',"EnergyBall")


Problem description:

This code I have causes usage to go up. If I killed 100 mobs at a time, the usage will go upto 60%-80%. What would be a better way to respawn mobs where lots of them can be killed without causing extreme usage. I could understand if it's upto 10%. But if a single player is killing 100 mobs that cause 60% usage, then if there's 10 players all killing 1000 mobs, the usage will be even higher, which can cause players to freeze up.
You could try to spread it out.

On top of your Respawn() function, just add
sleep(rand(5, 50))


Edit the values as you like. But beside adding some time to the whole thing, you'd spread the load over more time, thus reduce CPU use.

Enabling background on your Respawn function in addition to this could also help.
Try forcing atom's location to null and removing any references there might be. Let automatic garbage collection pick it up and remove the need for delete.
Best response
Enabling background isn't going to do anything. The del keyword is a blocking instruction, because it needs to assure consistency of the reference tree before it can be used further.

If you reach a point where you are calling del for anything other than managing built-in interface prompts, you are doing it wrong.

Simply put, you need to ensure that all references to the object are nulled and you need to move the location of the object to null.

If you have circular references, you need to break them. Calling del() is intensely wasteful, and should be avoided at all costs. The more objects you have in the world, the worse it will get.

In all honesty, I don't understand why the del keyword isn't deprecated.
In response to Ter13
Ter13 wrote:
Enabling background isn't going to do anything. The del keyword is a blocking instruction, because it needs to assure consistency of the reference tree before it can be used further.

If you reach a point where you are calling del for anything other than managing built-in interface prompts, you are doing it wrong.

Simply put, you need to ensure that all references to the object are nulled and you need to move the location of the object to null.

If you have circular references, you need to break them. Calling del() is intensely wasteful, and should be avoided at all costs. The more objects you have in the world, the worse it will get.

In all honesty, I don't understand why the del keyword isn't deprecated.

Because not every source code is as nicely organized and laid out as, well, I guess yours.

Been trying to get SS13 code to mostly use garbage collection, doesn't really work because the code is absolute shit.. And a mess.
Actually, I set background to 0 and it reduced the usage when I kill. However it seems that's not the reason for the lag. When I walk through the mobs, and aggravate them, it would cause the usage to go upto 70% or even greater. I can fix this by reducing the amount of mobs in the map. However it just seems the enemy AI isn't coded good enough.
Then your issue is with the AI pathfinding and not with the mob's dying.
Set_background creates a backup of cpu load, I had to tell the /tg/ss13 people to stop using it in every single proc.
In response to Jittai
Jittai wrote:
Set_background creates a backup of cpu load, I had to tell the /tg/ss13 people to stop using it in every single proc.

Ah, so that was your doing then, it helped. Although I still use it in some main areas of the code.

Any way..
We might be able to help you with your AI if you show us the code.
        EnemyAI()
//if(src.MultiCore) src=src.MultiCore
while(src.StartedBy)
while(src.Stunned||!src.CanMove) sleep(5)
if(!src.Target)
src.TauntedBy=null;src.StartedBy=null
else
if(src.Target.STM<=0) src.TargetMob(null)
if(src.Target && src.Target.invisibility) src.TargetMob(null)
if(src.TauntedBy && MyGetDist(src,src.TauntedBy)<=15) src.Target=src.TauntedBy
var/CurDistance=MyGetDist(src,src.Target)
if(CurDistance && CurDistance<=src.SightRange)
if(CurDistance==1)
src.dir=get_dir(src,src.Target)
MyFlick("PullBack",src)
src.Pulling=1
var/image/I=image('Effects.dmi',src,"CounterStep",src.layer-1,SOUTH)
if(src.Target.client) src.Target.client<<I
sleep(5)
if(I) I.loc = null
src.Pulling=0
MyFlick("Attack",src)
var/Action2Take="Attack"
if(rand(1,3)==2) Action2Take=pick(src.EnemySkills)
if(Action2Take=="Attack") src.Attack(rand(1,3))
else call(src,"[Action2Take]")()
spawn(3) src.dir=get_dir(src,src.Target)
else
if(!step_to(src,src.Target,1) && src.z!=8) src.TargetMob(null) //I believe it's this part that's causing the usage to spike. Because it gets no target, it'll respawn to orginal location, and it gets aggravated again, and keeps doing it.
else src.TargetMob(null)
sleep(src.MovementSpeed+5)
if(src.z==8) {src.loc = null;return}
src.TargetMob(null)
if(src.z==src.RespawnZ)
src.LevelShift(initial(src.Level))
src.loc=locate(src.RespawnX+rand(-1,1),src.RespawnY+rand(-1,1),src.RespawnZ)


if(!step_to(src,src.Target,1) && src.z!=8)    src.TargetMob(null)
I believe it's this part that's causing the usage to spike. Because it gets no target, it'll respawn to orginal location, and it gets aggravated again, and keeps doing it.
Aside from the fact that I'm not seeing a lot here, do you know how to use BYOND's profiler? It usually tells you exactly where the lag is coming from.
Not clue how to use it for Linux servers. :P