A complete, source-verified walkthrough for running your own Windrose dedicated server. We cover the official SteamCMD install on Windows and on Linux via Wine, every field in ServerDescription.json, both network modes (invite-code / ICE and DirectConnection), autostart on systemd and Windows Service, world backups, save migration from a local world, and the most common errors with real fixes. Every command and every default has been checked against the official documentation at playwindrose.com and cross-referenced with the Steam Community guide and working community setups.

00 // What is the Windrose dedicated server?

Windrose is the co-op pirate survival game that hit over 107,000 concurrent players on Steam in April 2026. The developer shipped a free, official dedicated server application on 14 April 2026 (Steam App ID 4129620), which lets you run a persistent world on a machine that is not your gaming PC — meaning friends can sail, trade, and weather storms together even when you are offline.

Two things make the Windrose server different from a typical dedicated-server setup:

  • Two connection modes. By default the server uses an invite-code system backed by ICE / UPnP NAT punch-through, so no port forwarding is required. An optional DirectConnection mode uses classic TCP and UDP on port 7777 instead, which is friendlier to servers on VPS infrastructure.
  • No RCON, no admin console, no web API. All administration happens by editing ServerDescription.json while the server is stopped and then restarting it. This is a conscious design choice by the developer and is a key reason managed hosts that provide their own control panels are attractive for non-technical users.

This guide walks through both modes, covers Windows (the primary supported platform) and Linux via Wine (officially supported), and documents every field in the config file — something the current crop of how-to articles from managed hosts do not.

01 // Requirements

The numbers below are the official minimums from the Windrose developer documentation. They assume the Windrose server process is the only significant workload on the machine. If you also run the game client on the same PC, double the RAM.

Player countCPURAMStorage
2 players2 cores @ 3.2 GHz (Xeon Scalable class)8 GB35 GB SSD
4 players2 cores @ 3.2 GHz12 GB35 GB SSD
10 players2 cores @ 3.2 GHz16 GB35 GB SSD
Self-host + play on same machine2 cores minimum24 GB total35 GB SSD + game install
Key insight

Windrose is RAM-bound, not CPU-bound. Every official tier specifies only 2 cores. Past 10-16 concurrent players the single-threaded main loop becomes the bottleneck, so faster cores beat more cores. There is no benefit to an 8-core VPS for Windrose unless you are hosting multiple games on the same box.

Operating system options:

  • Windows 10 / 11 / Windows Server 2022 / 2025 — primary supported platform. Easiest path. No Wine, no workarounds.
  • Linux via Wine — officially supported in the developer docs. Works on Ubuntu 22.04 and 24.04 with Wine 9.x, plus winbind and xvfb for headless operation. Recommended only if you are already a Linux sysadmin or want to stack multiple game servers on one VPS.

Tools you will need regardless of platform: SteamCMD (Valve’s official server downloader), a text editor for JSON, and — if you want the server to survive reboots — either systemd on Linux or Task Scheduler / NSSM on Windows.

Option 1 — Self-Managed VPS

Hostinger KVM 4 — 16 GB RAM, 4 vCPU, 200 GB NVMe

Exact match for the official 10-player tier. Full root access, best performance per euro, and enough headroom to run a second game server on the same box. Requires comfort with Linux + Wine, or installation of a Windows VPS image. €12.99/month.

Get Hostinger KVM 4 →
Option 2 — Managed, One-Click

Host Havoc — Windrose-Ready in Under 2 Minutes

Host Havoc offers a dedicated Windrose product line: one-click deploy, their own control panel for the invite code and config, automated restarts, DDoS protection, and 24/7 support. No Linux, no Wine, no firewall rules. The right pick if you want to be playing today rather than sysadmin-ing tonight.

Get Host Havoc Windrose →

Not sure which fits? Hostinger if you want control, flexibility, and the best €/performance ratio. Host Havoc if you want zero setup friction and someone else responsible for the uptime. Both are valid. The rest of this guide assumes you chose Hostinger (or your own hardware) and are doing the install yourself; skip to section 05 if you are on a managed host and only want to understand the config.

02 // Choose your connection mode

Windrose supports two completely different networking models and the choice affects almost every later step. Pick this first; everything else follows.

Mode A — Invite code / ICE (default)Mode B — DirectConnection
ConfigUseDirectConnection: falseUseDirectConnection: true
How players connectPaste invite code in gamePaste invite code in game
Port forwardingNot requiredRequired: TCP + UDP on port 7777
Router UPnPRequiredNot required
Static public IPNot requiredRecommended
Works behind CGNATSometimes (ICE may punch through)No
VPN compatibilityBreaks NAT punch-throughFine if VPN forwards ports
Best forHome PC / laptop hostsVPS, dedicated servers, fixed IPs
Typical use caseYou + a few friendsSmall community, anything on rented hardware
Setting the record straight

