Networking · 15 minutes
ZeroTier Private Realms
A public gate welcomes everyone; a ZeroTier realm welcomes only those you name. Put your server and your friends on one virtual network and the game appears in their lobby as if you all shared a LAN.
Why ZeroTier?
- No port forwarding — ZeroTier tunnels out; nothing is exposed publicly.
- No public IP needed — works behind CGNAT, home connections, dorms.
- Membership control — only authorized devices can even see the network.
DevXH supports ZeroTier two ways: hosting a native ZeroTier game, or binding an ordinary TCP/IP game to the ZeroTier interface only. This guide covers the native mode.
1 · Create the realm
Make a network at my.zerotier.com
Create a free account, then Create A Network. You'll get a 16-hex-digit
network ID like 0123456789abcdef — this is your realm's sigil. Under
Settings → Advanced, set Access Control to Private.
Join from the server
Install ZeroTier on the VPS and join the network. You can let DevXH do the join for you
via --server-zt-network, but doing it with the CLI keeps the node authorized
across restarts:
$ curl -s https://install.zerotier.com | sudo bash
$ sudo zerotier-cli join 0123456789abcdef
200 join OK
Back at my.zerotier.com, tick the checkbox next to the server's node ID to
authorize it. Note the managed IP it receives (e.g. 192.168.191.42) — that's
the server's address inside the realm.
Join from every player's machine
Each friend installs ZeroTier, joins the same network ID, and you authorize their node. Verify the mesh is alive with a ping to the server's managed IP:
$ ping 192.168.191.42
Reply from 192.168.191.42: bytes=32 time=28ms TTL=64
2 · Host the game
Start the server in ZeroTier mode:
$ /opt/devxh/devilutionx-server \
--server-zerotier \
--server-zt-network 0123456789abcdef \
--name "Crypt of the Inner Circle" \
--data-dir /opt/devxh/assets \
--save-dir /var/lib/devxh \
--config-dir /etc/devxh
Two ways to give the network
If the node already joined via zerotier-cli (step 1.2), you can omit
--server-zt-network — the server falls back to the network configured in its
ini, which by default is the Diasurgical public Earth network. Always set it explicitly for
a private realm.
Under systemd, just add the flags to ExecStart in your unit file — see
Raise Your First Gate for the full unit.
3 · Players join
- Stock DevilutionX → Multiplayer → ZeroTier.
- The realm's game (
Crypt of the Inner Circle) appears in the game list. - Join. If you set
--password, players are prompted for it.
Because the realm is private, the game is invisible to anyone outside ZeroTier — the strongest privacy option DevXH offers, with zero port forwarding.
Alternative: TCP bound to the realm
Prefer plain TCP/IP semantics but keep the privacy? Bind the game to the ZeroTier interface address only:
$ /opt/devxh/devilutionx-server --server-tcp 192.168.191.42 --name "Hidden Gate" ...
The port is unreachable from the public internet — only realm members see the listener. Clients join via Multiplayer → TCP/IP using the server's managed IP.
Troubleshooting
| Symptom | Fix |
|---|---|
| Game list stays empty | All nodes joined & authorized? Same network ID? The server is still running (journalctl -u devxh -f)? |
| Server never announces | ZeroTier can take a few moments to come online after a fresh join. Wait for zerotier-cli info to report ONLINE. |
| Join times out | Verify UDP 9993 outbound is not blocked on the VPS; ZeroTier needs it for its root servers. |
| Works locally, not remotely | Node IDs authorized at my.zerotier.com may have been pruned if the node was offline long — re-authorize. |