ID:1386508
 
(See the best response by Ter13.)
Code:


Problem description: How do you use the While() procedure without creating an infinite loop? I've tried many times, but I end up failing horribly. So could someone post an annotated example of a while procedure or explain clearly? Thanks :D

Basically just make the condition in it satisfiable! Usually by doing something within the while's sub-statements, that alters the condition:

var/i = 0
while (i < 10)
src << "[i]"
i++ // This bad-boy guarantees we'll exit the while loop
But how would I make it so it doesn't lag/crash my game and is active multiple times?
Best response
Well, you could sleep() at the end of each iteration of the loop. That will allow other procs in your world to run while the loop is in between cycles.

If you are running a loop several thousand times, you will want to set world.loop_checks to 0, otherwise the loop will stop processing after a while, the VM trying to prevent an infinite loop.

Also, a while() loop won't make your game "lag". Don't use that term unless talking about network latency.

When your code is taking too long to process, your CPU load is greater than the time allotted to it to perform tasks. This is basically "bottlenecking".

When you CPU is unable to handle the load you are giving it, your world isn't lagging, your CPU is just overloaded/bottlenecked.

As for what makes loops max out your CPU, when you instruct a loop to run forever, it will never finish. So if it isn't told to wait every now and again, the game will freeze or even crash, because it can't do anything else but run that loop. It's stuck, and can't update anything else.

To make loops fast, do as little as possible in them. That's the key idea to improving efficiency: Do as little work as possible.
Thanks Ter and Stephen. I think I have a clearer idea now ^^.
I don't think loop_check needs to be altered at all actually..

Using set background helps prevent what is known as lock up. This lock up occurs when the CPU is jacked because the loop is halting the world tick. By setting background, you allow for the game to delay the loop if it is exceeding the game's tick, and thus avoid lock-up all together.

Of course, the more the procedure does, the more sluggish the game will be. However, with set background applied the game should still be playable, but could be super slow until loop is finished. Also, I believe set background will not be stopped due to infinite loop. I can't swear to it, but I believe infinite loop is when it continues so many times pass the world tick.

To clarify why loop_check shouldn't be set to zero. Back in the day, it would actually cause the game to crash if the loop ran for too many times without creating a new thread and your loop check is designed to prevent that, and to prevent game from locking up forever due to a loop that never stops. I'm unsure as to whether this is still an issue, but I feel it is wise practice to always allow for a new thread to be formed if the loop will run indefinitely.

Example of simply while:
var/n=0
while(n<10)
set background = 1//The same as making it sleep(1) if it exceeds a world tick.
n++


Also, awhile back I did some looking into, and as for most CPU efficient, for(var/n = 0 to 10) proved to be the best choice some years ago.

for(var/n=0 to 10)
set background=1
src<<"I needed something inside this."


While was the slowest method, and for(var/n=0,n<10,n++) was the second best.

for(var/n=0,n<10,n++)
set background = 1
src<<"I needed something here as well."


Lastly, creating a new thread. To create a new thread you basically just use spawn(), I honestly can't remember what the technical terms are called, but this will break away from the current procedure running and run on it's own.

mob/proc/randomLoopExample(n)
n++
spawn(1)
randomLoopExample(n)

mob/proc/secondExample(t)
spawn(1)
secondExample("This ran second.")
src<<t


To conclude, don't set loop_check to zero, use for( to ), set background, and if you have a procedure that will run indefinitely, create a new thread by using spawn()
http://www.byond.com/forum/?post=927320#comment2983071

Just to clarify what spawn() does. A new thread, it is not. I'd probably describe it as "run this later".
In response to Stephen001
Stephen001 wrote:
http://www.byond.com/forum/?post=927320#comment2983071

Just to clarify what spawn() does. A new thread, it is not. I'd probably describe it as "run this later".

Thank you Stephen. It seemed so similar to multithreading that I just assumed. You wouldn't happen to know why spawn at one point was the only means of creating a loop that ran forever without BYOND crashing would you?
Ty Guys :)