What a master does
A master server is a small web service, on TCP port 49175 by default, that keeps a list of where servers are. Each listing is one server's game address, such as 203.0.113.4:49176, signed by the server that sent it, with the time it expires. That's all: no name, map or players.
The Server Browser reads the lists of several masters at once and merges them, giving each up to 2.5 seconds to answer, so a master far away or a lost packet doesn't leave the list empty. Then it asks every listed server, on the server's own game port, what it's playing: its name, map, game type, players, mods and Project Reclaimer version. It measures the ping on the way. So what players see comes live from each server, not from a master, and a server that doesn't answer is left out.
- Servers report their listing
- Backup while both default masters are down
- Masters share
- The browser reads masters
- The browser asks each server
Three masters are built into every client and always asked first. Two are the default masters, the ones every server reports to: the project's public master at http://148.251.153.44:49175 and a second master at http://23.159.176.140:49175. Each holds every server's listing, so while either is down, servers stay listed and players still see them. The third is http://127.0.0.1:49175, a master on the player's own PC, such as the one a dedicated server setup runs.
How a server gets listed
The server signs its listing
When it starts, a server makes a signing key and signs its game address with it. A listing is good for 3 minutes, and the server renews it long before then.
It reports to masters
Every 30 seconds, it sends the listing to both default masters. A dedicated server also sends it to the masters its host added under [master] peers, and every 5 seconds to the master on its own machine.
Masters share it
Every 60 seconds, each master swaps listings with the masters it knows, so a listing that reached one master reaches the others.
The browser finds it
When a player opens the Server Browser or refreshes it, the browser reads the masters, then asks the server what it's playing.
A server that stops drops off every list within 3 minutes of its last renewal. A hidden server reports nowhere: players reach it only by Direct Connect.
How masters share
There's no central list that everything depends on. The masters form a network, and each part of it learns about the rest:
- Masters name other masters. Every master's answer carries its listings and the other masters it reached lately, up to 64. The browser asks those masters too, in the same refresh, and remembers the ones that answer. That's how it finds servers the default masters don't know about.
- Masters swap every 60 seconds. Each master reads the lists of the masters it knows and of the masters those name, and sends its own listings on.
- New masters introduce themselves. A master that sends its listings to another names its own address. The other checks that address at its next swap and, once it answers, passes it on to everyone who asks. A dedicated host's master spreads this way, from the default masters to every player, without anyone adding it by hand.
- The browser remembers. It keeps the masters that answered for 30 days, one per IP address, and forgets one that fails two refreshes in a row. Masters you add under Settings → Connectivity → Master servers are always kept.
Listings stay intact on the way. They're signed, so a master that passes one on can't change its address or make it last longer, and when several masters hand out the same listing, the browser keeps the newest signed copy.
When a master goes down
The two default masters are the places every server reports to and every client knows. Each holds every listing, so while one is down, the Server Browser reads the other and nothing changes for players or hosts. The network is built to keep working without both of them, too.
For players
- The browser still asks every master it remembers and every master you added. Those masters hold the listings servers sent them and the ones they swapped with other masters.
- The line under the server list counts the masters that answered, and says Limited discovery: fewer than two sources reachable when fewer than two did.
- Favorites are asked directly at every refresh, so they show up even when no master lists them.
- A client that has never reached a master other than the default ones, such as a fresh install during an outage, knows no others yet. Adding one by hand fixes that, which is where a community's own master helps: share its address.
For servers
- A master's answer to a server's report names other masters it knows, starting at a random one, so different servers learn different masters. It only names masters that the server's players can reach.
- One default master taking a server's listing is enough. While neither does, the server also reports it to three of those masters, every 30 seconds. One that stops answering is replaced; one that failed is tried again only when no untried master is left.
- Those masters pass the listing on to the masters they swap with, and players' clients already know them from the masters' lists, so the server stays in the browser.
- Once a default master takes the listing again, the server reports to the default masters alone, and the backups' copies expire within 3 minutes.
- A dedicated server with a master on its machine learns backups from it every 5 seconds, so it has some even when it starts during an outage. A game hosted from Host Game learns them from the default masters, so one that starts while both are down has none until one answers.
The server's log says when it starts and stops using backups:
Discovery: no default master took this server's listing; reporting it to http://…, http://…, http://… until it does.
Discovery: a default master takes this server's listing again.
If the server hasn't learned any masters yet, the first line ends in no other master is known yet. instead. Every master keeps a copy of the listings it hears about, so each master someone runs is one more place the Server Browser can find servers while the default masters are down.
What a master can't do
A master can't
Change a listing's address or make it last longer. Let anyone into a server: players join the server itself. See games or players: it only holds addresses. Hand out an address players can't reach: one on a player's PC (127.0.0.1) or local network (192.168.x.x) only goes to players on that PC or network.
A master can
Leave listings out, hand out a listing again until it expires, or list addresses nobody hosts. The browser asks at most 1,024 servers per refresh and at most 32 on one machine, so a bad master can't aim players' browsers at anyone. Like any web server, it sees the IP address of everyone who reads it.
What a server says it's playing comes from the server itself. Signatures prove a listing wasn't changed on the way, not that its host is honest. See Legal & privacy for what the default masters and servers see.
Host a master
Running a master gives your community its own way into the Server Browser, one that keeps working when the default masters don't, and makes the whole network sturdier. It needs no game files, no Steam and no game install: only the Project Reclaimer program and one open TCP port.
Beside dedicated servers
Every dedicated server setup already runs a master on TCP 49175 ([master] enabled = true), and it introduces itself to other masters. Nothing to add: see the configuration file.
A master on its own
On a machine without the game, such as a small VPS, run only the master: one command on Windows, or the Docker image on Linux.
| What | Details |
|---|---|
| Software | project-reclaimer.exe from the download page: the game client includes the master. On Linux, the Docker image brings it. |
| Game files | None. |
| Windows | Windows 10, 11 or Server 2019 or newer (x64), with the Visual C++ 2015–2022 runtime. |
| Linux | Any x86-64 Linux with Docker (Engine and Compose 2.24 or newer). |
| Network | One TCP port, 49175 by default, open to the internet, at an address that doesn't change, since players and other masters remember it: a fixed IP address or a DNS name. The master also connects out to other masters on their ports. |
On Windows
- Download the programGet the game client from the download page, rename it from
project-reclaimer-version.exetoproject-reclaimer.exeand put it in a folder of its own, such asC:\reclaimer-master. Open a terminal in that folder. -
Start the master
It saysPowerShell
.\project-reclaimer.exe discovery-master --bind 0.0.0.0:49175Discovery bootstrap master listening on 0.0.0.0:49175and runs until you press Ctrl+C. Within a minute it holds every listing the default masters have. Start it from a terminal: opened with a double-click, the program starts the game instead. -
Open the port
In a terminal opened as administrator:
Behind a home router, forward TCP 49175 to this PC.PowerShell (administrator)
New-NetFirewallRule -DisplayName "Reclaimer master" -Direction Inbound -Protocol TCP -LocalPort 49175 -Action Allow
To start it with Windows, create a Task Scheduler task that runs C:\reclaimer-master\project-reclaimer.exe with the arguments discovery-master --bind 0.0.0.0:49175, starting in C:\reclaimer-master, at startup, whether or not a user is logged on.
The master keeps the masters it learned in peers.json, in Documents\My Games\Project Reclaimer\discovery of the account it runs as; the RECLAIMER_DISCOVERY_DIR environment variable names another folder. For another port, change 49175 in --bind and in the firewall rule, and give players that port.
On Linux with Docker
The dedicated server image includes the master. Run it with the master's command instead of the servers, and without a game folder.
Not yet tested on its own. The image, its start script and the master are the ones dedicated servers already run on Linux, where the master runs beside the servers. A container that runs only the master hasn't been tried yet.
reclaimer-master/
├─ compose.yaml the master: image, command, port
└─ data/ the masters it learned
-
Install Docker
Docker Engine with the Compose plugin, 2.24 or newer, on any x86-64 Linux:
Ubuntu
sudo apt install docker.io docker-compose-v2 -
Make the folder and add
compose.yamlSave compose.yaml inShellmkdir -p reclaimer-master/data cd reclaimer-masterreclaimer-master, or copy it from the file below. -
Start
The first start downloads the image. The log then saysShell
docker compose up -d docker compose logs -fDiscovery bootstrap master listening on 0.0.0.0:49175. - Open the portOpen TCP 49175 in your provider's firewall or security group. Docker opens published ports on the machine itself, past
ufw.
docker compose pull && docker compose up -d updates it to the newest release. On a machine that already runs the dedicated server image, don't add this: that container's master already serves TCP 49175.
compose.yaml
# A Project Reclaimer master server on its own, in Docker: no game servers
# and no game files. Guide: https://projectreclaimer.dev/masters
#
# Put this file in a folder of its own, next to an empty data/ folder, then:
#
# docker compose up -d
# docker compose logs -f
#
# Update to the newest release: docker compose pull && docker compose up -d
name: reclaimer-master
services:
master:
# The dedicated server image, which includes the master. Set IMAGE in
# .env to stay on one version.
image: ${IMAGE:-ghcr.io/projectreclaimer/project-reclaimer-dedicated:latest}
restart: unless-stopped
command: ["project-reclaimer", "discovery-master", "--bind", "0.0.0.0:49175"]
# The master stops cleanly on Ctrl+C (SIGINT).
stop_signal: SIGINT
stop_grace_period: 10s
environment:
# The masters it learned (peers.json) are kept in ./data/discovery.
# Z: is the container's / as the program, running under Wine, sees it.
RECLAIMER_DISCOVERY_DIR: 'Z:\server\discovery'
volumes:
- ./data:/server
ports:
- "49175:49175/tcp"
# The image's health check watches dedicated servers, which this
# container doesn't run.
healthcheck:
disable: true
security_opt:
- no-new-privileges:true
logging:
driver: json-file
options:
max-size: 10m
max-file: "3"
Get it known
A master started with discovery-master doesn't introduce itself to the masters it swaps with, the way a dedicated setup's master does, so the network learns about it from the people who list it. Any of these works:
- Players add it under Settings → Connectivity → Master servers:
http://your-address:49175on a line of its own, then Apply. Their browser reads it from then on and remembers the masters it names. See Join a game. - Dedicated server hosts add it to
[master] peers, or toRECLAIMER_DEDICATED_MASTER_PEERSin Docker. Their servers then report to it directly, and their master swaps listings with it and names it to everyone who reads theirs. From there it spreads to the rest of the network.
[master]
peers = ["http://your-address:49175"]
If you also host dedicated servers, the master in that setup already does all of this: you don't need a second one.
Check that it works
From another machine, ideally on another network, since many home routers can't reach their own public address from inside:
curl http://your-address:49175/v3/discovery
It answers with JSON: records, the listings it holds, and masters, the masters it knows. A minute after it starts, it should hold the same listings as the default masters, such as http://148.251.153.44:49175/v3/discovery or http://23.159.176.140:49175/v3/discovery. In Windows PowerShell 5, type curl.exe: plain curl is another command there.
Then add it in your own client under Settings → Connectivity → Master servers and open the Server Browser: the line under the list counts it among the masters that responded.
Troubleshooting
| Problem | What to do |
|---|---|
| Nobody else can reach it | Open TCP 49175 in the firewall, on the router or in your provider's security group, and test from another network. |
| It holds no listings | It reads the default masters every 60 seconds. Check that the machine can connect out to TCP 49175 on other machines; until it can, it only has what servers report to it directly. |
| The log says another master already serves port 49175 on this machine | A dedicated server setup or another master holds the port, and already does the job. This one waits and takes the port over if that one stops. To run both, give this one another port in --bind. |
| Double-clicking the program starts the game | Start the master from a terminal with its command, or from a Task Scheduler task. |
| The master lists a server that the browser doesn't show | The browser asks every server directly and leaves out one that doesn't answer on its UDP game port. The server's host opens that port; see the hosting guide. |
A server at 192.168.x.x isn't listed to players on the internet | That's on purpose: masters never hand out a local network's addresses outside it. The server's host sets its public_address, or leaves it empty to have it detected. |
| A server on another PC of your home network isn't in the browser | Many home routers don't pass their own internet address back inside the network, so a server listed at that address can't be reached from beside it. The browser finds servers on your own PC anyway: it asks the default masters which address they see your network at and asks those servers on your PC too. For one on another PC of your network, use Direct Connect with that PC's local address. |
| The line under the list says 0 masters responded, and the list is empty | No master answered within 2.5 seconds. Check that the PC can connect out to TCP 49175, then refresh. Before 0.8.12 the browser gave up on a master after two thirds of a second, which players far from the masters often hit: update the game. |
