RE:NODE
Browse hosting

Guides13 min read

Arma 3 server.cfg, basic.cfg, missions and headless clients

Every Arma 3 server.cfg setting worth changing, what basic.cfg really does, mission rotation and difficulty, admin commands, and setting up a headless client.

0 readers

An Arma 3 server is configured by two files with confusingly similar names and one command-line flag each. server.cfg, passed with -config=, holds everything about the server as a thing people join: its name, its passwords, its admins, its mission rotation, its security settings. basic.cfg, passed with -cfg=, holds a handful of network tuning values that almost nobody needs to change. Difficulty is in neither of them - it moved into the server profile years ago and that is still the most common reason a setting refuses to stick.

This guide goes through both files key by key, then mission rotation, the admin commands, and the headless client, which is the single largest performance gain available to a mission with a lot of AI and also the one most often set up incorrectly. For mod loading, keys and signatures, see an Arma 3 server and the mod list that will not load.

Starting the server: the command line and the ports#

A complete Linux start line looks like this:

bash
$ ./arma3server_x64 -port=2302 \    -config=cfg/server.cfg \    -cfg=cfg/basic.cfg \    -profiles=profiles -name=server \    -mod="@cba_a3;@ace" -serverMod="@server_only" \    -world=empty -autoInit -filePatching

The parts that matter:

  • `-config=` is server.cfg and `-cfg=` is basic.cfg. They are the wrong way round from what anyone would guess, and swapping them produces a server that starts, ignores your settings and tells you nothing.
  • `-profiles=` and `-name=` decide where the server profile is written. Everything about difficulty lives in a file under that directory, named after -name.
  • `-world=empty` stops the server loading Altis at startup. It saves memory and start-up time and there is no reason not to use it.
  • `-mod=` is the list clients must also have. `-serverMod=` is loaded by the server alone, for things like server-side anti-cheat or a logging mod. Putting a server-only mod in -mod= forces every player to download it for nothing.
  • `-autoInit` starts the mission without waiting for a player, and needs persistent = 1 in server.cfg to be useful.
  • `-filePatching` allows unpacked mission folders, which pairs with allowedFilePatching in the config.

Installing the server itself needs a Steam account: the Arma 3 dedicated server and, more importantly, any Workshop mod has to come from an account that owns the game, which anonymous SteamCMD cannot do. On RE:NODE the server is created as soon as payment clears and the install waits on the Setup tab for those credentials, stored as you typed them - so use a spare account rather than your main one. SteamCMD explained covers the download side in general.

The ports form a block starting at -port:

PortProtocolPurpose
2302UDPGame traffic and voice
2303UDPSteam query, the port the browser talks to
2304UDPSteam master
2305UDPReserved for voice
2306UDPBattlEye

Changing -port moves the whole block, so two servers on one machine want at least 100 ports between them. Arma 3 plans on RE:NODE include five allocations for exactly this reason, and more can be added on the Network tab. If the server runs but nobody can find it, the query port is the first suspect - see game server ports explained.

server.cfg: the settings that matter#

Identity and access:

server.cfg
hostname = "Our Arma 3 server";password = "";passwordAdmin = "a-long-random-string";serverCommandPassword = "a-different-long-string";maxPlayers = 40;admins[] = {"76561198000000000"};motd[] = {"Rules in the Discord", "Teamkilling is a ban"};motdInterval = 5;logFile = "server_console.log";

password is the join password and is empty for a public server. passwordAdmin is what you type after #login, and it should be long, because anyone who has it can restart your mission. serverCommandPassword is a third, separate password used for server commands issued by a client, and it is what a headless client needs. admins[] lists player UIDs that get admin rights without logging in at all, which is the better way to run staff on a server with more than one of them.

Security:

config
verifySignatures = 2;BattlEye = 1;kickDuplicate = 1;allowedFilePatching = 1;requiredBuild = 0;onUnsignedData = "kick (_this select 0)";onHackedData = "kick (_this select 0)";onDifferentData = "";

