First of all I would like to say thanks to all of you who donated even after I stopped posting. I appreciate this and feel like I owe you one. So here is some advanced stuff that might help you to save hours of debugging.
So as with everything in Arma, just when you think you sussed it out, something comes along that puts everything from its feet on its head. For example:
This is mad, right? However I can assure you, this could happen and there is perfectly logical explanation to it as well as a way to avoid it. But first let me remind you what the scheduler is.
For simplicity and to make it relevant to this post, the scheduler basically is an array that holds all the VM scripts. When you execute execVM or spawn command, the given script is added to the scheduler and a timestamp stored with it. Then on each script simulation the engine takes 1st script out of the scheduler and starts executing it, statement by statement, either until the end of the script reached or until 3ms execution time is exceeded, in which case the script is suspended right there and then, timestamp updated, scripts rearranged so that the oldest goes first and the process repeats on next simulation. This also means that the script can be suspended in between the statements. Let’s assume that in our example the suspension happened between first and last statement:
What happens to variable a in between? If variable a is global variable and shared between different scripts, it could get altered and the hint might show something else other than 123. This is to be expected, in fact. However, how on Earth can it get undefined? Well, the good news is, it doesn’t get undefined, not by itself anyway.
In Arma you can use different namespaces to store variable in. It could be an object, a group, a control, etc., as well as 4 script namespaces: UI namespace, mission namespace, profile namespace and parsing namespace. When you write your script without explicitly indicating the namespace, default namespace is used and it is mission namespace. However, when you want to operate in another namespace, like say UI namespace to work with displays and controls, you can use a handy with command:
While there is nothing wrong with this syntax, the problem could occur when it is used in scheduled script, because of the unpredictability of suspension. If you have several scripts running using different namespaces, it could happen that under load, when script is resumed, it is resumed in different namespace than the one it was running before suspension. So going back to our example:
And the result will be undefined variable error, since a doesn’t exist in UI namespace. See? Perfectly logical explanation to this madness. Is this a bug? Most likely. Will this get fixed? I don’t know. Can this be avoided? Yes, it can:
1. This bug doesn’t happen in unscheduled scripts because they never suspend and run up to the end, so you are safe using with command there.
2. Local variables exist across all 4 script namespaces. So the following will always work no matter what:
3. If you want to jump between namespaces, make sure you use namespaces explicitly:
In conclusion, the scheduler is both good and evil, depends on how you use it. Abusing it or not using it enough is equally bad. Use event handlers and FSMs for critical sections of the code and dump other non critical stuff in scheduled scripts, always bearing in mind their unpredictability.