Dedicated Server Settings¶
The Stationeers Dedicated Server (Steam app 600760) shares its configuration surface with the regular client build. There is no server-only Settings class and no server-only command dispatcher. The dedicated build is the same Unity assembly with Application.platform == WindowsServer (or -batchmode) flipping a handful of conditional paths.
Three orthogonal configuration layers determine how the server runs:
- Unity built-in launch flags (
-batchmode,-nographics,-logFile <path>,-screen-*, etc.) are consumed by the Unity engine before any Stationeers code runs. They are not in this page; see Unity's command-line reference. - Stationeers settings (
Settings.SettingData, persisted tosetting.xml). 80+ XML-serialized fields covering both client UI/performance and server behaviour. Set via-settings <Field> <Value>on the launch line, written intosetting.xmlby the runtime, or hand-edited in the file. - Stationeers commands (
CommandLinedispatcher, 70+ entries). Same dictionary serves both launch flags (with-prefix, multiple per launch) and runtime stdin (no prefix, one per line). Each command exposesHelpText,Arguments, andIsLaunchCmd.
Architecture¶
The single dispatcher is CommandLine.Process(string[], bool onLaunch = false) (decompile line 95111). When onLaunch is true (called from [RuntimeInitializeOnLoadMethod] CommandLine.ProcessOnLaunch), every -name token starts a new command and subsequent non-dash tokens accumulate as that command's arguments. When onLaunch is false (stdin path), only the first token may be -name-prefixed; later tokens are arguments to the first command. Same dispatch table either way.
The dispatch dictionary is initialised in the static constructor of CommandLine (line 94942):
public static class CommandLine
{
private static readonly SortedDictionary<string, CommandBase> _commandsMap;
...
static CommandLine()
{
_commandsMap = new SortedDictionary<string, CommandBase>
{
["achievements"] = new AchievementsCommand(),
["help"] = new HelpCommand(),
...
["save"] = new SaveCommand()
};
...
}
}
Each registered command derives from CommandBase and overrides:
string HelpText(one-line description for thehelpcommand)string[] Arguments(argument shape; used byhelpto format usage)bool IsLaunchCmd(advisory: whether the command makes sense on the launch line)string Execute(string[] args)(returns a string to print, or null)
Two helpers used inside Execute bodies are worth knowing about:
CommandBase.CannotAsClient(name)returns true when the local process is a remote client, blocking commands that only make sense on the server (Save, Ban, Kick).CommandBase.CannotInSinglePlayer(name)returns true in single-player, blocking client/server-only commands like Ban.
Settings (setting.xml keys)¶
The setting.xml file path is computed lazily by Settings.SettingData.Path (line 248582):
public static string Path
{
get
{
if (string.IsNullOrEmpty(_path))
{
_path = System.IO.Path.Combine(StationSaveUtils.GetSavePath(), "setting.xml");
}
return _path;
}
set { _path = value; }
}
So setting.xml defaults to <SavePath>/setting.xml where SavePath is itself a SettingData field. -settingspath <file-path> (the SettingsPathCommand at line 98695) overrides this explicitly; useful for forcing a server's setting.xml to a specific location independent of SavePath.
-settings <Field> <Value> is reflection-based via ClassManipulator<Settings.SettingData> (the SettingsCommand at line 98668). Every field in SettingData below is settable by name (case-insensitive). After each set, Settings.SaveSettings() writes the value back to setting.xml and NetworkManager.UpdateSessionData(ObjectInstance) propagates the change.
Server-relevant fields¶
Drawn verbatim from Settings.SettingData (lines 248236-248577).
| Field | Type | Default | XmlElement | Notes |
|---|---|---|---|---|
ServerName |
string | "Stationeers" |
yes | Display name in browser. |
StartLocalHost |
bool | false |
yes | Client-side "host this world on launch from main menu" toggle. The dedicated build's -load / -new / -loadlatest start the network listener directly; this flag is not required for a dedicated launch. |
ServerVisible |
bool | false |
yes | Publish to public server browser. Leave false for local-only. |
ServerPassword |
string | "" |
yes | Empty means open server. Clients must enter the same string in Direct Connect. |
AdminPassword |
string | "" |
yes | In-client admin commands. |
ServerAuthSecret |
string | "" |
NO [XmlElement] decoration but XmlSerializer persists public fields by default |
Shared secret. Required for serverrun. Server prints serverrun command can only be used if a ServerAuthSecret is set in setting.xml when missing (line 98635). |
ServerMaxPlayers |
int | 10 |
yes | No explicit clamping observed in the SettingData class. Public docs claim 1-30; enforcement may live in UI validation or join-time logic, not verified this pass. |
UpdatePort |
string | "27015" |
yes | UDP. Note string-typed despite holding a port number. |
GamePort |
string | "27016" |
yes | UDP. Note string-typed. |
UPNPEnabled |
bool | true |
yes | Set false for local-only servers to avoid advertising via UPnP. |
UseSteamP2P |
bool | true |
yes | Steam relay. |
DisconnectTimeout |
int | 10000 |
yes | Milliseconds. |
NetworkDebugFrequency |
int | 500 |
yes | Milliseconds. |
LocalIpAddress |
string | "" |
yes | Bind interface. Empty means default. |
AutoPauseServer |
bool | true |
NO [XmlElement] decoration but XmlSerializer persists public fields by default |
Pauses world simulation when no clients are connected. Relevant for tests that depend on game-time progression without a connected client. |
AutoSave |
bool | true |
yes | Recurring autosave. |
SaveInterval |
int | 300 |
yes | Seconds between autosaves. |
MaxAutoSaves |
int | 5 |
yes | Rotation count. |
MaxQuickSaves |
int | 5 |
yes | Rotation count. |
SavePath |
string | "" |
yes | Empty falls back to StationSaveUtils.DefaultPath (in batch mode: exe directory). Setting this to a directory makes saves, scripts, mods, and setting.xml itself live under it. |
Client UI / performance fields (full list, verbatim)¶
These fields live in the same SettingData struct and are settable on a dedicated server, but the server's batch-mode rendering loop does not consume most of them. Listed for completeness and for hand-editing setting.xml.
| Field | Type | Default |
|---|---|---|
SettingsVersion |
string | string.Empty |
ShowFps |
bool | false |
ShowLatency |
bool | false |
HUDScale |
int | 50 |
TooltipOpacity |
float | 0.95 |
IngamePortrait |
bool | true |
ExtendedTooltips |
bool | true |
ChatFadeTimer |
float | 10 |
DayLength |
int | 20 |
LegacyInventory |
bool | false |
ShowSlotToolTips |
bool | true |
DeleteSkeletonOnDecay |
DeleteSkeletonOnDecay | enum default |
Monitor |
int | 1 |
ScreenWidth |
string | "1920" |
ScreenHeight |
string | "1080" |
RefreshRate |
int | 60 |
GraphicQuality |
string | "Fantastic" |
TextureQuality |
string | "Very High" |
FullScreen |
bool | true |
Vsync |
bool | false |
Shadows |
string | "High" |
DistantShadows |
bool | false |
ShadowResolution |
string | "Very High" |
ShadowDistance |
int | 100 |
LightShadowDistance |
int | 50 |
RoomControlTickSpeed |
int | 1 |
ShadowNearPlaneOffset |
float | 0.2 |
ShadowCascades |
int | 4 |
ShadowCascade2Split |
float | 1f / 3f |
ShadowCascade4Split |
Vector3 | (1f/15f, 0.2f, 7f/15f) |
ThingShadowMode |
string | "High" |
ThingShadowDistanceMultiplier |
float | 2 |
RenderDistance |
string | "High" |
WorldOrigin |
bool | false |
Brightness |
int | 100 |
FieldOfView |
int | 70 |
ColorBlind |
string | "None" |
ParticleQuality |
string | "High" |
SoftParticles |
bool | true |
EnvironmentElements |
bool | true |
ExtendedTerrain |
bool | true |
VolumeLight |
string | "Full" |
PixelLightCount |
int | 8 |
MaxThingLights |
int | 256 |
Antialiasing |
string | "FXAA" |
FrameLock |
string | "Off" |
AtmosphericScattering |
bool | true |
AmbientOcclusion |
string | "Ultra" |
LensFlares |
bool | true |
DisableWaterVisualizer |
bool | true |
Clouds |
bool | false |
HelmetOverlay |
bool | true |
WeatherEventQuality |
string | "Medium" |
TerrainDetail |
string | "Medium" |
MinableDistance |
string | "Medium" |
TerrainDistance |
string | "Medium" |
MasterVolume |
int | 100 |
SoundVolume |
int | 100 |
VoiceNotificationVolume |
int | 90 |
MusicVolume |
int | 100 |
InterfaceVolume |
int | 100 |
VirtualVoices |
int | 512 |
RealVoices |
int | 32 |
UserSpeakerMode |
AudioSpeakerMode | Stereo |
LanguageCode |
LanguageCode | EN |
VoiceLanguageCode |
LanguageCode | EN |
Voice |
bool | false |
PopupChat |
bool | true |
CameraSensitivity |
int | 50 |
KeyList |
List |
empty |
InvertMouse |
bool | false |
InvertMouseWheelInventory |
bool | false |
MenuLite |
bool | false |
MouseWheelZoom |
bool | true |
FirstRun |
bool | true |
VoiceNotifications |
List |
empty |
CompletedTutorials |
List |
empty |
CompletedScenarios |
List |
empty |
DisplayHelperHints |
bool | true |
AutoExpandHelperHints |
bool | true |
VerticalMovementAxis |
ControllerData | default |
HorizontalMovementAxis |
ControllerData | default (no [XmlElement]) |
ForwardMovementAxis |
ControllerData | default (no [XmlElement]) |
VerticalLookAxis |
ControllerData | default (no [XmlElement]) |
HorizontalLookAxis |
ControllerData | default (no [XmlElement]) |
UseCustomWorkThreadsCount |
bool | false |
MinWorkerThreads |
int | Environment.ProcessorCount |
MinCompletionPortThreads |
int | Environment.ProcessorCount |
MaxWorkerThreads |
int | (Environment.ProcessorCount + 2) * 10 |
MaxCompletionPortThreads |
int | (Environment.ProcessorCount + 2) * 5 |
MaxConcurrentWorkers |
int | Environment.ProcessorCount - 1 |
CoroutineTimeBudget |
float | 1 |
SmoothTerrain |
bool | false |
SmoothTerrainAngle |
float | 60 |
ConsoleBufferSize |
int | 1024 |
LegacyCpu |
bool | false |
Command-line flags¶
The dispatch dictionary as registered in CommandLine's static constructor (decompile lines 94944-95038). Names with multiple keys (aliases) are grouped. Where a command exposes IsLaunchCmd = true, it can be used as a -name flag at launch; otherwise it is runtime-only (stdin or serverrun).
| Name(s) | Class | IsLaunchCmd | HelpText (verbatim where present) |
|---|---|---|---|
achievements |
AchievementsCommand | (mixed) | (not read this pass) |
help |
HelpCommand | (read help) | "Lists all available commands and their descriptions" (typical) |
clear |
ClearCommand | false | clears the console buffer |
quit |
QuitCommand | (any) | "immediately quits the game without any prompts" |
exit, leave |
ExitCommand | (alias for quit) | (not read this pass) |
newgame, new |
NewGameCommand | true | "Starts a new game at specific world automatically from launch.Must provide world name as argument" |
joingame, join |
JoinCommand | (mixed) | (not read this pass) |
steam |
SteamCommand | (mixed) | (not read this pass) |
listnetworkdevices |
ListNetworkDevicesCommand | false | (not read this pass) |
testbytearray |
TestByteArrayCommand | false | (debug) |
rocketbinary |
RocketBinaryCommands | false | (debug) |
imgui |
ImGuiCommands | false | (debug) |
atmos |
AtmosphereCommands | false | (debug) |
structurenetwork |
StructureNetworkCommand | false | (debug) |
thing |
ThingCommand | false | (debug) |
keybindings |
KeyBindingCommands | false | (debug) |
reset |
RestartCommand | false | "Restarts the application" |
version |
VersionCommand | false | (prints game version) |
rocket |
RocketCommand | false | (debug) |
unstuck |
UnstuckCommand | false | (debug) |
spacemap, spacemapnode |
SpaceMapCommand / SpaceMapNodeCommand | false | "Various space map debug functions" |
logtoclipboard |
LogToClipboardCommand | false | (debug) |
camera |
CameraCommand | false | (debug) |
kick |
KickCommand | false | server-only; disconnects a client |
ban |
BanCommand | false | "Bans a client from the server (server only command)". Args: <clientId> or refresh |
upnp |
UpnpCommand | (mixed) | (not read this pass) |
network |
NetworkCommand | false | (debug) |
pause |
PauseCommand | false | (toggle pause) |
say |
SayCommand | false | (server-side chat broadcast) |
world |
PrintWorldSettingsCommand | false | (debug) |
log |
LogCommand | false | (log inspection) |
discord |
DiscordCommand | false | (debug) |
settings |
SettingsCommand | true | "Change the settings.xml. e.g settings servermaxplayers 5" |
netconfig |
NetConfigCommand | true | (settings-style for NetConfig) |
settingspath |
SettingsPathCommand | true | "Sets the default settings path to a new location. Launch command only. If none found default is used." |
regeneraterooms |
RegenerateRoomsCommand | false | "Regenerates all rooms for the world" |
storm |
StormCommand | false | (debug) |
debugthreads |
DebugThreadsCommand | false | (debug) |
status |
StatusCommand | false | (server status snapshot) |
masterserver |
MasterServerCommand | (mixed) | (not read this pass) |
deletelooseitems |
DeleteLooseItemsCommand | false | (debug) |
emote |
EmoteCommand | false | (debug) |
expression |
CustomFacialExpressionCommand | false | (debug) |
serverrun |
ServerRunCommand | false | "Sends a message to the server to perform server side commands". Client-only; signs with Settings.CurrentData.ServerAuthSecret. |
windowheight |
ConsoleWindowHeightCommand | false | (debug) |
cleanupplayers |
CleanupPlayersCommand | false | (debug) |
networkdebug |
NetworkDebugWindowCommand | false | (debug) |
difficulty |
DifficultySettingsCommand | false | (debug) |
addgas |
AddGas | false | (debug) |
legacycpu |
LegacyCpuCommand | (mixed) | "Enables Legacy Cpu mode. Recommended for users with cpus below the recommended spec" |
trader |
TraderCommand | false | (debug) |
localization |
LocalizationCommand | false | (debug) |
deleteoutofbounds |
DeleteOutOfBoundsObjectsCommand | false | (debug) |
printgasinfo |
PrintPhaseChangeInfoCommand | false | (debug) |
structure |
StructureCommand | false | (debug) |
plant |
PlantCommand | false | (debug) |
physics |
PhysicsCommand | false | (debug) |
power |
PowerCommand | false | (debug) |
orbit |
OrbitalCommand | false | (debug) |
celestial |
CelestialCommand | false | (debug) |
dlc |
DLCCommand | false | (debug) |
entity |
EntityCommand | false | (debug) |
setbatteries |
SetBatteriesCommand | false | (debug) |
systeminfo |
SystemInfoCommand | false | (debug) |
profiler |
ProfilerCommand | false | (debug) |
prefabs |
ValidateSourcePrefabsCommands | false | (debug) |
helperhints |
WorldObjectiveCommand | false | (debug) |
exportworld |
ExportWorldCommand | false | (debug) |
worldsetting |
WorldSettingWindowCommand | false | (debug) |
liquid |
LiquidCommands | false | (debug) |
vegetation |
VegetationCommand | false | (debug) |
minables |
MinableCommand | false | (debug) |
testoctree |
TestOctreeCommand | false | (debug) |
terraineditor |
TerrainEditorWindowCommand | false | (debug) |
region |
RegionCommand | false | "Terrain region debugging" |
file |
FileCommand | (mixed) | (file ops) |
map |
MiniMapWindowCommand | false | (debug) |
terrain |
TerrainCommands | false | (debug) |
geyser |
GeyserCommand | false | (debug) |
reloadterraintexture |
ReloadTerrainTextureCommand | false | "Reloads the terrain textures from streaming assets" |
teleport |
TeleportCommand | false | (debug) |
lod |
LodDebugWindowCommand | false | (debug) |
clients |
ClientsCommand | false | (lists connected clients) |
densepools |
DensePoolCommand | false | (debug) |
loworbitstation |
LowOrbitStationCommand | false | (debug) |
clientinfo |
SerializedClientInfoCommand | false | (debug) |
player |
PlayerCommand | false | (debug) |
loadgame, load |
LoadGameCommand | true | "Loads a saved world file. This can also be used to start a new game via launch command. e.g -load \"my game save\" moon" |
loadlatest |
LoadLatestCommand | true | "Loads the latest saved file, including auto saves" |
save |
SaveCommand | false | "Saves the current game to specified path". Args: <filename> or delete (d / rm) <filename> or list (l) |
test |
BasicCommand (added at static-init time) | false | "Testing all the colours of the rainbow" |
Lifecycle commands deep-dive¶
-load <savename> [worldname] (LoadGameCommand, line 96508)¶
public override string HelpText =>
"Loads a saved world file. This can also be used to start a new game " +
"via launch command. e.g -load \"my game save\" moon";
public override string[] Arguments =>
new string[3] { "list", "<filename>", "<filename> (optional)<worldname>" };
public override bool IsLaunchCmd => true;
public override bool RequiresGameManagerIsInitialized => true;
Behaviour: if <savename> resolves to a directory under SavePath/saves containing exactly one .save file, load it. Otherwise, if <worldname> is provided, treat <savename> as the new save's name and start a new world on <worldname> with the default difficulty (Normal) and default start condition. Subcommand list (or l) prints the list of saves.
-loadlatest [savename] (LoadLatestCommand, line 96606)¶
Without args: scans all subdirectories of <SavePath>/saves, picks the file with the most recent LastWriteTime, loads it. With <savename>: scans only that named directory for the most recent file. Falls through to LoadGame's logic if "Latest save not found".
-new <world> [difficulty] [startcondition] (NewGameCommand, line 97302)¶
public override string HelpText =>
"Starts a new game at specific world automatically from launch." +
"Must provide world name as argument";
public override string[] Arguments =>
new string[3] { "worldname", "difficulty", "startcondition" };
public override bool IsLaunchCmd => true;
Source-side defaults: world = "Moon", difficulty = "Normal", startcondition = "Default". Validates each against WorldSetting.Find / DifficultySetting.Find / DataCollection.Get<StartConditionData>. Calls World.StartNewWorld(worldId) then prints Started new game in world <worldName>.
Critical caveat: the source's "Moon" default is stale. The runtime's actual valid world ids (verified 2026-04-28 by passing -new Moon and reading the error message) are:
Lunar(this is the moon)Mars2Europa3MimasHerschelVenusVulcan2Vulcan(marked Deprecated)
WorldSetting.Find("Moon") returns null because the world ids live in JSON / data files that were updated past the source's hardcoded default; WorldSetting.Find looks them up by id from the data store. So -new Moon (or no world arg, which falls back to "Moon") fails with No such world name: Moon. Valid worlds: Europa3, Lunar, Mars2, MimasHerschel, Venus, Vulcan (Deprecated), Vulcan2. Always pass an explicit valid id.
save <name> / save delete <name> / save list (SaveCommand, line 96400)¶
public override string HelpText => "Saves the current game to specified path";
public override string[] Arguments =>
new string[3] { "<filename>", "delete (d | rm) <filename>", "list (l)" };
public override bool IsLaunchCmd => false;
Behaviour: with no args, saves under XmlSaveLoad.Instance.CurrentStationName. With one positional arg that does not match delete/d/rm/list/l, saves under that name. Subcommands delete/rm/d <filename> remove a save directory recursively. list/l prints existing saves.
Confirmation log line on success (line 96453):
This is the line DedicatedServer/dedicated-server.ps1 -Save -Name <X> polls for in data/server.log to confirm completion.
Refuses to save when GameState != Running && != Paused. Refuses on remote clients via CommandBase.CannotAsClient("save").
quit / exit / leave (QuitCommand, line 98133)¶
public override string Execute(string[] args)
{
ConsoleWindow.PrintAction("exiting game");
Application.Quit();
return null;
}
No autosave. The Application.quitting event cancels in-flight autosaves rather than waiting for them. To preserve state, send save "<name>" and wait for the Saved <name> line before sending quit.
-settings <Field> <Value> (SettingsCommand, line 98668)¶
internal class SettingsCommand : ClassManipulator<Settings.SettingData>
{
public override string HelpText => "Change the settings.xml. e.g settings servermaxplayers 5";
protected override Settings.SettingData ObjectInstance => Settings.CurrentData;
protected override void OnValueChanged()
{
EnsureExistence();
Assets.Scripts.Networking.NetworkManager.UpdateSessionData(ObjectInstance);
Settings.SaveSettings();
}
}
Reflection-driven. Any field on SettingData is settable by name (the ClassManipulator base handles the lookup, set, type coercion). Each set persists setting.xml and notifies NetworkManager.
-settingspath <file-path> (SettingsPathCommand, line 98695)¶
public override string HelpText =>
"Sets the default settings path to a new location. " +
"Launch command only. If none found default is used.";
public override string[] Arguments => new string[1] { "<full-directory-path>" };
public override bool IsLaunchCmd => true;
public override string Execute(string[] args)
{
if (args.Length == 1)
{
FileInfo fileInfo = new FileInfo(args[0]);
Settings.SettingData.Path = fileInfo.FullName;
ConsoleWindow.PrintAction("Set custom settings path: " + fileInfo.FullName);
return null;
}
return "Invalid syntax";
}
Despite the help text saying "directory path", the implementation wraps the arg in new FileInfo(args[0]) and assigns the full file path. So the argument is a file path (the setting.xml file itself), not a directory. Help text is misleading.
serverrun <commandline> (ServerRunCommand, line 98588)¶
public override string HelpText => "Sends a message to the server to perform server side commands";
public override string[] Arguments => new string[1] { "Command" };
public override bool IsLaunchCmd => false;
public override string Execute(string[] args)
{
if (args.Length == 0) return "Invalid syntax";
if (Assets.Scripts.Networking.NetworkManager.IsClient)
SendMessageToServer(string.Join(" ", args));
else
ConsoleWindow.PrintError("Only clients can use this command");
return null;
}
private static void SendMessageToServer(string command)
{
NetworkClient.SendToServer(new ServerRunCommandMessage
{
ClientId = Assets.Scripts.Networking.NetworkManager.LocalClientId,
Secret = Settings.CurrentData.ServerAuthSecret,
Command = command
});
}
Server-side handler (line 98631):
public override void Process(long hostId)
{
if (string.IsNullOrEmpty(Settings.CurrentData.ServerAuthSecret))
{
ConsoleWindow.PrintError("serverrun command can only be used if a ServerAuthSecret is set in setting.xml");
return;
}
Client client = NetworkBase.Clients.Find(x => x.ClientId == ClientId);
if (client == null) { ... ClientId not found error ... }
else if (Secret != Settings.CurrentData.ServerAuthSecret)
{ ... mismatch error ... }
else
{
ConsoleWindow.PrintAction("client '<name>' ran command '<cmd>'");
CommandLine.Process(Command);
}
}
So serverrun is the closest in-game equivalent to RCON. Both client and server need ServerAuthSecret set to the same string. The server then runs the wrapped command through CommandLine.Process, giving the client access to the entire command surface (save, kick, ban, status, etc.).
kick <clientId> and ban <clientId> / ban refresh¶
BanCommand (line 94389) is server-only and refuses in single-player. Args: <clientId> (numeric ulong) or refresh to reload the blacklist file. KickCommand is similar but disconnects without persisting to the blacklist (not read this pass; mentioned for completeness).
Defaults summary¶
If you launch rocketstation_DedicatedServer.exe -batchmode -nographics -new Lunar with no other flags and no pre-existing setting.xml, you get:
- ServerName:
Stationeers - Open server (no
ServerPassword) - 10 max players
- Ports
27016(Game) /27015(Update) - UPNPEnabled: true
- UseSteamP2P: true
- AutoSave every 300s, retain 5 autosaves
- ServerVisible: false (not in public browser)
- ServerAuthSecret unset, so
serverrunfrom clients is rejected - AutoPauseServer: true (world pauses with no clients connected)
- SavePath: empty, falling back to
StationSaveUtils.DefaultPath. In batch mode that resolves to the directory containingrocketstation_DedicatedServer.exe. Worlds, scripts, and mods all live under that root. setting.xmlwritten to<SavePath>/setting.xmlon first save, which (with empty SavePath) is the exe directory.
Notes for DedicatedServer/dedicated-server.ps1¶
The launcher's current -Start flag set:
-batchmode -nographics
-settingspath <DedicatedServer>/data/setting.xml
-logFile <DedicatedServer>/data/server.log
-settings SavePath <DedicatedServer>/data
-settings GamePort 28016
-settings UpdatePort 28015
-settings LocalIpAddress 127.0.0.1
-settings AutoSave true
-settings AutoPauseServer false
-settings UPNPEnabled false
-settings ServerName "Local Test"
-settings ServerMaxPlayers 4
-settings ServerAuthSecret x
-load <SaveName> <Map> OR -new <Map>
Verified against the source:
LocalIpAddress 127.0.0.1pins RakNet to the loopback interface. Without it RakNet binds whichever interface comes up first, which on a developer machine with an active LAN is the LAN IP (10.20.30.200or similar) -- direct connections to127.0.0.1:28016then fail because no listener is bound there. Loopback binding makes the agent-driven test loop deterministic. To intentionally expose the server to the LAN, override or remove this line.UPNPEnabled falseis correct for a loopback-only test rig; the defaulttruewould advertise via UPnP. Redundant with the loopback bind but kept for documentation.- No
ServerPassword. The server is loopback-only, so unauthenticated connections from outside the machine are impossible at the network layer; a connection password adds no protection in that topology and just gets in the way of agent-driven test loops. Earlier launcher revisions hardcodedServerPassword x; that was removed once the LocalIpAddress pin landed. ServerAuthSecret xis kept; matching value on the client unlocksserverrunfor in-game admin commands without writing to the server's stdin (see ServerRunCommand at decompile line 98588).ServerMaxPlayers 4is below the default of 10. No clamping is visible at the SettingData level; the source-of-truth for upper bound (1-30 in public docs) was not located this pass.AutoPauseServer falsekeeps world simulation running with no clients connected (atmospheric simulation, growth, decay, autosave timer). Default istrue. Required for tests that depend on game-time progression between client sessions.AutoSave truematches the default; passing it explicitly is documentation, not a state change.GamePort 28016/UpdatePort 28015are offset by +1000 from the Stationeers client defaults (27016/27015) so the dedicated server runs alongside a hosting client on the same machine without RakNet's port-binding fallback.
Verification history¶
- 2026-04-28: page created from a fresh decompile of
Assembly-CSharp.dllat game version0.2.6228.27061(ilspycmd output at.work/decomp/0.2.6228.27061/Assembly-CSharp.decompiled.cs). All Settings field defaults are verbatim fromSettings.SettingData(decompile lines 248236-248577). Command dispatch dictionary verbatim fromCommandLinestatic constructor (lines 94942-95038). HelpText / Arguments / IsLaunchCmd values for the lifecycle commands (Save, Quit, LoadGame, LoadLatest, NewGame, Settings, SettingsPath, ServerRun, Ban) are verbatim from each command's class declaration. - 2026-04-28: launcher relocated from
tools/dedicated-server.ps1toDedicatedServer/dedicated-server.ps1(un-ignored alongsideDedicatedServer/CLAUDE.md). Flag set updated:StartLocalHost trueremoved (confirmed unnecessary on the dedicated build's load path),ServerAuthSecret xadded (enablesserverrunfrom a connected client). Path references and the "Notes for DedicatedServer/dedicated-server.ps1" section updated to match. Game-internals claims unchanged. - 2026-05-18: launcher flag set updated to pin
LocalIpAddress 127.0.0.1and dropServerPassword x. Confirmed via runtime test (host wrapper PID 25800, server UDP bind read viaGet-NetUDPEndpoint): without LocalIpAddress, RakNet bound UDP 28016 to the LAN IP10.20.30.200and refused loopback connections; with LocalIpAddress = 127.0.0.1, the bind moves to loopback and Direct Connect from a same-machine client succeeds. Removed ServerPassword because the loopback bind makes external auth at the network layer impossible to bypass, so a password adds friction without security. KeptServerAuthSecret x(it gatesserverrun, not connection). Also flippedAutoPauseServertofalsein the documented flag block to match the launcher, which has been carrying that flag for tests that need simulation between client sessions. - 2026-04-28: corrected world-id list in the
-newdeep-dive. NewGameCommand source declares"Moon"as the default butWorldSetting.Find("Moon")returns null at runtime; valid ids verified by runtime probe areLunar, Mars2, Europa3, MimasHerschel, Venus, Vulcan2, Vulcan (Deprecated). Defaults summary updated to use-new Lunaras the example.
Open questions¶
ServerMaxPlayersupper bound. The SettingData declaresint ServerMaxPlayers = 10without obvious clamping. Public docs claim 1-30. Enforcement may live in UI input validation, the network join handler, or a server-side reject path; not verified this pass.- The "(mixed)"
IsLaunchCmdentries in the command table reflect commands whose class declarations were not read in detail this pass. The dispatcher does not visibly gate runtime stdin onIsLaunchCmd, so the flag may be advisory only; whether the launch path enforces it is unverified. StartLocalHostconsumer path. Hypothesised to be the client's main-menu "host on launch" path, not consumed by the dedicated build's-load/-newflow. Verifying would require followingSettings.CurrentData.StartLocalHostreferences.- The full HelpText / Arguments for the bulk of the (non-lifecycle) commands listed in the command table were not transcribed. Each marked
(not read this pass)or(debug)is a candidate for follow-up if the launcher needs to invoke any of them.