Debugging Techniques are ways for a developers to debug (narrow down/determine the root source), or to learn and understand where and why errors or unexpected outcomes are occurring within their code.
Various links about code and how to write it:
IDE and Syntax Highlight
Syntax errors are a frequent occurrence when developing scripts. Syntax highlight will help you find typos in commands and in your scripts.
An Integrated Development Environment (short IDE) is a development environment software that provides among other things code analysis, code completion and syntax highlight to help you write better, more error free code.
See further Debugging Tools page section for download links.
An error in SQF will purely and simply halt the current script, leading to unpredictable behavior. Error are not to happen as it may reduce performance as well as break a mission/feature. So if you notice an issue, address it as your script will stop.
Debugging is usually as complicated as writing the actual code itself. You usually get hinted by the game, where some error happened, and what it was.
There are instances where actual error reason might be something completely different than announced (eg. you get the error on a variable being nil somewhere, but the actual error is that you mistyped it where you set it initially).
A script error will greet you with this box:
It tells you what went wrong, shows a snippet of the code that failed and what file and line it occurred in (unless you used a command combination like eg. compile loadFile "filename";). Knowing this, you now can proceed to find the actual reason why that specific piece of code errored.
To solve an issue, you must first to became aware that of it. Aside from your script not having the desired result/effect (if any), an error message can tell you about the problem.
- Be sure to use -showScriptErrors startup parameter to display the error on-screen when it happens
- To learn about the location in your script use preprocessFileLineNumbers to preprocessFile
- Read RPT files for more information (make sure -noLogs startup parameter is not active - otherwise the log will empty)
- Scripts running on a server use the ArmaXServer.RPT file which has varying location depending upon the type of server being run.
- Scripts running on a client use the ArmaX.RPT file.
The RPT is also used by the game's engine log other type of problems (low level engine issues, or content problems for example). Hence it will dump all kinds of debug information, warnings, errors as well as encountered script errors. One can also write information to it by using commands like diag_log.
|1.00 Arma 3
|1.00 Arma 2
|1.00 Armed Assault
|1.00 Operation Flashpoint
OFP root directory
Once the script error is located: Make sure to check first the BiKi page corresponding to the command/function you are using to learn about potential misuse or other important information mentioned on the page!
The most simple thing you can do is to output expected values. This can be done using for example diag_log or systemChat. Output yourself a few variables that relate to your problem (for example: When the error occurs because you land in some if block, output the corresponding variables inside of the if). You continue doing this until you hit the actual problem: When variable A is not set, go to where variable A gets set and check around there, repeat and continue.
The same can be done for non-critical errors like when a method is "just" computing the wrong values.
|Error Undefined variable in expression: _varName
|Variable _varName has not been initialised properly in this context.
|Error x elements provided, y is expected
|A wrong number of arguments in array was provided
_unit setPos ; // setPos only takes an array of 2 to 3 elements
|Read the wiki about said command.
Use typeName to output a variable type and compare it to the command's wiki page.
|Error type x, expected y
|An ill-typed argument was provided.
hint 5; // must be String or Structured Text, Number provided
|Error Zero divisor
|Pretty self-explanatory, somewhere in the code is a division by zero.
|Also happens when using an invalid select index.
["a", "b", "c"] select 20; // index can only be 0, 1 or 2
|Local variable in global space
|An attempt to private a public variable happened
private "myVar"; // should be "_myVar"
|Error Generic error in expression
|A sleep/uiSleep/waitUntil command has been used in an unscheduled environment.
|Further code reading is required.
Working with Addons
If you are working on an addon, repacking a PBO can be time-intensive. This operation can be replaced simply by creating a basic mission in the "Missions" or "MPmissions" (if your feature is multiplayer-specific) folder of your game installation, and running the mission locally. The easiest way of accomplishing this is by the use of Event Scripts to run your code such as init.sqf. Once you have tested your code this way, you can then sequentially pack your PBO when major changes have been made, rather than for each debug session of a script or piece of code.
Debugging specific sections of code
Although primitive, the combined use of diag_log, systemChat/hint and format can help to debug the content of function arguments. In the case that specific pieces of code do not run, or if specific if conditions don't appear to fire, debugging the variable content with diag_log can be useful. As with all debugging, as long as the developer is methodical and logical in checking each section of code that runs, finding bugs and resolving them can be straightforward.