WzServer Setup health check → /api/ping

(EXPERIMENTAL DOCUMENTATION - UNTESTED)

Written with AI assistance — the information here may not be correct. As a server admin, you use this guide at your own risk. Full disclaimer shown on first visit.

Wasteland-Z · Dedicated Server

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.

Game Server
Arma Reforger + the Wasteland-Z mod (from the Workshop). Where people play.
Gateway
The small program in this download. It carries player data between the game and the database.
MySQL
The database. Stores money, gear, progress, and the world — so nothing is lost on restart.

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.py and 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 server builds its own config files — you don’t have to

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\.

Before you begin

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.)

Choose your system
Part 1

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.

Planning 2–3 servers?

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.

1

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.

2

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
Game updated?

Whenever Reforger gets an official update, stop your servers and run this same script again. It only downloads what changed.

3

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.

Router / firewall

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.


Part 2

Database & gateway (one time)

Do these eight steps in order. Copy each command with the button on its right.

1

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
2

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;
Pick a password

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.

3

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.sql

It asks for the wastelandz password (from Step 2). No error message means it worked.

4

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.txt
5

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:

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 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.

Keep it private

config.py holds your password and key. Never share it or upload it anywhere public.

6

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.

7

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
Two hard rules

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.

8

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.confGATEWAY_URL already defaults to http://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_KEY followed by the same key you put in the gateway’s config.py in 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 .example from each name, and copy them into that same profile\hf_wastelandz\configs\ folder. configs\README.md lists 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 — see missions/README.md.)

Start the server again. Player data now saves to the database. You’re live.


Part 3

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.sql

Keep a copy of that file somewhere safe. It is your whole server’s save.

Troubleshooting

  • “Database connection failed” — the password in config.py doesn’t match Step 2, or MySQL isn’t running.
  • Port 5000 already in use — change port in config.py (and update GATEWAY_URL to match).
  • /api/ping won’t load — the gateway window isn’t running. Start it.
  • Money/gear not savingGATEWAY_URL or api_key don’t match between the game server and config.py.
  • Last location & kept gear don’t restore on relog (but money & inventory DO) — your game server’s SERVER_ID (in HFWastelandZ_server.conf) doesn’t match the server_id the 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. Set SERVER_ID to the gateway’s id and restart. The game log prints SERVER_ID MISMATCH with both values when it detects this — grep for it.

Part 4

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 1Server 2Server 3
Game port (UDP, forward it)200120022003
Browser port (UDP, forward it)177771777817779
Gateway port (local only)500050015002
Config fileserver1.jsonserver2.jsonserver3.json
Profile folderprofiles\server1profiles\server2profiles\server3

To add server 2 (server 3 is the same pattern):

  • Config: copy this download’s server\server2.json.example to C:\reforger\configs\server2.json — ports 2002/17778 and the Arland map are pre-set; change name and the admin password. The map is the scenarioId line — Wasteland-Z runs on top of any Game Master scenario:
    Everon (the big island):
    "scenarioId": "{59AD59368755F41A}Missions/21_GM_Eden.conf"
    
    Arland (the smaller southern island):
    "scenarioId": "{2BBBE828037C6F4B}Missions/22_GM_Arland.conf"
    e.g. server 1 on Everon, server 2 on Arland — same hive, so players keep their money, bank and gear when they switch.

    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.

  • Batch files: copy start_server1.batstart_server2.bat and stop_server1.batstop_server2.bat. Inside both, change every server1 to server2 and the title WZ-Server-1 to WZ-Server-2. (The install folder and workshop\ mods folder are shared — don’t copy those.)
  • Gateway: in config.py, un-comment the server-2 line in SERVERS and give it its own random api_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), set GATEWAY_URL http://127.0.0.1:5001/ and put server 2’s key in its HFWastelandZ_secrets.conf.
  • Match the SERVER_ID (critical): in server 2’s HFWastelandZ_server.conf, set SERVER_ID server-2 so it exactly matches that server’s server_id in the gateway’s SERVERS list. 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 prints SERVER_ID MISMATCH if it’s wrong.
  • Start it: remove the rem in front of the server-2 lines in start_all.bat. Forward UDP 2002 + 17778 in your router.