Some host blogs claim static port forwarding “does not work” for Windrose and that only UPnP mode is viable. This is incorrect per the official documentation: UseDirectConnection: true is a first-class supported path. It requires both TCP and UDP to be open on the chosen port — a detail community troubleshooting confirms: players get bounced to the main menu if only UDP is forwarded. If you are on a VPS, Mode B is almost always the right answer.

Which mode should you pick?

  • Hosting from your home PC with a normal consumer router? Mode A. You do not want to fight port forwarding on an ISP-supplied modem, and UPnP almost always works.
  • Hosting on a Hostinger KVM, a Windows VPS, or dedicated hardware? Mode B. You have a static public IP, you already control the firewall, and ICE+UPnP on a VPS is more fragile than a simple port-forward rule.
  • On ISP-level CGNAT (common on 4G / 5G home internet, some rural DSL)? Neither mode will expose a public endpoint reliably. Either pay for a static IPv4 from your ISP, tunnel through a VPS you control, or use Host Havoc.

We cover exact firewall and port-forward commands for Mode B later in section 06. The rest of the install steps are identical whichever mode you pick.

03 // Install on Windows

Windows is the primary supported platform. If you are on Windows 10, 11, or Server 2022/2025, this is the path of least resistance. The install takes about 10 minutes on a decent connection.

Step 1 — Install SteamCMD

SteamCMD is Valve’s command-line client for downloading dedicated-server builds. It is free and official.

  1. Download the SteamCMD zip from Valve’s CDN: https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip
  2. Create a dedicated folder, for example C:\steamcmd, and extract steamcmd.exe into it.
  3. Double-click steamcmd.exe once. It will self-update on first run, then drop you at a Steam> prompt. Close it.

Step 2 — Download the Windrose server

Open a Command Prompt (or PowerShell) in your SteamCMD folder and run:

steamcmd.exe +force_install_dir "C:\Game_Servers\Windrose_Server" +login anonymous +app_update 4129620 validate +quit

What each flag does:

  • +force_install_dir — where to install the server. Put it on a drive with at least 40 GB free. Avoid paths with spaces or non-ASCII characters.
  • +login anonymous — the Windrose dedicated server is a free, publicly downloadable app (ID 4129620). No Steam account needed.
  • +app_update 4129620 validate — downloads app 4129620 and verifies every file. Slower on the first run; essential if you ever need to recover a corrupt install.
  • +quit — exits SteamCMD cleanly when the download finishes.
If login anonymous fails

A minority of users hit a “no subscription” error on anonymous login. The known fix is to log in with real Steam credentials on an account that owns Windrose: +login <your-steam-username> and enter the password + 2FA code when prompted. You only have to do this once; SteamCMD caches the session.

Step 3 — First launch

Navigate to your install folder (C:\Game_Servers\Windrose_Server in our example). You will find two launchers:

  • StartServerForeground.batrecommended for first launch. Opens a visible console window so you can watch the startup log and copy your invite code.
  • WindroseServer.exe — starts the server as a background process with no window. Kill it via Task Manager. Use this for automation later, not for debugging.

Double-click StartServerForeground.bat. On first run, Windows Defender Firewall will pop a dialog asking whether to allow WindroseServer.exe through the firewall. Allow it on Private networks at minimum. If you plan to run DirectConnection mode on a public IP, also allow Public networks.

Once the server reaches steady state (usually 10-30 seconds), it will print an invite code — something like f1014dc1. This is also written into ServerDescription.json alongside the server. Share that code with anyone you want to connect.

Windows Defender false positive

SmartScreen sometimes flags WindroseServer.exe on first launch because it is a new, unsigned binary. Click More info → Run anyway. You can also add an explicit exception in Windows Security → Virus & threat protection → Manage settings → Add or remove exclusions.

That is the entire Windows install. If you want the server to survive reboots or crashes unattended, jump to section 07 for the Windows Service / Task Scheduler setup. Otherwise continue to the config section.

04 // Install on Linux via Wine

Linux is officially supported via Wine in the Windrose developer documentation. This is the path to take if you want to run Windrose on a €12.99 Hostinger KVM alongside other game servers, or if you already operate a Linux game-server fleet. The commands below are for Ubuntu 24.04 LTS; Ubuntu 22.04 works identically.

Step 1 — Create a dedicated user

Never run a game server as root. Create an unprivileged user first:

sudo adduser --system --group --home /opt/windrose --shell /bin/bash windrose
sudo mkdir -p /opt/windrose/server /opt/windrose/steamcmd
sudo chown -R windrose:windrose /opt/windrose

Step 2 — Enable 32-bit packages and install Wine

