Variables: Difference between revisions
SilentKiller (talk | contribs) (Added deallocation info as Dedboomer reported) |
Lou Montana (talk | contribs) (Informative box for local variable deallocation) |
||
Line 25: | Line 25: | ||
== Deletion == | == Deletion == | ||
Once created, variables will take up space in the computer's memory. This is not drastic for small variables, but if a big number of very large variables is used, some unneeded | Once created, variables will take up space in the computer's memory. This is not drastic for small variables, but if a big number of very large variables is used, some unneeded ones should be undefined in order to free up memory. This can be done by setting their value to [[nil]]. | ||
hugeVariable = nil; | hugeVariable = nil; | ||
Line 31: | Line 31: | ||
This effectively destroys a variable as if it had never existed. | This effectively destroys a variable as if it had never existed. | ||
{{Informative | Local variables are automatically freed (deleted from memory) when their scope is exited, avoiding the need to manually deallocate them.}} | |||
== Scopes == | == Scopes == | ||
Line 46: | Line 46: | ||
; public | ; public | ||
: A variable is broadcasted over the network and visible on all computers connected to the network. | : A global variable is broadcasted over the network and visible on all computers connected to the network. | ||
=== Local Variables === | === Local Variables === | ||
Line 56: | Line 56: | ||
_myLocalVariable = 0; | _myLocalVariable = 0; | ||
In functions you should additionally mark variables as private using the command [[private]]. Otherwise you may modify local variables of the | In [[Arma 3 Functions Library|functions]] you should additionally mark variables as private using the command [[private]]. Otherwise, you may modify local variables of the [[call]]ing script that are visible in the function. | ||
{{cc|Since {{arma3}} v1.54}} | |||
[[private]] _myLocalVariable = 0; | [[private]] _myLocalVariable = 0; | ||
{{cc|Before {{arma3}} v1.54}} | |||
[[private]] "_myLocalVariable"; | |||
_myLocalVariable = 0; | |||
{{cc|Alternative method to private multiple local variables at the same time}} | |||
[[private]] ["_myLocalVariable1", "_myLocalVariable2", (...)]; | |||
_myLocalVariable1 = 1; | |||
_myLocalVariable2 = 2; | |||
(...) | |||
=== Global Variables === | === Global Variables === | ||
Line 69: | Line 76: | ||
Global variables are visible on the whole computer where they are defined. Names given to units in the [[Mission Editor]] are also global variables pointing to those units, which may not be redefined or modified. | Global variables are visible on the whole computer where they are defined. Names given to units in the [[Mission Editor]] are also global variables pointing to those units, which may not be redefined or modified. | ||
[[Identifier]]s of global variables ''must not'' start with underscore. | [[Identifier]]s of global variables ''must not'' start with underscore. Besides this, they use the same rules as for all [[Identifier|identifiers]]. | ||
myGlobalVariable = 0; | myGlobalVariable = 0; | ||
=== Public Variables === | === Public Variables === | ||
Line 79: | Line 86: | ||
The value of a global variable gets broadcasted over the network using [[publicVariable]]. After the call of this command the variable will have the same value on all [[Client|clients]]. Once you modify the variable though you have to broadcast it manually ''again'' with [[publicVariable]]. | The value of a global variable gets broadcasted over the network using [[publicVariable]]. After the call of this command the variable will have the same value on all [[Client|clients]]. Once you modify the variable though you have to broadcast it manually ''again'' with [[publicVariable]]. | ||
== More | |||
== More information relative to private variable == | |||
If a private variable is initialized within a [[Control Structures]] (i.e. [[if]], [[for]], [[switch]], [[while]]) its scope will stay ''within'' this structure (i.e. outside of the structure it will still be seen as undefined). | If a private variable is initialized within a [[Control Structures]] (i.e. [[if]], [[for]], [[switch]], [[while]]) its scope will stay ''within'' this structure (i.e. outside of the structure it will still be seen as undefined). | ||
Line 97: | Line 106: | ||
Returns [[true]] since the variable was initialized before the [[if]]..[[then]] statement.<br> | Returns [[true]] since the variable was initialized before the [[if]]..[[then]] statement.<br> | ||
To initialize private variables so that they are available throughout the whole script (including any control structures), initialize it via the [[private]] command (e.g. {{Inline code | [[private]] _varname;}}) at the beginning of the script. | To initialize private variables so that they are available throughout the whole script (including any control structures), initialize it via the [[private]] command (e.g. {{Inline code | [[private]] _varname;}}) at the beginning of the script. | ||
== Data Types == | == Data Types == | ||
Line 103: | Line 113: | ||
Read the article [[Data Types]] for more information about variable types. | Read the article [[Data Types]] for more information about variable types. | ||
== Multiplayer Considerations == | == Multiplayer Considerations == | ||
Storing functions ( or any callable code) into global variables without securing them with [[compileFinal]] (since {{arma3}}) is a '''very''' bad practice in multiplayer. The biggest security risk would be to see it being overriden by a malicious usage of [[publicVariable]], setting potentially dangerous code in it. | |||
The best option is to declare your function in [[Arma 3 Functions Library|CfgFunctions]] so the engine secures it for you. | |||
If you want to manually create a global function, the best practice is the following: | |||
myGlobalVarFunction = [[compileFinal]] [[preprocessFileLineNumbers]] "functions\directory\functionsFile.sqf"; | |||
Line 120: | Line 131: | ||
* [[Data Types]] | * [[Data Types]] | ||
* [[Magic Variables]] | * [[Magic Variables]] | ||
* [[private]] ({{arma3}}) | |||
* [[local]] ({{arma2}}) | |||
[[Category: Scripting Topics]] | [[Category: Scripting Topics]] |
Revision as of 17:28, 7 April 2020
A variable is a "storage container" or "named placeholder" for data. You can read and modify the data once this container is created.
Requirements
The following links guide to the basics to understand this article:
Initialization
The first thing to do to create a variable is to find its name, also called identifier; this name must be speaking to the reader. Once you find a proper name, you have to tell the game engine that you are going to use this identifier. This is called initialization or declaration. This is how it is done:
myVariable = 0;
Before Arma 2, querying undefined (or uninitialized) variables returns nil (undefined value); from Arma 2 and later, it returns an "Error Undefined variable in expression" error.
Deletion
Once created, variables will take up space in the computer's memory. This is not drastic for small variables, but if a big number of very large variables is used, some unneeded ones should be undefined in order to free up memory. This can be done by setting their value to nil.
hugeVariable = nil;
This effectively destroys a variable as if it had never existed.
Scopes
Variables are only visible in certain scopes of the game. This prevents name conflicts between different variables in different scripts.
There are three scopes:
- local
- A variable is only visible in the script, or function, or Control Structures in which it was defined.
- global
- A variable is visible on the whole computer where it was defined.
- public
- A global variable is broadcasted over the network and visible on all computers connected to the network.
Local Variables
Local variables are only visible in a specific script, or function, or Control Structures.
The identifier of local variables in a script always has to started with an underscore.
_myLocalVariable = 0;
In functions you should additionally mark variables as private using the command private. Otherwise, you may modify local variables of the calling script that are visible in the function.
// Since Arma 3 v1.54 private _myLocalVariable = 0; // Before Arma 3 v1.54 private "_myLocalVariable"; _myLocalVariable = 0; // Alternative method to private multiple local variables at the same time private ["_myLocalVariable1", "_myLocalVariable2", (...)]; _myLocalVariable1 = 1; _myLocalVariable2 = 2; (...)
Global Variables
Global variables are visible on the whole computer where they are defined. Names given to units in the Mission Editor are also global variables pointing to those units, which may not be redefined or modified.
Identifiers of global variables must not start with underscore. Besides this, they use the same rules as for all identifiers.
myGlobalVariable = 0;
Public Variables
Public variables are global variables, visible on several computers in the network. You can never have true public variables, but you can emulate their behaviour.
The value of a global variable gets broadcasted over the network using publicVariable. After the call of this command the variable will have the same value on all clients. Once you modify the variable though you have to broadcast it manually again with publicVariable.
More information relative to private variable
If a private variable is initialized within a Control Structures (i.e. if, for, switch, while) its scope will stay within this structure (i.e. outside of the structure it will still be seen as undefined).
if (alive player) then
{
private _living = true;
};
hint format ["%1", _living];
Returns an error, since the private variable was not initialized before being used within a control structure.
private _living = false;
if (alive player) then
{
_living = true;
};
hint format ["%1", _living];
Returns true since the variable was initialized before the if..then statement.
To initialize private variables so that they are available throughout the whole script (including any control structures), initialize it via the private command (e.g. private _varname;
) at the beginning of the script.
Data Types
Variables may store certain values. The kind of the value specifies the type of the variable. Different operators and commands require variables to be of different types.
Read the article Data Types for more information about variable types.
Multiplayer Considerations
Storing functions ( or any callable code) into global variables without securing them with compileFinal (since Arma 3) is a very bad practice in multiplayer. The biggest security risk would be to see it being overriden by a malicious usage of publicVariable, setting potentially dangerous code in it.
The best option is to declare your function in CfgFunctions so the engine secures it for you.
If you want to manually create a global function, the best practice is the following:
myGlobalVarFunction = compileFinal preprocessFileLineNumbers "functions\directory\functionsFile.sqf";
See also
- Introduction to Arma Scripting
- Identifier
- Data Types
- Magic Variables
- private (Arma 3)
- local (Arma 2)