Deployment · 10 minutes
Raise Your First Gate
From a bare VPS to a public, always-on Diablo & Hellfire game: provision the server, drop in the binary and your MPQs, open one port, and install it as a service that survives reboots.
What you need
- Any Linux VPS or home server — DevXH needs no display, no window manager, and about 2% CPU at idle. The cheapest tier is plenty.
- Your own game MPQs (
hellfire.mpq,hfmonk.mpq, etc.) from a copy of Hellfire you own. DevXH never distributes game assets. - The
devilutionx-serverbinary (see Downloads), or build it yourself:
# Build both binaries from the modded source tree
$ cmake -B build-server -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF
$ cmake --build build-server -j$(nproc) --target devilutionx devilutionx-server
1 · Install the files
Create a home for the gate
A dedicated user and directory keep things tidy and safe. The server runs fine unprivileged.
$ useradd -r -m -U -d /opt/devxh -s /usr/sbin/nologin games
$ mkdir -p /opt/devxh/assets /var/lib/devxh /etc/devxh
Drop in the binary and your MPQs
Copy devilutionx-server to /opt/devxh and place your MPQ files
in /opt/devxh/assets. Then hand ownership to the service user:
$ cp devilutionx-server /opt/devxh/ && cp *.mpq /opt/devxh/assets/
$ chown -R games:games /opt/devxh /var/lib/devxh /etc/devxh
First run — prove it boots
Run it once by hand before wiring up systemd. You should see it bind port 6112 and idle:
$ /opt/devxh/devilutionx-server \
--data-dir /opt/devxh/assets \
--save-dir /var/lib/devxh \
--config-dir /etc/devxh \
--name "My First Gate"
Hosting game 'My First Gate' on TCP/IP (idle player: Server)
Stop it with Ctrl+C — it shuts down cleanly and saves. That's the whole smoke test.
Firewall
DevXH binds TCP 6112 on all interfaces. Open it in your VPS provider's
firewall and the OS firewall: ufw allow 6112/tcp (or the equivalent).
For a truly public game, no port-forwarding beyond that is needed.
2 · Run it as a service
Manual runs die when you log out. A systemd unit makes the gate eternal:
[Unit]
Description=DevXH dedicated server (DevilutionX headless)
After=network-online.target
Wants=network-online.target
[Service]
User=games
ExecStart=/opt/devxh/devilutionx-server \
--data-dir /opt/devxh/assets \
--save-dir /var/lib/devxh \
--config-dir /etc/devxh \
--name "My First Gate" --server-tcp
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
$ systemctl daemon-reload
$ systemctl enable --now devxh
$ systemctl status devxh # should read "active (running)"
Logs land in journald: journalctl -u devxh -f. Watch for
Hosting game ... on TCP/IP at startup and
Headless resync: ... 100% whenever a player joins — that's the world being
handed to them.
3 · Verify from outside
From your own PC, confirm the port answers before round-tripping a game client:
$ Test-NetConnection your.server.ip -Port 6112 # Windows PowerShell
$ nc -vz your.server.ip 6112 # Linux / macOS
Then run stock DevilutionX → Multiplayer → TCP/IP → enter
your server's IP → join My First Gate. The idle host will be waiting in town.
Full client walkthrough: Joining a Public Game.
Flag cheatsheet
| Flag | What it does |
|---|---|
--name "..." | Game name players see (default server-<pid>). |
--password "..." | Makes the game private; joiners are prompted. |
--port N | Listen on a different TCP port (default 6112). |
--game hellfire|diablo | Which campaign the gate hosts (default hellfire). |
--difficulty 0|1|2 | normal / nightmare / hell. Clients can't change it. |
--hero-class ... | Idle player class (warrior, rogue, sorcerer, monk…). |
--hero-name ... | Idle player name (default Server). |
--full-quests | Enable the full quest set. |
Monk, bard, barbarian
The monk class needs hfmonk.mpq; bard and
barbarian need hfbard.mpq / hfbarb.mpq — make sure
those files are in your assets dir before using those classes.
Your gate is now open. When you're ready to make it visible on the public server list, the membership backend registration is coming soon — meanwhile, share the IP with friends or the world.