User Tools

Site Tools


arma:scripting

Scripting

Scripting in ArmA is changed somewhat from OFP times.

In OFP we have the SQS scripts which are read line by line, in ArmA now we have the SQF scripts which are read like a code. They are so much more powerful and easier to use once you get the idea, do not be afraid of them even if you've mastered the SQS method before but now the SQF things look strange and scary. Trust me on this, learn it and you'll be amazed how great SQF scripting is.

In a nutshell you never ever should create ArmA SQS content anymore, always create only SQF scripts.

Introduction to ArmA scripting

During mission editing and addon editing you may come across situations where actions or features you would like to have in your mission or addon cannot be accomplished using the basic (or even the more advanced) capabilities of the mission editor or within config files (in the case of addons). Some examples of this might be really cinematic cutscenes in missions or special animations for an addon.

The solution to this is to take advantage of the game-engines ability to call on an even more advanced feature known as scripting. Armed Assault's scripting language gives you more direct control of core game commands. With any combination of these scripting commands you can then create custom processes that meet the specific needs of your mission or addon.

Terms

Before getting started, you should understand the meaning of some of these terms.

Script

When speaking about a script, it is generally considered a .sqs file, the same can be said for functions, since functions are a kind of script as well, the file ends with a .sqf. Both file types can be edited as a plain text file.

Game Engine

The core program of the game which reads and executes your scripting commands at run time.

Overview

How do you run SQF script?

argument execVM filename

Example:

var = [player] execVM "test.sqf";

Argument is passed to the script as local variable _this. The Script is first searched for in the mission folder, then in the campaign scripts folder and finally in the global scripts folder.

ArmA has “” quotes for STRINGS only and {} curled braces for CODE only. Script commands doesn’t have to be in one line now with the curled braces. Command lines always end with ; instead of a ; *or* carriage return. So you can format code to be more readable

{
    if (condition) then
    {
        DoSomething1;
        DoSomething2;
        DoSomething3;
        DoSomething4;
        DoSomething5;
     };
} forEach array;

Instead of the terrible ofp classic

{if (condition) then {DoSomething1; DoSomething2; DoSomething3; DoSomething4; DoSomething5;};} foreach array;

Comments

Comments are no longer the same character as the end of command character.

// my comment
instead of
; my comment

You can use block comments now.

/*
Comment line 1
Comment line 2
Comment line 3
Comment line 4
Comment line 5
Comment line 6
*/

Quotes are no longer a valid substitute for braces.

Some SQF things

Some misc SQF things here ;)

_resultArray = [0,""];
_handle = [_resultArray] execVM "resultScript.sqf";
// script runs and changes the _resultArray that is was given
waitUntil {scriptDone _handle};
_resultInt = _resultArray select 0;
_resultString = _resultArray select 1;

And

myFunction1 = compile loadFile "myFunction1.sqf";
myFunction2 = compile preprocessFile "myFunction2.sqf";
 
call myFunction1;
[1, 2] call myFunction2;

Return value?

value = call compile preprocessFile "return.sqf";
// value is now RETURN_VALUE
 
call compile preprocessFile "return.sqf";
// valid, but RETURN_VALUE is not saved anywhere

Private

Using the private list.

private ["_t", "_p", "_yea"];

Is to make the _local variables really a private ones in the SQF script.

Exit while loop

if (condition) exitWith {Code}
 
if (_x > 5) exitWith {echo "_x is too big"; _x}

And

for "_j" from 1 to 10 do
{
	player sideChat format ["%1",_j];
	if (_j == 5) exitWith {player sideChat "5 is enough"};
};
player sideChat "Complete";

Switch

Switch is quite nice option to check many conditions at once.

Example 1

switch (_a) do
{
	case 1:
	{
		hint "1";
	};
	case 2:
	{
		hint "2";
	};
	default
	{
		hint "default";
	};
;}

Example 2

switch (_a) do
{
	case true:
	{
		hint "true";
	};
	case false:
	{
		hint "false";
	};
	default
	{
		hint "default";
	};
};

Example 3

switch (_a) do
{
	case "string1":
	{
		hint "string1";
	};
	case "string2":
	{
		hint "string2";
	};
	default
	{
		hint "default";
	};
};

Script to nil

When you have script like this

MyScript = compile preProcessFile "myScript.sqf";

When you want to unload the script, set MyScript equal to nil.

MyScript = nil;

Dynamic Variables

Dynamic variables are very cool, sometimes on those random / complex missions you want to make variables later in the mission, which you cannot specify at mission start (hardcoded).

_MyVariable = 20;
_MyVariableContent = "MyContent";
call compile format["MyDynamic_%1=_MyVariableContent",_MyVariable];

This would create: MyDynamic_20 variable with content: “MyContent”

Another example

_name = format ["mytrigger%1", triggerIndex];
call compile format ["%1 = createTrigger [....]", _name];

Misc PMC Example Scripts

Place random vehicles + some units on all found pmc_ gamelogics script, here.

Running Scripts "Live"

When you start your mission in mission editor, you can go and edit your scripts and then they are called the next time, they will be reloaded at the same time so your edits to them will be usable.

This is very nice feature to have, just run ArmA in window mode as you should always do when mission editing, then edit away and for example keep a “runme.sqf” script in the dir executed from radio alpha (or action menu) repeatedly, then you can edit the runme.sqf and add any additional script there what you want to run.

You can now run a long mission and always bring new scripts into the play and so on. Imagine how many times have you play tested a mission and had to wrote down notes that “in this and that part you need to add XYZ”, but now… you can just write a quick script (or use existing one) and add that to the runme.sqf and just call it up… script is run and you can proceed with the mission. Great.

Global Scripts Dir

Global scripts dir means that you can place your scripts under one single directory which all mission editor missions can read.

In OFP you could place a directory in your OFP root dir called “Scripts”, ie d:\ofp\scripts\ and when you ran a mission, if you called a script it would be first searched from the mission dir and if not found then in this directory. The usefulness of this is that if you have a campaign or similar where you use same script over and over again, its very cool to place it on this one “common” dir instead of each and every mission dir. In campaigns it worked from <campaign>\scripts\ the same way.

However in ArmA it appears it will not work from d:\arma\Scripts\ anymore, BIS changed it a bit and now it can be found on:

<your_profile_path>\Users\<your_nickname>\Scripts\
arma/scripting.txt · Last modified: 2011-08-15 09:30 by snakeman