Just want to first say big thanks to Mike, Mikko and Sebastian for donations, even though I kinda stopped actively contributing to the blog with new stuff. I think I gonna make another post Arma related about SQF debugging, seeing this is something that could benefit both peoples, the new and not so new to Arma.

Arma’s SQF error handling looks like something that was made in a hurry, however with a few peculiarities to remember this can be quite a usable tool. First of all, what is involved? Error reporting in retail version is limited to error logging into .rpt file. This file is usually in:

C:\Users\<user>\AppData\Local\Arma 3\xxxxxxxxxxx<datetime>xxxx.rpt

In DEV version on screen errors are enabled as well, which are almost duplicates of what is logged into .rpt. In retail version on screen errors are suppressed on purpose, however anyone can enable them by adding -showScriptErrors into startup params for the game.

I seriously encourage you to make sure you add -showScriptErrors if you are modding retail version, as the feedback is immediate and helps to save hours and hours of hair pulling. Compare on screen error with .rpt error:


17:12:20 Suspending not allowed in this context
17:12:20 Error in expression <sleep 123>
17:12:20 Error position: <sleep 123>
17:12:20 Error Generic error in expression

The .rpt errors are usually more descriptive and are useful in case of multiple errors, as on screen errors might change too quickly in case of multiple errors. In this particular case .rpt message gives a clue what kind of general error this is: “Suspending not allowed in this context”, meaning sleep command was executed in unscheduled script which by nature does not allow suspension.

There are 2 types of errors, compiling errors and runtime errors. At the beginning, a script is a string that is parsed into a code. The syntax is checked during parsing, however any variables that are in the code are not yet initialised so cannot be checked. This is why the most common error during runtime is undefined variable:

17:39:27 Error in expression <[] spawn {getPos _obj}>
17:39:27 Error position: <_obj}>
17:39:27 Error Undefined variable in expression: _obj

Note that in this example the error happened in scheduled script (spawn {}). If the same is done in unscheduled script, the error is simply not shown. This complicates debugging a little bit, so keep this in mind.

There is also no guarantee that the script will stop as soon as error is encountered. In case of undefined variables the script is almost always will continue to run after throwing error, often producing even more errors. For example:

18:03:43 Error in expression <[] spawn {getPos _obj; hint str 123}>
18:03:43 Error position: <_obj; hint str 123}>
18:03:43 Error Undefined variable in expression: _obj

The hint with 123 is shown, but in this case:

18:04:56 Error in expression <[] spawn {hint 123; hint str 345}>
18:04:56 Error position: <hint 123; hint str 345}>
18:04:56 Error hint: Type Number, expected String,Text

The script aborts after “hint 123;” so no hint is shown.

If you need to quickly check if the variable is undefined, put it inside an array and hint or diag_log it, for example hint str [_myVar] or diag_log [_myVar]. If it is undefined, you either get [any] or an error if script is scheduled.

Now a little about some more common errors and what they mean. “Error Zero divisor” can be caused by both, dividing by zero or when trying to access array element out of range:

19:11:41 Error in expression <1/0>
19:11:41 Error position: </0>
19:11:41 Error Zero divisor
19:11:51 Error in expression <[1,2,3] select 10>
19:11:51 Error position: <select 10>
19:11:51 Error Zero divisor

Type error, happens when wrong type is given:

19:15:32 Error in expression <_arr =[]; {_arr pushBack _x} count [1,2,3]>
19:15:32 Error position: <pushBack _x} count [1,2,3]>
19:15:32 Error Type Number, expected Bool

In the above example the count command expects the last statement of the scope to return either NOTHING or BOOLEAN. pushBack command returns NUMBER, which is the index of pushed element, hence the error. This is why you should always check the documentation for commands on BIKI, what command expects for params and what it returns.

Missing punctuation:

19:22:26 Error in expression <spawn {} hint "123">
19:22:26 Error position: <{} hint "123">
19:22:26 Error Missing ;

In the above case “spawn” is treated as variable and not a command because the template for spawn command is ANYTHING spawn CODE. The ANYTHING is absent, so it is not recognised as command. Adding argument to spawn fixes this:

19:22:39 Error in expression <[] spawn {} hint "123">
19:22:39 Error position: <hint "123">
19:22:39 Error Missing ;

Now there is the same error only in different place, indicating that missing semicolon should separate spawn and hint.

In conclusion a view words about “black hole” code. The code that doesn’t cause any errors and is quietly ignored without any indication whatsoever that there is a problem. Missing end curly bracket } is the first one. Trying to execute:

call {hint '123';

goes nowhere. You can have 1000 { brackets and 999 } brackets and your code will simply not run without any indication. Bohemia should definitely look into fixing this in the engine. Another case is faulty preprocessor directive:

#defnie ABC 123

will not get preprocessed, because #define is misspelt. Not only that, preprocessFile command will return empty string ” for the whole code, even if you have 1000 lines of it. Again with no indication that something went wrong. So make sure you spell all directives correctly.