One key per server

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.

Will my PC handle it?

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.exeSet 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):

SetupServer & players/affinity mask
1 server (up to 128)WZ-Server-1 · 128none needed (whole chip; or FFFF for the big-cache group)
2 servers (2×128)WZ-Server-1 · 128FFFF
WZ-Server-2 · 128FFFF0000
3 servers (2×128 + 1×64)WZ-Server-1 · 128FFFF
WZ-Server-2 · 128FFFF0000
WZ-Server-3 · 64none (floats in the gaps)
4 servers (4×64 or 4×32)WZ-Server-1 · 64FF
WZ-Server-2 · 64FF00
WZ-Server-3 · 64FF0000
WZ-Server-4 · 64FF000000

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.

Part 1

Set it up (one time)

These are Ubuntu commands. Type them into the server’s terminal (connect with SSH). Every command is explained.

Planning 2–3 servers?

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.

New to Linux? The 60-second picture

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)
0

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.

1

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.

2

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
Game updated?

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.json

Don’t start it yet — it needs the database and gateway first (Steps 3–8). Step 9 does the first start.

3

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_installation

It asks a series of questions. Recommended answers:

  • VALIDATE PASSWORD component? — optional. N is 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 wastelandz login.
  • Remove test database and access to it?Y — the default test database is open to everyone.
  • Reload privilege tables now?Y — applies it all right away.
Safe to say yes

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.

4

Create the database

Open MySQL as admin:

sudo mysql

At 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;
Pick a password

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.

5

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.

Ownership — replace youruser

Change 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-gateway

Shortcut: 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.

Why the virtual environment (venv)?

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.

No-venv option (older systems)

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
6

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.

Keep it private

config.py holds your password and key. Never share it or upload it anywhere public.

7

Test that it runs

venv/bin/python gateway.py

This 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.)

Optional — curl check (needs a second terminal)

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/ping
8

Firewall

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
Two hard rules

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.)

Ports at a glance (per server — all UDP)
  • 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).

9

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/.

You’re running on defaults

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.conf

Set 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.conf

Add 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)
Server name & admin password

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.json
Optional — tune loot / economy later

To 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/ | tail

Copy 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.conf
OWNER a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d   # ← your GUID from the log, not this placeholder
⚠ No trailing spaces or Windows line-endings in this file

Wasteland-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.

Next: make it run on its own

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.


Part 2

Run · monitor · restart

Run the gateway as a service so it starts on its own and survives reboots. Built-in Linux tools only.

A

Make it a service (once)

Create the service file:

sudo nano /etc/systemd/system/wz-gateway.service

Paste 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.

B

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/reforger

Then 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 mysqlwz-gatewaywz-server1.

Is it running?

sudo systemctl status wz-server1

Green 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 -f

Ctrl+C stops watching (the service keeps running).

Is it alive?

curl http://127.0.0.1:5000/api/ping

Restart MySQL

sudo systemctl restart mysql

Start 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).sql

That file is your whole server’s save — keep copies somewhere safe.


Part 3

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 the server-2 line in SERVERS and give it its own random api_key (Step 6 command), then sudo 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), set GATEWAY_URL http://127.0.0.1:5001/ and put server 2’s key in its HFWastelandZ_secrets.conf.
  • Service: copy the kit’s /opt/wastelandz/server/wz-server2.service.example to /etc/systemd/system/wz-server2.service, change youruser, then sudo systemctl daemon-reload and sudo systemctl enable --now wz-server2. If ufw is on, open UDP 2002 + 17778.
One key per server

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.

Will the box handle it?

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 -e

One 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/size
98304K   ← 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):