Wine needs the 32-bit architecture enabled. Then install Wine 9.x from the WineHQ stable repository, plus the support packages Windrose needs (winbind for RPC, xvfb for headless display).

sudo dpkg --add-architecture i386
sudo mkdir -pm755 /etc/apt/keyrings
sudo wget -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key
sudo wget -NP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/ubuntu/dists/noble/winehq-noble.sources
sudo apt update
sudo apt install -y --install-recommends winehq-stable winbind xvfb cabextract fonts-wine

On Ubuntu 22.04 (Jammy), replace noble with jammy in the sources URL.

Verify Wine installed correctly:

wine --version
# wine-9.0 (or newer)

Step 3 — Install SteamCMD

SteamCMD ships in the Ubuntu multiverse repository:

sudo add-apt-repository -y multiverse
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install -y steamcmd

You will be prompted to accept the Steam Subscriber Agreement; select I AGREE.

Step 4 — Initialise the Wine prefix

Switch to the windrose user and create a fresh Wine prefix in its home directory. This keeps Wine’s fake Windows filesystem isolated from everything else.

sudo -iu windrose
export WINEPREFIX=/opt/windrose/.wine
export WINEARCH=win64
wineboot --init

The first wineboot run takes about 30 seconds and may download wine-mono and wine-gecko. Accept both prompts.

Step 5 — Download the Windrose server

This is the Linux-specific twist: the Windrose server is a Windows binary, so SteamCMD must be told to download the Windows platform build, not Linux.

cd /opt/windrose
steamcmd +@sSteamCmdForcePlatformType windows \
    +force_install_dir /opt/windrose/server \
    +login anonymous \
    +app_update 4129620 validate \
    +quit

The +@sSteamCmdForcePlatformType windows flag is critical. Without it SteamCMD will ask Steam for the Linux build of app 4129620, which does not exist, and the download will fail.

Step 6 — First launch under Wine

The server binary needs a virtual display because it initialises Unreal Engine rendering subsystems even in dedicated mode. Launch it inside xvfb-run:

cd /opt/windrose/server
xvfb-run -a wine WindroseServer.exe

Expect 20-60 seconds before the log settles. Watch for the invite code line, then Ctrl+C to stop cleanly (wineserver -k if it hangs). From here on you will run the server as a systemd service — covered in section 07.

“But Host Havoc says Linux corrupts saves”

That claim appears in at least one managed-host blog and does not match the official documentation or community reports. Wine is a first-class supported platform per the developer docs. The real risk with any Windrose install — Windows or Linux — is stopping the server with a kill -9 or a power loss mid-save. Always stop cleanly (Ctrl+C or systemctl stop) and keep the backups described in section 08. Do that and Linux is as reliable as Windows for Windrose.

05 // Configure ServerDescription.json

This is the single file that controls almost every tunable aspect of your server. There is no web panel, no RCON, no in-game admin console — you edit this JSON file while the server is stopped, then restart. Managed hosts can show you a nicer UI, but under the hood they are writing to the same fields.

Where it lives

  • Windows: <ServerRoot>\ServerDescription.json (e.g. C:\Game_Servers\Windrose_Server\ServerDescription.json)
  • Linux (via Wine): /opt/windrose/server/R5/ServerDescription.json

Open it in any text editor that understands UTF-8 (Notepad++, VS Code, nano). Stop the server before editing. Live-editing while the server is running will either be ignored, or worse, overwritten when the server shuts down.

Full field reference

Every field the server reads on startup. Italicised rows are ones the official docs mark “do not edit” or “reserved” — change them at your own risk.

FieldTypeDefaultWhat it does
Versionint1Config file schema version. Do not edit.
DeploymentIdstringbuild idBuild identifier, e.g. 0.10.0.0.251-master-9f800c33. Rewritten by the server on update.
PersistentServerIdstringautoUnique per-install server identity. Official docs say do not edit; behaviour will change in upcoming builds.
InviteCodestringautoThe 6+ character case-sensitive code players paste to join. You can customise it to something memorable — see scenarios below.
IsPasswordProtectedboolfalseEnable server-wide password. Must be true with a non-empty Password for password protection to actually engage.
Passwordstring""Server password. Only evaluated when IsPasswordProtected is true.
ServerNamestring""Display name shown alongside the invite code in-game. Helpful if you run multiple servers with similar codes.
WorldIslandIdstringworld idMust match the folder name of your world save under R5\Saved\SaveProfiles\Default\RocksDB\<GameVersion>\Worlds\. Mismatch = no world load.
MaxPlayerCountint4Concurrent-player cap. Official recommendation is to stay ≤ 10; higher values risk instability and save-file bloat.
UserSelectedRegionstring""One of SEA, CIS, or EU (EU covers North America per docs). Empty string = auto-detect.
P2pProxyAddressstring""IP address the P2P listening sockets bind to. Leave empty for all interfaces; set to a specific NIC IP on multi-homed hosts.
UseDirectConnectionboolfalseMaster switch between the two connection modes. false = ICE + UPnP (Mode A), true = direct TCP+UDP sockets (Mode B).
DirectConnectionServerAddressstring""Officially reserved for future use. Community reports of it working exist but we would not rely on it in production.
DirectConnectionServerPortint7777Port for Mode B. When UseDirectConnection is true, this port must be opened on both TCP and UDP in your firewall and router.