verifySignatures = 2 is the setting that makes mod keys matter: every mod a client loads must be signed by a key present in the server's keys/ folder. It is also the reason half of all "I cannot join" reports exist, and turning it off to make them stop is exactly the wrong fix. allowedFilePatching takes 0 for nobody, 1 for headless clients only, and 2 for everyone; 1 is the right answer on a server that uses a headless client and nothing else.

Votes:

config
voteMissionPlayers = 3;voteThreshold = 0.33;allowedVoteCmds[] = {};

voteThreshold above 1 disables voting entirely, which is what most organised groups want. Leaving it at the default on a public server means three people can vote your mission away.

Network behaviour:

config
disconnectTimeout = 90;maxdesync = 150;maxping = 500;maxpacketloss = 50;kickClientsOnSlowNetwork[] = {0,0,0,0};

The four numbers in kickClientsOnSlowNetwork correspond to desync, ping, packet loss and the "unresponsive" check: 0 warns, 1 kicks. Kicking on ping is tempting and usually a mistake, because Arma's ping figure spikes during loading and on a busy frame. Warn first, watch the log for a week, then decide. Latency, jitter and packet loss covers telling a genuinely bad connection from a busy one.

Persistence and voice:

config
persistent = 1;autoInit = 1;timeStampFormat = "short";disableVoN = 0;vonCodecQuality = 30;vonCodec = 1;

persistent = 1 keeps the mission running when the last player leaves, which is what a campaign server needs and what a scrim server does not. autoInit = 1 starts the first mission at boot rather than waiting for somebody to connect, and it does nothing at all without persistent.

Difficulty moved out of server.cfg#

Since Arma 3 1.58, difficulty is not configured in server.cfg. The config only names a preset per mission: Recruit, Regular, Veteran or Custom. The actual settings live in the server profile, a .Arma3Profile file written under the -profiles directory in a folder named after -name.

server.Arma3Profile
class DifficultyPresets{    class CustomDifficulty    {        class Options        {            reducedDamage = 0;            groupIndicators = 0;            friendlyTags = 0;            enemyTags = 0;            detectedMines = 0;            commands = 1;            waypoints = 1;            weaponInfo = 2;            stanceIndicator = 1;            staminaBar = 1;            weaponCrosshair = 0;            visionAid = 0;            thirdPersonView = 0;            cameraShake = 1;            scoreTable = 1;            deathMessages = 0;            vonID = 1;            mapContent = 0;            autoReport = 0;            multipleSaves = 0;        };        aiLevelPreset = 3;    };    class CustomAILevel    {        skillAI = 0.5;        precisionAI = 0.3;    };};

Two traps. The file does not exist until the server has run once with -name=, so there is nothing to edit on a fresh install until after the first start. And the server rewrites the profile on a clean shutdown, so an edit made to a running server is discarded the moment you stop it properly. Stop first, edit, then start.

aiLevelPreset = 3 selects the custom AI level defined below it. precisionAI is the one worth lowering: at high values the AI shoots with a consistency that no human match can survive, and most complaints about Arma being unfair are a precision value nobody turned down.

Missions, rotation and persistence#

Missions are .pbo files in mpmissions/, named missionName.worldName. The rotation is declared at the end of server.cfg:

server.cfg
class Missions{    class Mission_01    {        template = "co40_liberation.Altis";        difficulty = "Custom";        class Params {};    };    class Mission_02    {        template = "tvt30_assault.Malden";        difficulty = "Veteran";    };};missionWhitelist[] = {"co40_liberation.Altis", "tvt30_assault.Malden"};

template is the pbo filename without the extension, including the world - co40_liberation.Altis, not co40_liberation. Getting that wrong is the reason a mission does not appear in the list. The server plays the classes in order and loops back to the first when the last ends.