SetupServer & playersCPUAffinity=MemoryMax=
1 server (up to 128)wz-server1 · 128none needed (whole chip; or 0-7 16-23 for the big-cache group)32G
2 servers (2×128)wz-server1 · 1280-7 16-2332G
wz-server2 · 1288-15 24-3132G
3 servers (2×128 + 1×64)wz-server1 · 1280-7 16-2332G
wz-server2 · 1288-15 24-3132G
wz-server3 · 64unpinned (scheduler fills the gaps)24G
4 servers (4×64 or 4×32)wz-server1 · 640-3 16-1924G
wz-server2 · 644-7 20-2324G
wz-server3 · 648-11 24-2724G
wz-server4 · 6412-15 28-3124G

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_PASSWORD in config.py doesn’t match Step 4, or MySQL is stopped (sudo systemctl status mysql).
  • Service won’t start — run journalctl -u wz-gateway -e to see why; usually a wrong path or username in the service file.
  • Port 5000 in use — change port in config.py and update GATEWAY_URL.
  • Money/gear not savingGATEWAY_URL or api_key mismatch between the game server and config.py.
  • Last location & kept gear don’t restore on relog (but money & inventory DO) — the game server’s SERVER_ID (in HFWastelandZ_server.conf) doesn’t match the server_id the gateway uses for it (its SERVERS entry / 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. Set SERVER_ID to the gateway’s id and restart. The game log prints SERVER_ID MISMATCH with 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:

Wasteland-Z is live on the Workshop

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.

One game mode at a time

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.

Server broke after adding a mod — or after a game update?

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).

RoleCan do
OWNEREverything, including /admin restart. Set by editing the file only.
ADMINGame Master (Zeus), promote/demote others, save, all mission & spot editing.
MODKick, ban, mute, teleport, heal, god, announce.
TRUSTEDDonor / verified helper (reserved for future perks).
EVERYONEDefault — 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-3a4b5c6d7e8f

Those 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>
The rules

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:

SettingDefaultWhat it does
RESERVED_SLOTS_ENABLED0Master on/off. Set to 1 to turn it on.
RESERVED_BUFFER2Slots always kept free so staff join instantly.
RESERVED_HIGHRISK_COUNT8How many newest regular players are “bumpable.”
RESERVED_MIN_TIER20Lowest role treated as staff (20 = MOD).
RESERVED_TOTAL_SLOTS0Leave 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.

How to see it working

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.

Wasteland-Z · Admin Guide

Missions & the Mission Editor

Build your own missions in-game — no files to hand-write. Place enemies and structures with Zeus, chain them into a flow with logic steps, and let the pool spawn them on a timer. This is how it all fits together, in the order you actually do it.

A mission is Logic + Events

Two building blocks, and that’s the whole system:

Event
A scene you place in the world with Zeus — the enemies, the buildings, and markers showing where vehicles, loot and reinforcements appear. Events are the mission content.
+
Logic
The flow that drives the mission — show a message, wait until the enemies are dead, hand out a reward, clean up. Logic runs the mission.

A reward is the third piece — the thing players get (a loot crate or a vehicle). You build rewards once and reuse them across any mission.

What a mission looks like

A mission is an ordered list of steps — some are events (spawn a scene), the rest are logic (show a message, wait for a condition, hand out a reward, end the mission). A common shape: show a heads-up → spawn the event → wait until the enemies are dead → spawn a reward → complete. You arrange these steps in the Mission Editor.

Grab the example missions

You don’t have to start from a blank page. Download the example missions from the Wasteland-Z SETUP repo (the missions/ folder — copy events/, templates/ and rewards/ into your server’s <profile>/hf_wastelandz/missions/), then open them in the editor to see how a working mission is put together — then build your own the same way. More examples get added over time, so check back.

The pool runs it on a timer

You don’t spawn missions by hand for players. Finished missions go into the Mission Pool, which spawns them automatically — on a per-tier timer, away from players, with cooldowns so the same spot doesn’t reused instantly. You just build missions and turn the pool on.


Before you start

One-time setup

Do these once. After that, everything is in-game in the F8 admin menu.

A

Download & install the templates

Rewards are what missions hand out — loot crates and vehicles. Download the ready-made mission & reward templates from the Wasteland-Z SETUP GitHub, then copy the rewards into your server profile:

FROM:  missions/rewards/     # from the SETUP download
TO:    <profile>/hf_wastelandz/missions/rewards/

