Multiplayer server
Join a public server from the Browse page, install a dedicated server of your own in one command, add TLS, run a public room, and understand what it does.
There are three ways to play multiplayer: a public server from the game's list, a server you host yourself, or a LAN game from inside the app.
Public servers
Multiplayer ▸ Browse lists the public servers, the ones Steel Tide runs and the ones friends of the game run for it, with where each machine is, how many seats are taken of those the match will have, whether a match is on, and your round trip to it. Pick a server and you are in its lobby under your commander name, with no join code and no key: a public server asks for neither. The name is asked for the first time you open Multiplayer (one is rolled for you, and you can type your own) and lives in Settings ▸ General from then on.
Strangers meet there, so a public room keeps itself in order while nobody holds the host key:
- Language. With the server's content filter enabled (the default), chat is filtered in transit; on a public room a line the filter would touch is not sent at all, the sender is told, and the third such line removes them for half an hour. A name the filter would touch is refused at the door.
- The vote. Any seated player's three-dot menu on a roster row, or a click on a name in the chat, offers Vote to remove. A majority of the seated players other than the one it is about carries it (and at least two of them, so a 1v1 cannot vote its winner out); whoever is voted out is kept out for half an hour.
- A seat held in silence. A seated player who is not ready, has said nothing for three minutes, and has somebody ready waiting on them is moved to the stands so the room can start.
- Mute and report. Mute hides a player's chat on your device; Report… sends what happened, with the last lines of chat, to the server's admin, who reads it later. Nothing happens to the reported player on the spot.
The list itself comes from this site (steelti.de/servers.json), so a room that moves is a change here rather than an update of the game. A room using an incompatible network protocol is greyed with a word to update. Different game releases can play together when their protocol versions match.
Self-host server
Supported: systemd-based Linux on x86-64 and ARM64.
curl -fsSL https://steelti.de/setup.sh | bash
The installer creates an unprivileged steel-tide service, generates a host key and a join code, and prints the address, the host key and the join code. Players enter the connection details under Multiplayer ▸ Join in the game, or use steel connect in the command-line client.
Allow inbound TCP port 28785 in the machine's firewall and at your cloud provider. The server is one executable and serves no game: the apps carry their own client, and browsers play from play.steelti.de. Re-running the installer updates the executable without replacing keys or checkpoints.
Assign a domain
A bare-IP server is reachable from the apps alone. A browser refuses to open an unencrypted socket from an https:// page, so players in a browser can only join a server with a certificate, over wss://. With one, the installer also prints two links into play.steelti.de with the server filled in: one for the host, one for the players.
Point a DNS name at the machine (an A or AAAA record, not a proxy), make sure TCP 80 is reachable for the certificate challenge, then:
curl -fsSL https://steelti.de/setup.sh | bash -s -- --domain play.example.com --email you@example.com
Certificates come from Let's Encrypt and renew on certbot's timer; a deploy hook restarts the service after renewal. --port 443 gives links without a port in them. A TLS-terminating reverse proxy in front of the plain server works too: forward WebSocket upgrades to the game port.
The installer accepts --no-filter to turn content filtering off and --filter to turn it back on. An update without either flag preserves the setting. It is also controlled by STEEL_TIDE_FILTER=0 or 1 in server.env; restart the service after changing it. Filtering covers names, chat, links and public map text. Turning it off also disables the automatic filter strikes, while votes, mute, reports and admin moderation remain available.
Lobby and saves
- One server hosts one lobby or one active match.
- New games expose the same map, metal, fog and population options as a local Conquest match.
- The host does not have to be there. While no host is connected, the player who has been seated longest is the acting host (the roster tags them) and picks the map and rules, sets the seats, starts the match, pauses it and returns everyone to the lobby. A host who connects takes the room back. The admin console, uploading and downloading saves and the match record stay with the host key.
- A finished match returns to the lobby on its own once everyone who played has left, or five minutes after the result if nobody pressed the button; a running match that has had no player connected for five minutes does the same. Whoever joins while a match is on watches it from the stands — the host too, who can end it for everyone from the pause menu — and is back in line for a seat when the lobby returns.
- The host may upload any valid
.steel-tide-savefile; saved factions can be reassigned between human and AI but not deleted. Use the download button on the local Load Game screen to export one. - The server writes an atomic checkpoint at match start and every 60 simulated seconds.
Modded rooms
The host or acting host selects installed mods from the lobby's title-bar gear → Mods. Every player needs the required ids and exact versions. Missing registry mods can be installed from the join prompt before reconnecting; other mods must be installed manually. Set the required mods before uploading a save made with them. A loaded save fixes the room's mod list. See Modding for installation and authoring.
Running a public room, and more than one
A server for friends has a join code and a host who is there. --public makes the other kind: no join code, strangers welcome, and the conduct rules above in force while you are away. --name names it as the Browse page would show it, and --rooms N runs several rooms on one machine (a server is one lobby or one match), each a port higher than the last, on the same keys and certificate:
curl -fsSL https://steelti.de/setup.sh | bash -s -- --domain play.example.com --public --name "Harbour" --rooms 3
From a shell on the machine, the same console the host has in the game:
steel-tide-server admin players # who is in the room, from where
steel-tide-server admin kick Bob
steel-tide-server admin ban Bob 60 # for an hour; with no minutes, for good
steel-tide-server admin bans
steel-tide-server admin reports # what players reported, with the chat around it
steel-tide-server admin say Restarting in five minutes
steel-tide-server admin --room 2 players
Run as root it reads the key from the installer's server.env; help lists every verb. A public room is a server like any other, so it is yours to list on your own site or to hand to friends by address; the game's own list is ours.
Uninstall
To remove it while keeping saves and keys:
curl -fsSL https://steelti.de/uninstall.sh | bash
Hosting from the app
The desktop and mobile apps host a game without a server of their own: Multiplayer ▸ Host, a name, an optional join code, and Start hosting. The game announces itself on the local network, and other copies of the app on the same Wi-Fi list it under Multiplayer ▸ Browse, in the LAN section above the public servers: one tap to join, or the address the lobby shows for anyone typing it in. It is the same server the dedicated install runs, inside the app, so it needs no configuration and no port opened on a router; everyone is on the same network. Two things it does not do: encrypt, so a friend on a browser still needs a dedicated server with a domain and certificate, and keep running on a phone that has gone to the background; the match waits until the app is back.
Last edited