ID:2147673
 
(See the best response by Lummox JR.)
Code:


Problem description:

Good morning to all, the problem is that ia () is generating excessive consumption of resources of my pc.

this is de profile game:

                                       Profile results (total time)
Proc Name Self CPU Total CPU Real Time Calls
------------------------------------------------------ --------- --------- --------- ---------
/mob/enemy/New 7.047 2121.562 181.658 3
/mob/enemy/proc/combatIA 2181.531 2181.714 181.654 3
/obj/Del 8.149 8.149 8.202 4989


this is the code of my IA()
mob/enemy/New()
J_showbars(src)
J_update(src)
src.health=src.maxhealth
spawn(10) src.combatIA()
return ..()mob



ob/enemy
proc
combatIA()
while(src)
var/mob/closer = null
for(var/mob/M in oview(22,src))//Selecciona al objetivo más cercano
if(Frozen||froze||caught||captured||M.kawa||M.isdog||M.invisibility||M.NPC||Village==M.Village||istype(M,/mob/Animal/cat))
continue//estados
else
if(!closer)
closer=M
if(get_dist(M,src)<get_dist(closer,src))
closer=M
if(closer)
if(!Frozen&&!froze)
ai_check_dist(src,closer) //ataca si está a 1 cuadro
if(src.health>=(src.maxhealth*20)/100)//si esta a más de 30% de la vida:
walk_to(src,closer,1,3)
sleep(1)
if(prob(20)&&src.firing==0)
if(get_dist(src,closer) <= 1) ai_check_dist(src,closer)//si esta a menos de un cuadro ataca a tai
else jutsusIA(closer) //si no es asi :lleva a Jutsus.dm
else
if(prob(2))
health+=maxhealth*20/100
oview()<<"[src] regenera un 20% de su vida!!"
J_update(src)
else
walk_away(src,closer,10)//nuevo
if(prob(10))
if(istype(src,/mob/enemy/OSO))return
else Kawa(src)
spawn(20)walk(src,0)//nuevo
else //Si no hay nadie cerca, se cura lentamente.
if(health<maxhealth)
health+=(maxhealth*1/100)//se cura un 1% de la vida máxima
if(health>maxhealth) // si se pasa de curarse
health=maxhealth
J_update(src)
sleep(rand(4,6))



Thnaks for your help.
oview(22,src) is going to eat a ton of resources, toss that into an infinite loop? Bad idea, you need to rethink how you do AI activation and targeting entirely.

Ideally, you'd have the player activate the enemy when one comes into view of the other, then you'd set the enemy's target to that player and attack them from there, instead of constantly looking for players within a rather large view radius.
Also: IA?
In response to Lummox JR
sorry, is AI() but i speak spanish,then abbreviate as IA ()("Inteligencia Artificial" )

Sorry XD.

In response to Nadrew
Taknk you, y change for this:

mob/enemy
proc
combatIA(mob/enemy/Atacante,mob/Defensor)
while(Atacante)
var/mob/closer = null
if(get_dist(Atacante,Defensor) <= 22)
if(Frozen||froze||caught||captured||Defensor.kawa||Defensor.isdog||Defensor.invisibility||Defensor.NPC||Village==Defensor.Village||istype(Defensor,/mob/Animal/cat))
continue//estados
else
if(!closer)
closer=Defensor
if(get_dist(Defensor,Atacante)<get_dist(closer,Atacante))
closer=Defensor


and gone to the problem,now it is limited and not infinite.

thank you Nadrew , and sorry for my bad english


I can ask another question or should preferably open another post?
Best response
Feel free to keep your questions in this same thread if they're still on the topic of this code.

One of the things Nadrew was referring to is that you should really consider waking and sleeping enemies so that this loop doesn't run all the time. If every mob in the world is running this proc at all times, even the cases where it doesn't do very much will cost you CPU cycles.

One good way to go is to break your map up into different areas. When a player enters a sleeping area, you can wake up all the monsters in it and start their AI loops. When the last player leaves the area, the AI loops should be able to check on that (like a simple count of players) and go back to sleep. For this to work you need to track entry and exit properly, so whenever it's done without Move() (like by setting loc directly, or by logout) you'd have to handle those cases.

Here's roughly how that would look:

area
var/active
var/list/players
var/music

Entered(mob/M)
if(ismob(M) && M.key)
players[M] = null
// simple music handler; I threw this in for fun
if(music != M.music)
M.music = music
M << sound(music, channel=MUSIC_CHANNEL)
if(!active)
active = 1
for(var/mob/enemy/M2 in src) globalAIs[M2] = null
Exited(mob/M)
if(ismob(M)) players -= M
if(active && !(players && players.len))
active = 0 // let AI loops die

var/list/globalAIs = new

proc/GlobalAILoop() // call this in world/New() or somewhere similar
var/i
var/area/A
var/mob/M
spawn()
while(1)
for(M in globalAIs)
for(A=M.loc, A.loc,) A = A.loc
if(!A || !A.active)
globalAIs -= M
continue
M.DoAI() // do one tick of AI calculations for this mob
// cleanup
while(globalAIs.Remove(null));
sleep(world.tick_lag)
In response to Lummox JR
The question I have is about another code and another subject, I will open another post.


thank you very much Lummox JR, misinterpret the information Nadrew.

I will try to place zones for the activation of the AI () to be much more efficient, thank you very much everyone.