<profile> is wherever your server’s -profile points. Then in-game: F8 → MISSIONS → REWARDS → RELOAD — the templates appear in the list. If the panel shows 0 templates, the _index.json file didn’t get copied — copy it in too.

B

Turn on mission markers, and drop spawn markers on the map

The pool needs to know where missions may appear. You place spawn markers on the map — each one is a candidate location.

  • Turn on Debug / Mission markers so you can see them.
  • Drop a spawn marker and tag it EASY, MEDIUM, or HARD. Drop as many as you like — more markers means more variety in where missions land.
  • A marker with no tier tag accepts any tier. A tagged marker only accepts missions of that tier.
Keep them apart, keep them clear

The pool won’t spawn a mission within ~50 m of a player, and each spot goes on a ~10-minute cooldown after its mission ends. Spread markers around the map and away from busy areas.


Part 1

Build the Event (the scene)

The event is what players actually see and fight. You build it live with Zeus.

1

Create the event and set its tier

F8 → MISSIONS → EVENTS. Type a name, pick the tier / type, and click NEW EVENT. You’re now in event-edit mode.

2

Place the arrow, then build in Zeus

Press F8 to close the admin menu. An arrow appears in the world — that’s the scene’s reference point and facing.

  • Move the arrow to an open area where the scene should sit.
  • Open Zeus (hold Y) and place your AI soldiers and buildings / cover.
  • The first thing you place becomes the anchor — everything else is stored relative to it, so the whole scene keeps its shape wherever the mission spawns.
The AI stay frozen while you build

Enemies you place are automatically suspended and made damage-proof during editing — they won’t shoot you and you can’t accidentally kill them. They wake up only when the mission spawns for real.

3

Drop your markers

Back in the EVENTS tab, use the DROP buttons to mark where things go. Each marker faces the way you’re looking when you drop it — so stand where it goes, face the right direction, then click.

ButtonMarks where…
DROP VEHa vehicle spawns (point the way the nose should face).
DROP LOOTa loot crate / reward drops.
DROP WAVEa wave of enemies spawns (reinforcements, defenders).
DROP PATROL coming soona patrol route waypoint. (Route-following is being finished — see below.)
4

Save the event

Press F8 and click SAVE EVENT. The scene disappears from the world — that’s expected. It’s saved now; you can select it and spawn it again to check it, or stop it.


Part 2

Build the Mission (the flow)

5

Create the mission and load it into the editor

F8 → MISSIONS. Type a mission name, pick a tier (EASY / MEDIUM / HARD), and save — the name now appears in the list. Select it and click LOAD to open the full-screen Mission Editor.

Tip: open an existing mission first and use it as a reference for how the logic is laid out.

6

Add the event, the logic, and the rewards

  • Add the event: pick it from the EVENT LIBRARY and click ADD EVENT.
  • Add logic: click a logic type, set its options (a value box, condition buttons, or a picker — the panel changes to match), then click ADD LOGIC. See the logic reference below.
  • Add rewards: use SPAWN_REWARD and pick the reward from the list.
  • Reorder or fix steps with MOVE UP / MOVE DOWN, REPLACE SEL, and REMOVE NODE.
If adding logic glitches

Sometimes adding a logic step hangs the editor — a node won’t add, or the list stops responding. If that happens, exit the Mission Editor and go back in, then keep going. It’s harmless and you won’t lose saved work.

7

Save the mission

Click SAVE MISSION in the footer. Your flow is written to disk and is ready to test or pool.


Part 3

Pool it & run

8

Add the mission to the pool and start it

  • In the Mission Pool panel, select your mission and ADD it to the rotation.
  • Click START (or START ALL). The pool now spawns pooled missions on their tier timers.
  • Pause / resume per tier or all at once, any time.
TierDefault spawn interval
EASYevery 15 minutes
MEDIUMevery 30 minutes
HARDevery 60 minutes

One mission per tier spawns per interval (a steady trickle, not a burst). Intervals and the master on/off are tunable in active_pool.json. To test a single mission immediately, spawn it directly from the editor with SPAWN MISSION HERE.


Logic steps

