---
name: "Code Best Practices"
type: topic
source: https://community.bistudio.com/wiki/Code_Best_Practices
revid: 369844
updated: 2024-10-16T13:51:56Z
---

# Code Best Practices

### Getting Started

In the domain of development, any rule is a rule of thumb.
If a rule states for example that it is better that a line of code doesn't go over 80 characters, it doesn't mean that any line ***must not*** go over 80 characters; sometimes, the situation needs it.
If you have a good structure, **do not** change your code to enforce a single arbitrary rule.
If you break many of them, you may have to change something; again, this is according to your judgement.

With that being said, let's go!

#### Prerequisites

- An advanced text editor such as Visual Studio Code or Notepad++ - see Community Tools Category for useful tools and plugins
- Some English knowledge, helped if needed by a translator tool such as [Google Translate](https://www.google.com/translate) or [DeepL](https://www.deepl.com/)
- Access to this wiki is a plus (the Swiss flag is, too)
- Tutorials/examples (YouTube tutorials, community tutorials, Example Code)
- Google-Fu (a.k.a search engine skills)
- Arma Discord server: [ARMA](https://discord.gg/arma), channel `#arma3_scripting`

### Best Practices

#### Code Format

- Whatever you do about your code's format, **be consistent**.
- Choose an indentation format **and stick to it**. There is not especially one indent better than another (*but there sure are terrible ones*), again the important point here being *consistency*.
  - Common indentation styles are:
    - [K&R style](https://en.wikipedia.org/wiki/Indentation_style#K&R_style) indenting
    - [Allman style](https://en.wikipedia.org/wiki/Indentation_style#Allman_style) indenting
  - Use empty space. Line return, spaces before and after brackets, if this improves readability, use it: space is free.
  - indent with two/four spaces **or** one tab. Do not mix these.
  - *One-lining* (putting everything in one statement) memory improvement is most of the time not worth the headache it gives when trying to read it. Don't overuse it.
- `0 = myCommand` **was** "useful" only for editor fields that for no apparent reason refused commands returning a value. You do **not** need it in script files, and don't need it in editor fields anymore **since Arma 3 v2.04**.

#### Variable Format

- Name your variables and functions properly: While [SQF](../topics/SQF_Syntax.md) *is* (non-noticeably) impacted by variable name length, this should not take precedence on the fact that code must be readable by a human being.
  - Your variable names must have a meaning: variables like **_u** instead of **_uniform** should not exist. **_i** is an accepted iteration variable name (e.g in [for](../commands/for.md) loops).
  - It is recommended to use [camel-case](https://en.wikipedia.org/wiki/Camel_case) your variables; camel-casing (namingLikeThis) your variables and functions make the code naturally more readable, especially for long names.
- Prefix your public variables and [setVariable](../commands/setVariable.md) with your tag in order to avoid any conflict about other mods, scripts or mission variables.
- Make your variables **private** thanks to the [private](../commands/private.md) or [params](../commands/params.md) keyword in order to avoid accidental upper-scope overwriting of variables of the same name.
- Defined constants must be UPPERCASE_WITH_UNDERSCORES (e.g `#define SOME_CONST`).

#### Code Structuration

- **DRY:** **D**on't **R**epeat **Y**ourself. If you write the same code block or the same logic many times, export this code as a function and use parameters with it.
  - If your code has too many levels, it is time to split and rethink it - maybe using [exitWith](../commands/exitWith.md) (e.g `if (a) then { if (b) then { if (c) then { /* etc */  }; }; };`)
  - Do NOT use [macros](../topics/PreProcessor_Commands.md#macros) as functions - these hinder readability. Use functions instead.
- `// Comments` in your code must not explain *what* the code does, but *why* it is done this way (if needed). Your code organisation combined to your variable names must be enough to be read by a human.

#### Code/Files Organisation

- Use [CfgFunctions](../topics/Functions_Library.md#adding-a-function) to declare the functions that will be called frequently.
  - One Functions directory, with sub-directories if needed.
- Use [Event Scripts](../topics/Event_Scripts.md) as needed.
- Don't put **any code** in a unit's init box *but eventually* [local](../topics/Multiplayer_Scripting.md#locality) commands for this specific unit - **all** unit's init boxes are run client-side on client connection.

### Examples

| Bad Example | Good Example |
|---|---|
| **Good Practice examples** |  |
| `_unit = player;` | `private _unit = player;` |
| `private _uB = allUnits select { side _x == blufor };` | `private _bluforUnits = allUnits select { side _x == blufor };` |
| `private _plead = leader player;` | `private _playersLeader = leader player;` |
| `finalAssault = true; publicVariable "finalAssault";` | `PREFIX_finalAssault = true; publicVariable "PREFIX_finalAssault";` |
| `player setVariable ["MoneyInPocket", 250, true];` | `player setVariable ["PREFIX_MoneyInPocket", 250, true];` |
| ```<br>#define KILL(UNIT) UNIT setDamage 1<br>// ...<br>{<br>    KILL(_x);<br>} forEach (units group player - [player]);<br>``` | ```<br>private _killFnc = { _this setDamage 1; };<br>// ...<br>{<br>    _x call _killFnc;<br>} forEach (units group player - [player]);<br>``` |
| ```<br>// if player has less than 3/4 health<br>if (damage player > 0.25) then<br>{<br>    // if the player has no first aid kit<br>    if (not ("FirstAidKit" in items player))<br>    {<br>        // if player has room for first aid kit<br>        if (player canAdd "FirstAidKit") then<br>        {<br>             // add first aid kit to the player<br>            player addItem "FirstAidKit";<br>        }<br>        else<br>        {<br>            // set player's damage to 1/4<br>            player setDamage 0.25;<br>        };<br>    };<br>};<br>``` | ```<br>// player will need health at this stage of the mission<br>if (<br>    damage player > 0.25 &&<br>    not ("FirstAidKit" in items player)) then<br>{<br>    if (player canAdd "FirstAidKit") then<br>    {<br>        player addItem "FirstAidKit";<br>    }<br>    else // let's help him anyway<br>    {<br>        player setDamage 0.25;<br>    };<br>};<br>``` |
| **Flow Logic examples** |  |
| ```<br>if (alive player && damage player >= 0.9) then {<br>    hint "very damaged";<br>};<br>if (alive player && damage player >= 0.5 && damage player < 0.9) then {<br>    hint "quite damaged";<br>};<br>if (alive player && damage player > 0 && damage player < 0.5) then {<br>    hint "slightly damaged";<br>};<br>if (alive player && damage player == 0) then {<br>    hint "pristine state";<br>};<br>if (not alive player) then {<br>    hint "dead";<br>};<br>``` | ```<br>if (not alive player) exitWith { hint "dead"; };<br>private _playerDamage = damage player;<br>switch (true) do {<br>    case (_playerDamage >= 0.9): { hint "very damaged"; };<br>    case (_playerDamage >= 0.5): { hint "quite damaged"; };<br>    case (_playerDamage > 0)   : { hint "slightly damaged"; };<br>    default { hint "pristine"; };<br>};<br>``` |
| ```<br>if (cond1) then<br>{<br>    if (cond2) then<br>    {<br>        if (cond3) then<br>        {<br>            // hadouken code<br>        }<br>        else { /* failure 3 */ };<br>    }<br>    else { /* failure 2 */ };<br>}<br>else { /* failure 1 */ };<br>``` | ```<br>if (!cond1) exitWith { /* failure 1 */ };<br>if (!cond2) exitWith { /* failure 2 */ };<br>if (!cond3) exitWith { /* failure 3 */ };<br>// code<br>``` |
| **Format examples** |  |
| ```<br>if (not alive player) exitWith <br>{ hint "dead"; };<br>private _playerDamage = damage player;<br>switch (true) do {<br>case (_playerDamage >= 0.9): {hint "very damaged";};<br>case (_playerDamage >= 0.5): {<br>    hint  "quite damaged";};<br>case (_playerDamage > 0): { hint "slightly damaged"; };<br>  default<br>{<br>   hint "pristine";<br>  };<br>};<br>``` | ```<br>if (not alive player) exitWith { hint "dead"; };<br>private _playerDamage = damage player;<br>switch (true) do {<br>    case (_playerDamage >= 0.9): { hint "very damaged"; };<br>    case (_playerDamage >= 0.5): { hint "quite damaged"; };<br>    case (_playerDamage > 0)   : { hint "slightly damaged"; };<br>    default { hint "pristine"; };<br>};<br>``` |

### Final Words

- Remember: **consistency** is the most important thing!
- The Arma Discord server and its community can help: [ARMA](https://discord.gg/arma) (channel `#arma3_scripting`)
- Learn from others's scripts but do not steal code and pretend it is yours — be a decent human being. Stealing code and its consequences:
  - It soils your reputation and devaluates your actions once it is found out — and it *always* get found out. DMCA's are filled on Steam every day.
  - It makes people in the community get less helpful and more reluctant in giving advices. It can also prevent them to *release* an interesting feature!
- Don't try to obfuscate your code: it is considered rude, especially since you learnt from others.
  - Obfuscated code only makes it *harder* to get, but does not make it *copy-protected*. If the engine can read it, it can be obtained.
  - Obfuscated code is also slower on parsing and, depending on the quality of code and obfuscation, on execution too.
- Do not hesitate to help newcomers even if you do not know the whole topic: both sides will learn from it!
- Most important of all, have fun!

### See also

- [Code Optimisation](../topics/Code_Optimisation.md)
- [Code Positivity](../topics/Code_Positivity.md)
- [Mission Optimisation](../topics/Mission_Optimisation.md)
- [Multiplayer Scripting](../topics/Multiplayer_Scripting.md)

<sub>Source: [BI Community Wiki — Code Best Practices](https://community.bistudio.com/wiki/Code_Best_Practices) (revision 369844).</sub>
