{"name":"Arma 3: Functions Library","title":"Arma 3: Functions Library","type":"topic","url":"https://community.bistudio.com/wiki/Arma_3:_Functions_Library","revid":379070,"updated":"2026-09-25T10:49:19Z","aliases":["Arma 3 Functions Library","CfgFunctions","Functions Library (Arma 3)"],"markdown":"Arma 3's **Functions Library** is the way to declare mission, campaign or addon's Functions. The main difference from older Function Libraries is that it runs automatically and does not require a Functions module.\n\nThe advantages of using the Functions Library over e.g execVM an SQF file are as follow:\n\n1. **Automatic compilation upon mission start** into a global variable - no need to remember direct paths to files.\n1. **Anti-hack protection** using compileFinal (see Arma 3: Writing a Function - Recompiling and BIS_fnc_recompile)\n1. **Listing in the Functions Viewer**\n1. **Advanced debugging options**\n1. **Optional immediate execution upon mission start**, without need for manual call\n1. **Potential performance improvements**\n\n> [!IMPORTANT]\n> This page is about Arma 3 Functions Library.\n>\n> - For Arma 2/Arma 2:OA, see Arma 2: Functions Library.\n> - For Take On Helicopters, see Take On Helicopters: Functions Library.\n\n### Function Declaration\n\nFunctions are configured within the `CfgFunctions` class.\n\nMission and campaign specific functions can be configured in Description.ext/Campaign Description.ext, while addon functions are defined in Config.cpp.\nConfiguration structure is the same in both cases.\n\n> [!NOTE]\n> The root directory (noted as **<ROOT>** on this page) is the origin from which the game will try to load function files. It depends on `CfgFunctions`' location:\n>\n> - if Description.ext, **<ROOT>** means the mission's root directory\n> - if Campaign Description.ext, **<ROOT>** means the campaign's root directory\n> - if in config, **<ROOT>** means the **game**'s root directory. The addon path needs to be set manually.\n\nSee a basic example config:\n\n```\nclass CfgFunctions\n{\n    class TAG\n    {\n        class Category\n        {\n            class functionName {};\n        };\n    };\n};\n```\n\n- The function's name will be **TAG**_fnc_**functionName**\n- The function will be loaded:\n  - from config: `<ROOT>\\Category\\fn_functionName.sqf`\n  - from description.ext: `<ROOT>\\functions\\Category\\fn_functionName.sqf`\n\n> [!IMPORTANT]\n> **config.cpp only**:\n>\n> - `<ROOT>` in mods is defined by the `file` mandatory attribute - see the file section below.\n> - Anywhere outside of running mission, refer to the functions stored in uiNamespace. e.g:\n>\n>   ```sqf\n>   arguments call (uiNamespace getVariable \"TAG_fnc_functionName\");\n>   ```\n\n#### Config Levels\n\nA **CfgFunctions** config is made of three levels: Tag, Category, and Function.\n\n##### Tag\n\nTo prevent duplicates, every author must create a subclass with a unique tag and create functions under it.\nThe tag name will be used when composing a function name (e.g **BIS**_fnc_spawnGroup).\n\n```\nclass CfgFunctions\n{\n    class TAG\n    {\n        class Category\n        {\n            class myFunction {};\n        };\n    };\n\n    class TAG_WeaponManagement\n    {\n        tag = \"TAG\"; // the function will be named TAG_fnc_myOtherFunction\n        class Category\n        {\n            class myOtherFunction {};\n        };\n    };\n};\n```\n\n###### Attributes\n\n###### tag\n\nThe `tag` attribute can override the config tag set differently.\n\n##### Category\n\nThe category name changes the function's category in the Functions Viewer. It does not change the function's name, only the loading path.\n\n```\nclass CfgFunctions\n{\n    class TAG\n    {\n        class Category\n        {\n            class myFunction {};\n        };\n\n        class OtherCategory\n        {\n            file = \"My\\Category\\Path\";\n            class myFunction {}; // file path will be <ROOT>\\My\\Category\\Path\\fn_myFunction.sqf\";\n        };\n\n        class DataCategory\n        {\n            requiredAddons[] = { \"A3_Data_F\" }; // Optional requirements of CfgPatches classes. If some addons are missing, category functions will not be compiled.\n            class myDataFunction {};\n        };\n    };\n};\n```\n\n###### Attributes\n\n###### file\n\nThe `file` attribute can override the category's loading path segment - it is required for mods.\n\n###### requiredAddons\n\nThe category can skip loading if a required addon is missing by setting its dependency with the `requiredAddons` attribute.\n\n##### Function\n\n> [!NOTE]\n> By convention, the function class should be named in **camelCase** and not have its first letter capitalised (e.g PascalCase):\n>\n> - ✓ TAG_fnc_myFunction\n> - ✗ TAG_fnc_MyFunction\n> - ✓ TAG_fnc_POWRescue\n\n```\nclass CfgFunctions\n{\n    class TAG\n    {\n        class Category1\n        {\n            class myFunction {};\n        };\n\n        class Category2\n        {\n            file = \"Path\\To\\Category\";\n            class myFunction\n            {\n                file = \"My\\Function\\Filepath.sqf\"; // file path will be <ROOT>\\My\\Function\\Filepath.sqf\", ignoring \"Path\\To\\Category\"\n            };\n\n            class myFSMFunction\n            {\n                preInit        = 1;\n                postInit    = 1;\n                ext            = \".fsm\";\n                preStart    = 1;\n                recompile    = 1;\n            };\n        };\n    };\n};\n```\n\n###### Attributes\n\n| Attribute | Description | Available in |  |\n|---|---|---|---|\n| Attribute | Description | Description.ext | config.cpp |\n| file | the `file` attribute can be used to manually set the file path.<br>> [!IMPORTANT]<br>> The **file** entry **overrides** Category's set path and ignores it entirely (they are not merged). | ✓ | ✓ |\n| preInit | the `preInit` attribute (formerly known as \"forced\") can be set to 1 to call the function upon mission start, before objects are initialized.<br>Passed arguments are `[\"preInit\"]`.<br>The function is run in an **unscheduled environment**. | ✓ | ✓ |\n| postInit | the `postInit` attribute can be set to 1 to call the function upon mission start, after objects are initialized.<br>Passed arguments are `[\"postInit\", didJIP]`.<br>The function is run in a **scheduled environment** so suspension is allowed, but **any long term suspension will halt the mission loading until suspension is done**. | ✓ | ✓ |\n| ext | the `ext` attribute can be used to set function file's type; it can be one of:<br>- \".sqf\" (default)<br>- \".fsm\" (see FSM) | ✓ | ✓ |\n| preStart | the `preStart` attribute can be set to 1 to call the function upon game start, before title screen, but after all addons are loaded. | ✗ | ✓ |\n| recompile | the `recompile` attribute can be set to 1 to recompile the function upon mission start (functions in Description.ext are always compiled upon mission (re)start) | ✗ | ✓ |\n| headerType | the `headerType` adds code to the beginning of functions that can:<br>- Set up the Meta Variables _fnc_scriptParent and _fnc_scriptName<br>- Name the current scope via the command scriptName<br>- Adds debug information by saving the current execution order in the Array _fnc_scriptMap.<br>Possible values are:<br>- -1: No header - Adds nothing, literally adds a blank String to the beginning of functions. The functions will have no debug or Meta Variables assigned for it and the scope will not be named. Useful to reduce the performance overhead or if custom debug system is used.<br>- 0: Default header - The default header changes based on the current Debug Mode<br>- 1: System header - Incorporates the Meta Variables _fnc_scriptParent. Also names the current scope.<br>  ```sqf<br>  private _fnc_scriptNameParent = if (isNil '_fnc_scriptName') then { '%1' } else { _fnc_scriptName };<br>  scriptName '%1';<br>  ```<br>See the following section for more information. | ✓ | ✓ |\n\n> [!IMPORTANT]\n> Notes about `preInit` and `postInit` defined in **config.cpp**:\n>\n> - these attributes will make the function run **on each, every and any mission start**\n> - Any scripting error will prevent the mission from being loaded correctly\n> - Server admins might blacklist the whole addon if they find out the function is used for hacking\n\n### Advanced Knowledge\n\n#### Meta Variables\n\n- **_fnc_scriptName**: String - Name of the script\n- **_fnc_scriptNameParent**: String - Name of the parent script\n- **_fnc_scriptMap**: Array - List of all parent scripts\n\n#### Debug Modes\n\nDevelopers can access several debug modes using *BIS_fnc_functionsDebug* function. **For this to work function recompiling has to be allowed!**\n\n##### Debug Mode 0\n\ndefault - incorporates the Meta Variables _fnc_scriptParent and _fnc_scriptName and names the current scope.\n\n```sqf\nprivate _fnc_scriptNameParent = if (isNil \"_fnc_scriptName\") then { \"%1\" } else { _fnc_scriptName };\nprivate _fnc_scriptName = \"%1\";\nscriptName _fnc_scriptName;\n```\n\n##### Debug Mode 1\n\nAs per *Debug Mode 0* and also saves the current execution order in the Array _fnc_scriptMap.\n\n```sqf\nprivate _fnc_scriptNameParent = if (isNil \"_fnc_scriptName\") then { \"%1\" } else { _fnc_scriptName };\nprivate _fnc_scriptName = \"%1\";\nscriptName _fnc_scriptName;\nprivate _fnc_scriptMap = if (isNil \"_fnc_scriptMap\") then { [_fnc_scriptName] } else { _fnc_scriptMap + [_fnc_scriptName] };\n```\n\n##### Debug Mode 2\n\nAs per *Debug Mode 1* and also outputs execution order using textLogFormat ( textLogFormat is not available in the retail version of Arma3 ) is it available in Diagnostics exe?\n\n```sqf\nprivate _fnc_scriptNameParent = if (isNil \"_fnc_scriptName\") then { \"%1\" } else { _fnc_scriptName };\nprivate _fnc_scriptName = \"%1\";\nscriptName _fnc_scriptName;\nprivate _fnc_scriptMap = if (isNil \"_fnc_scriptMap\") then { [_fnc_scriptName] } else { _fnc_scriptMap + [_fnc_scriptName] };\ntextLogFormat [\"%1 : %2\", _fnc_scriptMap joinString \" >> \", _this];\n```\n\n### See Also\n\n- Initialisation Order\n- Arma 3: Functions Viewer\n- Arma 3 Functions\n- Writing a Function Tutorial","sections":[{"heading":null,"level":1,"markdown":"Arma 3's **Functions Library** is the way to declare mission, campaign or addon's Functions. The main difference from older Function Libraries is that it runs automatically and does not require a Functions module.\n\nThe advantages of using the Functions Library over e.g execVM an SQF file are as follow:\n\n1. **Automatic compilation upon mission start** into a global variable - no need to remember direct paths to files.\n1. **Anti-hack protection** using compileFinal (see Arma 3: Writing a Function - Recompiling and BIS_fnc_recompile)\n1. **Listing in the Functions Viewer**\n1. **Advanced debugging options**\n1. **Optional immediate execution upon mission start**, without need for manual call\n1. **Potential performance improvements**\n\n> [!IMPORTANT]\n> This page is about Arma 3 Functions Library.\n>\n> - For Arma 2/Arma 2:OA, see Arma 2: Functions Library.\n> - For Take On Helicopters, see Take On Helicopters: Functions Library."},{"heading":"Function Declaration","level":3,"markdown":"Functions are configured within the `CfgFunctions` class.\n\nMission and campaign specific functions can be configured in Description.ext/Campaign Description.ext, while addon functions are defined in Config.cpp.\nConfiguration structure is the same in both cases.\n\n> [!NOTE]\n> The root directory (noted as **<ROOT>** on this page) is the origin from which the game will try to load function files. It depends on `CfgFunctions`' location:\n>\n> - if Description.ext, **<ROOT>** means the mission's root directory\n> - if Campaign Description.ext, **<ROOT>** means the campaign's root directory\n> - if in config, **<ROOT>** means the **game**'s root directory. The addon path needs to be set manually.\n\nSee a basic example config:\n\n```\nclass CfgFunctions\n{\n    class TAG\n    {\n        class Category\n        {\n            class functionName {};\n        };\n    };\n};\n```\n\n- The function's name will be **TAG**_fnc_**functionName**\n- The function will be loaded:\n  - from config: `<ROOT>\\Category\\fn_functionName.sqf`\n  - from description.ext: `<ROOT>\\functions\\Category\\fn_functionName.sqf`\n\n> [!IMPORTANT]\n> **config.cpp only**:\n>\n> - `<ROOT>` in mods is defined by the `file` mandatory attribute - see the file section below.\n> - Anywhere outside of running mission, refer to the functions stored in uiNamespace. e.g:\n>\n>   ```sqf\n>   arguments call (uiNamespace getVariable \"TAG_fnc_functionName\");\n>   ```"},{"heading":"Config Levels","level":4,"markdown":"A **CfgFunctions** config is made of three levels: Tag, Category, and Function."},{"heading":"Tag","level":5,"markdown":"To prevent duplicates, every author must create a subclass with a unique tag and create functions under it.\nThe tag name will be used when composing a function name (e.g **BIS**_fnc_spawnGroup).\n\n```\nclass CfgFunctions\n{\n    class TAG\n    {\n        class Category\n        {\n            class myFunction {};\n        };\n    };\n\n    class TAG_WeaponManagement\n    {\n        tag = \"TAG\"; // the function will be named TAG_fnc_myOtherFunction\n        class Category\n        {\n            class myOtherFunction {};\n        };\n    };\n};\n```"},{"heading":"Attributes","level":6,"markdown":""},{"heading":"tag","level":6,"markdown":"The `tag` attribute can override the config tag set differently."},{"heading":"Category","level":5,"markdown":"The category name changes the function's category in the Functions Viewer. It does not change the function's name, only the loading path.\n\n```\nclass CfgFunctions\n{\n    class TAG\n    {\n        class Category\n        {\n            class myFunction {};\n        };\n\n        class OtherCategory\n        {\n            file = \"My\\Category\\Path\";\n            class myFunction {}; // file path will be <ROOT>\\My\\Category\\Path\\fn_myFunction.sqf\";\n        };\n\n        class DataCategory\n        {\n            requiredAddons[] = { \"A3_Data_F\" }; // Optional requirements of CfgPatches classes. If some addons are missing, category functions will not be compiled.\n            class myDataFunction {};\n        };\n    };\n};\n```"},{"heading":"Attributes","level":6,"markdown":""},{"heading":"file","level":6,"markdown":"The `file` attribute can override the category's loading path segment - it is required for mods."},{"heading":"requiredAddons","level":6,"markdown":"The category can skip loading if a required addon is missing by setting its dependency with the `requiredAddons` attribute."},{"heading":"Function","level":5,"markdown":"> [!NOTE]\n> By convention, the function class should be named in **camelCase** and not have its first letter capitalised (e.g PascalCase):\n>\n> - ✓ TAG_fnc_myFunction\n> - ✗ TAG_fnc_MyFunction\n> - ✓ TAG_fnc_POWRescue\n\n```\nclass CfgFunctions\n{\n    class TAG\n    {\n        class Category1\n        {\n            class myFunction {};\n        };\n\n        class Category2\n        {\n            file = \"Path\\To\\Category\";\n            class myFunction\n            {\n                file = \"My\\Function\\Filepath.sqf\"; // file path will be <ROOT>\\My\\Function\\Filepath.sqf\", ignoring \"Path\\To\\Category\"\n            };\n\n            class myFSMFunction\n            {\n                preInit        = 1;\n                postInit    = 1;\n                ext            = \".fsm\";\n                preStart    = 1;\n                recompile    = 1;\n            };\n        };\n    };\n};\n```"},{"heading":"Attributes","level":6,"markdown":"| Attribute | Description | Available in |  |\n|---|---|---|---|\n| Attribute | Description | Description.ext | config.cpp |\n| file | the `file` attribute can be used to manually set the file path.<br>> [!IMPORTANT]<br>> The **file** entry **overrides** Category's set path and ignores it entirely (they are not merged). | ✓ | ✓ |\n| preInit | the `preInit` attribute (formerly known as \"forced\") can be set to 1 to call the function upon mission start, before objects are initialized.<br>Passed arguments are `[\"preInit\"]`.<br>The function is run in an **unscheduled environment**. | ✓ | ✓ |\n| postInit | the `postInit` attribute can be set to 1 to call the function upon mission start, after objects are initialized.<br>Passed arguments are `[\"postInit\", didJIP]`.<br>The function is run in a **scheduled environment** so suspension is allowed, but **any long term suspension will halt the mission loading until suspension is done**. | ✓ | ✓ |\n| ext | the `ext` attribute can be used to set function file's type; it can be one of:<br>- \".sqf\" (default)<br>- \".fsm\" (see FSM) | ✓ | ✓ |\n| preStart | the `preStart` attribute can be set to 1 to call the function upon game start, before title screen, but after all addons are loaded. | ✗ | ✓ |\n| recompile | the `recompile` attribute can be set to 1 to recompile the function upon mission start (functions in Description.ext are always compiled upon mission (re)start) | ✗ | ✓ |\n| headerType | the `headerType` adds code to the beginning of functions that can:<br>- Set up the Meta Variables _fnc_scriptParent and _fnc_scriptName<br>- Name the current scope via the command scriptName<br>- Adds debug information by saving the current execution order in the Array _fnc_scriptMap.<br>Possible values are:<br>- -1: No header - Adds nothing, literally adds a blank String to the beginning of functions. The functions will have no debug or Meta Variables assigned for it and the scope will not be named. Useful to reduce the performance overhead or if custom debug system is used.<br>- 0: Default header - The default header changes based on the current Debug Mode<br>- 1: System header - Incorporates the Meta Variables _fnc_scriptParent. Also names the current scope.<br>  ```sqf<br>  private _fnc_scriptNameParent = if (isNil '_fnc_scriptName') then { '%1' } else { _fnc_scriptName };<br>  scriptName '%1';<br>  ```<br>See the following section for more information. | ✓ | ✓ |\n\n> [!IMPORTANT]\n> Notes about `preInit` and `postInit` defined in **config.cpp**:\n>\n> - these attributes will make the function run **on each, every and any mission start**\n> - Any scripting error will prevent the mission from being loaded correctly\n> - Server admins might blacklist the whole addon if they find out the function is used for hacking"},{"heading":"Advanced Knowledge","level":3,"markdown":""},{"heading":"Meta Variables","level":4,"markdown":"- **_fnc_scriptName**: String - Name of the script\n- **_fnc_scriptNameParent**: String - Name of the parent script\n- **_fnc_scriptMap**: Array - List of all parent scripts"},{"heading":"Debug Modes","level":4,"markdown":"Developers can access several debug modes using *BIS_fnc_functionsDebug* function. **For this to work function recompiling has to be allowed!**"},{"heading":"Debug Mode 0","level":5,"markdown":"default - incorporates the Meta Variables _fnc_scriptParent and _fnc_scriptName and names the current scope.\n\n```sqf\nprivate _fnc_scriptNameParent = if (isNil \"_fnc_scriptName\") then { \"%1\" } else { _fnc_scriptName };\nprivate _fnc_scriptName = \"%1\";\nscriptName _fnc_scriptName;\n```"},{"heading":"Debug Mode 1","level":5,"markdown":"As per *Debug Mode 0* and also saves the current execution order in the Array _fnc_scriptMap.\n\n```sqf\nprivate _fnc_scriptNameParent = if (isNil \"_fnc_scriptName\") then { \"%1\" } else { _fnc_scriptName };\nprivate _fnc_scriptName = \"%1\";\nscriptName _fnc_scriptName;\nprivate _fnc_scriptMap = if (isNil \"_fnc_scriptMap\") then { [_fnc_scriptName] } else { _fnc_scriptMap + [_fnc_scriptName] };\n```"},{"heading":"Debug Mode 2","level":5,"markdown":"As per *Debug Mode 1* and also outputs execution order using textLogFormat ( textLogFormat is not available in the retail version of Arma3 ) is it available in Diagnostics exe?\n\n```sqf\nprivate _fnc_scriptNameParent = if (isNil \"_fnc_scriptName\") then { \"%1\" } else { _fnc_scriptName };\nprivate _fnc_scriptName = \"%1\";\nscriptName _fnc_scriptName;\nprivate _fnc_scriptMap = if (isNil \"_fnc_scriptMap\") then { [_fnc_scriptName] } else { _fnc_scriptMap + [_fnc_scriptName] };\ntextLogFormat [\"%1 : %2\", _fnc_scriptMap joinString \" >> \", _this];\n```"},{"heading":"See Also","level":3,"markdown":"- Initialisation Order\n- Arma 3: Functions Viewer\n- Arma 3 Functions\n- Writing a Function Tutorial"}],"categories":["Arma 3: Editing","Functions Library"],"groups":["Scripting"]}