Common edit scenarios

Start the server once with default settings so the file is generated, then stop it and apply one of these edits.

Custom invite code + server name (friends-only)

{
    "InviteCode": "dragonden",
    "ServerName": "Dragonden — Keishin & friends",
    "MaxPlayerCount": 6,
    "UserSelectedRegion": "EU"
}

Any invite code under 6 characters is rejected. Case matters: Dragonden and dragonden are different codes.

Password-protected public server

{
    "IsPasswordProtected": true,
    "Password": "a-long-shared-secret",
    "ServerName": "Public EU — password in Discord",
    "MaxPlayerCount": 10
}

Both IsPasswordProtected: true and a non-empty Password are required; only one of the two is a no-op.

Mode B (DirectConnection) on a VPS with a static IP

{
    "UseDirectConnection": true,
    "DirectConnectionServerPort": 7777,
    "P2pProxyAddress": "",
    "ServerName": "Windrose VPS — direct"
}

Pair this with a firewall that opens TCP and UDP 7777 — full commands in section 06.

No RCON, no admin console, no remote API

Windrose has no runtime admin interface today. There is no rcon.exe, no web dashboard, no /kick command. The only supported management workflow is: stop server → edit ServerDescription.json → restart server. Third-party game-server panels such as AMP or GPortal are warned against in the official documentation because of World Island ID mismatches. This is the main reason managed hosts like Host Havoc can justify their price — they build their own admin UI on top of file edits. If you need live kick/ban tooling today, managed is the pragmatic path.

06 // Network and ports

Only Mode B (UseDirectConnection: true) requires firewall and router work. If you are on Mode A you can skip ahead to section 07 — UPnP handles everything dynamically.

Ports to open

PortProtocolDirectionPurpose
7777TCPInboundDirect connection handshake
7777UDPInboundDirect connection game traffic
Both protocols, or nothing works

The single most common Mode B failure mode is forwarding UDP only. The server listens on both TCP and UDP; clients bounce back to the main menu if TCP is closed. Always open the port on both protocols.

Windows Firewall (PowerShell, as Administrator)

New-NetFirewallRule -DisplayName "Windrose TCP 7777" -Direction Inbound -Protocol TCP -LocalPort 7777 -Action Allow
New-NetFirewallRule -DisplayName "Windrose UDP 7777" -Direction Inbound -Protocol UDP -LocalPort 7777 -Action Allow

To remove later:

Remove-NetFirewallRule -DisplayName "Windrose TCP 7777"
Remove-NetFirewallRule -DisplayName "Windrose UDP 7777"

Linux firewall (UFW on Ubuntu)

sudo ufw allow 7777/tcp comment "Windrose TCP"
sudo ufw allow 7777/udp comment "Windrose UDP"
sudo ufw reload
sudo ufw status verbose

If you use firewalld (CentOS, Rocky, AlmaLinux):

sudo firewall-cmd --permanent --add-port=7777/tcp
sudo firewall-cmd --permanent --add-port=7777/udp
sudo firewall-cmd --reload

Hostinger VPS: the extra firewall layer

Hostinger KVM instances have a control-panel firewall that sits in front of your OS firewall. Opening ports in ufw is not sufficient — you also need to allow them in the Hostinger panel:

  1. Log in to hPanel → VPS → your server → SettingsFirewall.
  2. Create a new rule allowing TCP 7777 from 0.0.0.0/0 (inbound).
  3. Create a second rule allowing UDP 7777 from 0.0.0.0/0 (inbound).
  4. Save. Hostinger applies changes in under 30 seconds.

Home router port forwarding

If you are hosting from a home PC in Mode B, your router needs to forward external port 7777 to your PC’s LAN IP on both protocols. The exact UI differs per router, but the fields you need are always:

  • Service name: Windrose
  • External port: 7777
  • Internal IP: your PC’s LAN address (check with ipconfig on Windows, ip a on Linux)
  • Internal port: 7777
  • Protocol: Both TCP and UDP (create two rules if your router only allows one protocol per rule)

Test the port from the outside

From a machine outside your network (tether to 4G, use a friend’s connection, or use an online port-check tool), verify both protocols are open:

