Creators can build everything from a simple configuration tweak to completely new weapons,
vehicles, factions, gameplay systems, user interfaces, missions and even entire terrains.
The difficult part for beginners is usually not writing a few lines of code. The real challenge
is understanding how Arma 3 organizes addons, how config.cpp interacts with
SQF scripts, how PBO files are built and how a finished modification is loaded,
tested and eventually distributed through Steam Workshop.
- How Arma 3 mods and PBO files are structured
- Which official modding tools you should install
- How to create your first addon
- How config.cpp and CfgPatches work
- How to create and register SQF functions
- How to test and debug an addon
- How multiplayer locality affects scripting
- How to use Addon Builder and HEMTT
- How addon signing works
- How to publish a mod to Steam Workshop
1. How Arma 3 Mods Work
An Arma 3 mod normally contains one or more addons. During development,
an addon is simply a directory containing source files.
config.cpp
SQF scripts
P3D models
PAA textures
RVMAT materials
sounds
animations
icons
stringtables
When the addon is ready for the game, those files are normally packaged inside a
.pbo file.
A finished mod can look like this:
@MyMod
│
├── addons
│ ├── mymod_main.pbo
│ ├── mymod_weapons.pbo
│ └── mymod_vehicles.pbo
│
├── keys
│ └── mymod.bikey
│
├── mod.cpp
├── logo.paa
└── README.txt
Do not install community addons directly into Arma 3’s original Addons directory.
Use separate mod folders such as
@MyMod.2. What Can You Create?
| Mod Type | Typical Files |
|---|---|
| Gameplay system | SQF + config.cpp |
| Weapon | P3D + textures + config.cpp |
| Vehicle | P3D + model.cfg + textures + config.cpp |
| Uniform | P3D + textures + config.cpp |
| Retexture | PAA + config.cpp |
| Sound mod | OGG/WSS + config.cpp |
| User interface | HPP + SQF + textures |
| Faction | config.cpp + assets |
| Mission framework | SQF + description.ext |
| Terrain | WRP + terrain data + objects |
| Animations | RTM + config |
If this is your first project, avoid beginning with a completely new vehicle or terrain.
A small configuration and SQF addon will teach the core Arma concepts much faster.
3. Essential Downloads
Arma 3 Tools
The official development toolkit supplied by Bohemia Interactive.
Visual Studio Code
A modern editor suitable for SQF, configuration and project management.
4. Understanding Arma 3 Tools
Addon Builder
Addon Builder converts your development directory into a PBO that Arma 3 can load.
It can also binarize supported content during the build process.
Object Builder
Object Builder is used to create and edit Arma-compatible 3D model files.
This becomes important when you begin creating weapons, vehicles, buildings or custom objects.
Terrain Builder
Terrain Builder is Bohemia Interactive’s official tool for creating custom Arma terrain.
Publisher
Publisher packages and uploads completed Arma 3 modifications to Steam Workshop.
TexView / ImageToPAA
These tools are useful for working with Arma’s PAA texture format.
5. Create Your First Arma 3 Addon
In this tutorial we will create a custom ammunition crate.
The crate will:
- Appear in Eden Editor
- Inherit an existing NATO ammunition box
- Use its own unique classname
- Execute a custom SQF function
- Receive predefined weapons, magazines and medical supplies
We will use this addon prefix:
prb_a3guide
Avoid generic class names such as
NewWeapon, MyCrate orSoldier1. Two mods using the same classname can conflict.A much better convention is:
YOURTAG_Project_Class
Example:
PRB_A3Guide_TrainingCrate
6. Create the Project Structure
prb_a3guide
│
├── config.cpp
│
└── functions
└── fn_initCrate.sqf
When using the traditional Arma development drive, your project could be located at:
P:\prb_a3guide\
7. Creating config.cpp
The config.cpp file is one of the most important parts of an Arma addon.
It defines dependencies, classes, functions, weapons, vehicles and many other components.
Create:
config.cpp
Then add:
class CfgPatches
{
class PRB_A3Guide
{
name = "PRB Arma 3 Modding Guide Example";
author = "Your Name";
requiredVersion = 1.0;
requiredAddons[] =
{
"A3_Weapons_F_Ammoboxes"
};
units[] =
{
"PRB_A3Guide_TrainingCrate"
};
weapons[] = {};
};
};
class CfgFunctions
{
class PRB
{
class A3Guide
{
file = "\prb_a3guide\functions";
class initCrate {};
};
};
};
class CfgVehicles
{
class Box_NATO_Ammo_F;
class PRB_A3Guide_TrainingCrate : Box_NATO_Ammo_F
{
scope = 2;
scopeCurator = 2;
displayName = "Modding Guide Training Crate";
author = "Your Name";
class EventHandlers
{
init = "(_this select 0) call PRB_fnc_initCrate";
};
};
};
8. Understanding CfgPatches
Every addon should contain a CfgPatches definition.
One of the most important properties is:
requiredAddons[]
It tells Arma which addons must already be loaded before yours.
requiredAddons[] =
{
"A3_Weapons_F_Ammoboxes"
};
Because our custom crate inherits a vanilla Arma ammunition box, its original addon
must be loaded first.
9. Understanding CfgVehicles
Despite its name, CfgVehicles contains much more than vehicles.
It can contain:
- Soldiers
- Cars
- Aircraft
- Buildings
- Objects
- Backpacks
- Ammo boxes
- Modules
Our config first references an existing Arma class:
class Box_NATO_Ammo_F;
Then we inherit from it:
class PRB_A3Guide_TrainingCrate : Box_NATO_Ammo_F
The new crate receives the behavior of the original object, while allowing us to
override selected properties.
10. scope and scopeCurator
scope = 2;
scopeCurator = 2;
These values make the class available to the appropriate game systems.
scope = 2 allows the class to be publicly available, while
scopeCurator = 2 makes it available to Zeus/Curator.
11. Registering SQF Functions
Arma provides CfgFunctions for organizing reusable scripts.
class CfgFunctions
{
class PRB
{
class A3Guide
{
file = "\prb_a3guide\functions";
class initCrate {};
};
};
};
Arma will look for:
functions\fn_initCrate.sqf
and make it available as:
PRB_fnc_initCrate
The common naming convention is:
TAG_fnc_functionName
12. Create Your First SQF Function
Create:
functions\fn_initCrate.sqf
Then add:
/*
File:
fn_initCrate.sqf
Description:
Initializes the tutorial ammunition crate.
Parameters:
0: OBJECT - Crate being initialized
Returns:
Nothing
*/
params [
["_crate", objNull, [objNull]]
];
if (isNull _crate) exitWith {};
if (!isServer) exitWith {};
clearWeaponCargoGlobal _crate;
clearMagazineCargoGlobal _crate;
clearItemCargoGlobal _crate;
clearBackpackCargoGlobal _crate;
// Weapons
_crate addWeaponCargoGlobal [
"arifle_MX_F",
2
];
// Magazines
_crate addMagazineCargoGlobal [
"30Rnd_65x39_caseless_mag",
20
];
// Medical supplies
_crate addItemCargoGlobal [
"FirstAidKit",
10
];
diag_log format [
"[PRB A3 GUIDE] Training crate initialized: %1",
_crate
];
13. Why isServer Matters
Arma multiplayer scripting is heavily affected by locality.
if (!isServer) exitWith {};
This prevents our inventory initialization from unnecessarily running on every connected machine.
Before writing networked code, always ask:
Which machine should execute this code?
Possible answers include:
- The server
- Every client
- The owning client
- A Headless Client
- Every machine
Many scripts that work perfectly in Eden Editor can fail in multiplayer because locality
was not considered.
14. Event Handlers
Our crate contains:
class EventHandlers
{
init = "(_this select 0) call PRB_fnc_initCrate";
};
When the object initializes, Arma calls our custom function and passes the crate object to it.
15. CBA_A3
Community Base Addons, commonly called CBA_A3, is one of the most important
community frameworks in Arma 3 modding.
It provides systems for:
- Extended Event Handlers
- Mod settings
- Keybindings
- Events
- Utility functions
- Scheduled execution
- Compatibility frameworks
Do not automatically add CBA as a dependency for every tiny mod. If vanilla Arma functionality
is enough, keeping dependencies minimal can be beneficial.
16. Creating mod.cpp
While the PBO defines addon content, mod.cpp describes the overall mod.
@PRB_A3_Guide
│
├── addons
│ └── prb_a3guide.pbo
│
├── mod.cpp
└── logo.paa
Example:
name = "PRB Arma 3 Modding Guide";
author = "Your Name";
tooltip = "PRB Arma 3 Modding Guide";
tooltipOwned = "PRB";
overview = "Example addon created using the Arma 3 modding guide.";
actionName = "Website";
action = "https://example.com";
hideName = 0;
hidePicture = 0;
17. Build the PBO
Launch:
Steam
→ Library
→ Tools
→ Arma 3 Tools
→ Addon Builder
Select your source directory:
P:\prb_a3guide
Choose your output directory:
Arma 3\@PRB_A3_Guide\addons
The result should be:
prb_a3guide.pbo
18. Configure the Addon Prefix
Inside Addon Builder options, set:
Addon prefix:
prb_a3guide
This must match paths used inside your config.
file = "\prb_a3guide\functions";
texture and model errors.
19. Load Your Mod
Open Arma 3 Launcher:
MODS
→ Local Mod
→ Select @PRB_A3_Guide
→ Enable Mod
Then launch Arma 3.
20. Test in Eden Editor
Open Eden Editor and choose a terrain such as Altis.
Search for:
Modding Guide Training Crate
Place:
- Your custom crate
- A playable soldier
Start the scenario and inspect the crate.
You should see:
- 2 MX rifles
- 20 6.5 mm magazines
- 10 First Aid Kits
21. Debugging Arma 3 Mods
Debugging is a major part of Arma development.
A useful startup parameter is:
-showScriptErrors
Enable script errors during development instead of allowing problems to silently remain hidden.
22. Learn to Read the RPT Log
The Arma RPT log is one of your most useful debugging tools.
You can write custom messages using:
diag_log "My addon loaded";
Or:
diag_log format [
"Player object: %1",
player
];
Using an identifiable prefix makes your messages easy to find:
[MYMOD]
23. Common Error: Undefined Variable
Example:
Error Undefined variable in expression
You may have written:
_crtae addItemCargoGlobal ["FirstAidKit",10];
instead of:
_crate addItemCargoGlobal ["FirstAidKit",10];
24. Common Error: Function Not Found
Example:
Undefined variable in expression: PRB_fnc_initCrate
Check:
- CfgFunctions
- The function filename
- The addon prefix
- The function directory
- Whether the SQF file was packed into the PBO
25. Common Error: Missing Config Entry
You may encounter something like:
No entry 'bin\config.bin/...'
Common causes include:
- Incorrect classname
- Incorrect inheritance
- Missing required addon
- Typing errors
- Incorrect config hierarchy
Use Arma’s Config Viewer to inspect existing classes rather than guessing classnames.
26. Missing Texture Errors
If Arma reports:
Cannot load texture
Check:
- Texture path
- Filename
- File extension
- PBO prefix
- Whether the texture was actually packed
27. Development with -filePatching
Arma provides:
-filePatching
for development workflows using unpacked files.
This can reduce rebuild time during certain types of development.
However, your final public release should work correctly from packaged PBO files.
28. Modern Arma Development with HEMTT
After learning the traditional workflow, serious projects should consider
HEMTT.
HEMTT provides:
- Repeatable builds
- SQF linting
- Config validation
- PBO creation
- Development builds
- Release builds
- Git integration
- Automated workflows
Install HEMTT
winget install hemtt
Update:
winget upgrade hemtt
Create a Project
hemtt new my-awesome-mod
cd my-awesome-mod
Validate the Project
hemtt check
Development Build
hemtt dev
Normal Build
hemtt build
Create a Release
hemtt release
Launch Arma
hemtt launch
29. Mikero’s Tools
Mikero’s Tools have been widely used by experienced Arma mod developers for many years.
They include utilities for areas such as:
- PBO extraction
- PBO creation
- Config processing
- Project validation
- Arma data preparation
Visit Mikero’s Tools
30. Creating a Vehicle Retexture
A basic retexture project may look like:
prb_vehicle
│
├── config.cpp
└── data
└── vehicle_co.paa
Example config:
class CfgVehicles
{
class B_MRAP_01_F;
class PRB_CustomHunter : B_MRAP_01_F
{
scope = 2;
displayName = "Custom Hunter";
hiddenSelectionsTextures[] =
{
"\prb_vehicle\data\vehicle_co.paa"
};
};
};
Always verify the original model and configuration before creating a retexture.
31. Creating New 3D Assets
A completely new Arma vehicle can require considerably more work.
A complete project may include:
P3D model
model.cfg
config.cpp
textures
RVMAT materials
Geometry LOD
Fire Geometry
View Geometry
Memory Points
Animations
Hit Points
Selections
Shadow LOD
PhysX configuration
Sounds
Weapons
Turrets
A sensible learning path is:
Config addon
↓
SQF addon
↓
Retexture
↓
Simple object
↓
Weapon
↓
Vehicle
32. Terrain Modding
Terrain creation typically involves:
- Terrain Builder
- Buldozer
- Heightmaps
- Satellite imagery
- Surface masks
- layers.cfg
- Terrain objects
- World configuration
Terrain development is a large subject on its own.
Trying to learn terrains, vehicles, modelling and SQF at the same time is usually inefficient.
33. Better SQF Project Organization
Avoid projects that look like this:
script1.sqf
newscript.sqf
test2.sqf
finalscript.sqf
finalscript2.sqf
Use functional directories:
functions
│
├── AI
│ ├── fn_spawnPatrol.sqf
│ └── fn_setCombatState.sqf
│
├── Inventory
│ ├── fn_fillCrate.sqf
│ └── fn_clearCrate.sqf
│
└── UI
├── fn_openDialog.sqf
└── fn_updateDialog.sqf
34. Use params
Instead of:
_unit = _this select 0;
_weapon = _this select 1;
_amount = _this select 2;
prefer:
params [
"_unit",
"_weapon",
"_amount"
];
You can also define default values and expected types:
params [
["_unit", objNull, [objNull]],
["_weapon", "", [""]],
["_amount", 1, [0]]
];
35. call vs spawn
Example using call:
_result = [_unit] call PRB_fnc_calculateSomething;
Example using spawn:
[_unit] spawn PRB_fnc_longProcess;
Code created using spawn runs in a scheduled environment and can use
commands such as:
sleep
Do not randomly replace call with spawn.
Understand which execution environment your function actually requires.
36. Avoid Expensive Loops
Avoid:
while {true} do
{
// expensive calculations
};
When a loop is appropriate, use reasonable delays:
while {true} do
{
// logic
sleep 1;
};
Even better, use event-driven systems whenever possible.
37. Multiplayer Testing
A mod working in singleplayer does not automatically mean that it is multiplayer safe.
Test:
- Singleplayer
- Local hosted multiplayer
- Dedicated server
- Multiple clients
- Join in progress
- Respawn
- Mission restart
- Server restart
Important concepts include:
locality
remoteExec
public variables
server authority
Join In Progress
object ownership
global commands
local commands
38. Server and Client Responsibilities
Typical server responsibilities:
- AI spawning
- Authoritative game state
- Persistence
- Objectives
- Global vehicle creation
Typical client responsibilities:
- User interfaces
- Local effects
- Camera effects
- Notifications
- Local interactions
39. Use Git
Once a project grows beyond a few files, use version control.
A repository might contain:
addons/
include/
tools/
.hemtt/
README.md
LICENSE
.gitignore
Git provides version history, rollback, collaboration, branching and proper release tracking.
MyMod-final, MyMod-final2 andMyMod-real-final. Use Git.40. Signing Your Mod
Many multiplayer servers use signatures to verify client addons.
Relevant Bohemia tools include:
DSCreateKey
DSSignFile
DSUtils
A signed mod might contain:
@MyMod
│
├── addons
│ ├── mymod.pbo
│ └── mymod.pbo.mykey.bisign
│
└── keys
└── mykey.bikey
The private signing key should remain securely stored by the developer.
41. Preparing a Release
@MyMod
│
├── addons
│ ├── mymod_main.pbo
│ ├── mymod_main.pbo.mykey.bisign
│ ├── mymod_functions.pbo
│ └── mymod_functions.pbo.mykey.bisign
│
├── keys
│ └── mykey.bikey
│
├── mod.cpp
├── logo.paa
├── README.md
└── LICENSE
Remove unnecessary development files before publishing.
42. Publishing to Steam Workshop
Open:
Arma 3 Tools
→ Publisher
Select your completed mod directory:
@MyMod
Add:
- Mod name
- Description
- Preview image
- Tags
- Visibility
- Change notes
Download the Workshop version yourself and verify that it works before making it public.
43. Workshop Dependencies
If your mod requires another mod such as:
- CBA_A3
- ACE3
- RHS
- CUP
state the dependency clearly and configure the appropriate Steam Workshop
Required Items.
44. Do Not Redistribute Other People’s Assets
Being able to extract an asset from another PBO does not automatically mean you have
permission to use it.
This applies to:
- Models
- Textures
- Sounds
- Scripts
- Animations
- Icons
- Code
Prefer:
- Your own content
- Official samples
- Openly licensed content
- Assets for which you have explicit permission
45. Recommended Learning Path
Stage 1 — Eden Editor
Units
Triggers
Waypoints
Modules
Debug Console
Stage 2 — SQF
Variables
Arrays
Hash maps
Conditions
Loops
Functions
params
Event handlers
Stage 3 — Addons
config.cpp
CfgPatches
CfgVehicles
CfgWeapons
CfgFunctions
PBO files
Prefixes
Stage 4 — Multiplayer
Locality
remoteExec
JIP
Server/client execution
Synchronization
Stage 5 — Assets
PAA
RVMAT
P3D
LODs
Selections
Animations
Materials
Stage 6 — Professional Workflow
Git
HEMTT
Automated builds
Linting
Signatures
Release management
Steam Workshop
46. Essential Arma 3 Modding Resources
Functions Library Documentation
Addon Builder Documentation
HEMTT Documentation
CBA_A3 GitHub
Mikero’s Tools Downloads
47. Release Checklist
- ☐ Arma starts without addon configuration errors.
- ☐ No recurring script errors appear in the RPT.
- ☐ Every classname has a unique project prefix.
- ☐ requiredAddons[] is correct.
- ☐ Multiplayer functionality has been tested.
- ☐ Dedicated server functionality has been tested where required.
- ☐ No unauthorized third-party content is included.
- ☐ Development-only files have been removed.
- ☐ PBO signatures are included if required.
- ☐ The private signing key is not included.
- ☐ Dependencies are documented.
- ☐ Workshop Required Items are configured.
- ☐ Version and changelog are updated.
- ☐ The Workshop-downloaded build has been tested.
Frequently Asked Questions
Is Arma 3 difficult to mod?
Arma 3 has a steeper learning curve than many games because its modding system combines SQF,
configuration classes, PBO packaging, networking and asset pipelines. Small script and config
projects, however, are relatively easy to begin with.
Do I need programming experience to create an Arma 3 mod?
Not necessarily. Basic SQF scripting can be learned while creating small projects.
More advanced multiplayer systems and frameworks benefit greatly from programming experience.
What programming language does Arma 3 use?
Gameplay scripting primarily uses SQF, while addon configuration is normally written using
Arma configuration syntax in files such as config.cpp.
Do I need Arma 3 Tools?
For many traditional modding workflows, yes. Arma 3 Tools provides utilities including Addon
Builder, Object Builder, Terrain Builder and Publisher.
What is a PBO file?
A PBO is the packaged format commonly used for Arma addon content. Configuration, scripts,
models and other resources can be stored inside it.
Should beginners use HEMTT?
It is useful to first understand the basic addon structure and PBO workflow. After that,
HEMTT is an excellent choice for larger projects because it provides repeatable builds,
validation and release automation.
Can I create Arma 3 mods without creating 3D models?
Yes. Many excellent mods consist primarily of SQF scripting and configuration changes.
Gameplay systems, AI modifications, modules and utility frameworks can be created without
building new 3D assets.
Why does my mod work in singleplayer but not multiplayer?
The most common reason is locality. Some Arma commands execute locally while others affect
multiple machines. Server ownership, clients, JIP and remote execution must be considered
when writing multiplayer systems.
Can I publish my Arma 3 mod on Steam Workshop?
Yes. Arma 3 Tools includes Publisher, which is used to upload complete modifications to
Steam Workshop.
Conclusion
Arma 3 modding can initially appear complicated because several technologies are connected
together: SQF scripting, configuration classes, PBO packaging, multiplayer locality,
models, textures, signatures and Workshop distribution.
The best strategy is to start small.
Create something
↓
Load it in Eden
↓
Run one function
↓
Build the PBO
↓
Read the RPT
↓
Find an error
↓
Fix it
↓
Add another feature
The simple ammunition crate built in this guide already teaches many of the concepts used
inside much larger Arma 3 projects:
CfgPatches
CfgVehicles
Inheritance
CfgFunctions
SQF
Event handlers
Multiplayer locality
PBO prefixes
Addon Builder
Debugging
Mod folders
Once these concepts become familiar, moving into custom weapons, vehicles, factions,
interfaces, gameplay frameworks or completely new terrains becomes significantly easier.
Arma 3 may have been released many years ago, but its modding environment remains one of
the most powerful available to PC players. The learning curve is substantial, but that same
complexity is what allows community developers to create experiences that can transform
Arma into an entirely different game.