The editor builds every step for you — you click the type, then set its options with a value box, condition buttons, or a picker. These are the ones you’ll use most.

StepWhat it doesYou set
Popup messageShows a message to everyone, then continues.The message text.
Wait until AI deadPauses the mission until the targeted enemies are gone.Click the event, ADD TARGET the group(s), pick ALL / ANY / LEADER.
Wait (duration)Pauses for a set number of seconds.Seconds.
Spawn rewardDrops a reward template at a loot marker.ADD TARGET the loot marker, pick the reward.
Spawn lootDrops a loot crate filled from a loot pool.ADD TARGET a marker, name the pool.
Spawn vehicleSpawns a drivable vehicle at a vehicle marker.ADD TARGET the marker, pick a vehicle. More →
Set vehicle optionsLocks / heals / fuels / god-modes a mission vehicle.ADD TARGET the vehicle, cycle the buttons. More →
Spawn waveSpawns a hostile AI group at a wave marker.ADD TARGET the wave marker, name the group prefab.
Wait until hackPauses until players hack a terminal you placed.Pick the terminal, set TIME / RADIUS / STARTUP / DECAY. More →
ObjectiveA goal gate: wait for a condition, optionally show a toast.A condition (kill / reach a spot / hold for N seconds).
Unlock rewardOpens a locked reward (e.g. a reward vehicle) so players can use it.ADD TARGET the reward’s marker.
Complete / FailEnds the mission as a win or a loss.Nothing.
Complete if / Fail ifEnds the mission the moment a condition is met (checked constantly).ADD TARGET + condition.
Mission timeoutFails the mission after N seconds. A safety net.Seconds.
Clear eventDespawns an event’s entities mid-mission.The event.
Call missionChains another mission at the same spot.The mission name.

Zeus AI & waiting for the fight to end

The bread-and-butter mission: place enemies, wait until they’re dead, hand out the reward.

Placing the enemies

Anything you drop in Zeus during event editing becomes part of the event — individual soldiers or whole groups. They spawn hostile to every player faction (nobody can befriend them), and by default they hold their ground near where you placed them, so they don’t wander off and leave a straggler somewhere across the map.

Waiting until they’re dead

Add a Wait until AI dead step, click the event, and ADD TARGET the group(s) you want to wait on. Then choose:

  • ALL — every member of the group is dead (the usual choice).
  • ANY — at least one has died.
  • LEADER — the group’s leader is dead.

You can target more than one group — the step waits for all of them. Once satisfied, the mission moves to the next step (spawn the reward, complete, etc.).

Reinforcements & objectives

  • Spawn wave drops a fresh hostile group at a WAVE marker — use it for defenders or a second push. Kill them with a Complete if … all dead or another Wait until AI dead.
  • Objective supports kill, reach a spot (any player within range of a marker), and hold for N seconds, with an optional on-screen toast when met.

Vehicles

A mission vehicle comes from one of two places, and that changes how you control it:

  • Placed in Zeus — part of the event, already sitting there when the mission spawns.
  • Spawned by logic — a Spawn vehicle step creates one at a VEH marker, at any point you choose.

Vehicles you place in Zeus

Drop the vehicle in Zeus like any other object while building the event. To change how it behaves, add a Set vehicle options step and ADD TARGET the vehicle itselfyou do not need a vehicle marker to change the behavior of a Zeus-placed vehicle.

Because logic steps run in order, you can condition the same vehicle at the start of the mission and again at the end. For example:

  • Lock it at the start, then Unlock it on mission complete — the vehicle becomes the payoff for finishing.
  • Set it out of fuel or god-moded at the start, then refuel or release it at the end.

Spawning a vehicle with logic

  1. In the event, DROP VEH where it should appear — face the way the nose should point.
  2. Add a Spawn vehicle step, ADD TARGET that marker, and pick a vehicle from the catalog (grouped by category: Cars, Vans, Armored, Helicopters…).

Put the step wherever you want it to fire — up front, or as a reward on mission complete. The vehicle spawns drivable and automatically faces where the marker points. A VEH marker is required here, because you’re creating a brand-new vehicle at that spot.