# TCP test
nc -vz YOUR.PUBLIC.IP 7777
# UDP test (no clean success signal; absence of ICMP unreachable is the pass)
nc -vzu YOUR.PUBLIC.IP 7777

Web-based checkers like portchecker.co only test TCP. A TCP-only pass does not mean UDP is open. If you can only test from inside your LAN, you are testing NAT hairpin, not the real external path — always test from an outside connection.

07 // Autostart and crash recovery

You do not want to log in and double-click a .bat file every time your host reboots. Both Windows and Linux have first-class tools for running the Windrose server as a background service that starts on boot and restarts on crash.

Windows — Task Scheduler

Task Scheduler is the supported way to autostart processes on Windows Server and Windows 10/11. The command below creates a task that runs StartServerForeground.bat on boot, as the SYSTEM account, with no GUI popup.

From an elevated Command Prompt:

schtasks /Create /TN "Windrose Server" /TR "C:\Game_Servers\Windrose_Server\StartServerForeground.bat" /SC ONSTART /RU SYSTEM /RL HIGHEST /F

Flag breakdown:

  • /TN — task name as it appears in Task Scheduler
  • /TR — the program to run (full path, no quotes needed inside if path has no spaces; quote it if it does)
  • /SC ONSTART — trigger: when Windows boots
  • /RU SYSTEM — run as SYSTEM (no login required)
  • /RL HIGHEST — run with highest privileges (needed for some firewall exceptions)
  • /F — overwrite the task if it already exists

Enable crash-restart by editing the task in the GUI: open Task Scheduler → Task Scheduler Library → Windrose Server → Properties → Settings, then tick “If the task fails, restart every: 1 minute, Attempt to restart up to: 99 times.”

Test without rebooting:

schtasks /Run /TN "Windrose Server"
# Stop:
schtasks /End /TN "Windrose Server"
# Disable:
schtasks /Change /TN "Windrose Server" /DISABLE

Linux — systemd

Create a systemd unit at /etc/systemd/system/windrose.service:

sudo tee /etc/systemd/system/windrose.service > /dev/null <<'EOF'
[Unit]
Description=Windrose Dedicated Server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=windrose
Group=windrose
WorkingDirectory=/opt/windrose/server
Environment="WINEPREFIX=/opt/windrose/.wine"
Environment="WINEARCH=win64"
Environment="WINEDEBUG=-all"
Environment="DISPLAY=:0"
ExecStart=/usr/bin/xvfb-run -a /usr/bin/wine WindroseServer.exe
ExecStop=/usr/bin/wineserver -k
Restart=on-failure
RestartSec=15
TimeoutStopSec=30
StandardOutput=append:/var/log/windrose/server.log
StandardError=append:/var/log/windrose/server.err

[Install]
WantedBy=multi-user.target
EOF

Create the log directory and enable the service:

sudo mkdir -p /var/log/windrose
sudo chown windrose:windrose /var/log/windrose
sudo systemctl daemon-reload
sudo systemctl enable --now windrose.service

Control and inspection commands:

sudo systemctl status windrose       # current state + last 10 log lines
sudo systemctl restart windrose      # clean restart
sudo systemctl stop windrose         # graceful stop (kills wineserver)
sudo journalctl -u windrose -f       # live tail
tail -f /var/log/windrose/server.log # alternative file tail
Why Restart=on-failure not always

on-failure restarts the server when it exits with a non-zero status or is killed by a signal — i.e. a real crash. always restarts even when you manually systemctl stop it, which makes debugging painful. The 15-second RestartSec gives Wine time to fully clean up its file locks before the next start, avoiding spurious save-file corruption warnings.

With autostart in place the server will survive reboots, kernel updates, and most crash scenarios without manual intervention. The next two sections cover the things autostart cannot protect you from: data loss and build updates.

08 // Backups

Windrose stores world state in a RocksDB-backed directory tree. RocksDB files are locked while the server is running, so a hot backup will capture inconsistent state and probably corrupt. Always stop the server before copying save files.

Where save files live

<ServerRoot>\R5\Saved\SaveProfiles\Default\RocksDB\<GameVersion>\Worlds\<WorldID>\

Example for a 0.10.0 build: C:\Game_Servers\Windrose_Server\R5\Saved\SaveProfiles\Default\RocksDB\0.10.0\Worlds\...

The WorldDescription.json file inside the <WorldID> folder is the manifest. Back up the entire <WorldID> directory — partial copies are useless.

Windows backup script

Save as backup-windrose.bat and run from Task Scheduler nightly at 04:00:

@echo off
set SERVER_ROOT=C:\Game_Servers\Windrose_Server
set BACKUP_DIR=D:\Backups\windrose
set TS=%DATE:~-4%-%DATE:~3,2%-%DATE:~0,2%_%TIME:~0,2%%TIME:~3,2%
set TS=%TS: =0%

