ID:2187896
 
(See the best response by Ter13.)
Code:
mob
proc
moveRun(i)
if(i)
if(stamina > 5)
state = STATE_RUN
move_speed *= speed
accel += 2
world << output("Running.", "chat")
else if(!i)
if(state == STATE_RUN)
state = STATE_NULL
move_speed /= speed
accel -= 2
while(state == STATE_RUN)
lastRun = world.time
staminaChange(0, 5)
world << output("[usr] has [stamina] stamina. Stamina percentage is [round(stamina/maxStamina * 100)].","chat")
sleep(20)


Problem description:
If I were to run, stop running, then start before the sleep(20) ends - it will create two instances of the loop. How would I resolve this?



You could add an if that only does what u wanna do if last run +20 is less than or equal to world.time
Best response
mob
var/tmp
state = STATE_NULL
state_time = 0
proc
moveRun(i)
if(i&&state!=STATE_RUN)
var/time = world.time

state = STATE_RUN
state_time = time
move_speed *= speed
accel += 2
world << output("Running.","chat")

var/ntime = time
while(state==STATE_RUN&&state_time==time&&stamina>0)
if(world.time>=ntime) //only do this every 2 seconds.
staminaChange(0,5)
world << output("[usr] has [stamina] stamina. Stamina percentage is [round(stamina/maxStamina * 100)].","chat")
ntime = world.time+20
sleep(world.tick_lag) //repeat every tick so the loop will end immediately on state change
if(state==STATE_RUN&&state_time==time) //this only happens when the user runs out of stamina
state = STATE_NULL
state_time = world.time
move_speed /= speed
accel -= 2
else if(!i&&state==STATE_RUN)
state = STATE_NULL
state_time = world.time


The reason you are getting two loops is because they aren't gated properly.

With state machines, I like to not only track the state, but also the time that the state was last changed. This makes it so that state loops don't tend to double-trigger unless you enter, exit, and then enter the same state in the same frame, which shouldn't be allowed in the first place.

With state loops, I also prefer not to sleep for any period of time longer than a tick. sleeping for longer than one tick can mean that iterations can overlap if the state machine transitions states multiple times during a longer sleep.
In response to Ter13
Thanks for your help!