Morrowind scripting: on timers and global variables

BTB, on 30 May 2010 - 08:32 PM, said:

I just noticed this post, and I'm not exactly sure what it means.
I've seen you before, in the MPP thread, and I know that English isn't exactly your best language. But you do really seem to know what the hell you're talking about, so... yeah, if you could elaborate a bit, that would be great. I didn't write the script myself, so I'm really not entirely sure how it works.

It is just basic scripting, if you forget to reset a timer it will work the first time only...

If ( timer <= 2 )
	return
Endif
set timer to 0

 

BTB, on 30 May 2010 - 09:41 PM, said:

Sorry in advance if this is a stupid question, but wouldn't this timer reset every time the script ran anew?

No. Global scripts variables may reset (loose their values) if the global script never runs in a game session.
As this is a script autostarted on loading game end never stopped during the game session, you are running this global script each frame, so variable values are preserved, and (luckily!) you are responsible of/can rely on variable values.

A more detailed explanation on script variables from MSFD below: 

General Information: Scripts, Commands and Syntax

Types of scripts

Local scripts

Any script that is running on an object or Actor in the game (assigned in the script-dropdown field of the object or Actors object window) is a local script. Local scripts are only active if the cell is loaded – this is the current interior cell, or the current and all directly neighboring exterior cells. When the object is outside of this range the script is not running, but the local variables are saved. You cannot stop a local script using Stopscript.
 

Global scripts

Any script that is not attached to any object is a global script, and is by default not executed until you call it (see below). Note that there is no default object for a global script to work on, so objects must always be specified: while the following will work in a local script attached to an NPC:
 

AITravel 1150, 8899, 1110

You will have to specify the NPC in a global script:
 

"NPC_ID"->AITravel 1150, 8899, 1110 ;NPC_ID is the ID, the unique identifier for 
;each object in the editor


Global scripts are active all the time once they have been activated and until they are specifically terminated. Thus, once activated, they will be processed every frame as described for locals scripts above. That is why they should be used with caution, as too many, or too complicated global scripts can easily slow the game down a lot.
  The command to start a non-active script is: 

StartScript, "Script ID"

With Tribunal and Bloodmoon you also have the option to make a script start automatically with the game. In the TESCS under the menu Gameplay/Edit starting Scripts/ you can add any script to the list of automatically started scripts.

  The function to terminate a global script is: 

StopScript, "Script ID"

Variables local to a global script will be saved temporarily when the script is stopped and restarted. In order to ensure that variables are always saved, the script must be run at least once every load session. If you need to be sure the variables are reset, you should reset them yourself: don't rely on it happening automatically.

A simple way to ensure variables are saved is to use a startscript (only available with expansions); so for example the startscript might look something like this:
 

begin KeepVarsScript

if ( ScriptRunning, MyScript == 0 )
    set MyScript.KeepVars to 1
    StartScript MyScript
endif
StopScript KeepVarsScript
end

…and the script "MyScript" might look like this:

 

begin MyScript

short KeepVars
if ( KeepVars == 1 )
    set KeepVars to 0
    StopScript MyScript
    return
endif
;main body of script goes here
end

It is possible to use the StartScript function to run global scripts that are tied to an object or Actor. These are called "targeted scripts". 
"Object_ID"->StartScript "Script_ ID"
These scripts resemble both local scripts (in that the functions called always default to the object or Actor the script targets) and global scripts (in that they are always running and can be terminated with StopScript).

Note: read more on the special case of "targeted scripts" in the Tips and Tricks section.

 

 

BTB, on 30 May 2010 - 11:23 PM, said:

Ok.
Is it proper to set the timer to 0 after the timer bit, like this:
If ( timer <= 2 )
    return
Endif
set timer to 0

Or do I stick it at the very end of the script, after the abilities are added back?

It should be the same in practice, as long as the instruction is executed before calling the test If ( timer <= 2 ) again in a future frame.
I suggest resetting the variable as soon as possible though, this way, having test and reset lines near each other you visually reduce the risk to forget the reset part.