schtasks /End /TN "Windrose Server"
timeout /t 10 /nobreak > nul

robocopy "%SERVER_ROOT%\R5\Saved" "%BACKUP_DIR%\%TS%\Saved" /E /R:2 /W:5 /NFL /NDL

schtasks /Run /TN "Windrose Server"

forfiles /P "%BACKUP_DIR%" /D -7 /C "cmd /c if @isdir==TRUE rd /s /q @path"

This stops the server, waits 10 seconds for locks to release, copies the Saved directory (which includes world + logs + crash dumps), restarts the server, then prunes backups older than 7 days.

Linux backup script

Save as /usr/local/bin/backup-windrose.sh and wire into cron:

#!/usr/bin/env bash
set -euo pipefail
SERVER_ROOT=/opt/windrose/server
BACKUP_DIR=/var/backups/windrose
TS=$(date -u +%Y-%m-%dT%H-%M-%SZ)

mkdir -p "$BACKUP_DIR"
systemctl stop windrose
sleep 5

tar -czf "$BACKUP_DIR/windrose-$TS.tar.gz" -C "$SERVER_ROOT" R5/Saved

systemctl start windrose

# Retain 7 daily + 4 weekly
find "$BACKUP_DIR" -name "windrose-*.tar.gz" -mtime +7 \
    ! -name "windrose-*-Sun-*" -delete
find "$BACKUP_DIR" -name "windrose-*-Sun-*.tar.gz" -mtime +28 -delete

Install the cron job:

sudo chmod +x /usr/local/bin/backup-windrose.sh
echo "0 4 * * * root /usr/local/bin/backup-windrose.sh" | sudo tee /etc/cron.d/windrose-backup

For off-box backups, pipe the tarball to rclone, rsync, or aws s3 cp immediately after it is written. A backup that only lives on the same disk as the server is not a real backup.

09 // Updates

Windrose is still in active Early Access. New builds ship often and occasionally change the world-save schema (the 0.8 → 0.10 jump, for example, required a migration step). Update carefully.

Update workflow

  1. Back up first. Run the backup script from section 08 and verify the tarball / directory actually exists before you touch anything else.
  2. Stop the server cleanly. schtasks /End /TN "Windrose Server" on Windows, sudo systemctl stop windrose on Linux.
  3. Re-run SteamCMD with the same flags. SteamCMD will diff against your install and only pull changed files:
    # Windows
    steamcmd.exe +force_install_dir "C:\Game_Servers\Windrose_Server" +login anonymous +app_update 4129620 validate +quit
    
    # Linux
    sudo -iu windrose steamcmd +@sSteamCmdForcePlatformType windows +force_install_dir /opt/windrose/server +login anonymous +app_update 4129620 validate +quit
  4. Check the GameVersion folder. If your save path was RocksDB\0.10.0\Worlds\... before the update and is now RocksDB\0.11.0\Worlds\..., the build bumped schema. Your world will not auto-load in the new folder — see section 10.
  5. Restart the server and watch the log. A successful update will print the new build id in the first 30 seconds. A failed schema migration will usually throw a “world not found” error and force the server to generate a fresh world — stop immediately if you see that, your live world is at risk.
Do not auto-update unattended

Some guides recommend running app_update on a cron timer. For Windrose during Early Access we strongly advise against it. One bad schema migration at 03:00 with no human watching the log is how communities lose weeks of builds. Manual updates — ideally on a weekend when you can watch the first post-update session — are the safe default until the game hits 1.0.

10 // Migrate a save between builds

When a Windrose update bumps the save schema, the new server build looks for worlds in a new <GameVersion> folder. Your existing world still lives in the old folder, untouched. You have to move it by hand — there is no automatic migration in Early Access builds.

Walkthrough (0.10.0 → 0.11.0 as an example)

  1. Stop the server.
  2. Navigate to <ServerRoot>\R5\Saved\SaveProfiles\Default\RocksDB\.
  3. You will see two folders, one per build: 0.10.0\ and 0.11.0\. The new folder contains only an empty Worlds\ directory.
  4. Copy the entire <WorldID> directory from 0.10.0\Worlds\ into 0.11.0\Worlds\. Do not merge or rename — copy the whole folder as-is.
  5. Open ServerDescription.json and confirm WorldIslandId still matches the folder name you just copied. It should.
  6. Start the server and watch the log. A successful migration logs “world loaded” within about 30 seconds. If the server instead generates a new empty world, stop immediately and restore from backup — the schema jump was bigger than a folder copy can handle.
Migration across major versions can fail

A file-level copy works when the save schema is backwards-compatible. If the developers introduced breaking changes — new entity types, reworked stats, changed tile IDs — the new build will reject the old save. Always test migrations on a copy of the world, not your live file. If the copy fails to load cleanly, you have three options: stay on the old build for a while, wait for an official migration tool, or accept the world loss and start fresh.

