Set up your server, step by step.
Everything, in the order you run it — install the Arma Reforger server, make the database, start the gateway, and wire them together with simple start/stop scripts. No prior server experience needed. Pick your operating system below and follow the numbered steps.
The game, the mod, and this kit
Arma Reforger is Bohemia Interactive’s military simulation game (PC and Xbox), built on the Enfusion engine — the platform that succeeds Arma 3. Anyone can host a dedicated server, and mods install themselves: when a player joins a modded server, the game downloads its mods automatically from the built-in Workshop.
Wasteland-Z is a hardcore PVP open-world mod for Arma Reforger, by Heavy Forge, Inc. The world after the Z — the outbreak ended, the cities emptied, and what survived now scavenges, fights, and trades for what’s left. Town-based scarcity loot, missions, gun / general / vehicle stores, a server-authoritative money economy with ATM banking, three-faction PVP, and a cross-server hive: the same money, bank and gear on every server in a cluster. It runs on top of any Game Master scenario, on any map. The gameplay concept honors the A3 Wasteland lineage, rebuilt ground-up for Reforger.
This kit is the server side — for admins who want to host a Wasteland-Z server: the guide below, the gateway program, the database schema, example configs, and start/stop scripts. Just want to play? You need nothing from here — find a Wasteland-Z server in the Reforger server browser and join. The mod installs itself.
What you're building
A working server is three programs talking to each other. You install all three once, then they run on their own.
What's in this download
- gateway/
- The gateway program. Copy this whole folder to your server and run it.
- gateway/setup_database.sql
- Builds every database table in one shot. You run this once.
- gateway/config.example.py
- The settings template. You copy it to
config.pyand fill in your password + key. - gateway/start_gateway.bat
- Windows one-click start.
- configs/
- Reference copies of the server settings (loot, vehicles, towns, admins…) — the server writes its own working copies on first start (see below), so these are for reading and optional pre-tuning, not required drop-ins. The README inside lists each file and which ones auto-create; every setting is documented inline.
- missions/
- Reward templates for the mission system, plus a guide to authoring missions in-game.
- server/
- Game-server kit — SteamCMD install script, example
server1.json, and the start/stop batch files (auto-restart loop included).
The first time Wasteland-Z starts, it writes a complete, ready-to-run set of config files into your server profile’s hf_wastelandz\configs\ folder, each pre-filled with the current defaults. You can start with no config files at all and edit the generated ones afterwards — that’s the recommended path, because the files the server writes always match the mod version you’re running (a hand-copied kit file can fall behind after an update).
Auto-created on first start: HFWastelandZ_server.conf, HFWastelandZ_secrets.conf, HFWastelandZ_admins.conf, HFWastelandZ_blacklist.conf, HFWastelandZ_command_tiers.conf, HFWastelandZ_loadouts.conf, HFWastelandZ_town_tiers.conf, HFWastelandZ_loot_spawn_filter.conf, HFWastelandZ_item_catalog.conf, HFWastelandZ_vehicle_spawn.conf, HFWastelandZ_server_message.txt, plus the per-map files under configs\map\<MapName>\ (towns, spawn points, loot pools, world loot, and the gun / general / vehicle store catalogs — these regenerate for whatever map you load).
The two you must fill in yourself: HFWastelandZ_secrets.conf is written with a placeholder API key you must replace, and HFWastelandZ_admins.conf is written empty so you must add your Bohemia Identity GUID (not your Steam number) to become an admin — see Step 9d. Everything else runs on defaults until you decide to change it.
Where everything lives on your server
After setup you have three top-level folders (Linux /opt/ shown below; Windows mirrors this under C:\reforger\ plus your gateway folder). The spot that trips people up: HF’s live config files sit under the profile’s extra profile/ subfolder.
/opt/ ├── wastelandz/ # THIS KIT (git clone) — reference copies, read-only │ ├── gateway/ # gateway program + setup_database.sql + config.example.py │ ├── configs/ # reference *.example HF settings (optional pre-tuning) │ ├── missions/ # mission reward templates + in-game authoring guide │ └── server/ # systemd + server1/2.json examples + SteamCMD script │ ├── wastelandz-gateway/ # the RUNNING gateway (copied out of the kit) │ ├── config.py # YOUR DB password + gateway key — never share or commit │ ├── gateway.py # the Flask service │ ├── setup_database.sql # builds the tables (tables only — holds NO credentials) │ └── venv/ # isolated Python you create (Ubuntu 24.04 / PEP 668) │ └── reforger/ # the game server ├── server/ # ArmaReforgerServer + game files (from SteamCMD) ├── workshop/ # -addonDownloadDir: Workshop mods download here, shared by all servers │ └── addons/ │ └── Wasteland-Z_68A616565DECAB19/ # the downloaded mod (data.pak) ├── configs/ │ └── server1.json # Reforger config: server NAME, admin password, mods, scenario └── profiles/ └── server1/ # -profile dir for this server ├── logs/ # console.log lives here └── profile/ # $profile: root <-- note the extra 'profile/' level └── hf_wastelandz/ ├── configs/ # *** HF configs: server.conf, secrets.conf, admins.conf, catalogs... └── missions/ # mission reward templates go here
Key takeaway: the HF config files are at /opt/reforger/profiles/server1/profile/hf_wastelandz/configs/ — note the profile/ level Enfusion adds. On Windows it’s the same shape under C:\reforger\profiles\server1\profile\hf_wastelandz\configs\.
You need a PC (or rented machine) that stays on, and this download. That’s it — the guide covers installing the game server itself, and the server downloads from Steam anonymously (no Steam account needed). The Wasteland-Z mod downloads automatically from the Reforger Workshop the first time the server starts.
“This download” = the setup kit’s GitHub repo. To grab it: open the repo page → green Code button → Download ZIP → unzip anywhere on your PC. No git and no GitHub account needed. (Linux users can skip the ZIP — the Linux tab’s Step 1 pulls it straight onto the server.)
Install the game server
Three steps: get SteamCMD, download the server with it, drop in a config. The server\ folder of this download has everything ready-made.
Build server 1 first. Part 4 adds each extra server: the game installs once; every additional server is a config file with new ports (+ its own map if you want) and its own start script.
Make the folders and get SteamCMD
SteamCMD is Valve’s little downloader — it fetches and updates the dedicated server. Make this folder layout (one parent folder, four inside):
C:\reforger\ steamcmd\ ← SteamCMD lives here server\ ← the game server gets installed here configs\ ← your server settings (server1.json) profiles\ ← each server's save data + Wasteland-Z configs workshop\ ← downloaded mods (shared by all your servers)
Get SteamCMD from Valve’s official page: developer.valvesoftware.com/wiki/SteamCMD — under Windows it links the steamcmd.zip download. Unzip it into C:\reforger\steamcmd\. No Steam account is needed — the dedicated server downloads anonymously.
Download the server
Copy the server\ folder from this download into C:\reforger\scripts\, then double-click install_or_update_server.bat. It pulls the Arma Reforger dedicated server (Steam app 1874900, a few GB) into C:\reforger\server\.
If you prefer typing it yourself, the script just runs:
C:\reforger\steamcmd\steamcmd.exe +force_install_dir C:\reforger\server ^ +login anonymous +app_update 1874900 validate +quit
Whenever Reforger gets an official update, stop your servers and run this same script again. It only downloads what changed.
Drop in the server config
Copy server\server1.json.example to C:\reforger\configs\server1.json and open it in Notepad. Set two things:
name— your server’s name in the browser list.passwordAdmin— a password only you know.
Everything else already works: the Wasteland-Z mod is pre-listed in mods (it auto-downloads on first start), and the map is Everon (21_GM_Eden). For Arland instead, set scenarioId to {2BBBE828037C6F4B}Missions/22_GM_Arland.conf.
Players connect over UDP ports 2001 (game) and 17777 (server browser). On a home connection, forward both UDP ports to this PC in your router. On a rented server, allow them in the provider’s firewall panel.
Don’t start it yet — first set up the database and gateway below, so the server has something to save into.
Database & gateway (one time)
Do these eight steps in order. Copy each command with the button on its right.
Install the two programs you need
Install MySQL 8 (the database) and Python 3.12+ (runs the gateway).
- MySQL: get the MySQL Installer from dev.mysql.com → install MySQL Server. When it asks, set a root password and write it down.
- Python: get it from python.org. On the first install screen, tick “Add python.exe to PATH” — this matters.
Check both installed — open Command Prompt and run:
python --version mysql --version
Create the database
Open “MySQL 8.0 Command Line Client” from the Start menu (it asks for the root password from Step 1). Paste these four lines — they make an empty database and a login for the gateway:
CREATE DATABASE wastelandz;
CREATE USER 'wastelandz'@'localhost' IDENTIFIED BY 'your_password_here';
GRANT ALL PRIVILEGES ON wastelandz.* TO 'wastelandz'@'localhost';
FLUSH PRIVILEGES;Replace your_password_here with a password you choose, and write it down — the gateway needs it in Step 5. Because MySQL 8’s password policy is on, it must be 8+ characters with an upper- and lower-case letter, a number, and a symbol (e.g. Wast3land_Z!) — a weaker one fails with ERROR 1819.
Build the tables
This fills the empty database with every table the game needs. Open a normal Command Prompt, go to the folder where you unzipped this download, and run:
mysql -u wastelandz -p wastelandz < gateway\setup_database.sqlIt asks for the wastelandz password (from Step 2). No error message means it worked.
Put the gateway in place
Copy the whole gateway folder somewhere permanent — for example C:\wastelandz-gateway. Open Command Prompt in that folder and install the parts it needs:
pip install -r requirements.txtEnter your settings
First generate the gateway key — a unique API key (use a different one for every server). Copy the 64-character line it prints:
python -c "import secrets; print(secrets.token_hex(32))"In the gateway folder, make a copy of config.example.py and name the copy config.py. Open config.py in Notepad and set two things:
DB_PASSWORD= the password you made in Step 2.- Set
api_key— the GATEWAY KEY, shown in the file asCHANGE_ME_UNIQUE_KEY_1— to the key you just generated. Each server needs its own unique gateway key.
Leave host as 127.0.0.1 and port as 5000.
config.py holds your password and key. Never share it or upload it anywhere public.
Start it and check
Double-click start_gateway.bat (or run python gateway.py). A black window opens and stays open — that’s normal, leave it running. You should see Database connection: OK and a Listening… line.
Now open a browser to:
http://127.0.0.1:5000/api/ping
You should see "status":"ok" and "database":"connected". That means the gateway and database are talking.
Firewall
If the gateway and the game server are on the same computer (the normal setup) — do nothing. Local connections already work.
Only if a different computer or a Discord bot needs to reach the gateway, open port 5000 to that one address:
netsh advfirewall firewall add rule name="WZ Gateway" dir=in action=allow ^ protocol=TCP localport=5000 remoteip=THE.OTHER.IP.ADDRESS
Never open port 5000 to everyone (no wide-open rule). And leave MySQL’s port 3306 closed — the gateway reaches it locally; the internet never should.
Connect the game server — then first start
Start the server once (double-click C:\reforger\scripts\start_server1.bat) and let it boot — it downloads the Wasteland-Z mod and creates its profile folder, then Wasteland-Z writes starter config files into C:\reforger\profiles\server1\profile\hf_wastelandz\configs\. Close the server window, then wire it up:
HFWastelandZ_server.conf—GATEWAY_URLalready defaults tohttp://127.0.0.1:5000/(correct for a local gateway); only change it if your gateway is on another machine/port.- In
…\hf_wastelandz\configs\HFWastelandZ_secrets.conf, add a line:API_KEYfollowed by the same key you put in the gateway’sconfig.pyin Step 5. (A ready-made template with key-generation instructions ships in this download:configs\HFWastelandZ_secrets.conf.example.) - Want to pre-tune settings? Take the files in this download’s
configs\, remove.examplefrom each name, and copy them into that sameprofile\hf_wastelandz\configs\folder.configs\README.mdlists what each file controls; every setting is documented inside its file. - Copy
missions\rewards\into…\profiles\server1\profile\hf_wastelandz\missions\rewards\— these are the loot crates and vehicles missions hand out. (Missions themselves are built in-game — seemissions/README.md.)
Start the server again. Player data now saves to the database. You’re live.
Run · monitor · stop
Day-to-day, with zero server knowledge: every piece runs in its own labeled window. If a window is open, that piece is running. Close a window, that piece stops — nothing else is touched. The batch files live in C:\reforger\scripts\.
Start everything
Double-click start_all.bat. It opens the WZ-Gateway window, waits a few seconds, then opens WZ-Server-1 (and 2/3 if you enabled them).
Crash protection
Each server window runs a loop: if the game server crashes or closes, it restarts by itself in 10 seconds. The gateway just keeps running.
Stop ONE game server
Close its WZ-Server-1 window (the X), or double-click stop_server1.bat. The gateway and any other servers stay up.
Stop the gateway only
Close the WZ-Gateway window. Game servers keep running (players keep playing; saves hold in memory and it catches up when you start the gateway again — don’t leave it off long).
Stop everything
Close all the WZ-… windows. Done. (Stop servers before the gateway so last saves land.)
Watch it (monitor)
The windows are the monitors — gateway saves/loads scroll in WZ-Gateway, the game log scrolls in each server window.
Start on boot
Press Win+R, type shell:startup, Enter — then put a shortcut to start_all.bat in the folder that opens. Everything launches when you log in. (Prefer no auto-login? Use Task Scheduler → At startup instead.)
Game updated?
Stop the server windows, run install_or_update_server.bat, start again. The Wasteland-Z mod updates itself on server start.
Is it alive?
Browse http://127.0.0.1:5000/api/ping anytime. status: ok = healthy.
Restart MySQL
Win+R → type services.msc → find MySQL80 → right-click → Restart.
Back up your data (do this regularly)
mysqldump -u wastelandz -p wastelandz > wastelandz_backup.sqlKeep a copy of that file somewhere safe. It is your whole server’s save.
Troubleshooting
- “Database connection failed” — the password in
config.pydoesn’t match Step 2, or MySQL isn’t running. - Port 5000 already in use — change
portinconfig.py(and updateGATEWAY_URLto match). - /api/ping won’t load — the gateway window isn’t running. Start it.
- Money/gear not saving —
GATEWAY_URLorapi_keydon’t match between the game server andconfig.py. - Last location & kept gear don’t restore on relog (but money & inventory DO) — your game server’s
SERVER_ID(inHFWastelandZ_server.conf) doesn’t match theserver_idthe gateway uses for it. Money/inventory are hive-wide so they still work; only per-server data (your position, kept-on-relog gear) needs the two ids to match. SetSERVER_IDto the gateway’s id and restart. The game log printsSERVER_ID MISMATCHwith both values when it detects this — grep for it.
Two or three servers on one PC
One database, one gateway, several game servers — that’s a hive. Players keep the same money, bank and gear on every server in the hive; each server keeps its own world (positions, placed objects, map). One gateway serves them all — you do not run a second gateway or database.
The finished two-server setup, and how the pieces talk:
players → UDP 2001/17777 → WZ-Server-1 (Everon) → http://127.0.0.1:5000 + key #1 ─┐ players → UDP 2002/17778 → WZ-Server-2 (Arland) → http://127.0.0.1:5001 + key #2 ─┤ └→ WZ-Gateway → MySQL The gateway tells the servers apart by the PORT each one calls (5000 vs 5001) and proves it with that server's key. Both ports are ONE gateway window, and everything right of the players is local to the PC — nothing exposed.
Every extra server is the same four things with different numbers. The unique-ports table:
| Server 1 | Server 2 | Server 3 | |
|---|---|---|---|
| Game port (UDP, forward it) | 2001 | 2002 | 2003 |
| Browser port (UDP, forward it) | 17777 | 17778 | 17779 |
| Gateway port (local only) | 5000 | 5001 | 5002 |
| Config file | server1.json | server2.json | server3.json |
| Profile folder | profiles\server1 | profiles\server2 | profiles\server3 |
To add server 2 (server 3 is the same pattern):
- Config: copy this download’s
server\server2.json.exampletoC:\reforger\configs\server2.json— ports 2002/17778 and the Arland map are pre-set; changenameand the admin password. The map is thescenarioIdline — Wasteland-Z runs on top of any Game Master scenario:e.g. server 1 on Everon, server 2 on Arland — same hive, so players keep their money, bank and gear when they switch.Everon (the big island): "scenarioId": "{59AD59368755F41A}Missions/21_GM_Eden.conf" Arland (the smaller southern island): "scenarioId": "{2BBBE828037C6F4B}Missions/22_GM_Arland.conf"
Any other map — including community maps — works the same way. Find its ID on the Workshop website: open the map mod’s page at reforger.armaplatform.com/workshop and click its Scenarios tab — the ScenarioId shown there (it looks like
{GUID}Missions/Name.conf) is what goes inscenarioId. Add that map mod to the same server’smodslist too. - Batch files: copy
start_server1.bat→start_server2.batandstop_server1.bat→stop_server2.bat. Inside both, change everyserver1toserver2and the titleWZ-Server-1toWZ-Server-2. (The install folder andworkshop\mods folder are shared — don’t copy those.) - Gateway: in
config.py, un-comment theserver-2line inSERVERSand give it its own randomapi_key(Step 5 command). Restart the gateway window — it now listens on 5000 and 5001. - Wire it: in
profiles\server2\profile\hf_wastelandz\configs\(created on server 2’s first start), setGATEWAY_URL http://127.0.0.1:5001/and put server 2’s key in itsHFWastelandZ_secrets.conf. - Match the SERVER_ID (critical): in server 2’s
HFWastelandZ_server.conf, setSERVER_ID server-2so it exactly matches that server’sserver_idin the gateway’sSERVERSlist. If they differ, last-location and kept-gear will silently not restore on that server (money/inventory still work, since those are hive-wide). The game log printsSERVER_ID MISMATCHif it’s wrong. - Start it: remove the
remin front of the server-2 lines instart_all.bat. Forward UDP 2002 + 17778 in your router.
Each server gets its own gateway port and its own random api_key — that’s how the gateway tells them apart. Never reuse a key across servers.
Each Reforger server is heavy — roughly a few CPU cores and 4–8 GB RAM per server under load. Two servers want a strong 8-core machine; three want more. The gateway and MySQL are lightweight by comparison.
Big box? Give each server its own cores
RAM needs no dividing — Windows hands it out on demand, and a full 128-player server uses roughly 8–16 GB. (Windows has no simple per-program RAM cap like Linux’s — skip that part.) CPU is the part worth splitting: a big AMD chip (e.g. a 16-core Ryzen 7950X3D) is really two groups of 8 cores, each sharing one pot of very fast memory (cache). Two servers squeezed into one group fight over the pot — give each server its own group.
On Windows the tool is the /affinity flag. In start_server1.bat, change the server line:
rem before: "%SERVER_EXE%" -config "%CONFIG%" -profile "%PROFILE%" -addonDownloadDir "%ADDONS%" -maxFPS 60 rem after — server 1 pinned to the first 16 processor numbers (group one): start "" /affinity FFFF /wait "%SERVER_EXE%" -config "%CONFIG%" -profile "%PROFILE%" -addonDownloadDir "%ADDONS%" -maxFPS 60 rem and in start_server2.bat — the next 16 (group two): start "" /affinity FFFF0000 /wait "%SERVER_EXE%" -config "%CONFIG%" -profile "%PROFILE%" -addonDownloadDir "%ADDONS%" -maxFPS 60
The mask is a code for “which processors”. FFFF = the first 16 processor numbers; Windows usually numbers each core twice back-to-back, so that’s the first 8 cores = the first group (the big-cache one on X3D chips — give it to your busiest server). /wait keeps the auto-restart loop working. Sanity-check anytime: Task Manager → Details → right-click ArmaReforgerServer.exe → Set affinity shows exactly which processors each server is allowed on.
Cheat-sheet: 1–4 servers on a 16-core PC (two 8-core groups; Windows numbers each core twice back-to-back):
| Setup | Server & players | /affinity mask |
|---|---|---|
| 1 server (up to 128) | WZ-Server-1 · 128 | none needed (whole chip; or FFFF for the big-cache group) |
| 2 servers (2×128) | WZ-Server-1 · 128 | FFFF |
| WZ-Server-2 · 128 | FFFF0000 | |
| 3 servers (2×128 + 1×64) | WZ-Server-1 · 128 | FFFF |
| WZ-Server-2 · 128 | FFFF0000 | |
| WZ-Server-3 · 64 | none (floats in the gaps) | |
| 4 servers (4×64 or 4×32) | WZ-Server-1 · 64 | FF |
| WZ-Server-2 · 64 | FF00 | |
| WZ-Server-3 · 64 | FF0000 | |
| WZ-Server-4 · 64 | FF000000 |
The logic: 1–2 servers → a whole group each (max cache per server). 4 servers → half a group (4 cores) each — plenty at 32–64 players, and no server ever spans both groups. 3 servers is the awkward count: pin the two big ones, let the third float. Player caps live in each serverN.json (maxPlayers); what actually loads a core is AI + player count together, so watch Task Manager on busy nights and adjust aiLimit before touching the masks.
Different CPU? Older Intels (e.g. an i9-9900K, 8 cores) are one group — no favourite half; split down the middle with FF / FF00 and expect lower comfortable player caps. Newer hybrid Intels (12th gen up, e.g. an i7-13700K) mix fast P-cores (numbered first, each twice back-to-back) and small E-cores (after them): pin game servers to P-cores (FF / FF00) and leave the E-cores unpinned — they carry the gateway, MySQL and Windows itself. See your layout anytime: Task Manager → Details → right-click the server → Set affinity lists every processor number.
Set it up (one time)
These are Ubuntu commands. Type them into the server’s terminal (connect with SSH). Every command is explained.
Build server 1 first. Part 3 adds each extra server: the game installs once; every additional server is a config file with new ports (+ its own map if you want) and its own service. The kit ships the server-2 files pre-made.
Your Windows PC is the remote control; the Linux box is the machine that runs everything. You type commands into it over SSH — open PowerShell on your PC and run ssh youruser@your-server-ip (SSH is built into Windows, nothing to install). Every command below is typed into that window.
Linux has no C:\. Your personal folder is /home/youruser — written ~ for short, so ~/reforger would mean /home/youruser/reforger. Software you install yourself goes in /opt/ by convention — that’s this guide’s equivalent of making C:\reforger\, and everything lives there:
/opt/wastelandz ← this setup kit, straight from GitHub (Step 1) /opt/reforger ← the game server (Step 2) /opt/wastelandz-gateway ← the running gateway (Step 5)
Accounts — you and your friends
Your rented box hands you the root login — the master account. Setting up from it is fine. First job: make an admin account for yourself and each friend who’ll help run the server — an admin can do everything in this guide (restart servers, edit configs, run game updates) without needing you.
See your admins:
getent group sudo # the admins — every name after the last ':' is one
Add an admin (yourself, or a friend who’ll help run the server — two commands, that’s it):
sudo adduser dave # pick any name; it asks you to set a password sudo usermod -aG sudo dave # make him an admin
Dave logs in with ssh dave@your-server-ip and the password you set (he can change it with passwd). He must log out and back in once for admin power to kick in — then he can do everything in this guide: restart servers, edit configs, run updates. Only add people you trust with the whole box.
Remove an admin:
sudo deluser dave sudo # drops admin power, keeps his login sudo deluser --remove-home dave # deletes the account completely
Do the steps below from root or from your own admin account — the commands work either way. One thing to remember for later: the service files in Part 2 and Step 9 have a User= line — put your account name there, so the game and gateway run under your account.
Get the files onto the server
Everything in this kit is one GitHub repo. Two ways to get it onto the Linux box — pick one:
Option A — git (recommended). One command pulls the whole kit straight onto the server; updating later is one more command. On the server:
sudo apt install -y git sudo git clone https://github.com/Motavar/HF_WastelandZ_SETUP.git /opt/wastelandz sudo chown -R $USER /opt/wastelandz
Get updates later with: cd /opt/wastelandz then git pull
Option B — WinSCP (drag & drop). On your PC: open the repo page on GitHub → green Code button → Download ZIP → unzip it. Make the target folder on the server first:
sudo mkdir -p /opt/wastelandz sudo chown $USER /opt/wastelandz
Then connect WinSCP (a free tool) to the server and drag the unzipped folder’s contents into /opt/wastelandz — it works like copying between two Explorer windows.
Install the game server
SteamCMD is Valve’s little downloader — it fetches and updates the dedicated server. On Ubuntu it lives in the “multiverse” package section, so enable that first:
sudo add-apt-repository multiverse sudo dpkg --add-architecture i386 sudo apt update sudo apt install -y steamcmd
A license screen appears during install — accept it. No Steam account is needed; dedicated servers download anonymously.
Not on Ubuntu? Debian, Arch and other distros install SteamCMD differently — see Valve’s official page for yours: developer.valvesoftware.com/wiki/SteamCMD. The rest of this guide works the same once steamcmd is installed.
Make the game server’s folder layout (same idea as C:\reforger\ on Windows), then download the server into it — a few GB:
sudo mkdir -p /opt/reforger/server /opt/reforger/configs /opt/reforger/profiles /opt/reforger/workshop sudo chown -R $USER /opt/reforger steamcmd +force_install_dir /opt/reforger/server +login anonymous +app_update 1874900 validate +quit
Whenever Reforger gets an official update, stop your servers and re-run that same steamcmd line. It only downloads what changed.
Drop in the ready-made config from the kit (Wasteland-Z is pre-listed in mods — it works as-is; open it in nano later to rename your server — save/exit with Ctrl+O, Enter, Ctrl+X):
cp /opt/wastelandz/server/server1.json.example /opt/reforger/configs/server1.jsonDon’t start it yet — it needs the database and gateway first (Steps 3–8). Step 9 does the first start.
Install MySQL and Python
Update the package list, then install both:
sudo apt update sudo apt install -y mysql-server python3 python3-pip
Then lock MySQL down and set the root password:
sudo mysql_secure_installationIt asks a series of questions. Recommended answers:
- VALIDATE PASSWORD component? — optional.
Nis fine (you set your own strong passwords). - New root password — set a strong one and write it down.
- Remove anonymous users? — Y — closes password-less access.
- Disallow root login remotely? — Y — root only connects locally; the gateway uses its own
wastelandzlogin. - Remove test database and access to it? — Y — the default
testdatabase is open to everyone. - Reload privilege tables now? — Y — applies it all right away.
None of these touch the wastelandz database or login you create in the next step — they only strip out MySQL’s insecure defaults. Answering Y to all four is the right call for a dedicated server.
Create the database
Open MySQL as admin:
sudo mysqlAt the mysql> prompt, paste these four lines, then type exit:
CREATE DATABASE wastelandz;
CREATE USER 'wastelandz'@'localhost' IDENTIFIED BY 'your_password_here';
GRANT ALL PRIVILEGES ON wastelandz.* TO 'wastelandz'@'localhost';
FLUSH PRIVILEGES;Replace your_password_here with one you choose and write it down — you need it in Step 6. Because you enabled MySQL’s password policy in Step 3, it must be 8+ characters with an upper- and lower-case letter, a number, and a symbol (e.g. Wast3land_Z!) — a weaker one fails with ERROR 1819.
Set up the gateway
Copy the gateway out of the kit into its own folder (the running copy stays separate, so kit updates never touch your live settings), then build the database tables and install its Python parts:
# the running copy gets its own folder sudo mkdir -p /opt/wastelandz-gateway sudo chown $USER /opt/wastelandz-gateway cp -r /opt/wastelandz/gateway/. /opt/wastelandz-gateway/ # build the tables (logs in as the wastelandz user) cd /opt/wastelandz-gateway mysql -u wastelandz -p wastelandz < setup_database.sql # create an isolated Python environment and install the gateway into it sudo apt install -y python3-venv python3 -m venv venv source venv/bin/activate pip install -r requirements.txt # give the whole folder (incl. the venv) to the account the service will run as sudo chown -R youruser:youruser /opt/wastelandz-gateway
The mysql line asks for the wastelandz password you set in Step 4, then builds the tables — no output means it worked. The script itself holds no usernames or passwords; you never edit it.
youruserChange both youruser parts to your Linux username and group (it’s username:group). This must be the same user you’ll put in the service’s User= line in Part 2.
Not sure what yours are? Run these two:
whoami # prints your username (e.g. motavar) id -gn # prints your primary group (e.g. motavar)
On Ubuntu/Debian your primary group is the same as your username, so the two are almost always identical. For a user named motavar the command is:
sudo chown -R motavar:motavar /opt/wastelandz-gatewayShortcut: you can type $USER:$USER instead and the shell fills in your username automatically — the same $USER the earlier chown steps use.
Why it matters: if you created the venv while in a root shell (e.g. after a sudo -i or a sudo mysql session), the files end up owned by root, and the gateway service — which runs as your user — can’t read or run them. The chown -R above fixes that no matter who created the files, so it’s safe to always run.
Modern Ubuntu (24.04 / Python 3.12) blocks system-wide pip install to protect the OS Python — you’d hit error: externally-managed-environment. A venv is an isolated Python just for the gateway: the clean, recommended way. Your prompt shows (venv) once it’s active, and that’s why Step 7 and the service below run venv/bin/python.
On systems without that restriction (older Ubuntu/Debian), you can skip the venv and install into system Python — then Step 7 and the service use plain python3 instead of venv/bin/python:
pip3 install -r requirements.txt # to force it on a PEP-668 system instead of using a venv (not recommended): pip3 install -r requirements.txt --break-system-packages
Enter your settings
First generate the gateway key — a unique API key (use a different one for every server). Copy the 64-character line it prints:
python3 -c "import secrets; print(secrets.token_hex(32))"Now copy the template to the real settings file and open it in nano:
cp config.example.py config.py nano config.py
Set DB_PASSWORD to your Step 4 password, and set api_key — the GATEWAY KEY, shown in the file as CHANGE_ME_UNIQUE_KEY_1 — to the key you just generated. Each server needs its own unique gateway key. Leave host as 127.0.0.1 and port as 5000. Save in nano: Ctrl+O, Enter, Ctrl+X.
config.py holds your password and key. Never share it or upload it anywhere public.
Test that it runs
venv/bin/python gateway.pyThis runs the gateway in the foreground, so it holds this terminal — that’s normal (it’s a server, meant to keep running). Look for Database connection: OK in its output — that line is your success check. Then press Ctrl+C to stop it; Part 2 below runs it properly on its own. (venv/bin/python works whether or not the venv is “activated”; a no-venv install uses plain python3 gateway.py.)
Because the gateway holds this terminal, the curl check has to run from a separate SSH session while the gateway is still running. Or just skip it — once it’s a service (Part 2) it runs in the background and curl works from any terminal:
curl http://127.0.0.1:5000/api/pingFirewall
Gateway on the same box as the game server (normal) — nothing to do. Local traffic is already allowed.
Only for a remote server or bot, open port 5000 to that one address:
sudo ufw allow from THE.OTHER.IP.ADDRESS to any port 5000 proto tcp
Never run ufw allow 5000 on its own — that opens it to the whole internet. And leave MySQL’s port 3306 closed; it only needs to be reached locally.
If you turned ufw on, also open the game’s own ports so players can join: sudo ufw allow 2001/udp and sudo ufw allow 17777/udp. (Ubuntu ships with ufw off — then there’s nothing to do.)
- Open to the internet:
2001(game — players join) &17777(A2S / Steam query — this is the Steam port; it’s what lists your server in the browser). Server 2 =2002/17778, etc. - Optional:
19999(RCON remote admin) — only if you use it, and restrict it to your admin IP; never open it wide. - Keep local, never public:
5000(gateway — open only to a remote bot’s IP if off-box) &3306(MySQL).
No separate “Steam” ports are needed — Reforger isn’t a Source-engine server (no 27015 etc.), and SteamCMD downloads are outbound (nothing to forward).
Connect your game server — then first start
Start the game server once and let it boot — it downloads the Wasteland-Z mod from the Workshop and writes its starter config files. This is the command (one long line — same program, its config, its profile folder, the shared mods folder):
cd /opt/reforger/server ./ArmaReforgerServer -config /opt/reforger/configs/server1.json -profile /opt/reforger/profiles/server1 -addonDownloadDir /opt/reforger/workshop -maxFPS 60
When it settles, press Ctrl+C to stop it. Wasteland-Z has now written its starter config files into /opt/reforger/profiles/server1/profile/hf_wastelandz/configs/.
Wasteland-Z ships with working defaults for everything — loot, economy, missions, weapons, vehicles. To go live you only need to set two things: the gateway URL and its key (steps a & b below). Everything else is optional tuning you can do later.
a Gateway URL — already set for a local gateway
The mod defaults GATEWAY_URL to http://127.0.0.1:5000/, which is correct when the gateway is on the same box (the normal setup) — so you can skip this. Only edit it if your gateway runs on a different machine or port:
nano /opt/reforger/profiles/server1/profile/hf_wastelandz/configs/HFWastelandZ_server.confSet the GATEWAY_URL line to your gateway’s address (keep the trailing slash), then save: Ctrl+O, Enter, Ctrl+X.
b Give it the gateway key
Open the secrets file:
nano /opt/reforger/profiles/server1/profile/hf_wastelandz/configs/HFWastelandZ_secrets.confAdd a line — API_KEY then a space then the same gateway key from Step 6 (the one in config.py for this server). Save and exit the same way. A ready-made template ships at /opt/wastelandz/configs/HFWastelandZ_secrets.conf.example.
c Add the mission reward templates
cp -r /opt/wastelandz/missions/rewards /opt/reforger/profiles/server1/profile/hf_wastelandz/missions/These are the loot crates and vehicles missions hand out. (Missions themselves are built in-game — see missions/README.md.)
Now start it again (same command). Player data saves to the database — you’re live.
+ Two optional asides (not required to go live)
Those aren’t HF settings — they live in the Reforger config server1.json (the name and passwordAdmin fields). Change them any time:
nano /opt/reforger/configs/server1.jsonTo customize loot/economy/etc., rename the kit’s /opt/wastelandz/configs/*.example files (drop .example) and copy them into the profile’s hf_wastelandz/configs/ folder. configs/README.md documents each one — none of it is needed to go live.
d Make yourself the admin
Do this once it’s running. Wasteland-Z admins are keyed by Bohemia Identity GUID — a lowercase xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx code tied to your Bohemia account. It is NOT your Steam number. There are two ways to find yours:
1) In the game (easiest): launch Arma Reforger, click your profile in the upper-right corner — your Identity GUID is listed there. Copy it.
2) From the server log: join the running server once, then read it out of the log:
grep -rh "Authenticated player" /opt/reforger/profiles/server1/logs/ | tailCopy the identityId= value on the line with your player name. (After Part 2 makes it a service, you can use sudo journalctl -u wz-server1 | grep "Authenticated player" instead.)
Add yourself as OWNER in the admin file:
nano /opt/reforger/profiles/server1/profile/hf_wastelandz/configs/HFWastelandZ_admins.confOWNER a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d # ← your GUID from the log, not this placeholderWasteland-Z matches admins by exact ID text. A stray trailing space after the GUID, or Windows line-endings (from editing or pasting on Windows), are invisible in most editors but make the ID silently fail to match — you stay a regular player, with no error shown. After saving, strip any hidden characters and verify:
cd /opt/reforger/profiles/server1/profile/hf_wastelandz/configs sed -i 's/[[:space:]]*$//' HFWastelandZ_admins.conf cat -A HFWastelandZ_admins.conf
In the cat -A output your OWNER line must end in just $ — no ^M and no space before it. Why: RESOLVED July 5, 2026 — the mod’s config parser now strips trailing whitespace and Windows line-endings (^M) at the read boundary, so your ID matches even with hidden characters. This sed line is kept as belt-and-suspenders (and is still needed on older mod builds) — it never hurts to run. Restart the server after editing — then F8 opens the admin menu and /zeus gives you Game Master.
Right now you’re starting the game server by hand to confirm it works. Part 2 → Step B turns it into a background service (wz-server1) that starts on boot and restarts itself if it crashes — do that once you’ve seen it boot and connect to the gateway.
Run · monitor · restart
Run the gateway as a service so it starts on its own and survives reboots. Built-in Linux tools only.
Make it a service (once)
Create the service file:
sudo nano /etc/systemd/system/wz-gateway.servicePaste this in (change youruser to your Linux username), then save and exit — in nano: Ctrl+O, Enter, then Ctrl+X:
[Unit] Description=WastelandZ Gateway After=network.target mysql.service [Service] WorkingDirectory=/opt/wastelandz-gateway ExecStart=/opt/wastelandz-gateway/venv/bin/python /opt/wastelandz-gateway/gateway.py Restart=on-failure User=youruser [Install] WantedBy=multi-user.target
That ExecStart path is the venv — pointing systemd straight at venv/bin/python runs the gateway inside the venv automatically; you do not activate it for a service. (A no-venv install uses /usr/bin/python3 instead.) Set User= to your Linux username, and make sure that user owns /opt/wastelandz-gateway (the chown -R from Step 5). Then turn it on — this starts it now and on every reboot:
sudo systemctl daemon-reload sudo systemctl enable --now wz-gateway
Don’t want to type it? The kit ships this file ready-made: copy /opt/wastelandz/server/wz-gateway.service.example to /etc/systemd/system/wz-gateway.service and just change youruser.
Make the game server a service
Same idea as Step A, but for the game server. (You did its one-time first boot back in Part 1, Step 9 — that generated its config files; this step makes it run permanently in the background.) First make sure your user owns what the server writes to (its profiles/ and logs/) — needed if you ran any of the install as root:
sudo chown -R youruser:youruser /opt/reforgerThen drop in the ready-made service file and set your username:
sudo cp /opt/wastelandz/server/wz-server1.service.example /etc/systemd/system/wz-server1.service sudo nano /etc/systemd/system/wz-server1.service # set User= to your Linux username (save: Ctrl+O, Enter, Ctrl+X) sudo systemctl daemon-reload sudo systemctl enable --now wz-server1 sudo systemctl status wz-server1 # look for "active (running)"
The game server now starts on boot and restarts itself if it crashes — same as the gateway.
Your three services: wz-server1 (the game server), wz-gateway (the gateway), and mysql (the database). Every command below works on any of them — just swap the name. After a reboot they start on their own; if you ever start them by hand, the order is mysql → wz-gateway → wz-server1.
Is it running?
sudo systemctl status wz-server1Green active (running) = good. It opens a scrollable view — press q to exit back to the prompt.
Restart / stop / start
sudo systemctl restart wz-gateway sudo systemctl stop wz-gateway sudo systemctl start wz-gateway
Watch live logs (monitor)
journalctl -u wz-gateway -fCtrl+C stops watching (the service keeps running).
Is it alive?
curl http://127.0.0.1:5000/api/pingRestart MySQL
sudo systemctl restart mysqlStart on boot (on / off)
sudo systemctl enable wz-server1 sudo systemctl disable wz-server1
Your earlier enable --now already turned both on — they auto-start after a reboot.
Back up your data (do this regularly)
mysqldump -u wastelandz -p wastelandz > wastelandz_backup_$(date +%F).sqlThat file is your whole server’s save — keep copies somewhere safe.
Two or three servers on one box
One database, one gateway, several game servers — a hive. Players keep the same money, bank and gear on every server; each server keeps its own world (positions, placed objects, map). The Windows tab’s “Part 4” ports table applies here too: game 2001/2002/2003, browser 17777/17778/17779, gateway 5000/5001/5002.
The finished two-server setup, and how the pieces talk:
players → UDP 2001/17777 → wz-server1 (Everon) → http://127.0.0.1:5000 + key #1 ─┐ players → UDP 2002/17778 → wz-server2 (Arland) → http://127.0.0.1:5001 + key #2 ─┤ └→ wz-gateway → mysql The gateway tells the servers apart by the PORT each one calls (5000 vs 5001) and proves it with that server's key. Both ports are ONE gateway process, and everything right of the players is local to the box — nothing exposed.
You install the game once. /opt/reforger/server/ and the shared workshop/ mods folder serve every server. Each extra server is just a config file + profile folder + systemd unit with different numbers. To add server 2:
# its own config — new ports, its own map, its own name. # The kit ships one pre-made (ports 2002/17778 + Arland already set): cp /opt/wastelandz/server/server2.json.example /opt/reforger/configs/server2.json nano /opt/reforger/configs/server2.json
In server2.json: set your server name + admin password (ports 2002/17778 and the Arland map are pre-set). Save and exit nano: Ctrl+O, Enter, Ctrl+X. The map is the scenarioId line — Wasteland-Z runs on top of any Game Master scenario, so a two-server hive can offer two different worlds:
# server1.json — Everon (the big island): "scenarioId": "{59AD59368755F41A}Missions/21_GM_Eden.conf" # server2.json — Arland (the smaller southern island): "scenarioId": "{2BBBE828037C6F4B}Missions/22_GM_Arland.conf"
Any other map — including community maps — works the same way. Find its ID on the Workshop website: open the map mod’s page at reforger.armaplatform.com/workshop and click its Scenarios tab — the ScenarioId shown there (it looks like {GUID}Missions/Name.conf) is what goes in scenarioId. Add that map mod to the same server’s mods list too.
Each server starts with the same program, pointed at its own config + profile (the profile folder is created on first start):
# server 1 — Everon /opt/reforger/server/ArmaReforgerServer -config /opt/reforger/configs/server1.json -profile /opt/reforger/profiles/server1 -addonDownloadDir /opt/reforger/workshop -maxFPS 60 # server 2 — Arland /opt/reforger/server/ArmaReforgerServer -config /opt/reforger/configs/server2.json -profile /opt/reforger/profiles/server2 -addonDownloadDir /opt/reforger/workshop -maxFPS 60
Then wire server 2 into the hive exactly like Step 9 did for server 1:
- Gateway: in
config.py, un-comment theserver-2line inSERVERSand give it its own randomapi_key(Step 6 command), thensudo systemctl restart wz-gateway— it now listens on 5000 and 5001. - Wire it: in
/opt/reforger/profiles/server2/profile/hf_wastelandz/configs/(created on server 2’s first start), setGATEWAY_URL http://127.0.0.1:5001/and put server 2’s key in itsHFWastelandZ_secrets.conf. - Service: copy the kit’s
/opt/wastelandz/server/wz-server2.service.exampleto/etc/systemd/system/wz-server2.service, changeyouruser, thensudo systemctl daemon-reloadandsudo systemctl enable --now wz-server2. Ifufwis on, open UDP 2002 + 17778.
Each server gets its own gateway port and its own random api_key — that’s how the gateway tells them apart. Never reuse a key across servers.
Each Reforger server is heavy — roughly a few CPU cores and 4–8 GB RAM per server under load. Two servers want a strong 8-core machine; three want more. The gateway and MySQL are lightweight by comparison.
Start / stop / restart anything — one pattern
Every piece is a service with a name — wz-server1, wz-server2, wz-gateway, mysql — and one command pattern drives them all. Learn it once with server 1:
sudo systemctl start wz-server1 # start it sudo systemctl stop wz-server1 # stop it (players get dropped) sudo systemctl restart wz-server1 # stop + start in one go sudo systemctl status wz-server1 # running or not? (green "active" = good) journalctl -u wz-server1 -f # watch its live log — Ctrl+C stops watching, not the server
Swap the name for any other piece: bounce only server 2 = sudo systemctl restart wz-server2; stop the gateway = sudo systemctl stop wz-gateway; restart the database = sudo systemctl restart mysql. Each piece is independent — players on server 1 keep playing while you bounce server 2.
Order? After a full stop (or a reboot where something didn’t come up): mysql first, then wz-gateway, then the game servers. A briefly-down gateway doesn’t crash the game servers — saves pause and Wasteland-Z resyncs every player automatically when it comes back — but don’t leave it down long.
Big box? Give each server its own cores
RAM first — there’s nothing to divide. Linux hands out memory on demand: a full 128-player Reforger server uses roughly 8–16 GB, MySQL + the gateway a few more. Even three servers fit comfortably in 64 GB. The only setting worth adding is a per-server safety cap (below) so a memory leak can never take down the whole box.
CPU is the part worth splitting. A big AMD chip (like a 16-core Ryzen 7950X3D) is really two groups of 8 cores glued together. Each group shares one pot of very fast memory called cache — the chip’s short-term memory. A game server runs best when its group belongs to it alone; two servers squeezed into one group fight over the pot and both get slower. The fix is one line per server that says “you may only use these cores” — one server per group.
1 See your two groups
Run (looks, changes nothing):
lscpu -eOne row per CPU number. Look at the last digit on each row: rows ending in 0 are group one, rows ending in 1 are group two. On a 16-core AMD chip you’ll typically see: CPU numbers 0–7 and 16–23 end in 0 (group one), 8–15 and 24–31 end in 1 (group two). (Why 32 CPU numbers on a 16-core chip? Each core can run two things at once, so it shows up twice.)
On an “X3D” chip, one group has a much bigger memory pot — the fast one. See which:
cat /sys/devices/system/cpu/cpu0/cache/index3/size /sys/devices/system/cpu/cpu8/cache/index3/size98304K ← 96 MB = the BIG pot. First line is cpu0, so group one has it. 32768K ← 32 MB = the normal pot (cpu8’s group — group two).
Give the big-pot group to your busiest server. If the 96 MB shows up on the second line instead, swap the two CPUAffinity lines in Step 2. Not an X3D chip? Both lines read the same — the split still works, there’s just no favourite group.
2 Pin each server to its group
Edit each server’s service file (the kit’s .service.example already ships these two lines commented out — you just delete the leading #):
sudo nano /etc/systemd/system/wz-server1.service # then repeat for wz-server2.service
In the [Service] section of each file, uncomment (or add) its own pair of lines — wz-server1.service gets group one, wz-server2.service gets group two (they are separate files; never put both pairs in one). Save each (Ctrl+O, Enter, Ctrl+X):
# ── these two lines go in wz-server1.service (group one — the big-pot group) ── CPUAffinity=0-7 16-23 MemoryMax=32G # ── and these two go in the SEPARATE file wz-server2.service (group two) ── CPUAffinity=8-15 24-31 MemoryMax=32G
3 Apply
sudo systemctl daemon-reload sudo systemctl restart wz-server1 wz-server2
CPUAffinity = “this service may only run on these cores.” MemoryMax = if the server ever leaks past the cap, systemd kills it (and Restart=on-failure brings it right back) instead of the box dying. Leave the gateway and mysql unpinned — they’re lightweight and slot into whatever’s idle. Verify with htop: each server’s load stays inside its own core block. One core pegged at 100% while its neighbours idle is the engine’s normal single-thread ceiling, not a problem to fix — the levers for a struggling full server are aiLimit in serverN.json and Wasteland-Z’s mission/AI density settings.
Cheat-sheet: 1–4 servers on a 16-core box (two 8-core groups; CPU numbers per the usual AMD layout — verify yours with lscpu -e, Step 1):
| Setup | Server & players | CPUAffinity= | MemoryMax= |
|---|---|---|---|
| 1 server (up to 128) | wz-server1 · 128 | none needed (whole chip; or 0-7 16-23 for the big-cache group) | 32G |
| 2 servers (2×128) | wz-server1 · 128 | 0-7 16-23 | 32G |
| wz-server2 · 128 | 8-15 24-31 | 32G | |
| 3 servers (2×128 + 1×64) | wz-server1 · 128 | 0-7 16-23 | 32G |
| wz-server2 · 128 | 8-15 24-31 | 32G | |
| wz-server3 · 64 | unpinned (scheduler fills the gaps) | 24G | |
| 4 servers (4×64 or 4×32) | wz-server1 · 64 | 0-3 16-19 | 24G |
| wz-server2 · 64 | 4-7 20-23 | 24G | |
| wz-server3 · 64 | 8-11 24-27 | 24G | |
| wz-server4 · 64 | 12-15 28-31 | 24G |
The logic: 1–2 servers → a whole group each (max cache per server). 4 servers → half a group (4 cores) each — plenty at 32–64 players, and no server ever spans both groups. 3 servers is the awkward count: keep the two big ones on their own groups and let the third float. Player caps live in each serverN.json (maxPlayers); what actually loads a core is AI + player count together, so watch htop on busy nights and adjust aiLimit before touching the core map. RAM: even the 4-server row uses under half of a 128 GB box.
Different CPU? Step 1 tells you the truth about any chip. If every row’s last digit is 0, your chip is one group (most older Intels, e.g. an i9-9900K): there’s no favourite to pick — split the cores in half (first half + their twins to server 1, the rest to server 2) and expect lower comfortable player caps on older chips. Newer Intels (12th gen up, e.g. an i7-13700K) mix fast P-cores and small E-cores — in lscpu -e the P-cores appear twice (they have twins), E-cores once. Pin game servers to P-cores only and leave the E-cores unpinned — they carry the gateway, MySQL and the system.
Troubleshooting
- “Database connection failed” —
DB_PASSWORDinconfig.pydoesn’t match Step 4, or MySQL is stopped (sudo systemctl status mysql). - Service won’t start — run
journalctl -u wz-gateway -eto see why; usually a wrong path or username in the service file. - Port 5000 in use — change
portinconfig.pyand updateGATEWAY_URL. - Money/gear not saving —
GATEWAY_URLorapi_keymismatch between the game server andconfig.py. - Last location & kept gear don’t restore on relog (but money & inventory DO) — the game server’s
SERVER_ID(inHFWastelandZ_server.conf) doesn’t match theserver_idthe gateway uses for it (itsSERVERSentry /SERVER_ID). Money/inventory are hive-wide so they still work; only per-server data (position, kept-on-relog gear) needs the ids to match. SetSERVER_IDto the gateway’s id and restart. The game log printsSERVER_ID MISMATCHwith both values when it detects this —grep -i "SERVER_ID MISMATCH"your log.
Add, remove & track mods
Same on Windows and Linux. There is no installer — the mods list inside your server config (server1.json) is the mod manager. On every start the server reads that list, auto-downloads anything missing from the Reforger Workshop into your workshop folder, and loads exactly what’s listed — nothing else.
Add a mod
Find it on the official Workshop site: reforger.armaplatform.com/workshop. The mod’s ID is right in its page URL — the 16 characters before the name, e.g. …/workshop/68A616565DECAB19-wasteland-z. Add one block to the mods list and restart the server:
The kit already pre-lists it in every mods block, so you don’t need to add it by hand — but here’s its page: reforger.armaplatform.com/workshop/68A616565DECAB19 (mod ID 68A616565DECAB19).
"mods": [
{
"modId": "68A616565DECAB19",
"name": "Wasteland-Z"
},
{
"modId": "ABCDEF1234567890",
"name": "Cool Helmet Pack"
},
{
"modId": "0123456789ABCDEF",
"name": "Winter Uniforms"
}
]The name is your own label — write whatever helps you remember what it is. The commas are the one gotcha: every mod’s closing } gets a comma except the last one — and never a semicolon, JSON doesn’t use them. So when you add a mod at the end: the block that used to be last gains a comma, the new last block has none.
Remove a mod — including a problem mod
Delete its block from the list, restart. That’s the whole procedure — the server only loads what’s listed. The mod’s downloaded files stay in the workshop folder but are completely inert; if you want the disk space back, delete the folder named with that mod’s ID inside the workshop folder.
Can’t I just comment a mod out?
Not in this file. server1.json is JSON, and JSON forbids comments — one // line and the server refuses the whole config. So in the json, deleting the block is the only off switch. The convenient middle ground is a parking file: keep a plain text file next to your configs that nothing reads, and move benched mod blocks there instead of losing them:
mods-parked.txt — your parking lot; the server never reads this file.
Copy a block back into server1.json's "mods" list to re-enable it.
{ "modId": "ABCDEF1234567890", "name": "Cool Helmet Pack" }, broke after 1.7 update, retry later
{ "modId": "0123456789ABCDEF", "name": "Winter Uniforms" }, summer season — bring back in December
{ "modId": "FEDCBA9876543210", "name": "Extra Car Pack" }, testing caused rubber-banding(Wasteland-Z’s own .conf files are different — those are KEY VALUE format and take # comments freely. Only the game server’s .json is strict.)
Track your mods
The mods list is the single source of truth — one block per mod, nothing can load that isn’t in it. Running several servers? Each serverN.json has its own list, so server 1 and server 2 can run different mod sets. To see what a server actually loaded, its boot log prints every addon as it starts.
Wasteland-Z is a game mode — it owns the gameplay. Content mods (weapons, clothing, vehicles, buildings) sit alongside it fine; adding another game-mode mod makes the two fight. If a mod’s Workshop page says “game mode,” it doesn’t belong on a Wasteland-Z server.
Remove the last mod you added, restart. If it broke right after a Reforger update instead: mod authors need a few days to catch up with game patches — remove your extra mods, restart, then add them back one at a time as they’re updated.
Players, roles & reserved slots
This part is the same on Windows and Linux — it’s done with config files and in-game commands.
The five roles
Every player has a role. Higher beats lower. Roles live in one file: $profile:HFWastelandZ_admins.conf, keyed by Bohemia Identity GUID (a lowercase xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx code — not your Steam number; see Part 1 → Step 9d for how to find yours).
| Role | Can do |
|---|---|
| OWNER | Everything, including /admin restart. Set by editing the file only. |
| ADMIN | Game Master (Zeus), promote/demote others, save, all mission & spot editing. |
| MOD | Kick, ban, mute, teleport, heal, god, announce. |
| TRUSTED | Donor / verified helper (reserved for future perks). |
| EVERYONE | Default — every normal player. No line needed. |
Make someone a mod, admin, or owner
Your first admin — and the only way to set OWNER — is by editing the file. Add a line and restart:
# in $profile:HFWastelandZ_admins.conf
OWNER a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d
ADMIN b2c3d4e5-6f7a-8b9c-0d1e-2f3a4b5c6d7e
MOD c3d4e5f6-7a8b-9c0d-1e2f-3a4b5c6d7e8fThose are Bohemia Identity GUIDs (lowercase 8-4-4-4-12 hex), one per admin — find yours via Part 1 → Step 9d. Put no trailing space after the GUID (see the gotcha in Step 9d). Anyone not listed is EVERYONE.
After you have one admin, change roles live, no restart, from in-game chat:
/admin promote <name|playerId> <EVERYONE|TRUSTED|MOD|ADMIN>
You must be ADMIN or OWNER to change roles. An ADMIN can grant any role up to and including ADMIN. OWNER is never granted in-game — it’s file-only so no one can lock you out, so seed yourself as OWNER in the file first. You can change anyone at or below your own rank (an ADMIN can demote a peer ADMIN), but never someone above you — and an OWNER can never be changed in-game by anyone.
You can also change roles in the game — open the F8 admin menu → Players tab. The right-hand STAFF list shows everyone with a role (including offline people); click a player or staff row, then a role button (twice to confirm).
See who has what role
/admin who
Lists everyone online with their role. Any MOD or higher can run it.
Change what each command needs (command tiers)
Every command has a minimum role. To run it, your role must be equal or higher. Change any command’s required role in $profile:HFWastelandZ_command_tiers.conf:
# format: <command>.<subcommand> = <ROLE> admin.god = OWNER # only owner can use god mode admin.kick = ADMIN # mods can no longer kick
So admins.conf sets what role each player has, and command_tiers.conf sets what role each command needs. Restart to apply changes.
Reserved login slots (staff always get in)
Keeps a couple of slots open so your staff can always join a full server, without permanently wasting seats. Set these in $profile:HFWastelandZ_server.conf:
| Setting | Default | What it does |
|---|---|---|
| RESERVED_SLOTS_ENABLED | 0 | Master on/off. Set to 1 to turn it on. |
| RESERVED_BUFFER | 2 | Slots always kept free so staff join instantly. |
| RESERVED_HIGHRISK_COUNT | 8 | How many newest regular players are “bumpable.” |
| RESERVED_MIN_TIER | 20 | Lowest role treated as staff (20 = MOD). |
| RESERVED_TOTAL_SLOTS | 0 | Leave 0 on a real server (read automatically). Only set on a Workbench test host. |
Setup: in the game’s config.json, set game.maxPlayers to your playable count plus the buffer, and set RESERVED_TOTAL_SLOTS to that same number. Example: 128 players → maxPlayers 130, RESERVED_BUFFER 2. ADMIN/OWNER always get in; MOD only bumps regular players.
It runs on the server, so watch the server console / log — set HF_DEBUG_ADMIN 1 in server.conf and you’ll see lines like ReservedSlots: ON total=130 buffer=2… and BUMP… when it acts. Players in a bumpable slot also see a “high-risk” banner in their HUD.