ID:2185995
 
Not a bug
BYOND Version:511.1365
Operating System:Windows 10 Home
Web Browser:Firefox 50.0
Applies to:Dream Maker
Status: Not a bug

This is not a bug. It may be an incorrect use of syntax or a limitation in the software. For further discussion on the matter, please consult the BYOND forums.
Descriptive Problem Summary:
If you define a var on a proc, and on the same proc you use spawn() while(), even when that var is updated on the proc, it won't suffer any change below while()

Numbered Steps to Reproduce Problem:
Use the following command.

Code Snippet (if applicable) to Reproduce Problem:
Let's imagine we have this:

mob/proc/Test()
var/T
spawn(30) T = 1
spawn() while(!T) {world<<"Called"; sleep(10)}


It'll continue displaying "Called" after 3 seconds. For some reason T value isn't updated on while, even if you try something like world<<"Called [T]", it'll still display "Called " (not "Called 1").

Expected Results:
while(!T) should stop.

Actual Results:
while(!T) is called as T value isn't updated on that.

Does the problem occur: Yes
Every time? Or how often? Every time
In other games? Yes
In other user accounts? Yes
On other computers? Yes

When does the problem NOT occur?
If you define the var on a mob, obj, or anything that exists on the game outside of that proc, it'll work. If T was a var defined for every mob, and it was updated on the proc, while(!T) would stop working after 3 seconds. But if the var is defined on the proc, it won't.

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked? (Visit http://www.byond.com/download/build to download old versions for testing.)
I've tested every BETA Version and it occured in all of them.

This isn't a bug.

DM Reference (spawn):
Any vars you have defined in the proc itself, including arguments, will be copied between the spawned code and the code that runs right away. This means that if one part modifies one of those vars, the other part will not see that change. Changes made to objects, lists, datums, etc. however will be visible to both code blocks.
Kaiochao resolved issue (Not a bug)
The way to solve your issue is with an object var, a static var, or a datum.

Currently you're using a local var. Local vars and arguments get copied in spawn() and sleep(). A spawned proc is basically forked off of the original, and doesn't maintain any ties to it.

An object var would of course be something like mob/var/tmp/testing. You'd use the testing var instead of T. Since the object (the mob) is available to both copies of the proc, if one modifies src.testing, the other can see the change.

A static var (which in BYOND is basically identical to a global var right now) is another way to go. It's the same deal as the mob var, only obviously you only have one copy.

A datum is also a way to go. This is like the object var solution, except 1) you don't need to clutter your mob up with extra vars, and 2) the datum can be as complex as you like, holding more than one piece of info about its state.

// mob var
mob/var/tmp/testing
mob/verb/Test()
spawn(30) testing = 1
while(!testing)
world<<"Called"
sleep(10)
testing = 0

// static var; shared by all mobs, because it's effectively global
mob/var/static/testing
mob/verb/Test()
spawn(30) testing = 1
while(!testing)
world<<"Called"
sleep(10)
testing = 0

// datum var
procstate
var/value
mob/verb/Test()
var/procstate/state = new
spawn(30) state.value = 1
while(!state.value)
world<<"Called"
sleep(10)

There is an important difference between these approaches. In the mob var approach, you can change the proc so that if you call Test() more than once, it won't register the second try until it the first finishes. In the static var approach, if one mob is testing they're all testing. And with the datum version, while the datum does clean up after itself which is nice, you can't prevent Test() from being called twice.