class Params sets the mission parameters that the mission itself defines - time of day, respawn rules, AI count. The names come from the mission's own description.ext, so they differ for every mission and an invalid one is ignored rather than reported. The mission whitelist restricts what can be selected or voted, which matters on a server where anyone can be voted admin.

For a persistent campaign, one mission plus persistent = 1 and autoInit = 1 is the whole rotation: the server starts the mission at boot, holds it while nobody is on, and keeps going. For a session-based group, leave persistent off so the mission ends cleanly when everyone leaves, and use #missions to pick the next one.

basic.cfg and the myth of network tuning#

basic.cfg is where the internet's Arma advice goes to die. A typical file:

basic.cfg
MaxMsgSend = 128;MaxSizeGuaranteed = 512;MaxSizeNonguaranteed = 256;MinBandwidth = 131072;MaxBandwidth = 2097152000;MinErrorToSend = 0.001;MinErrorToSendNear = 0.01;MaxCustomFileSize = 0;class sockets{    maxPacketSize = 1400;};

Here is the uncomfortable version. The defaults are correct for nearly every server, the values circulating in forum posts were tuned for a specific machine on a specific connection in about 2014, and pasting somebody else's file is as likely to hurt as help.

The two worth touching:

  • `MaxCustomFileSize = 0` blocks custom player faces and sound files. On a public server this is a straightforward win: it removes a category of nuisance content and a small attack surface.
  • `MaxMsgSend` controls how many messages the server sends per simulation cycle. Raising it can reduce desync when the server has CPU headroom, and makes things worse when it does not, because the messages queue instead. Change it by one step, run #monitor for a session, and write down what happened.

maxPacketSize is the one to leave alone unless you know the path MTU, which on a hosted server you do not control.

Admin commands#

Log in from the in-game chat with #login <passwordAdmin>, or be listed in admins[] and skip it.

CommandWhat it does
#login <password>Become admin, #logout to stop
#missionsOpens the mission selection screen
#restartRestarts the current mission
#reassignRestarts and sends everyone back to slot selection
#shutdownStops the server process
#kick <name>Disconnects a player
#exec ban <name>Bans, writing to the ban list
#lock, #unlockStops and allows new connections
#userlistPrints connected players and their UIDs
#monitor <seconds>Prints server FPS and object counts, 0 to stop
#vote admin <name>Players vote someone admin, if allowed

#monitor 5 is the most useful thing in that list. It prints the server's frame rate into chat every five seconds, and server FPS is the number that decides whether a mission plays well. A healthy server sits near its cap. Below about 20 the AI starts to behave visibly badly - slow reactions, late pathing, groups that stand still. Below 10 nothing works and no network setting will save it. That number falls as AI count rises, which is what the headless client is for. The general version of this argument is in what tick rate actually means.

There is also BattlEye's own RCon, configured in BEServer_x64.cfg in the BattlEye folder with RConPassword and RConPort. It is what external admin tools connect to, and its protocol is not encrypted, so treat the port as local-only and the password as a secret that should never be reused. RCON safely covers the general case.

Headless clients#

Arma's simulation is largely single-threaded, and on a long mission it is the AI that eventually saturates that thread. A headless client is a second Arma process that connects to the server as a client with no graphics, takes ownership of AI groups the mission hands it, and simulates them on its own thread. On a mission built for it, moving fifty AI groups off the server can be the difference between an hour-three firefight that plays and one that crawls.

The server side is three things:

server.cfg
headlessClients[] = {"127.0.0.1"};localClient[] = {"127.0.0.1"};serverCommandPassword = "a-different-long-string";

headlessClients[] tells the server which addresses are allowed to connect as headless. localClient[] marks them as local, which exempts them from the bandwidth limits meant for players on domestic connections - without it the headless client is throttled like a player and does not help. Both take the loopback address when the headless client runs on the same machine, which it should.

The client side is the same binary with -client:

