{"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:\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> - 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> - 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 class **CfgFunctions**\n {\n \tclass TAG\n \t{\n \t\tclass Category\n \t\t{\n \t\t\tclass functionName {};\n \t\t};\n \t};\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> - `<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 class CfgFunctions\n {\n \tclass TAG\n \t{\n \t\tclass Category\n \t\t{\n \t\t\tclass myFunction {};\n \t\t};\n \t};\n\n \tclass TAG_WeaponManagement\n \t{\n \t\t**tag** = \"TAG\"; `// the function will be named **TAG_fnc_myOtherFunction**`\n \t\tclass Category\n \t\t{\n \t\t\tclass myOtherFunction {};\n \t\t};\n \t};\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 class CfgFunctions\n {\n \tclass TAG\n \t{\n \t\tclass Category\n \t\t{\n \t\t\tclass myFunction {};\n \t\t};\n\n \t\tclass OtherCategory\n \t\t{\n \t\t\t**file** = \"My\\Category\\Path\";\n \t\t\tclass myFunction {}; `// file path will be **<ROOT>**\\My\\Category\\Path\\fn_myFunction.sqf\";`\n \t\t};\n\n \t\tclass DataCategory\n \t\t{\n \t\t\t**requiredAddons[]** = { \"A3_Data_F\" }; `// Optional requirements of CfgPatches classes. If some addons are missing, category functions will not be compiled.`\n \t\t\tclass myDataFunction {};\n \t\t};\n \t};\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> - ✓ TAG_fnc_myFunction\n> - ✗ TAG_fnc_MyFunction\n> - ✓ TAG_fnc_POWRescue\n\n class CfgFunctions\n {\n \tclass TAG\n \t{\n \t\tclass Category1\n \t\t{\n \t\t\tclass myFunction {};\n \t\t};\n\n \t\tclass Category2\n \t\t{\n \t\t\tfile = \"Path\\To\\Category\";\n \t\t\tclass myFunction\n \t\t\t{\n \t\t\t\t**file** = \"My\\Function\\Filepath.sqf\"; `// file path will be **<ROOT>**\\My\\Function\\Filepath.sqf\", ignoring \"Path\\To\\Category\"`\n \t\t\t};\n\n \t\t\tclass myFSMFunction\n \t\t\t{\n \t\t\t\t**preInit**\t\t= 1;\n \t\t\t\t**postInit**\t= 1;\n \t\t\t\t**ext**\t\t\t= \".fsm\";\n \t\t\t\t**preStart**\t= 1;\n \t\t\t\t**recompile**\t= 1;\n \t\t\t};\n \t\t};\n \t};\n };\n\n###### Attributes\n\n| Attribute | Description | Available in |  |\n|---|---|---|---|\n| 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> - 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\n\nArma 3 Editing","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:\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> - 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> - 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 class **CfgFunctions**\n {\n \tclass TAG\n \t{\n \t\tclass Category\n \t\t{\n \t\t\tclass functionName {};\n \t\t};\n \t};\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> - `<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 class CfgFunctions\n {\n \tclass TAG\n \t{\n \t\tclass Category\n \t\t{\n \t\t\tclass myFunction {};\n \t\t};\n \t};\n\n \tclass TAG_WeaponManagement\n \t{\n \t\t**tag** = \"TAG\"; `// the function will be named **TAG_fnc_myOtherFunction**`\n \t\tclass Category\n \t\t{\n \t\t\tclass myOtherFunction {};\n \t\t};\n \t};\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 class CfgFunctions\n {\n \tclass TAG\n \t{\n \t\tclass Category\n \t\t{\n \t\t\tclass myFunction {};\n \t\t};\n\n \t\tclass OtherCategory\n \t\t{\n \t\t\t**file** = \"My\\Category\\Path\";\n \t\t\tclass myFunction {}; `// file path will be **<ROOT>**\\My\\Category\\Path\\fn_myFunction.sqf\";`\n \t\t};\n\n \t\tclass DataCategory\n \t\t{\n \t\t\t**requiredAddons[]** = { \"A3_Data_F\" }; `// Optional requirements of CfgPatches classes. If some addons are missing, category functions will not be compiled.`\n \t\t\tclass myDataFunction {};\n \t\t};\n \t};\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> - ✓ TAG_fnc_myFunction\n> - ✗ TAG_fnc_MyFunction\n> - ✓ TAG_fnc_POWRescue\n\n class CfgFunctions\n {\n \tclass TAG\n \t{\n \t\tclass Category1\n \t\t{\n \t\t\tclass myFunction {};\n \t\t};\n\n \t\tclass Category2\n \t\t{\n \t\t\tfile = \"Path\\To\\Category\";\n \t\t\tclass myFunction\n \t\t\t{\n \t\t\t\t**file** = \"My\\Function\\Filepath.sqf\"; `// file path will be **<ROOT>**\\My\\Function\\Filepath.sqf\", ignoring \"Path\\To\\Category\"`\n \t\t\t};\n\n \t\t\tclass myFSMFunction\n \t\t\t{\n \t\t\t\t**preInit**\t\t= 1;\n \t\t\t\t**postInit**\t= 1;\n \t\t\t\t**ext**\t\t\t= \".fsm\";\n \t\t\t\t**preStart**\t= 1;\n \t\t\t\t**recompile**\t= 1;\n \t\t\t};\n \t\t};\n \t};\n };"},{"heading":"Attributes","level":6,"markdown":"| Attribute | Description | Available in |  |\n|---|---|---|---|\n| 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> - 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\n\nArma 3 Editing"}],"categories":["Arma 3: Editing","Functions Library"],"groups":["Scripting"]}