ID:141859
 
Code:
New()
set background = 1
..()
while(1) // Infinite loop for attacking
for(var/mob/M in oview(1)) // For every mob in 1 space within the slime
if(src.npc_atk == 1) // If the monster is set to 'attack'
view() << "[src.name] attacks [M.name]!"
M.hp -= rand(min_dmg, max_dmg) // Attack with an amount of damage specified by min_dmg and max_dmg
src.npc_atk = 0 // Set the attack back to 0
if(M.hp <= 0)
death(M)
continue // Continue with the loop


Problem description:
When the game is run, it SEVERELY lags due to the infinite loop in the monster code. The problem is, I can't figure out how to do this without an infinite loop. I set the proc in the background to stop it from slowing down the loading process, but it still lags.

You should stick a sleep() in there somewhere.
//This is how I usually manage inf loops..
New()
spawn while(1)
sleep(1)
//etc.

Just because without delays, it could loop infinite times in no time.
In response to Kaiochao
I guess using an empty for() loop is more efficient than a while loop.
In response to Speedro
They are both the same. I don't think for() loops automatically add a delay to it.


In response to Kaiochao
No, they don't. I was just told it's one less check the server has to do therefore making it more efficient.
In response to Speedro
Either way, not putting a delay in an infinite will pretty much freeze the game.
Ok, here is what you should work on:

1) When a variable can only be 0 (false) or 1 (true), use Boolean logic. False values include 0, null, and "", while true values are everything else (all numbers besides 0, text, datums, atoms, etc.).

To check if a variable is true, just use if(var).
To check if a variable is false, just use if(!var).
To check if multiple conditions are true, use if(var && var1)
To check if one or another condition is true, use if(var || var1)

Same goes for false values in the last two, just add ! before each variable. && (and) and || (or) also work with other operators, such as bit operators (>>, <<, ^, &, |, etc. you won't learn these for a while), normal operators (==, <, >, <=, >=, etc.), and the likes. Just make sure you don't violate the order of operations; most programmers use tons of grouping symbols to prevent this.

2) set background. This shouldn't be used unless you know something isn't an infinite loop even though the game disagrees.

3) Misuse of continue. Loops will continue themselves; continue is usually used to skip to the next iteration of a loop:

mob/verb/one2ten_odds()
for(var/N in 1 to 10)
if(N\2 == round(N/2)) continue //if it's even, go to the next num
//Don't use this formula
//there's probably much better ones
//out there
world << N


In response to Speedro
for() without anything in it is rather unsightly, and due to the fact that it's an infinite loop, one of two things are going to happen:
1) There is no delay, and it locks up your game.
2) There is a delay, and the efficiency is a moot point.
No one is ever going to be able to measure any supposed efficiency gain, ever, so use whichever you prefer. Most use while(1).
In response to Popisfizzy
Alright. I was just told here, on the developer forum that an empty for loop was better than an empty while loop.
In response to Jeff8500
Jeff8500 wrote:
>              if(N\2 == round(N/2)) continue //if it's even, go to the next num
> //Don't use this formula
> //there's probably much better ones
> //out there
>



I'd recommend one involving the modulus operator (%). It allows you to directly check the remainder from a division operation.
In response to Jon88
Thanks, I never thought of using that for checking if a number is a decimal! I've used it before for more obscure things, too; the human mind is very strange at times.
In response to Popisfizzy
Popisfizzy wrote:
for() without anything in it is rather unsightly,

It's shorter to type, anyway; and you yourself use ugly statements, so it must not be so bad despite your opinion it's unsightly. :P

No one is ever going to be able to measure any supposed efficiency gain, ever, so use whichever you prefer.

The efficiency gain is minimal, but you're wrong in that it's measurable through the world profiler with some testing code, like, probably, most things. Though regardless of speed difference, I just don't like my functions doing silly things like repeatedly checking whether 1 is a true value or not, if I can avoid it. You can also stick if(1) at random points in your code for the same effect - the efficiency loss won't harm you at all, but why do it in the first place?
In response to Kaiochao
WOW! That really helped the lag! Thanks for all your help, my problem is fixed.
In response to Armiris
Obviously. >_> That's the whole point. =\ If you have an infinite loop with no delay in it, it will freeze your game because not only it hogs the processor, it doesn't let any other proc run (only one proc runs at a time).
mob/verb/hog_game()
:Label
goto Label
//same as
for()
;

Like that, the execution never ends (the loop is infinite!). All your processor does is endlessly jump to a previous position in the code, and because the verb never returns (exits/ends) it doesn't run other things.

Note what set background does is (inconsistently, according to need) occasionally sleep at the end of loop iterations. It's often not so useful, though.