Set vehicle options — the controls

Whichever way the vehicle got there, Set vehicle options conditions it. ADD TARGET the vehicle, then cycle the buttons (no typing):

ButtonEffect
LOCKSeals the vehicle for all players until you unlock it.
GODMakes it invincible.
FUELSets fuel: 0 / 25 / 50 / 75 / 100%.
HEALTH100% = fully repaired; below 100 = visibly damaged.
AMMO coming soonRearm isn’t wired yet — leave on NO CHANGE.
Vehicle health, honestly

Setting HEALTH 100 fully repairs. Any value below 100 damages the vehicle but isn’t an exact percentage, and 0 doesn’t make a quiet wreck — it explodes (a proper burnt-out wreck is still being built). For a beat-up-but-usable vehicle, set a mid HEALTH and lock/god as needed.

Reward vehicles & locking

A vehicle can also be a reward — spawned locked (and optionally out of fuel) as the objective, then opened with an Unlock reward step once players earn it. A reward vehicle destroyed while still locked respawns, so it can’t be griefed before it’s claimed. Lock behavior is the lock_flags field in the reward template — combine flags by adding their numbers:

lock_flagsMeaning
0Unlocked from the moment it spawns.
1Locked to the mission faction until unlocked.
2Locked to the single player who unlocks it.
4Fuel drained on spawn.
5Faction-locked + no fuel (1 + 4).

The no-ammo and damaged lock flags exist in the template but aren’t functional yet — see coming soon.


Hack terminals

A hold-the-ground objective: players must stand in a circle around a terminal and hold it while a timer counts down.

Place the terminal

  1. In the event, click PLACE HACK ITEM — the terminal (a laptop) spawns into your hands.
  2. Walk it to the spot and place it. SAVE EVENT.

Wire it into the mission

Add a Wait until hack step, pick the terminal from the event’s items, then cycle the four config buttons:

ButtonSetsValues
TIMETotal hack countdown.1 / 2 / 5 / 10 / 15 min
RADIUSHow big the hold-circle is.10 / 15 / 20 / 25 / 30 m
STARTUPOptional commit hold before the main timer.Off / 3 / 5 / 10 s
DECAYWhat happens when the circle empties mid-hack.Off (pause) / Slow / Med / Hard

How it plays

Players approach the terminal, use it to START, and hold the circle. The countdown pauses when the circle is empty and resumes when someone steps back in (or decays backward if you set DECAY). Anyone who leaves gets a warning to get back in. When the timer hits zero with someone inside, the hack completes and the mission continues.

Always pair a hack with a timeout

A hack has no built-in failure — if players never finish it, the mission waits forever. Add a Mission timeout step (or a global timer) so an unfinished hack fails cleanly.


Advanced & coming soon

These are in the editor but not fully live yet. You may see the buttons — here’s the honest status so you don’t build a demo around them:

FeatureStatus
Patrol routes (DROP PATROL → patrol path)coming soon Waypoints drop, but route-following needs a Workbench step to finish. AI hold position for now.
Helicopter spawns (Spawn heli)coming soon Crewed-heli logic is written; awaiting a prefab hookup and flight testing.
Escort objectivescoming soon Placeholder — not usable yet.
Silent vehicle wrecks (health 0)coming soon A 0-health vehicle currently explodes; a proper burnt wreck is in progress.
Vehicle rearm / exact repair%coming soon AMMO and partial-repair are not wired yet.

Gotchas & where files live

Common snags
  • Adding logic hangs the editor → exit and re-enter the Mission Editor, then continue.
  • A marker points the wrong way → you faced the wrong direction when you dropped it. Stand on it, face the right way, drop again.
  • REWARDS shows 0 templates_index.json is missing from the rewards folder.
  • A hack mission never ends → you forgot a Mission timeout.
  • The reward never dropped → the earlier Wait until AI dead is still waiting. Confirm every targeted group actually dies.

Where mission files live on your server

<profile>/hf_wastelandz/missions/
├── rewards/            # the templates from this kit (+ any you add)
├── events/             # saved scenes        (*.event.json)
├── templates/          # saved missions      (*.mission.json)
├── <MapName>/spots/     # per-map spawn markers
└── active_pool.json    # pool timers + on/off switch

