ID:1532997
 
Code:
mob
var/team = 0 // 0 - citizens, 1 - Thugs, 2 - animals, 3 - monsters, 4 - mythological beasts
ai
var
courage = 0 // 0 - flee. 1 - flee below 50 HP.(ONLY USE FOR PASSIVE CHARACTERS) 2 - never flee
mob/target // who am I mad at?
spawnpoint // Where did I spawn?
abilities = list() // What special abilities do I have?
health
New() // var/health used to define HP.value and maxvalue
..()
HP = new(health,health)
spawnpoint = src.loc
spawn(1) ai()
proc
ai()
if(target) // Am I mad, yet?
if(get_dist(src,target) > 10) // My enemy is too far away, forget about them.
if(!src.courage) del src // Cowardly characters are usually passive citizens or thugs. We don't need them.
target = null
switch(courage)
if(0)
step_away(src,target) // Step away from your target.
if(1)
if(src.HP.value < src.HP.max_value/2) // My HP is rather low. I should stop fighting.
src.courage = 0
else
attack()
if(2)
attack()
else
switch(team)
if(0)
sleep(25)
step_rand(src)
if(get_dist(src,spawnpoint) >= 10)
step_to(src,spawnpoint)
if(1)
sleep(5)
for(var/mob/M in oview())
if(M.team != src.team) // That's an enemy.
get_target(M)
else
if(get_dist(src,M )> 3)
step_to(src,M) //Get back with my team.
if(2)
sleep(10)
if(courage)
for(var/mob/M in oview())
if(M.team != src.team)
get_target(M)
else
break
step_rand(src)
if(get_dist(src,spawnpoint) >= 10)
step_to(src,spawnpoint)

spawn(1) ai()

attack()
get_target(mob/M)
src.target = M
call_for_help()

call_for_help()
for(var/mob/ai/M in oview())
if(M.team == src.team)
M.target = src.target
else break
takedmg(dmg,mob/m)
get_target(m)
flick("hit",src)
src.HP.Add(-dmg)
if(!src.HP.value)
icon_state = "die"
sleep(5)
del src


Problem description:

This is loosely based off of Forum_Account's A.I. system, but what I'm using brings the CPU to its knees when the NPC's are used in mass quantities. (50+).

Thanks.


- GamerMania
I notice that your AI is running all the time. It might be a good idea to make AI inactive until an enemy walks into attack range. You can do this by activating the AI loop by overriding the clients move() proc, and deactivating when the monsters cannot find an enemy.

You could also try activating/deactivating by some sort of zone system with areas of some sort. Just some thoughts.

If monsters are not supposed to attack other monsters and only attack players, I'd use a list to track users that are logged in and then loop through that list rather than every mob in oview().

var/list/loggedInClients=new/list()
client
New()
..()
//You probably want to handle this when players actually are logged in.
if(!loggedInClients.Find(C)) loggedInClients+=C

Del()
..()
if(loggedInClients.Find(C)) loggedInClients-=C


Use a for statement similar to this.

for(var/client/C in loggedInClients)
if(C.mob in oview(src))


Also, I'm not sure if orange() is faster or not. One of the better developers could probably answer that. I'm just waking up and don't have time to preform tests.
Thanks for the suggestions, Lavitiz, but some of them would either go against the goals of this project, or only work in Singleplayer.

It turns out the changing some sleep() calls to spawn() brought my CPU usage down from 90% to 33%. However, for some reason, the player's movement is still lagged. I'm going to have to look more into this.


Thanks, again.


- GamerMania
How would it not work with multiplayer? You can have the said monsters doing their AI stuff way before the player even moves into view.

I'm no expert, but sleep should not have a negative effect on CPU Usage. If I recall spawn() actually has more overhead.