bash
$ ./arma3server_x64 -client -connect=127.0.0.1 -port=2302 \    -password="" -mod="@cba_a3;@ace" \    -profiles=profiles -name=HC -world=empty

The mod list must match the server's exactly. The password is the server's join password, not the admin one.

And then the part most guides skip: the mission has to support it. A headless client does nothing unless the mission contains a headless client slot and code that transfers AI groups to it once it connects. Frameworks aimed at long missions generally do; a mission from the workshop with no mention of it in the description generally does not, and running a headless client against one costs you memory and gains you nothing.

Two honest caveats for hosted servers. A headless client is a second Arma process, so it wants its own core and a couple of gigabytes of memory. On a plan with a hard CPU limit - one container per server, throttled to the share you bought - the headless client draws from the same allowance, so it only helps if there is genuinely unused CPU inside your limit rather than unused cores on the machine. And if the headless client is refused at connection, check headlessClients[] first and the mod list second; those two account for nearly every case. CPU vs RAM for game servers is worth reading before deciding which limit you are actually hitting.

Troubleshooting#

The server does not appear in the browser. The Steam query port, -port plus one, is closed or in use. Joining by IP works while the browser does not, which is the quick way to confirm it.

My server.cfg changes do nothing. -config= and -cfg= are the wrong way round, or the path is wrong and the server is running on defaults. The startup log names the file it loaded.

Difficulty settings keep reverting. You edited the profile while the server was running and it was rewritten on shutdown. Stop the server, edit, start.

The mission is not in the list. The template value is missing the world name, the pbo is not in mpmissions/, or missionWhitelist[] excludes it.

Players get "session lost" at the loading screen. A mod or signature mismatch. With verifySignatures = 2 the key must be in keys/, and the client must have the same mod version, not just the same mod.

Mods load on Windows and not on Linux. Linux is case sensitive and Arma mod folders and pbo names are frequently mixed case. Lowercase the mod folder and its contents, or use a downloader that does it for you.

Everything is fine for two hours and then it crawls. AI count. Run #monitor 5, watch the server FPS fall, and either cut the AI the mission spawns or set up a headless client.

`autoInit` is not starting the mission. It needs persistent = 1. A weekly scheduled restart is still worth having on a persistent server - see restart schedules that help.

FAQ#

What is the difference between -config and -cfg in Arma 3?

-config= loads server.cfg, which holds the server name, passwords, admins, security settings and mission rotation. -cfg= loads basic.cfg, which holds network tuning. The naming is counter-intuitive and swapping them silently gives you a default server.

Where do I set Arma 3 server difficulty?

In the server profile, not server.cfg. The config only names a preset per mission; the values behind Custom live in a .Arma3Profile file under the -profiles directory. Edit it with the server stopped, or it will be overwritten.

How many players can an Arma 3 server hold?

maxPlayers sets the cap, but the real limit is the mission's slot count and the CPU. Sixty players on a well-built mission is routine; the same server dies at thirty if the mission spawns several hundred AI, because AI is what consumes the frame time.

Do I need a headless client?

Only if your mission supports one and AI is your bottleneck. Run #monitor 5 during a bad moment: if server FPS is falling while CPU is pinned and the mission has a lot of AI, a headless client helps. If the mission has no headless slot, it does nothing.

Which ports does an Arma 3 server need?

UDP 2302 for the game, 2303 for the Steam query, 2304 for the Steam master, 2305 reserved for voice and 2306 for BattlEye. They move as a block if you change -port.

Can I change basic.cfg to fix desync?

Rarely. Desync in Arma is almost always the server running out of frame time, not the network running out of bandwidth. Fix the AI count first, measure with #monitor, and only then adjust MaxMsgSend by one step at a time.


Comments

Completely anonymous: no account, no email, no cookie. We store the name you type, the text and the time - nothing else. Links are limited and markup is not rendered.

0/2000