ID:1108508
 
(See the best response by Rotem12.)
Code:
mob/Death_Eater_NPC
name = "Death Eater"
icon = 'Death Eater.dmi'
HP = 4000
Attack = 1000
var/target
New()
spawn(1)
Look()
proc/Look()
set background = 1
while(src)
for(var/mob/M in oview())
if(M.client)
if(M.DE)
return
else
target = M
src.dir = get_dir(src,target)
step(src,dir)
sleep(10)
new/obj/projectile/confringo(usr)
Projectile_Check()
proc/Projectile_Check()
for(var/obj/projectile/P in oview())
if(get_dist(src,P)<3)
if(P.owner == src)
return
else
var/stepchance = rand(1,2)
if(stepchance == 1)
step_away(src,P)
else
return
else
return


Problem description:

When featured in the game, it causes lag. I think it has to do with the "while" loop, but I don't know how to fix it.

I'd say try a conditional at the end of the loop, making sure that the mob is still in view. As it stands, the proc will continually run without end. In fact, change the conditional in the loop to only be true if there's a target.
mob/Death_Eater_NPC
name = "Death Eater"
icon = 'Death Eater.dmi'
HP = 4000
Attack = 1000
var/target
New()
.=..()
spawn()
Look()
proc/Look()
set background = 1
while(src)
if(!target)
return
else
for(var/mob/M in oview())
if(M.client)
if(M.DE)
return
else
target = M
src.dir = get_dir(src,target)
step(src,dir)
src.dir = get_dir(src,target)
sleep(5)
new/obj/projectile/confringo(usr)
Projectile_Check()
proc/Projectile_Check()
for(var/obj/projectile/P in oview())
if(get_dist(src,P)<3)
if(P.owner == src)
return
else
var/stepchance = rand(1,2)
if(stepchance == 1)
step_away(src,P)
else
return
else
return


Like this?

EDIT: Hm, it makes the mob unresponsive when I add that.
Whoops. I'm too tired to actually be of any use. You've got an infinite loop going on no matter what because you're got the loop running the entire duration of the mob's life. Don't do that.
How do I make this not so?
while(src) // This causes quasi-infinite loop


LummoxJR handles this by having mobs only be active if there's a mob in the area in one of this Dream Tutors IIRC.

Found it This
Thank you.
I couldn't even get it to work with implementing his code. I'm going to sleep. Hopefully, it will make more sense when I'm actually awake.
Best response
I find Forum_account's Enemy AI demo to be a good way to learn how to efficiently handle AIs.

It guides you step by step with examples, pretty handy for learning.

http://www.byond.com/developer/Forum_account/EnemyAI

And a quote from the hub: "How to manage AI loops efficiently with thousands of mobs."
This worked. I thank you and Lugia both for providing me with useful references, but for the most part I guess Forum_Account is the real person to thank if he's reading this. :P

Here's the code for anyone who wants to use NPC's that shoot projectiles:

mob/Death_Eater_NPC
name = "Death Eater"
icon = 'Death Eater.dmi'
HP = 4000
Attack = 1000
var/target
New()
..()
spawn(rand(10,20)) Look()
proc/Look()
for(var/mob/M in oview())
if(M.client)
if(!M.DE)
target = M
src.dir = get_dir(src,target)
step(src,dir)
src.dir = get_dir(src,target)
sleep(3)
new/obj/projectile/confringo(src)
sleep(3)
new/obj/projectile/confringo(src)
sleep(3)
step_away(src,target)
new/obj/projectile/confringo(src)
Projectile_Check()
break
spawn(2) Look()
proc/Projectile_Check()
for(var/obj/projectile/P in oview())
if(get_dist(src,P)<3)
if(P.owner == src)
return
else
var/stepchance = rand(1,2)
if(stepchance == 1)
step_away(src,P)
else
return
else
return


With a few modifications, that should work in almost any game.