ID:1928881
 
(See the best response by Stephen001.)
Code:
mob/var
tmp/training=0
player/p

mob/proc
TrainingLoop()
var/player/p=usr
while(p&&p.training)//While both values are true
p.TrainGain()//Wait 300 ticks (30 seconds)
spawn()
p.TrainingLoop()

Stop_TrainingLoop()
var/player/p=usr
p.training=0

Start_TrainingLoop()

var/player/p=usr
p.training=1
p.TrainingLoop()
TrainGain()
var/player/p=usr
if(p.potlvl=="Weak")
//Hidden, basically was the gainlayout for training. No proc or anything game after it.



mob/verb
Train()
set hidden=1
var/player/p=usr
if(p.training==0)
p.Start_TrainingLoop()
p.icon_state="Train"
p << "You start to train."
p.frozen=1
else
p.Stop_TrainingLoop()
p.icon_state=""
p << "You stop training."
p.frozen=0


Problem description:

First off... I've never in my life of coding ever understanded how to functionally loop without all this bunch of lag and errors and what not.

This is my first time working on a project where certain loops are included and I wanted to try this on my own.
Using a reference from a friend, I still can't come to get a functional loop and I've tried everything from set background =1 , to spawn(1), to while() to... idk.

You could see in the coding via // comments, I even had to delete certain spawn's because I felt like they were the problems, still no change.

But nothing works and I always end up with this error:

Infinite loop suspected--switching proc to background.
If it is not an infinite loop, either do 'set background=1' or set world.loop_checks=0.
proc name: TrainingLoop (/mob/proc/TrainingLoop)
source file: Training and Gains.dm,9
usr: Boiy (/player)
src: Boiy (/player)
call stack:
Boiy (/player): TrainingLoop()
Boiy (/player): Start TrainingLoop()
Boiy (/player): Train()
Add set background=1 under TrainingLoop, also you should enable the Lines option by clicking Ctrl+L will help show the lines where the errors happen.
In response to Zasif
Never knew the Lines thing, thanks. & I'll test the background proc once more.
Tried adding set background =1 into TrainingLoop proc.

mob/var
tmp/training=0
player/p

mob/proc
TrainingLoop()
set background = 1
var/player/p=usr
while(p&&p.training)//While both values are true
p.TrainGain()
p.TrainingLoop()

Stop_TrainingLoop()
var/player/p=usr
p.training=0

Start_TrainingLoop()

var/player/p=usr
p.training=1
p.TrainingLoop()


Got another error via in-game, one of the few that I kept getting:

runtime error: Maximum recursion level reached (perhaps there is an infinite loop)
To avoid this safety check, set world.loop_checks=0.
proc name: TrainGain (/mob/proc/TrainGain)
usr: Lol (/player)
src: Lol (/player)
call stack:
Lol (/player): TrainGain()
Lol (/player): TrainingLoop()
Lol (/player): TrainingLoop()
Lol (/player): TrainingLoop()
Lol (/player): TrainingLoop()
Lol (/player): TrainingLoop()
Lol (/player): TrainingLoop()
Lol (/player): TrainingLoop()
Lol (/player): TrainingLoop()
Lol (/player): TrainingLoop()
...
Lol (/player): TrainingLoop()
Lol (/player): TrainingLoop()
Lol (/player): TrainingLoop()
Lol (/player): TrainingLoop()
Lol (/player): TrainingLoop()
Lol (/player): TrainingLoop()
Lol (/player): TrainingLoop()
Lol (/player): TrainingLoop()
Lol (/player): Train()

At this point im lost.
In response to HaxRp
HaxRp wrote:
Tried adding set background =1 into TrainingLoop proc.
    TrainingLoop()
while(p&&p.training)//While both values
p.TrainingLoop()


Stop that. Stop that now.
Best response
Basically as NNAAAAHH rightly notes, and BYOND does also with it's error message, you've created a procedure that calls itself, without actually ever finishing. The result is something like this:

TrainingLoop() calls p.TrainingLoop()
p.TrainingLoop() then calls p1.TrainingLoop()
p1.TrainingLoop() then calls p2.TrainingLoop()
p2.TrainingLoop() then calls ...

Forever. Simply don't call p.TrainingLoop(). Your while loop already takes care of the looping for you, no need to include /another/ loop by way of recursion.
In response to HaxRp
Okay, firstly; why are you making a new mob variable and assigning it usr? Do you not know how src works?

What is the use of mob/var/player/p(or any of the cases of var/player/p=usr) here? It seems completely and utterly useless. StartTrainingLoop is three lines of code in a proc that could be cut to one line in the verb you call it from(src.training=1), then simply calling the 'loop'. Also, instead of having an entire proc for one variable change, just set src.training=0. Both of those procs are useless and should've never been created, only increasing the number of procs you have to call to get where you're wanting to go.

Just gonna throw this out there, since it looks like you're re-creating a zeta source with what you've provided here(in terms of quality(no, this isn't a insult; I'm only trying to help you improve)).
mob/verb/Train()
training=!training//no need for a proc to do each of these
if(training)//only have it written with the if statement to allow you to only call the loop when needed
src<<"You're now training!"
TrainingLoop()
else
src<<"You're not training!"
mob/proc/TrainingLoop()
icon_state="Training"//so much easier!
while(training)
TrainGain()
sleep(300)//Never call a proc inside itself. Not sure what purpose that served any way, if the while loop breaks out, it'll break out again when you call the proc again, until something changes(hence infinite loop)


Oh, and your loops allow for a player to 'double train', if they call the loop again before the 30 second mark, it'll continue the one loop and call a new one.
Appreciated NNAAAAH, and yes this training proc I believe was taken from a finale/dbz or some type of other source, I remember seeing this but then again a friend of mine on skype pulled it up for me and I've been trying to work it ever since.

Oh and the reason I used p for the usr var was because....nothing was happening when running the game and testing the proc, figured being more specific would help, it showed a difference but the looping fail continued.

But again, thank, really enlightened me to alot.