How it works
The dedicated command reads dedicated.toml and starts every server listed in it. Each server runs in its own process with its own name, port and games, so a crash in one never touches the others, and a server that stops is restarted automatically.
Every server reports its address to the two default master servers, which every player's Server Browser reads, and to this machine's own master. The browser then asks each server on its game port what it's playing, so players see the live game, players and ping. Or they join by address with Direct Connect.
reclaimer/
├─ dedicated.toml every server and setting, commented
├─ project-reclaimer.exe
├─ game/ files copied from your own game install
├─ content/ maps, game types and mods every server shares
│ ├─ Maps/
│ ├─ Game Modes/
│ └─ Mods/
├─ playlists/ playlist files (one example is provided)
├─ bans.json bans shared by every server
└─ data/<server>/ each server's log and live status
No game files come with Project Reclaimer. Every host copies the few files a server needs from their own installation of the game.
Requirements
| What | Details |
|---|---|
| Software | project-reclaimer.exe from the download page: the game client includes the dedicated server. From 0.8.14, each release also has project-reclaimer-dedicated-version.exe, a build without the game client that runs servers only. On Linux, the Docker image brings it. |
| Game files | Your own Steam copy of Halo: The Master Chief Collection with Halo 3 installed, campaign included, on the PC where you create the server folder. |
| 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): the image brings Wine and the server. Tested on Ubuntu 20.04. Without Docker: 64-bit Wine 9 or newer, winetricks, and xvfb on a machine without a display. Not yet tested. |
| Disk | About 1.5 GB for one map; about 5.5 GB for every multiplayer map. Both include the two campaign maps Forge's campaign vehicles and AI come from (about 520 MB). |
| Memory, CPU | About 85 MB and under a tenth of a core per server while it waits for players; about 1.1 GB and a quarter of a core during a two-player game. |
| Network | One UDP port per server (49176, 49177, …), which players join and the Server Browser asks what the server is playing, and one TCP port for this machine's master (49175). The optional remote console uses TCP at each game port number, for your own tools. |
Each server holds up to 16 players, split-screen players included; max_players sets fewer.
Quick start: Windows
- Download the programGet the game client from the download page and rename it from
project-reclaimer-version.exetoproject-reclaimer.exe, the name the commands below use. Open a terminal in its folder. -
Create the server folder from your game install
This creates
C:\reclaimerwith a commenteddedicated.toml, an example playlist and an empty ban list, and copies the game files a server needs, including the campaign'scampaign.mapand040_voi.mapfor Forge's campaign vehicles and AI:PowerShell.\project-reclaimer.exe dedicated init C:\reclaimer --from--fromon its own uses Steam's default game location. For another Steam library, give the folder:--from "D:\SteamLibrary\steamapps\common\Halo The Master Chief Collection". Add--maps "Guardian,Valhalla"to copy only the maps you host. On the same drive, files are hard-linked instead of copied. - Copy the program into the server folderCopy
project-reclaimer.exeintoC:\reclaimer. - Edit
dedicated.tomlSet your server names, ports, admins and what each server plays. See the configuration file and custom playlists. -
Check, then start
PowerShell
cd C:\reclaimer .\project-reclaimer dedicated check .\project-reclaimer dedicatedcheckverifies the game files, the configuration, every playlist, map and game type, and the ports, and names anything that's missing. If your servers name Workshop mods by ID, it downloads the missing ones first. -
Open the ports
In a terminal opened as administrator:
Behind a home router, forward the same ports to this PC, or setPowerShell (administrator)
New-NetFirewallRule -DisplayName "Reclaimer games" -Direction Inbound -Protocol UDP -LocalPort 49176-49177 -Action Allow New-NetFirewallRule -DisplayName "Reclaimer browser" -Direction Inbound -Protocol TCP -LocalPort 49175 -Action Allowupnp = trueindedicated.toml.
Ctrl+C stops every server. To start them with Windows, create a Task Scheduler task that runs C:\reclaimer\project-reclaimer.exe with the argument dedicated, starting in C:\reclaimer, at startup, whether or not a user is logged on.
Quick start: Linux with Docker
On Linux, the easiest way is the Docker image. It runs the same servers as on Windows, under Wine inside the image, so the rest of this guide applies as it is: the same dedicated.toml, commands, bans, votes, playlists and mods. Docker adds one command to start, stop and update, and settings through environment variables.
One file to host. Each release publishes the image as ghcr.io/projectreclaimer/project-reclaimer-dedicated, so all you need is compose.yaml and your own game files: nothing to build and nothing else to download. The image holds Wine and Project Reclaimer, never game files.
Tested on Ubuntu 20.04 with an image built from source: both servers of the first start run under Wine, the server browser lists them on other machines, and a player joined and played a game. Not yet tested: pulling the published image, host networking and UPnP, Docker Desktop, several players at once, and shared mods in a container.
reclaimer/
├─ compose.yaml the service: image, folders, ports
├─ .env optional settings
└─ server/ the server folder, as on Windows
├─ dedicated.toml written on the first start, commented
├─ game/ files copied from your own game install
├─ content/ playlists/ bans.json
└─ data/<server>/ each server's log and live status
-
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 reclaimer cd reclaimerreclaimer, or copy it from the file below. -
Put the game files in
server/gameOn a Windows PC with the game, rundedicated init C:\reclaimer --fromas in the Windows quick start and upload that folder asserverwith thescpWindows includes; that brings adedicated.tomltoo:PowerShell, on the Windows PCscp -r C:\reclaimer you@host:reclaimer/serverreclaimer/servermustn't exist yet, or the upload lands inside it asserver/reclaimer. Or make the folders withmkdir -p server/gameand copy the files in by hand, keeping their folders, such asserver/game/halo3/halo3.dll. With the game installed on this machine through Steam, copy nothing: make the same folders and setGAME_DIRin.envto the game's folder. Make the folders yourself before the first start: a folder Docker has to create for you belongs to root. - Choose settings (optional)Save env.example as
.envnext tocompose.yamland uncomment what you change, such asRECLAIMER_DEDICATED_HOST_NAMEorRECLAIMER_DEDICATED_ADMINS. It lists every environment variable. -
Start
The first start downloads the image, writesShell
docker compose up -d docker compose logs -fserver/dedicated.tomlwith two servers (a Slayer playlist on UDP 49176, which needs Guardian, Valhalla, The Pit and Last Resort, and Slayer on Guardian on UDP 49177), checks everything and starts them. With fewer maps, change the servers in that file. The servers report to the project's public master, so players find them in the Server Browser without adding anything. - Open the portsOpen TCP 49175 and the UDP ports in your provider's firewall or security group. Docker opens published ports on the machine itself, past
ufw.
If something is missing, the log says what and the container waits: fix it in the server folder, and the servers start by themselves within 15 seconds.
compose.yaml
The whole file, the same one the image's own guide uses. Its settings come from .env, so you rarely need to edit it.
# Project Reclaimer dedicated servers in Docker (Linux containers; the
# servers run under Wine). Full guide: docs/docker.md.
#
# This file is all a host needs: it runs the published image, so no copy
# of the repository and no build. Put it in a folder of its own, then:
#
# 1. Copy Halo 3's files from your own MCC installation into
# server/game/ next to this file (halo3/halo3.dll, halo3/maps/shared.map,
# the maps you host, and campaign.map with 040_voi.map for Forge's
# campaign vehicles and AI). The image contains no game files.
# 2. Optional: a .env file next to this one with your settings
# (see .env.example).
# 3. docker compose up -d
# docker compose logs -f
#
# On first start the container writes a commented dedicated.toml into the
# server folder; edit it for names, maps, playlists and admins, then
# `docker compose restart`. Commands for running servers:
# docker compose exec reclaimer dedicated status
# docker compose exec reclaimer dedicated ban <player ID | IP | CIDR> --reason "..."
# Opt-in executable updates: RECLAIMER_DEDICATED_AUTO_UPDATE=true in .env.
# Update the container image: docker compose pull && docker compose up -d
#
# To build the image from a checkout of the repository instead, add
# compose.build.yaml (see there).
name: reclaimer
services:
reclaimer:
# The newest release; set IMAGE in .env to stay on one version.
image: ${IMAGE:-ghcr.io/projectreclaimer/project-reclaimer-dedicated:latest}
restart: unless-stopped
# The supervisor stops each server cleanly on Ctrl+C (SIGINT).
stop_signal: SIGINT
stop_grace_period: 30s
# Every RECLAIMER_DEDICATED_* setting in .env overrides dedicated.toml,
# as do PUID, PGID and RECLAIMER_XVFB (see .env.example).
env_file:
- path: .env
required: false
volumes:
- ${SERVER_DIR:-./server}:/server
# Read-only: the servers never change the game files.
- ${GAME_DIR:-./server/game}:/server/game:ro
# The Forge library and other caches, kept across updates.
- cache:/cache
# The master's TCP port, and one UDP port per server in dedicated.toml
# (49176 and 49177 for the two servers the first start creates). Change
# them in .env; a published port must equal the port inside.
ports:
- "${RECLAIMER_DEDICATED_MASTER_PORT:-49175}:${RECLAIMER_DEDICATED_MASTER_PORT:-49175}/tcp"
- "${GAME_PORTS:-49176-49177}:${GAME_PORTS:-49176-49177}/udp"
# Remote console (docs/rcon.md): TCP at each game port number, for
# tools on this machine only. Set RECLAIMER_DEDICATED_RCON_PASSWORD
# and RECLAIMER_DEDICATED_RCON_ADDRESS=0.0.0.0 in .env too.
# - "127.0.0.1:${GAME_PORTS:-49176-49177}:${GAME_PORTS:-49176-49177}/tcp"
# On Linux, host networking replaces the port list: every port in
# dedicated.toml is reachable without listing it, and UPnP can reach the
# router. Uncomment this and remove "ports:" above.
# network_mode: host
security_opt:
- no-new-privileges:true
# Roughly: under 0.1 core and 100 MB per idle server, 0.25 core and
# 1-2 GB per server during a game. Uncomment to cap the container.
# cpus: "2"
# mem_limit: 6g
logging:
driver: json-file
options:
max-size: 10m
max-file: "3"
volumes:
cache:
Versions and updates
compose.yaml runs latest, the newest release, and docker compose pull && docker compose up -d updates to the next one. To stay on one version, name it in .env and run docker compose up -d:
IMAGE=ghcr.io/projectreclaimer/project-reclaimer-dedicated:0.8.0
Every release has its own tag, such as 0.8.0, and 0.8 follows the newest 0.8.x. Pre-releases, such as 0.9.0-beta.1, are only published under their own tag, never as latest.
To have the servers update Project Reclaimer by themselves, set RECLAIMER_DEDICATED_AUTO_UPDATE=true in .env and run docker compose up -d; see automatic updates. The container keeps the updated program in server/.reclaimer, so recreating it from the same image keeps the update; an image with a different build starts again from that image's own. Automatic updates don't change the image: docker compose pull && docker compose up -d still brings Wine and the rest of it. To stay on a pinned IMAGE, leave automatic updates off.
Everyday use
Run these in the folder with compose.yaml:
| Task | Command |
|---|---|
| Follow the log | docker compose logs -f |
| Players, addresses, the master | docker compose exec reclaimer dedicated status |
| Ban, lift a ban | docker compose exec reclaimer dedicated ban <target> --reason "…", … dedicated unban <target> |
| Remote console commands | docker compose exec reclaimer dedicated rcon players (see RCON) |
| Check files and settings | docker compose run --rm reclaimer dedicated check |
Apply dedicated.toml edits | docker compose restart |
Apply .env or compose.yaml edits | docker compose up -d |
| Stop, start | docker compose stop, docker compose start |
| Update | docker compose pull && docker compose up -d |
- The container restarts by itself after a crash or reboot, and Docker reports it healthy while every server runs and the server browser's master answers. Each server also logs to
server/data/<server>/server.log. - More servers: add a
[[server]]block with the next port, widenGAME_PORTSin.envto cover it (GAME_PORTS=49176-49180) and rundocker compose up -d. One container runs up to 32 servers. - Host networking: uncomment
network_mode: hostincompose.yamland remove itsports:. Every port indedicated.tomlis then reachable without listing it, and UPnP can reach a home router. - File owner: the servers run as the owner of the server folder, so the files they write are yours.
PUIDandPGIDin.envchoose another user and group; use those rather than Compose'suser:. - Mods and playlists: put shared maps, game types and mods in
server/content, and playlists inserver/playlists. The image has no Steam, so copy Workshop mods intoserver/content/Modsyourself; see Workshop downloads in Docker. - Remote console: inside a container it must listen on every interface to be published at all. Set
RECLAIMER_DEDICATED_RCON_PASSWORDandRECLAIMER_DEDICATED_RCON_ADDRESS=0.0.0.0in.env, and uncomment the TCP line underports:incompose.yaml, which publishes the consoles on the host's own127.0.0.1only. See RCON.
Linux without Docker
Experimental. Wine installed on the machine itself hasn't been tested yet; the Docker image has, so use it if you can. The start script and service file below aren't in the downloads yet, so for now this way isn't available. If you try it later, please report problems along with the server log from data/<server>/server.log.
- Prepare the folder on WindowsOn a Windows PC with the game installed, follow steps 1–3 of the Windows quick start, and put
reclaimer-dedicated.shin the folder too. Upload it with thescpWindows includes, for examplescp -r C:\reclaimer you@server:/srv/reclaimerin PowerShell. -
Install Wine and its helpers
Debian / Ubuntu
sudo dpkg --add-architecture i386 && sudo apt update sudo apt install wine64 winetricks xvfb -
Check and start
The first run creates a Wine prefix and installs the Visual C++ runtime into it.
Shell
cd /srv/reclaimer chmod +x reclaimer-dedicated.sh ./reclaimer-dedicated.sh check ./reclaimer-dedicated.sh -
Open the ports
Shell
sudo ufw allow 49176:49177/udp && sudo ufw allow 49175/tcp - Run it as a service (optional)Install
reclaimer-dedicated.service(instructions inside the file), thensystemctl enable --now reclaimer-dedicated.
The script accepts every dedicated command, such as ./reclaimer-dedicated.sh status. Servers never use ports below 1024, so they don't need root.
The configuration file
dedicated init writes a fully commented dedicated.toml. Relative paths are relative to the file's folder. A small setup with two servers looks like this:
game = "game"
content = "content"
public_address = "" # empty: detect this machine's public address
upnp = false
auto_update = false # true: install each new release and restart
host_name = "My Community"
admins = [
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
]
[master]
enabled = true
port = 49175
[rcon]
password = "" # set one to turn on the remote console
address = "127.0.0.1"
[defaults]
voice = true
text_chat = true
votes = true
max_players = 16
[[server]]
name = "Community Rotation"
port = 49176
playlist = "playlists/community.playlist.json"
[[server]]
name = "Snipers Only"
port = 49177
map = "Valhalla"
game = "Game Modes/snipers.bin"
max_players = 8
General settings
| Setting | Default | Meaning |
|---|---|---|
game | "game" | Folder with the game files. |
content | "content" | The Maps, Game Modes and Mods every server shares. |
data | "data" | One folder per server: its log, live status and settings. |
bans | "bans.json" | The ban list every server shares. |
public_address | detect | The IPv4 address or DNS name players connect to. Empty asks your router (with UPnP) or api.ipify.org. |
upnp | false | Ask the router to forward the ports. Leave it off on a VPS. |
auto_update | false | Install new stable releases by themselves and restart the servers, which interrupts their games. See automatic updates. |
host_name | "Dedicated server" | Shown under each server's name in the browser, on its card and in its lobby. Dedicated servers always use this name, never a player's nickname. |
admins | [] | Player IDs who may kick and ban on every server. |
stats_server | public service | The stats service finished games are reported to, so players' ranks count them. Empty uses the project's public service, "off" reports nowhere, or give your own service's address. |
Discovery ([master])
| Setting | Default | Meaning |
|---|---|---|
enabled | true | Run this machine's master. Only one runs per machine; other configurations share it. Servers report to the two default masters either way. |
port | 49175 | Its TCP port. |
peers | [] | More masters, as https://… addresses: every server reports to them too, and this machine's master shares listings with them. |
origin | none | The address players use when an HTTPS reverse proxy sits in front of it. |
Players find your servers without adding anything: every server that isn't hidden reports to the two default masters (the project's public master and a second master), to this machine's master and to your peers, and masters pass on the other masters they know. While one default master is down, the other keeps your servers listed. A hidden server reports nowhere; players reach it by Direct Connect.
If both default masters stop answering, each server also reports to three other masters it learned from the masters it reports to, until one of them is back, so it stays in players' browsers. Nothing needs setting up; the server log says when it starts and stops doing this.
Masters only hand out addresses players can reach. A public_address of 127.0.0.1 lists your servers to this machine only, and a local-network one (192.168.x.x) lists them to that network, and to everyone else under the internet address the default masters see. Leave public_address empty to have it detected.
How masters share listings and fall back when one is down, and how to run a master on its own, on a machine without the game: see Master servers.
Each server ([[server]])
| Setting | Meaning |
|---|---|
name | Required and unique, up to 48 characters. |
port | Required, unique UDP game port (1024–65535). |
playlist | A playlist file: a rotation of three or more games players vote on. |
map + game | One map and game type for every game, named as in a playlist entry. |
variant | A saved custom game or shareable game type (.json). |
max_players | Players admitted at once, 1 to 16 (default 16), split-screen players included. |
voice, text_chat, votes | Voice chat, text chat and player votes. All on by default. |
chat_log | Keep the server's text chat in a file per day; see chat logs. On by default. |
hidden | Online but never listed; players join by address. |
password | A password players need to join; empty (the default) lets anyone in. See private servers. |
share_mods | Let players who lack a mod this server's games use download it from the server itself, and fall back to the server when a Steam Workshop download fails. Off by default. Workshop mods download through Steam either way. See Mods. |
share_rate | Upload limit for downloads from the server together, in Mbit/s (default 20). 0 is no limit, which check warns about. |
host_name, admins | This server's own host name, and extra admins for this server only. |
rcon_port, rcon_password | This server's remote console TCP port (its game port number unless set) and its own password. |
enabled | false keeps the entry without running it. |
Choose one of playlist, map + game, or variant per server. [defaults] takes the same optional settings for every server that doesn't set its own. A server with none of them plays Slayer on Guardian.
Private servers
Set password in a [[server]] block to make players enter it to join, or under [defaults] for every server. A server with password = "" is open even when [defaults] has one. Restart the servers after changing it.
[[server]]
name = "Clan Practice"
port = 49178
map = "The Pit"
game = "Slayer"
password = "a password you give your players"
- The Server Browser marks the server PRIVATE, and joining asks for the password, from the list, by Direct Connect or with a join link. A wrong one can be tried again.
- Up to 128 bytes of text; capitals and spaces count. The password never appears in listings or join links, and players prove they know it over the encrypted connection instead of sending it.
- It's separate from the remote console's password, and doesn't hide the server: use
hiddenfor that. - Players need 0.8.10 or later to join a private server. Servers without a password still take older versions.
RECLAIMER_DEDICATED_PASSWORDsets the[defaults]password, for example in Docker's.env.
Environment variables
Every setting outside [[server]] can also come from an environment variable: RECLAIMER_DEDICATED_ and the setting's name in capitals, with MASTER_ before the [master] ones, RCON_ before the [rcon] ones and WORKSHOP_ before the [workshop] ones. That suits Docker, systemd and other service managers, and works the same on Windows.
| Variables | Settings |
|---|---|
RECLAIMER_DEDICATED_PUBLIC_ADDRESS, _HOST_NAME, _ADMINS, _STATS_SERVER, _UPNP, _AUTO_UPDATE | The general settings. |
RECLAIMER_DEDICATED_MASTER_ENABLED, _MASTER_PORT, _MASTER_PEERS, _MASTER_ORIGIN | [master] |
RECLAIMER_DEDICATED_RCON_PASSWORD, _RCON_ADDRESS | [rcon], the remote console |
RECLAIMER_DEDICATED_WORKSHOP_ITEMS, _WORKSHOP_STEAMCMD, _WORKSHOP_USERNAME | [workshop], Workshop downloads |
RECLAIMER_DEDICATED_MAX_PLAYERS, _VOICE, _TEXT_CHAT, _CHAT_LOG, _VOTES, _HIDDEN, _PASSWORD, _SHARE_MODS, _SHARE_RATE, _PLAYLIST, _VARIANT | [defaults]: a server's own setting still wins. |
RECLAIMER_DEDICATED_GAME, _CONTENT, _DATA, _BANS | The folders. |
- A variable replaces the file's setting; an empty one leaves it.
ADMINS,MASTER_PEERSandWORKSHOP_ITEMSadd to the file's lists, separated by commas or spaces. - Flags take
trueorfalse(also1/0,yes/no,on/off). - A misspelt
RECLAIMER_DEDICATED_name stops the start, so a typo is never silently ignored.dedicated checkanddedicatedlist the variables in use.
Custom playlists
A playlist is a rotation of games, each a map with a game type, optionally with its own rules. A server running a playlist lets players vote on what to play next:
- Before each game, the lobby shows three games drawn at random from the whole playlist and None of the above, with a countdown (20 seconds unless you set another). The order of the file plays no part.
- Each game comes up in proportion to its weight: one with
"weight": 2comes up twice as often as one without. The game just played sits out the next ballot. - The game with the most votes is played. Ties go to the game offered first. With no votes, the first game offered starts, so a quiet server plays games in proportion to their weights.
- If None of the above wins outright, a new ballot opens with games that haven't been turned down yet.
- An empty server keeps its ballot closed and opens a fresh one when a player arrives.
1. Build the playlist
In the client (recommended)
Pick maps and game types from what you have installed. The editor checks every game and writes the file for you.
By hand
Playlists are short JSON text files. Write one in any text editor, or edit one the client saved.
In the client:
- Open the Playlists pageIn Host Game, choose the Playlist row in the lobby's setup, then New playlist.
- Add gamesPick a Map and a Game type and choose Add to Rotation. Repeat for at least three games. Installed mod maps are in the Map list too. Add Lobby Game adds whatever the lobby is set up to play, rules included. To have a game come up more often, select it and drag Weight (1 to 100); beside it is the game's share of the playlist's total weight.
- Change a game's rules (optional)Select the game and choose Open in lobby. Change its options as usual, then choose Save to playlist.
- Save itName the playlist and choose Save playlist. Games that aren't installed are marked MISSING, and repeats DUPLICATE; fix those first. The file is saved in
Documents\My Games\Project Reclaimer\Playlists; Open folder shows it.
By hand, a playlist looks like this:
{
"version": 2,
"name": "Community Rotation",
"vote_seconds": 30,
"games": [
{ "map": "Guardian", "game": "Slayer", "weight": 2 },
{ "map": "Valhalla", "game": "Capture the Flag" },
{ "map": "The Pit", "game": "Slayer", "name": "Slayer to 50", "rules": { "score_to_win": 50 } },
{ "map": "Valhalla", "game": "Slayer", "name": "BR Starts",
"options": { "player.primary_weapon": "Battle rifle", "player.secondary_weapon": "Magnum" } },
{ "map": "Maps/my_arena.json", "game": "Game Modes/snipers.bin" }
]
}
2. Put it on the server
Copy the playlist file into the server folder's playlists/ folder. If it uses your own saved maps or game types, copy those too: saved maps from Documents\My Games\Project Reclaimer\Maps into content/Maps, and game types from Documents\My Games\Project Reclaimer\Game Modes into content/Game Modes. Also make sure the server's game/ folder has every base map the playlist uses.
3. Point a server at it
In dedicated.toml, set playlist on a server (or under [defaults] for every server). Remove any map, game or variant from that server.
[[server]]
name = "Community Rotation"
port = 49176
playlist = "playlists/community.playlist.json"
max_players = 12
4. Check and restart
.\project-reclaimer dedicated check
check resolves every game in the playlist against the game and content folders and names anything missing, by game number. Then restart the servers: each server reads its playlist and content when it starts.
To try a playlist quickly on one PC, run a single server with it: .\project-reclaimer.exe local-server --playlist my.playlist.json, then join it from the client's Server Browser.
Playlist file reference
| Field | Meaning |
|---|---|
name | The playlist's name, shown in the lobby. |
vote_seconds | Voting time, 5 to 120 seconds. Optional; 20 by default. |
version | File format version. Optional; currently 2. |
games | The rotation: 3 to 128 games. Their order doesn't matter: ballots draw them at random by weight. |
Each game in games:
| Field | Meaning |
|---|---|
map | A base map by its title or file name ("Valhalla" or "riverworld"), a saved map in content/Maps ("Maps/my_arena.json"), the name stored inside a saved map, or a mod map: "workshop:item ID/map file name", or its name when only one installed map has it. Base maps win over saved maps and mod maps with the same name. |
game | A game mode ("Slayer", "Capture the Flag", …), a file in content/Game Modes, or the name stored inside a saved game type. Modes win over saved game types with the same name. |
weight | Optional. How often ballots offer this game compared with the others, 1 to 100; 1 when left out. A game can't be listed twice: raise its weight instead. |
name | Optional. The name players see for this game. |
rules | Optional. Scoring values to change, such as { "score_to_win": 50 }. Everything else keeps its default. |
options | Optional. Game options layered over the game type, keyed section.key. Values are a number or the option's label as the client shows it, ignoring case. |
Names are matched ignoring case. Some option keys to start with:
| Option | Example value |
|---|---|
player.primary_weapon | "Battle rifle", or "Random" for a new one at every spawn |
player.secondary_weapon | "Magnum", or "Map default" for the map's own (called "None" before 0.8.10) |
map.weapons | which weapons are placed on the map |
map.vehicles | "None" |
rounds.limit | 3 (one round unless set) |
rounds.early_victory | off unless set |
The easiest way to get option keys right is to change the options in the client's lobby and use Save to playlist: the editor writes only the settings that differ, with their exact keys. An unknown key or label is reported by game number.
Mod maps in a playlist
From 0.8.14, playlist games can be on mod maps. Pick them in the client's editor, which saves them by their Workshop item, or write them by hand: workshop:, the Workshop item's ID, a slash and the map's file name without .map. A mod map's name works too when only one installed map has it.
{
"version": 2,
"name": "Modded customs",
"games": [
{ "map": "workshop:2981234567/arena", "game": "Capture the Flag" },
{ "map": "workshop:2981234567/arena", "game": "Slayer", "options": { "rounds.teams": 1 } },
{ "map": "Guardian", "game": "Gun Game" }
]
}
- The ID is the number after
id=in the item's Workshop address. A server downloads the items its playlist names before it starts (see Workshop downloads), anddedicated modsprints the reference of every mod map it has, ready to paste. - Players get the playlist's mods as they join, like any server's mods. Before each game's countdown, every player prepares the map that won the vote, so everyone loads it together.
- Once your servers run 0.8.14, players need 0.8.14 or later to play their playlists, also playlists without mod maps.
Rules and limits
- At least three games, and no game may repeat another. Changed rules or options make a different game; a renamed but otherwise identical game is still a repeat. To offer a game more often, give it a
weight. - Editing sessions (Forge) can't be playlist games.
- A playlist can use up to 23 different mod maps, from at most 16 mods. Two mod maps whose map IDs clash, or two different mods' maps with the same file name, can't be in one playlist.
- A playlist stores no server settings, so it works for anyone with the same maps and game types. Share it freely.
Maps and game types
Put shared content in the content folder; every server on the machine sees it.
| Folder | Files |
|---|---|
content/Maps | Map variants (.mvar) and saved maps from the map editor (.json). |
content/Game Modes | Game variants (.bin) and shareable game types (.json), scripted game modes included. |
content/Mods | One folder per mod: a Workshop item's folder, or a custom .map, with its .mapinfo if it has one. See Mods. |
- Map and game variants reach players automatically when they join. Mods reach them through Steam Workshop, or from the server when it shares them.
- The first
dedicated checkor start puts the scripted game modes Gun Game, Growth, One in the Chamber and Zone Control incontent/Game Modes/Project Reclaimer. Name them like any saved game type, such asgame = "Gun Game"or{ "map": "Guardian", "game": "Growth" }in a playlist. A script runs on the server only; players don't need the file. See game modes on a dedicated server. - A saved map can hold objects from other maps. To host it, the server needs those maps in its
game/folder; the simplest is to rundedicated init --fromwithout--mapsto copy every multiplayer map. Campaign vehicles and AI come fromcampaign.mapand040_voi.map, whichdedicated initcopies either way. The first start builds a library of those objects (about 340 MB, in about half a minute), and the first start after each update builds it again and removes the old one. - A server with only some maps edits in Forge with the objects of the maps it has, and players with every map can join it.
- Players who lack a map a game needs, or a mod they have no way to download, are refused with a message that names it.
- Restart the servers after adding content.
Mods
A server can host mod maps, and saved maps with Forge objects from mod maps. A player who lacks a mod gets it as they join, in one of two ways:
- Through Steam Workshop. A mod from the Workshop downloads through Steam on the player's PC, and is checked against your server's copy. This works with nothing turned on: your server needs no Steam, account or key.
- From your server. With
share_modson, players download what they lack from your server itself, over the same encrypted port they play on. That covers mods that aren't on the Workshop, and a Workshop download that fails.
There's no web host, file mirror or Workshop upload to set up.
1. Add the mods
Copy each mod's folder into content/Mods, one folder per mod, or let the server download Workshop mods by ID. Every server on the machine sees them.
A Workshop mod
Copy the item's folder as it is from steamapps\workshop\content\976730 in your Steam library. It holds ModInfo.json, multiplayer, maps and sometimes the mod's own shared.map and sound banks, which players get with its maps. Keep its ModInfo.json: it names the Workshop item players download. You can rename the folder.
A single map
A folder with the .map and its matching .mapinfo, beside it or in an info subfolder, plus any shared.map or campaign.map the mod comes with. A multiplayer .map without a .mapinfo works too: it's listed under its file name, blam_mountain.map as “Blam Mountain”.
content/Mods/
├─ 2981234567/ a Workshop item's folder, copied as it is
│ ├─ ModInfo.json
│ ├─ multiplayer/arena.json
│ ├─ maps/arena.map
│ ├─ halo3/maps/shared.map the mod's own shared.map, if it has one
│ └─ halo3/fmod/pc/ the mod's own sound banks, if it has any
└─ canyon/ a single map
├─ canyon.map
└─ canyon.mapinfo
- Folder names don't matter: a mod is known by its files. Every server with the same files offers the same mod, so a player who got it from one server already has it for yours.
- Players only ever get what a game needs from a mod: its maps and their metadata, images and sound banks. Programs, scripts and any other files in the folder are never sent.
- A Workshop map is played with the map ID its author set in the mod tools. One that has none, as many Workshop maps do, gets an ID made from its file name, the same on every PC. Players need 0.8.12 or later for those maps.
- A mod with its own
shared.map, beside its map or in its package'shalo3/mapsfolder, has its maps read from that file, as the mod was built. - A Workshop item copied somewhere else, or renamed, is still known by its
ModInfo.json. Only an unusual package without that information needs areclaimer-workshop.jsonbeside itsModInfo.jsonto name its item, such as{"item": 2899741683, "folder": ""}, wherefolderis the package's folder inside the item (empty for the item itself). - To keep a mod in
content/Modswithout using it, list its folder incontent/disabled-mods.json, such as{"packages": ["Mods/canyon"]}, and restart the servers. It's the file the client's Settings → Mods switches write in a player's folder.
2. Choose what the server plays
- A mod map with a game type: name the map in
map, with agame, like a base map: by its Workshop reference,"workshop:item ID/map file name", or by its name when only one installed map has it. Or put mod maps in a playlist. - A mod map with your own rules: on a PC with the client and the mod, choose the mod map and a game type in Host Game, set the rules in Game Options and choose Save as variant. Copy the new file from
Documents\My Games\Project Reclaimer\Game Modesintocontent/Game Modesand name it in the server'svariant. The file has a random name; rename it if you like. The file keeps where the map was on the PC that saved it; the server plays its own copy fromcontent/Modsinstead, the one with the same file name and map ID, so copy the mod there too. - A saved map with objects from mod maps: copy it into
content/Mapsand name it inmapor in a playlist, like any saved map. The server works out which mods its objects come from.
[[server]]
name = "Community Maps"
port = 49178
variant = "content/Game Modes/canyon-slayer.json"
[[server]]
name = "Arena CTF"
port = 49179
map = "workshop:2981234567/arena"
game = "Capture the Flag"
If the server has no matching copy of a saved game's mod map, dedicated check names the map and where it looked.
3. Share them
Workshop mods need nothing more: players download them through Steam, even with sharing off. They need Steam running and signed in to an account with MCC; the game asks them to start Steam if it isn't. To send mods from your server too, for mods that aren't on the Workshop and for players whose Workshop download fails, turn on sharing. It's off until you do. Set it in [defaults] for every server, or in one [[server]]:
[defaults]
share_mods = true # players who lack a mod download it from the server
share_rate = 20 # Mbit/s for all of a server's downloads together
The environment variables RECLAIMER_DEDICATED_SHARE_MODS and RECLAIMER_DEDICATED_SHARE_RATE set the same two defaults, for example in Docker's .env. Then restart the servers.
dedicated check, the supervisor and the server's log warn about a server that uses mods with no download source, neither the Workshop nor sharing, which turns away every player who lacks them, and about one that shares them with no upload limit:
Warning 'Community Maps' uses mods (Canyon) with no download source: players who lack them cannot join. Provide Workshop sources or set share_mods = true for direct downloads.
Warning 'Community Maps' shares mods with no upload limit (share_rate = 0): downloads can take its whole upload and make its games lag. Set share_rate, in Mbit/s.
Workshop downloads
From 0.8.14, a server can download Workshop mods itself, by item ID, so there's nothing to copy from a game PC. Before the servers start, it downloads every item they name: in map or a playlist as workshop:item ID/map file name, and the items listed under [workshop]. The ID is the number after id= in the item's Workshop address. List items under [workshop] when you know only their IDs, and put it before the [[server]] blocks:
[workshop]
items = [2981234567]
dedicated mods downloads the items and prints the reference of every mod map the server has, to paste into map or a playlist. dedicated check and dedicated download missing items too.
.\project-reclaimer dedicated mods
Workshop 2981234567: acquiring from Steam
Workshop 2981234567: ready
workshop:2981234567/arena Arena
The server downloads through Steam in one of two ways:
The Steam app on the same PC
With no steamcmd set, the server asks the Steam app on its PC, which must be running and signed in to an account that owns MCC. It loads Steam's runtime from the game installation game names, which a server folder made with dedicated init doesn't include: point game at the game's own folder, or use SteamCMD.
SteamCMD
On a server without the Steam app, install Valve's SteamCMD and sign in to it once yourself with an account that owns MCC, entering the Steam Guard code if asked. Then set steamcmd and username.
C:\steamcmd\steamcmd.exe +login your_steam_account +quit
[workshop]
items = [2981234567]
steamcmd = 'C:\steamcmd\steamcmd.exe'
username = "your_steam_account" # the account name only, never a password
| Setting | Default | Meaning |
|---|---|---|
items | [] | Workshop item IDs to download, up to 64 in all with those the servers name. A collection isn't an item: list each item's ID. |
steamcmd | none | SteamCMD's program. Without it, the Steam app on this PC downloads. |
username | "" | The Steam account SteamCMD is signed in with. Empty tries an anonymous download, which Steam may refuse. |
- Project Reclaimer uses SteamCMD's saved sign-in and never asks for, sees or stores your Steam password. When the sign-in expires, sign in to SteamCMD again the same way.
- Each item is installed in
content/Mods/Workshop/item ID, with everything players need from it. Later starts check its files and use it as it is. - To update an item, stop the servers that use it, delete its folder and run
dedicated modsagain. A running server's mods never change underneath it. - A download that fails stops the start and names the item. SteamCMD's own log is in
data/workshop-cache. - Players still get the mods as before: through the Workshop, or from your server with
share_mods. - Tested: downloads through the Steam app. Not yet tested: a download through SteamCMD with a signed-in account.
Workshop downloads in Docker
The Docker image has no Steam, so its servers can't download Workshop items by themselves. A separate SteamCMD service that runs beside them, signed in by you in its own terminal so the servers never see your Steam sign-in, isn't in the downloads yet, so for now this way isn't available. Until then, copy the mods' folders into server/content/Mods and name their maps by name in map or a playlist: a workshop: reference makes the server try to download the item, which fails without Steam.
Objects from mods come packed
A saved map that uses a few objects from a big mod doesn't make players download the whole mod. While a server shares mods, it packs just the objects its current game uses from each one, usually a few MB where the mod is hundreds, and players download that instead. Packs are listed as the mod's name followed by "(objects)".
- Only the game being played comes packed. A playlist's listing still names the full mods of its other games.
- The server checks that a pack gives exactly the same objects as the mod before it offers it. If it doesn't, players need the whole mod, as before.
- Packs come only from the server, so they need
share_mods. Without it, players download the whole mods through the Workshop instead.
What players see
- Your server's listing names its mods. The Server Browser tags it with how many: 1 mod when a player has them all, 1 mod when they can download what they lack, through the Workshop or from your server, and 1 mod when a mod has no download source.
- Joining opens Required mods with the exact size to download. Once the files are in and checked, the player joins by themselves, without restarting.
- Players who lack a mod they can't download, one that isn't on the Workshop while you don't share it, see it marked "No download source".
- A download never replaces a different map with the same file name. When you host a new version of a mod, players who have the old one see "Map name clashes with mod on this PC" until they delete it in Settings → Mods.
See Mods in the player guide for the rest.
Bandwidth and safety
share_ratecaps what all of one server's downloads send together, so the games on the machine stay smooth. At the default 20 Mbit/s, a 150 MB mod takes about a minute to reach one player; players downloading at the same time share the limit.- Maps travel in checked chunks of about 1 MB. A player who joins from the Server Browser takes them from your server and up to three other listed servers that share the same mod, all at once, so the more servers share a mod, the faster everyone gets it.
- A server sends up to four downloads at once, at most two to one address. A player whose download stalls for 30 seconds gives up their place.
- Downloads don't take a player slot, but your IP bans apply to them.
- A server only sends the files of the mods its current games use, found by their fingerprint, never by a path a player asks for. Nothing else in the server folder is reachable.
- Players check every chunk and file against its SHA-256 fingerprint as it arrives. A server that sends a damaged chunk is dropped and the chunk comes from another, and a cut-off download resumes with the chunks it already has.
Limits
- A server's games can use up to 16 mods, each with up to 8 maps and 512 files. An objects pack counts as one mod and holds at most 256 MB.
- A mod's map can be up to 4 GB, a sound bank 2 GB and an image 8 MB. A map whose files don't fit is left out of the mod whole.
- One game session can use at most 23 mod maps: the game lists 50 multiplayer maps, 27 of them its own. Installed mods don't count until they're played. Rarely, two mod maps whose map IDs clash can't both be used in one session.
- A playlist can use up to 23 different mod maps; see mod maps in a playlist.
Admins, kicks and bans
Players are identified by their player ID: 64 hexadecimal characters tied to their community profile. Players find theirs in the client under Settings → Connectivity → Your player ID, which has a Copy button. dedicated status lists every connected player's name, ID and address.
List admins by player ID in admins, for every server or for one. In a game, an admin can:
- Tap Tab to pin the scoreboard and use Kick or Ban on a player's row. Ban asks for a second click.
- Type in chat:
/kick <name> [reason],/ban <name> [reason], or/banip <name> [reason]to ban their address too./helplists the commands.
A kicked player sees why on their main menu and can rejoin after two minutes. A ban goes on the shared ban list and applies to every server. Admins can't remove other admins.
Manage bans from the command line, from the remote console or by editing bans.json. Changes apply to running servers within a second, and a connected player who matches is removed. --for bans for a time (30m, 12h, 7d, 2w) instead of for good; a banned player reads how long is left:
.\project-reclaimer dedicated ban 0123…cdef --reason "Cheating"
.\project-reclaimer dedicated ban 89ab…4567 --for 7d --reason "Team killing"
.\project-reclaimer dedicated ban 203.0.113.4
.\project-reclaimer dedicated ban 198.51.100.0/24
.\project-reclaimer dedicated unban 203.0.113.4
.\project-reclaimer dedicated bans
{
"players": [{ "id": "0123…cdef", "name": "Bravo", "reason": "Cheating" }],
"ips": [{ "ip": "198.51.100.0/24", "reason": "Spam" }]
}
Only id or ip is required; a timed ban adds "expires" (Unix seconds), stops applying then, and leaves the file at its next change. A file that doesn't parse is reported in the server log and ignored, keeping the bans already in force. Profiles are free to create, so a banned player can come back with a new one; address bans help, but can also catch everyone behind a shared address.
Chat logs
Each server keeps what its text chat carries in a file of its own, one per day: data/<server>/chat/2026-09-27.log. Times are UTC, like the server log's, so a report can be checked against the joins, kicks and votes around it. Each line names the channel, the sender and their full player ID, the one dedicated ban takes; [Server] lines are the server's own kicks, bans and votes.
14:03:12 [All] Alpha (0123…cdef): gg
14:03:20 [Team Red] Bravo (89ab…4567): push their base
14:05:41 [Server] Charlie was kicked by Alpha.
Set chat_log = false to keep none. Old files are never removed. Chat logs hold what players wrote along with their IDs: keep them only as long as you need them, and tell your players that the server keeps them.
Remote console (RCON)
Moderation tools, Discord bots and web panels can manage your servers through a password-protected remote console: list players with their IDs, scores, health and shields, read the chat, joins and kills as they happen, kick, ban (also for a time), mute text and voice chat, send server lines to everyone or one player, end the round or the game, change the map, mode or next game, rename the server, set its join password, spread players over teams, and run votes. It's off until you set a password in dedicated.toml:
[rcon]
password = "a long passphrase only your tools know" # 8 to 128 characters
address = "127.0.0.1" # tools on this machine only; "0.0.0.0" for every network
Restart the servers. Each then listens on TCP at its own game port number: the server on UDP 49176 answers RCON on TCP 49176. rcon_port and rcon_password in a [[server]] give one server another port or its own password, for example for a community that moderates only its server. RECLAIMER_DEDICATED_RCON_PASSWORD and RECLAIMER_DEDICATED_RCON_ADDRESS set the two [rcon] settings.
Two protocols on one port
Source RCON
The protocol of Valve's games, which ready-made RCON clients, libraries in most languages and hosting panels speak: commands in, text out.
WebSocket
JSON replies, and live events: chat lines with the sender's player ID, joins, leaves, kicks, bans, mutes, votes, every kill, the game starting and ending, and whether a map change or team change worked. Browsers speak it too, so a web panel can connect directly.
RCON desktop client
From 0.8.11, each release comes with Project Reclaimer RCON, reclaimer-rcon-version.exe: a Windows program for moderators that needs no game or server on their PC. Get it from the RCON client downloads, which hold only that program and its checksum, or from the assets of the game's newest release.
- ConnectDouble-click the file and enter the server's Host (a name or IP address, without a port), its RCON Port, normally the game port such as
49176, and the RCON Password, then choose Connect. An optional Moderator name tells players and the server's log who is acting. - Watch the serverThe player list refreshes every five seconds, with each player's service tag, whether they're alive, their health and shields, and how long ago they last died. The console shows chat, joins, leaves, kills and moderation as they happen, and whether a game or team change worked. JSON shows each event's fields and Copy copies the console.
- Act on a playerSelect a player to prepare a
tell,kick,ban,muteorunmutewith their player ID, change the message, time or reason, and choose Send. Status, Players, Bans, Maps, Modes, Next game, Votes and Help run those commands, and any command can be typed; Up and Down bring back earlier ones. - Run the gameThe Manage menu prepares a command to load a map and mode, change only one of them, set the next game, rename the server, set the join password, redistribute or shuffle the teams, or start, pass or cancel a vote. Change it, such as the map's name, and choose Send.
- It uses the WebSocket protocol and connects to the server directly, not through a
wss://proxy. From outside the server's network, use a VPN or an SSH tunnel (see Security): withssh -L 49176:127.0.0.1:49176 you@server, connect to host127.0.0.1, port49176. - It never saves the password or the connection, and clears the password field once you're signed in. A
passwordcommand is hidden as you type it and left out of the command history. A lost connection isn't retried on its own, and neither are commands, since one that got no answer may already have run: connect again yourself.
From the command line
On the server's machine, dedicated rcon reads the password and port from dedicated.toml, so it needs no setup:
.\project-reclaimer dedicated rcon players
.\project-reclaimer dedicated rcon --server "Community Rotation" kick Bravo spamming
.\project-reclaimer dedicated rcon --watch
--server names the server when several have RCON, --watch follows a server's chat and events until Ctrl+C, and --json prints replies as JSON. Put options before the command. In Docker, run it with docker compose exec reclaimer dedicated rcon ….
Commands
| Command | What it does |
|---|---|
status | The server, its address, what it plays, where the round stands, players and limits, and a vote under way. |
players | Every connected player: number, name, player ID, address, admin or muted, split-screen players at their PC, and during a game their team, score and kills/deaths. |
say <text>, tell <player> <text> | A [Server] line in everyone's chat, or in one player's. |
kick <player> [reason] | Removes the player. They read who and why, and can rejoin after two minutes. |
ban <player> [time] [reason] | Bans the player's ID, for good or for a time such as 30m, 12h, 7d or 2w. Also takes the player ID, address or range of someone who isn't connected. |
banip <player> [time] [reason] | Bans a connected player's ID and their address. |
unban <target>, bans | Lifts a ban, by the banned player's name or written as it was banned (ID, address or range); lists the bans in force with who banned and how long is left. A name that more than one ban carries, such as a player banned by ID and by address, lifts nothing: use the ID or address from bans. |
mute <player> [time] [reason], unmute <player> | Nobody hears the player's text or voice chat: the server stops relaying them, for the time given, until unmute or until the server restarts. Rejoining keeps it. |
endround, endgame | Ends the round as if its time ran out, or ends the game with the scores as they stand. |
help [command] | The command list, or one command. |
Name a player by their number in players (#3), their player ID, or their name when only one connected player has it; quote names with spaces. The console acts with the host's authority, so it can kick, ban and mute admins too. Bans go on the ban list every server shares. Players read “Bravo was kicked by an admin.”, or the name a WebSocket tool says it acts for.
Game, server and vote commands
Servers on 0.8.14 or later also take these commands, which change what the server plays, its name and join password, and run its votes.
| Command | What it does |
|---|---|
maps, modes | The maps and saved maps, or the game modes and saved game types, the server has, each with the name to use in the commands below. |
map <map> | Ends the game and plays this map next, with the same rules. |
mode <mode> | Ends the game and plays this mode or saved game type next, on the same map. |
load <map> <mode> | Ends the game and plays both next. Quote names with spaces: load "The Pit" "Capture the Flag". |
nextmap [<map> [<mode>]] | Sets the next game without ending this one; without a mode, the rules stay as they are. On its own, says what's next and lists the playlist. |
servername [<name>] | Renames the server, or says its name. |
password [<password>] | Sets the password players need to join, or says whether one is set; password "" opens the server. It never shows the password, and doesn't change the console's own. |
teamcount [2-8] | Spreads the players over that many teams in a team round being played, or says how many teams have players. Needs enough players and a map with that many teams. |
shuffle, shuffleteams | Shuffles the players across the teams that have players, evening out their numbers. |
vote | The vote under way with its count, and the playlist ballot with its games and votes. |
startvote <endround | endgame | shuffle | kick | playlist> [player] | Calls a vote for the players to answer; kick names the player. Unlike a player's call, it starts with no yes vote. playlist opens the playlist ballot. |
passvote | Passes the vote under way, or closes the playlist ballot so the leading game wins as usual. |
cancelvote | Ends the vote under way with no result, or cancels the playlist ballot. The playlist then waits until startvote playlist or a map, mode, load or nextmap. |
- A map or mode change ends the current game and starts the chosen one in the next lobby; a server waits for a player before starting it. On a playlist server, it replaces one vote, and the playlist goes on after that game.
- The reply only says the change was accepted. Whether it worked comes after, as a
controlevent in the WebSocket stream and the client's console. A change that fails is dropped, and the server picks its next game as usual. - Map changes take base maps and saved maps, the ones
mapslists. A mod map can't be loaded from the console; put it in a playlist instead. - A new server name or join password lasts until the server restarts;
dedicated.tomlstays as it is. teamcountandshufflemove the players there are; they don't change the game type or limit the teams players join later.
players also gives each player's service tag, whether they're alive, their health and shields (as fractions, not percentages), and the seconds since they last died. In JSON, engine_id identifies each player in kill events, which come for every death, suicides and team kills included, and guest_players gives the same for split-screen players. A value the server can't tell yet, such as the last death before anyone has died, is null.
Security
- RCON is not encrypted. Keep
address = "127.0.0.1"and reach it from elsewhere through an SSH tunnel (ssh -L 49176:127.0.0.1:49176 you@server) or a VPN. If the servers must listen on every network, allow only your tools' addresses to the TCP ports in the firewall. A web panel can reach the WebSocket protocol through an HTTPS reverse proxy (wss://). - Five wrong passwords from one address within ten minutes lock that address out for up to ten minutes.
- The server log records every sign-in and wrong password with the client's address, and every command that changes something with where it came from.
- The password is kept in
dedicated.tomland in each server'sdatafolder: keep the server folder private. Change the password, then restart the servers, when someone should no longer moderate. - In Docker, see the remote console note under Everyday use: the consoles are published on the host's own
127.0.0.1only.
Player votes
So a server without an admin online can still deal with a griefer, players can vote to kick a player, end the round, end the game or, in team games, shuffle the teams. Votes are on unless a server (or [defaults]) sets votes = false.
- A vote passes as soon as more than half of the players on the server have voted yes (2 of 3, 3 of 4 or 5, 9 of 16), and fails after 30 seconds.
- One vote runs at a time. A kick vote needs at least three players and can't name an admin. A shuffle needs a team game with a round being played and at least two players.
- A player whose vote failed can call the next one after a minute.
- A player kicked by vote can rejoin after two minutes. Ending the game finishes it with the scores as they stand.
- A passed shuffle deals every player, split-screen players included, at random across the teams in play, so no team has more than one player more than another. If everyone was on one team, a second team comes back. Team scores stay with their teams. It evens out player counts, not skill.
Players call and cast votes from the pinned scoreboard (Vote Kick on a player's row; Shuffle, End Round and End Game in the title row) or in chat with /vote kick <name>, /vote endround, /vote endgame or /vote shuffle; see how to play. The remote console can call, pass and cancel votes too.
Running and updating
dedicatedprints joins, leaves, kicks, bans and errors with each server's name;--verboseprints everything. Every line also goes todata/<server>/server.log.dedicated statusfirst shows whether the server browser's master answers and how many of your servers it lists (Master · TCP 49175 · lists 2/2 servers), then each server's address, game and players, such as3/16 players. Split-screen players count too, and are named on the line of the player whose PC they play on (split screen: Player 2, Player 3). It fails while a server is down or the master doesn't answer, so monitoring and health checks can use it.- A server that stops is restarted after 5 seconds, then after longer waits if it keeps stopping, up to five minutes.
- Empty servers wait in their lobby using very little CPU, and start a game when someone joins.
To update Project Reclaimer, stop the servers, replace project-reclaimer.exe with the new download (renamed the same way), and start them again, or turn on automatic updates. Servers tell the Server Browser which version they run: a player on another version sees it on your server's card, and a join that fails because one side lacks something the other has says which side needs to update. Keep your servers on the newest release: from 0.8.14, for example, servers send the Server Browser their map and game variants' names and their players' names, which older servers don't.
After a game update on Steam, copy the new engine file into game/ once a Project Reclaimer release supports it. dedicated check names the file if it doesn't match.
Automatic updates
From 0.8.14, servers can update Project Reclaimer by themselves. It's off until you turn it on, at the top of dedicated.toml (before any [section]), or with RECLAIMER_DEDICATED_AUTO_UPDATE=true, such as in Docker's .env. Restart the servers once to start it.
auto_update = true
- The servers check for a new stable release when they start and every hour after. Pre-releases are never installed.
- A new release downloads while the games go on, and is checked against the release's SHA-256 checksum before it replaces the program. Then every server stops and starts again on the new version, with the same settings. Games under way end, and players have to join again.
- It installs the release's server-only build,
project-reclaimer-dedicated-version.exe, under the program's own file name, so that file then runs servers but not the game. Play from another copy. - The program's folder must be writable by the account the servers run as. Run one
dedicatedper copy of the program, so two never update the same file. - A failed check or download leaves the servers running and tries again an hour later; the console says why.
- It updates Project Reclaimer only. Copy new game files yourself after a game update on Steam, and in Docker,
docker compose pullstill updates the image (see Docker). - Settings, bans, playlists, content and game files stay as they are. Set
auto_update = falseand restart to stop updating; the version installed stays.
Troubleshooting
| Problem | What to do |
|---|---|
check names a missing map or game type | Copy the map into game/ (rerun dedicated init --from) or the file into content/, or fix the name in the playlist. |
check says the engine file doesn't match | The game was updated. Use a Project Reclaimer release that supports that version. |
| Servers don't appear in the browser | Open each server's UDP port: the browser asks every server directly and leaves out one that doesn't answer. Check public_address, and run project-reclaimer server-status <address>:<port> from another machine to see what a server answers. |
| Players see the server but can't join | Open or forward the server's UDP port. On a home connection behind shared carrier NAT, incoming connections may not be possible at all. |
With upnp = true, the log says “Manual setup may be needed” | Before 0.8.15, once another program on the PC had looked for devices on the network through Windows, the server's search for the router stayed on the PC for minutes. 0.8.15 searches over the connection that reaches the internet: update the server. If it still fails, check that UPnP is on in the router, or forward the ports by hand. |
| A port is already in use | Give each server its own port, and make sure no other program uses 49175. |
check warns that a server uses mods with no download source | Those mods aren't known as Workshop items and the server doesn't share them. Copy Workshop mods with their original ModInfo.json, or set share_mods = true for that server or in [defaults]; otherwise players who lack the mods can't join. |
| Players are asked to start Steam when they join | Your server's mods download through Steam Workshop, which needs Steam running on the player's PC, signed in to an account with MCC. With share_mods = true, they download from your server when Steam isn't available. |
check warns that a server shares mods with no upload limit | Set share_rate in Mbit/s, below your upload, so downloads can't make the games lag. |
| Mod downloads are slow | Raise share_rate if your upload allows. Sharing the same mod on more servers also helps: players who join from the Server Browser take chunks from up to four servers at once. |
| Players say a map “clashes with” a mod on their PC | They have another version of that mod. They delete it in Settings → Mods, then join again. |
check says the campaign maps are missing | The servers still run, but can't load saved maps with campaign vehicles or AI. Rerun dedicated init --from, or copy campaign.map and 040_voi.map from halo3\maps in the game's folder into game/halo3/maps. |
| Players can't join a private server | They need the password and 0.8.10 or later. Capitals and spaces count. Remove the password, or set password = "" on that server, to open it again. |
| Players' joins fail, saying the server needs an update | Your server runs an older Project Reclaimer than they do, and the game uses something only the newer one has. Update the servers to the newest release. |
| RCON tools can't connect | Set a password under [rcon] and restart the servers. The console listens on TCP at each game port number, on 127.0.0.1 unless you set address. dedicated check shows the ports and whether they're free. |
| A playlist is rejected | It needs three or more games with no repeats and no editing sessions, and at most 23 different mod maps. The server log names the game number. |
| The server log says players did not acknowledge the playlist map | A player on a version before 0.8.14 is on the server: everyone needs 0.8.14 or later on a 0.8.14 playlist server. If it says a player could not prepare the map, that player checks their mods in Settings → Mods or restarts their game. |
check or the start stops at a Workshop item | Its download failed. With the Steam app: it must be running, signed in to an account that owns MCC, and game must be the game's own folder. With SteamCMD: sign in to it again with steamcmd +login account +quit; its log is data/workshop-cache/item ID.log. In Docker, see Workshop downloads in Docker. |
check names a mod map that a saved game type uses | The server has no copy of it. Copy the mod's whole folder into content/Mods; if check says the server has another version of the map, put the version the game type was saved with there. |
| Servers don't update by themselves | Put auto_update = true at the top of dedicated.toml, before any [section], and restart them. The console says when a check or download fails; the program's folder must be writable. |
When reporting a problem, include the server's log from data/<server>/server.log.
