Script Interruption

From BISim Wiki
Jump to: navigation, search

Script interruption is a technology introduced in VBS2 2.x. Its purpose is to ensure scripts cannot decrease the overall performance to the point where it would adversely affect the simulation performed by engine. This introduces certain complexity one has to be aware of when creating scripts.

Contents

Scheduled vs. non-scheduled

The scripts most affected by this technology are ones that are time-sensitive – in a scheduled environment you cannot rely on something being executed exactly when you want it to. If you are working on a time-sensitive script it is essential you try to stick to non-scheduled environment as much as possible.

Scheduled Environment

Scheduled environment is subject to script interruption (scheduling). That means your script can be interrupted at any time, either to give the opportunity for another script to run or to allow the engine to perform other necessary tasks. The former case has also the very important implication that an event called “race condition” may occur.

Race Conditions

A race condition could occur when two or more scripts are working with one global resource (such as a global variable) at the same time. An example in SQF could be:

// Script 1
_damage = damage player;
_damage = _damage * 0.5;
player setDamage _damage;

// Script 2
player setDamage (damage player + 0.1);

Now, let’s imagine we start both scripts at the same time and player’s damage is 0.1. Since they’re both running in scheduled environment we cannot be certain in what order the commands will be executed. Based on this randomness the following outcomes are possible:

The best practice is to simply avoid such case. If this is not possible at all, you can use the noInterrupt command to act as a mutex as demonstrated in the example below. See below for further explanation of the command.

noInterrupt true; // mutex lock
_damage = damage player;
_damage = _damage * 0.5;
player setDamage _damage;
noInterrupt false; // mutex release

Non-scheduled Environment

Unlike scheduled, non-scheduled environment is not subject to the script interruption at all – your script will run until it has finished, no matter how long it takes. This has two disadvantages – you cannot use suspending commands (sleep, uiSleep and waitUntil) and the engine will stop performing other simulations while the script is being executed. That means complex scripts could very negatively impact performance. On the other hand, non-scheduled environment is ideal for anything time-critical.

Determining which environment your script is running in

There are several rules that determine whether you are working with scheduled or non-scheduled environment

Scheduled

Anything that creates a new “thread” (script) is automatically scheduled, i.e.

Non-scheduled

Code contained within the following is always non-scheduled:

Furthermore, using the call command will allow you to remain in the non-scheduled environment. Since call can be combined with compile and preprocessFile, this is what you should be using in favor of execVM whenever possible.

player execVM "doSomething.sqf"; // Bad

player call compile preprocessFile "doSomething.sqf"; // Good

Too many scripts running

The more scripts/“threads” running at one time, the more time will be taken by the script switching logic and the less time the chosen script has to run before being interrupted again. As a result, this number should be kept as low as possible, using call compile preprocessFile "script.sqf" in place of execVM "script.sqf" as demonstrated above unless it is absolutely necessary to do otherwise. You should limit the number of scripts with infinite loops checking for some conditions and see if a similar logic cannot be performed using an event handler.

noInterrupt

The noInterrupt command allows you to temporarily disable script interruption. This command should be used with caution and only when necessary as it will prevent other scripts from running and possibly negatively affect the overall performance of VBS.

-scriptInterruption

The -scriptInterruption startup parameter allows you to change the behavior of script interruption. It is not recommended to disable it permanently but it can be a useful tool when debugging problems with your scripts to narrow down the problem. You can read more about it in the manual.

Technical description

This section details the actual workings of the script interrupter within the engine. You do not need to understand it and it is here mainly for those who are curious.
All scripts placed in a queue ordered from the least recently executed to the most recently executed script. Every time the limit for processing scripts within the current frame is reached, the execution of the current script is interrupted. Upon entering the new frame a new script to execute is selected based on whether its condition allows it (the script might be sleeping or waiting for a condition). Thanks to the ordering, the least recently run script with a satisfied condition will run. If no script satisfies its condition the whole process is repeated the next frame.

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox