Lints - SQF
required_version
Code: L-S01
Default Severity: Error
Minimum Severity: Error
Checks for command usage that requires a newer version than specified in CfgPatches
Example
Incorrect
class CfgPatches {
class MyAddon {
units[] = {};
weapons[] = {};
requiredVersion = 2.00;
};
};
private _leaky = getWaterLeakiness vehicle player; // getWaterLeakiness requires 2.16
Check the wiki to see what in version commands were introduced.
event_insufficient_version
Code: L-S02IV
Default Severity: Error
Minimum Severity: Error
Checks for event handlers that require a newer version than specified in CfgPatches
Example
Incorrect
class CfgPatches {
class MyAddon {
units[] = {};
weapons[] = {};
requiredVersion = 2.00;
};
};
_this addEventHandler ["OpticsModeChanged", { // Requires 2.10
hint 'Optics mode changed';
}];
Check the wiki to see what in version events were introduced.
event_unknown
Code: L-S02UE
Default Severity: Warning
Minimum Severity: Warning
Checks for unknown event used in event handlers
Configuration
- ignore: List of unknown event names to ignore
[lints.sqf.event_unknown]
options.ignore = [
"HealingReceived",
]
Example
Incorrect
_this addEventHandler ["HealingReceived", { // HealingReceived is not a valid event
hint 'Healing received';
}];
Check the wiki to see what events are available.
event_incorrect_command
Code: L-S02IC
Default Severity: Error
Minimum Severity: Error
Checks for event handlers used with incorrect commands
Example
Incorrect
_this addEventHandler ["MPHit", {
hint 'Hit';
}];
Correct
_this addMPEventHandler ["MPHit", {
hint 'Hit';
}];
static_typename
Code: L-S03
Default Severity: Help
Minimum Severity: Help
Checks for typeName
on static values, which can be replaced with the string type directly
Example
Incorrect
if (typeName _myVar == typeName "") then {
hint "String";
};
Correct
if (typeName _myVar == "STRING") then {
hint "String";
};
Explanation
typeName
is a command that returns the type of a variable. When used on a constant value, it is slower than using the type directly.
command_case
Code: L-S04
Default Severity: Help
Minimum Severity: Help
Checks command usage for casing that matches the wiki
Configuration
- ignore: An array of commands to ignore
[lints.sqf.command_case]
options.ignore = [
"ASLtoAGL",
"AGLtoASL",
]
Example
Incorrect
private _leaky = getwaterleakiness vehicle player;
Correct
private _leaky = getWaterLeakiness vehicle player;
if_assign
Code: L-S05
Default Severity: Help
Minimum Severity: Help
Checks if statements that are used as assignments when select or parseNumber would be more appropriate
Example
Incorrect
private _x = if (_myVar) then {1} else {0};
Correct
private _x = parseNumber _myVar;
Incorrect
private _x = if (_myVar) then {"apple"} else {"orange"};
Correct
private _x = ["orange", "apple"] select _myVar;
Explanation
if
statements that are used as assignments and only return a static value can be replaced with the faster select
or parseNumber
commands.
find_in_str
Code: L-S06
Default Severity: Help
Minimum Severity: Help
Checks for find
commands that can be replaced with in
Example
Incorrect
if (_haystack find _needle > -1) ...
Correct
if (_needle in _haystack) ...
Explanation
The in
command is faster than find
when searching for a substring in a string.
select_parse_number
Code: L-S07
Default Severity: Help
Minimum Severity: Help
Checks for select
commands that can be replaced with parseNumber
Example
Incorrect
private _isWater = [0, 1] select (surfaceIsWater getPos player);
Correct
private _isWater = parseNumber (surfaceIsWater getPos player);
Incorrect
private _isLand = [1, 0] select (surfaceIsWater getPos player);
Correct
private _isLand = parseNumber !(surfaceIsWater getPos player);
Explanation
Using select
on an array with 0 and 1 can be replaced with parseNumber
for better performance.
format_args
Code: L-S08
Default Severity: Error
Minimum Severity: Warning
Checks for format commands with incorrect argument counts
Example
Incorrect
private _text = format ["%1", "Hello", "World"];
Correct
private _text = format ["%1", "Hello World"];
Incorrect
private _text = format ["%1 %2", "Hello World"];
Correct
private _text = format ["%1 %2", "Hello", "World"];
Explanation
The format
and formatText
commands requires the correct number of arguments to match the format string.
banned_commands
Code: L-S09
Default Severity: Error
Minimum Severity: Warning
Checks for broken or banned commands.
Configuration
- banned: Additional commands to check for
- ignore: An array of commands to ignore
[lints.sqf.banned_commands]
options.banned = [
"execVM",
]
options.ignore = [
"echo",
]
Example
Incorrect
echo "Hello World"; // Doesn't exist in the retail game
Explanation
Checks for usage of broken or banned commands.
if_not_else
Code: L-S11
Default Severity: Help (Disabled)
Minimum Severity: Help
Checks for unneeded not
Example
Incorrect
if (!alive player) then { player } else { objNull };
Correct
if (alive player) then { objNull } else { player };
!
can be removed and else
order swapped
var_all_caps
Code: L-S17
Default Severity: Help
Minimum Severity: Help
Checks for global variables that are ALL_CAPS and may actually be a undefined macro
Configuration
- ignore: An array of vars to ignore
[lints.sqf.var_all_caps]
options.ignore = [
"XMOD_TEST", "MYMOD_*",
]
Example
Incorrect
private _z = _y + DO_NOT_EXIST;
Explanation
Variables that are all caps are usually reserved for macros. This should should help prevent any accidental typos or uses before definitions when using macros. .
in_vehicle_check
Code: L-S18
Default Severity: Help
Minimum Severity: Help
Recommends using isNull objectParent X
instead of vehicle X == X
Example
Incorrect
if (vehicle player == player) then { ... };
Correct
if (isNull objectParent player) then { ... };
Explanation
Using isNull objectParent x
is faster and more reliable than vehicle x == x
for checking if a unit is currently in a vehicle.
bool_static_comparison
Code: L-S20
Default Severity: Help
Minimum Severity: Help
Checks for a variable being compared to true
or false
Example
Incorrect
if (_x == true) then {};
if (_y == false) then {};
Correct
if (_x) then {};
if (!_y) then {};
invalid_comparisons
Code: L-S21
Default Severity: Help
Minimum Severity: Help
Checks for if statements with impossible or overlapping conditions
Example
Incorrect
// This will never be true
if (_x < 20 && _x > 30) then { ... };
// If _x is less than 20, it will also be less than 10
if (_x < 20 && _x < 10) then { ... };
Explanation
This lint checks for if statements with impossible or overlapping conditions. This can be caused by typos or incorrect logic. HEMTT is not able to determine the intent of the code, so it is up to the developer to fix the condition.
this_call
Code: L-S22
Default Severity: Help (Disabled)
Minimum Severity: Help
Checks for usage of _this call
, where _this
is not necessary
Example
Incorrect
_this call _my_function;
Correct
call _my_function;
Explanation
When using call
, the called code will inherit _this
from the calling scope. This means that _this
is not necessary in the call, and can be omitted for better performance.
reasign_reserved_variable
Code: L-S23
Default Severity: Error
Minimum Severity: Error
Prevents reassigning reserved variables
Example
Incorrect
call {
_this = 1;
};
{
private _forEachIndex = random 5;
} forEach allUnits;
Explanation
Reassigning reserved variables can lead to unintentional behavior.
marker_update_spam
Code: L-S24
Default Severity: Help
Minimum Severity: Help
Checks for repeated calls to global marker updates
Example
Incorrect
"my_marker" setMarkerAlpha 0.5;
"my_marker" setMarkerDir 90;
"my_marker" setMarkerSize [100, 200];
"my_marker" setMarkerShape "RECTANGLE";
Correct
"my_marker" setMarkerAlphaLocal 0.5;
"my_marker" setMarkerDirLocal 90;
"my_marker" setMarkerSizeLocal [100, 200];
"my_marker" setMarkerShape "RECTANGLE";
Explanation
The setMarker*
commands send the entire state of the marker to all clients. This can be very expensive if done repeatedly.
Using the setMarker*Local
on all calls except the last one will reduce the amount of data sent over the network.