11 // Performance tuning

Windrose is a Unity–Unreal hybrid built on Rocks DB persistence. It is more CPU-bound than RAM-bound at small player counts, so the biggest wins come from single-thread speed and NVMe storage, not from adding more cores.

Place the server on NVMe, not spinning rust

RocksDB does many small sequential writes during autosave. On a 7200rpm HDD the autosave cycle can visibly pause the server at higher player counts. SATA SSDs are acceptable; NVMe is better. All Hostinger KVM plans are NVMe by default.

Windows: set the power plan to High performance

Default Windows Server installs use Balanced, which aggressively parks cores and throttles clocks. Switch to High performance from an elevated prompt:

powercfg /setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c

Linux: pin the CPU governor to performance

Default Ubuntu Server uses the schedutil or powersave governor. On a dedicated server you almost always want performance:

sudo apt install -y linux-tools-common linux-tools-generic cpufrequtils
echo 'GOVERNOR="performance"' | sudo tee /etc/default/cpufrequtils
sudo systemctl restart cpufrequtils

Silence Wine debug output (Linux only)

Wine’s default logging is chatty and writes to stderr on every event. The WINEDEBUG=-all line in the systemd unit we wrote in section 07 already handles this — no further action needed. If you did not use our systemd unit, add that environment variable to whichever launcher you are using. Users report 10-20 % CPU reductions on idle frames just from silencing debug.

Cap MaxPlayerCount at what your CPU can actually serve

The server accepts large values in MaxPlayerCount, but each additional player adds persistent-state work that does not parallelise well. Practical ceilings based on community reports:

Host CPURecommended MaxPlayerCount
Hostinger KVM 2 (2 vCPU)4–6
Hostinger KVM 4 (4 vCPU)8–10
Hostinger KVM 8 (8 vCPU)10 (Windrose’s own recommended ceiling)
Desktop Ryzen 5 / i5 13th gen+8–10

Pushing past 10 concurrent players on any hardware is experimental per the official documentation. Save-file bloat and mid-session desyncs become more likely, and there is no way to reduce the damage after the fact short of restoring from backup.

12 // Troubleshooting

The problems that actually bite Windrose server admins in the wild, ranked by how often we see them in community threads.

SymptomRoot causeFix
Players paste the invite code, get bounced back to the main menu in Mode B. Only UDP 7777 forwarded — TCP is still blocked. Open TCP and UDP 7777 in every firewall layer (OS, host panel, router). Re-test from outside your network.
SteamCMD fails with “account logon denied / no subscription”. Anonymous login intermittently fails on some Steam regions. Use a real Steam login that owns Windrose: +login <username>. Once cached you do not need to enter it again.
On Linux the server process exits within 2–3 seconds of startup. Missing winbind, xvfb, or a broken Wine prefix. Re-run the install commands in section 04. Run a manual xvfb-run -a wine WindroseServer.exe to see the actual error.
Server generates a fresh empty world after an update. Save schema jumped and the new <GameVersion> folder is empty. Stop immediately, restore from backup, then follow the migration steps in section 10.
Invite code rejected as invalid on save. Fewer than 6 characters, or contains symbols. Use 6+ characters from 0-9, a-z, A-Z only. Case is significant.
Mode A server works locally but not for external players. Router has UPnP disabled, or ISP is using CGNAT. Enable UPnP in the router admin. If still failing, check for CGNAT (run curl ifconfig.me and compare to your router’s WAN IP). CGNAT = switch to Mode B on a VPS.
Windows SmartScreen blocks WindroseServer.exe. Unsigned binary on a fresh install. Click More info → Run anyway, or add the folder to Defender exclusions. Not a real security issue for this app.
Server runs fine for 30 minutes then freezes during autosave. Storage is too slow (HDD under load) or antivirus is scanning RocksDB files mid-write. Move install to NVMe. Exclude the server directory from Windows Defender real-time scanning.
Third-party panel (AMP, GPortal community) shows the server but no players can join. Panel-managed install used a non-matching WorldIslandId. Panels are explicitly warned against in official Windrose docs. Move to bare SteamCMD + config edits, or use a vetted managed host like Host Havoc.

Getting more diagnostics

  • Windows: run StartServerForeground.bat from an elevated prompt to keep the console open even on crash. Screenshot the last 30 lines before submitting a bug report.
  • Linux: sudo journalctl -u windrose -n 200 --no-pager dumps the last 200 lines; /var/log/windrose/server.err captures just stderr.
  • Clean reproduction: back up your current install, then test the same problem against a fresh default install. If the fresh install is fine, the bug is in your config or world; if it also fails, the bug is in the build and worth filing upstream.