Everything except rewards/ is created and managed by the in-game tools — you don’t hand-edit these. To fine-tune spawn cadence, active_pool.json can be edited by hand; the server re-reads it on restart.

Wasteland-Z · Keeping current

Update the gateway.

The Wasteland-Z mod updates itself from the Reforger Workshop every time the server starts — you never touch it. The gateway is the one piece you host yourself, so when a new version ships you refresh its code by hand. Almost always that means replacing a single file: gateway.py.

Only the gateway needs a manual update

  • The mod (gameplay, menus, everything players see) — auto-downloads from the Workshop on server start. Nothing to do.
  • The database — your data stays as it is. A release only touches the schema in rare cases, and its notes say so explicitly.
  • The gateway — the small Python program you run. New logic ships as an updated gateway.py. That’s what this page covers.
The usual case is one file

Most gateway updates change only gateway.py. The steps below replace just that file and leave your config.py — your database password and gateway key — completely untouched.

Quick update

Replace gateway.py from GitHub

Run these in your running gateway folder — the working copy you made during setup (/opt/wastelandz-gateway/ on Linux, C:\wastelandz-gateway\ on Windows), not the reference kit folder.

1

Back up the file you have now

So you can roll back in seconds if the new one misbehaves.

# Linux
cd /opt/wastelandz-gateway
cp gateway.py gateway.py.bak

# Windows (Command Prompt)
cd C:\wastelandz-gateway
copy gateway.py gateway.py.bak
2

Download the latest gateway.py

This pulls the current file straight from the kit’s public repo and writes it over the old one. curl ships with modern Windows and Linux alike, so the command is the same on both.

curl -fL -o gateway.py https://raw.githubusercontent.com/Motavar/HF_WastelandZ_SETUP/main/gateway/gateway.py

-f makes curl fail loudly on a bad address instead of saving an error page over your file; -L follows GitHub’s redirect. The URL points at this kit’s main branch, file gateway/gateway.py.

Got a 404? Check the file didn’t blank

If the download errors, your gateway.py may have been emptied. Check its size — on Linux ls -l gateway.py, on Windows dir gateway.py — and if it’s empty, put the backup back with cp gateway.py.bak gateway.py (Windows: copy gateway.py.bak gateway.py) before trying again.

3

Restart the gateway

The new code only takes effect after a restart.

# Linux — systemd service
sudo systemctl restart wz-gateway
sudo systemctl status wz-gateway --no-pager

# Windows — close the WZ-Gateway window, then start it again
# (double-click start_gateway.bat, or run: python gateway.py)
4

Confirm it’s healthy

Hit the health check — you want status: ok.

curl http://127.0.0.1:5000/api/ping

Or just browse to http://127.0.0.1:5000/api/ping. On Linux you can also watch the live log with sudo journalctl -u wz-gateway -f.

Roll back if something’s off

Restore the backup and restart:

# Linux
cp gateway.py.bak gateway.py && sudo systemctl restart wz-gateway

# Windows
copy gateway.py.bak gateway.py

When the update is more than one file

Once in a while a release also changes other files — new Python packages (requirements.txt), the config template (config.example.py), or the database schema (setup_database.sql). The release notes call that out. When it happens, refresh the whole kit instead of one file:

# Linux — update the reference kit (the git clone), then copy the gateway across
cd /opt/wastelandz
git pull
cp -r /opt/wastelandz/gateway/. /opt/wastelandz-gateway/

# if requirements changed, re-install inside the venv
cd /opt/wastelandz-gateway
source venv/bin/activate
pip install -r requirements.txt

sudo systemctl restart wz-gateway
Your config.py is safe — leave it alone

config.py holds your database password and gateway key and is never stored in the repo, so git pull and the single-file curl both leave it untouched. The cp -r above copies only the program files the kit ships — it does not contain a config.py, so your live one stays in place. Never overwrite it.

If a release ever needs a database change, its notes give the exact SQL to run — apply that separately. A normal gateway update never touches your data.