It's not a matter of variables vs functions; that's surface-level syntax and not very important in the grand scheme of things.
The issue here is internal implementation vs. externally-visible interface. If you look at LinkClass::setAction(), you can see there is already a bunch of code there that tries to prevent scripts from issuing actions that break the consistency of the game state. That's the way that actions (and anything else scriptable) should be handled, not by tweaking the internal state and damn the consequences.
I don't know if you're a computer science student, but a key concept in computer science is that of
invariants: relations that you can prove must be true about an algorithm as it's running, and that you can use to reason that an algorithm is correct. For example, in a for loop, you know that the index variable
must be between the start and end of the for loop range, because if it weren't, the loop would have terminated on the previous iteration. This lets you write code like
Code:
for(int i=0; i<size; i++)
array[i] = 0;
without worrying that you might segfault due to writing past the end of the array.
If some external agent is allowed to muck with the internals of your code at any time (for example, by setting a breakpoint, and writing new values to memory) it is extremely easy to break your code, because you can no longer trust your invariants. I can set i to be size+1 at some point in the middle of executing the loop, and bam, your program crashes. To prevent this, any changes that you make to the program's internal state need to be aware of, and go out of their way to preserve, the invariants. Instead of letting the user write random integer values directly into the memory address of i, you provide a callback which reads the user's new requested value, and sanitizes it, before continuing with the loop.
It is the same with the ZC engine, except much more complicated, because the invariants are unclear and undocumented, and require great effort to tease out in a lot of cases.