13 // Config generator (coming soon)

We are building a Windrose config generator as part of our server config generator tool. It will cover the same 14 fields documented in section 05, produce a validated ServerDescription.json, and include presets for the common modes (friends-only, password-protected public, Mode B on VPS). Check back in a day or two — guide ships first, tool follows.

Why this guide first, tool second

A config generator is only useful if you already understand what the fields mean and which combinations are valid. The guide above is the prerequisite. Once you have read through the field reference and the connection-mode decision, a generator that writes the JSON for you saves typing — but it can’t replace the judgement calls. We would rather ship the guide honestly than ship a tool that hides the complexity.

14 // Frequently asked questions

Do I need a Steam account to host a Windrose server?

Usually no — the Windrose dedicated server (app ID 4129620) is a free, anonymous-installable SteamCMD app. Occasionally Steam returns a “no subscription” error on anonymous login from certain regions; the workaround is to log in once with a real Steam account that owns Windrose. You do not need to keep that account logged in.

Can I run the server on the same PC I play on?

Yes, but double the RAM requirement. Windrose client + Windrose dedicated server together comfortably need 24 GB system RAM (16 GB client + 8 GB server). 16 GB total is too tight — both processes swap and you will see stutter during autosave. If you only have 16 GB, host on a VPS or dedicated box and play from your PC as a normal client.

How many concurrent players does a Windrose server handle?

Official recommendation is up to 10 concurrent players. The server accepts higher values in MaxPlayerCount but performance and save-file integrity become experimental above that threshold. For stable play with 10 players, a 4 vCPU / 16 GB host (Hostinger KVM 4) is the minimum we would recommend; 8 players is the sweet spot on that tier.

Does Windrose support mods or plugins?

Not at the dedicated server level as of the current Early Access builds. There is no plugin API, no scripting hook, and no mod loader. Any customisation is limited to the 14 fields in ServerDescription.json. This is likely to change as the game matures — we will update this guide when mod support ships.

Is there an RCON, admin console, or web panel?

No. Windrose ships with no runtime admin interface. All management happens by stopping the server, editing ServerDescription.json, and restarting. Third-party panels like AMP and GPortal are warned against in the official documentation because of WorldIslandId mismatches. If you need live kick/ban tooling today, a managed host such as Host Havoc builds a panel on top of file edits for you.

Can I migrate my single-player world to a dedicated server?

Yes. Client saves live at %LOCALAPPDATA%\R5\Saved\SaveProfiles\<Profile>\RocksDB\<GameVersion>\Worlds\<WorldID>\ on Windows (equivalent paths for Stove and Epic). Copy that <WorldID> folder into the server’s R5\Saved\SaveProfiles\Default\RocksDB\<GameVersion>\Worlds\ directory and set WorldIslandId in ServerDescription.json to match. Versions must match: a 0.10.0 client save will not load on a 0.11.0 server without the migration steps in section 10.

What’s the real difference between Mode A and Mode B?

Mode A (default, UseDirectConnection: false) uses ICE + UPnP to negotiate a peer-to-peer connection through your router automatically. No port forwarding, but needs UPnP and will not work on CGNAT. Mode B (UseDirectConnection: true) uses fixed TCP+UDP sockets on port 7777; you open the port once and it works for everyone, including players behind restrictive networks. VPS hosting almost always wants Mode B; home PCs almost always want Mode A.

Do I need a static public IP address?

Mode A: no. The invite code handles connection negotiation regardless of IP changes. Mode B: recommended but not strictly required — a dynamic DNS hostname pointing at your current public IP works. If your ISP puts you behind CGNAT, no amount of dynamic DNS will help; either pay for a static IPv4 or host on a VPS.

What happens when Windrose releases an update?

Clients auto-update through Steam/Epic/Stove on launch. The server does not auto-update — you re-run the SteamCMD command from section 09 whenever you want the new build. Clients on mismatched versions cannot join. During Early Access we recommend updating manually, backing up first, and watching the first post-update session for schema-migration problems.

Is Linux hosting officially supported?

Yes, via Wine. The official Windrose server documentation lists Wine with winbind and xvfb as a supported path for Linux dedicated hosting. Wine is first-class, not a hack. Linux pairs well with a systemd unit and a Hostinger KVM for always-on dedicated hosting at a much lower price than Windows VPS equivalents.

Self-host or managed — what should I pick?

Self-host if you already run Linux servers, want root access, and value cost per month (Hostinger KVM 4 at ~€12.99/mo versus €15+ for managed Windrose). Managed if you want zero terminal work, live admin tooling, and support that can help at 02:00 when something breaks (Host Havoc). Both are valid — we run our own deployment on a Hostinger KVM 4 because we like the control, but we link to Host Havoc because for a lot of players that trade-off is not worth it.