One thought is to how the game is storing the local variables of functions. Since these variables are only ever initialized on script initialization, I am lead to infer that they are stored until the script is unloaded--not deallocated when the function execution is completed.
That is correct: "local" variables are only local in terms of visibility scope, not in terms of storage allocation.
Along with this, I think that each non-function event is handled (relatively) concurrently, let me know if I'm wrong.
Here are the things as far as I understand/know them:
* time slicing of the execution of behaviour scripts (and Osiris code) happens in terms of frames (I'm not entirely sure yet whether these correspond to rendered frames though)
* Every frame, every active "reaction" of every active behaviour script executes one operation/statement
* If you catch an "event" in a behaviour script, everything this event handler does is executed in the same frame. If it throws events that are caught by other items/characters, those are also executed inline in the same frame (not if the events are caught by Osiris code though, afaik), and before continuing to the next line of the original event.
I don't think the code of multiple event handlers (or the same event handler for multiple object instances) can ever execute in parallel (that would probably break a lot of scripts). However, I'm not aware of any guaranteed ordering, so in that sense they indeed run relatively concurrently.
Secondly, I could save by outsourcing each character's scripting to "control" scripts, held by a player (not story scripting, I won't even entertain the notion. Also it would break saves). This would mean that NPCs would only hold information unique to themselves, as well as some functions for interfacing with the control script.
Lastly, I could save by reviewing all global variables that I use for passing data between function calls and replace them with a set of common, reusable variables (because we cannot pass data through them implicitly. Why, we'll never know). Functions that would never impose risk of racing conditions with one-another would share variables.
Both of these approaches are indeed possible. Regarding why no implicit parameter passing for functions: my guess is that it's to avoid having to maintain a dynamic stack (and the same probably goes for why the local variables are static).