## How to run server - **Install SteamCMD** - instructions: https://developer.valvesoftware.com/wiki/SteamCMD - create user called `steam` or change `force_install_dir` to be your full path - **Install NuclearOptionServer** template: ```sh steamcmd +force_install_dir +login anonymous +app_update 3930080 -beta -betapassword validate +quit ``` example: ```sh steamcmd +force_install_dir /home/steam/NuclearOptionServer +login anonymous +app_update 3930080 validate +quit ``` - **UDP ports** - (defaults, can be changed in `DedicatedServerConfig.json`) - if running locally or behind firewall then these UDP ports might need to be opened to allow users to find and connect to the server - game port `7777` - query port `7778` - **Run Server (linux)** - `cd NuclearOptionServer` enter the install directory - `chmod +x NuclearOptionServer.x86_64` *set server as executable* - `chmod +x RunServer.sh` *set the bash script as executable* - `./RunServer.sh` - `RunServer.sh` can be edited copied or modified to change how it is run - **Run Server (windows)** - `cd NuclearOptionServer` enter the install directory - `./RunServer.bat` - `RunServer.bat` can be edited copied or modified to change how it is run - or run manually using `NuclearOptionServer.exe -logFile server.log -limitframerate 30` - use `-DedicatedServer ` argument to set custom config path - on linux this should be added to `RunServer.sh` - **Configure** `DedicatedServerConfig.json` - After first running the server DedicatedServerConfig.json will be created with default values, you can then edit this to change the server settings ### Default Config ```json { "MissionDirectory": "/home/steam/NuclearOption-Missions", "ModdedServer": false, "Hidden": false, "ServerName": "Nuclear Option Server", "Port": { "IsOverride": false, "Value": 0 }, "QueryPort": { "IsOverride": false, "Value": 0 }, "Password": "", "MaxPlayers": 16, "BanListPaths": [ "ban_list.txt" ], "DisableErrorKick": false, "ErrorKickImmuneListPaths": [], "NoPlayerStopTime": 30.0, "PostMissionDelay": 30.0, "RotationType": 0, "MissionRotation": [ { "Key": { "Group": "BuiltIn", "Name": "Escalation" }, "MaxTime": 7200.0 }, { "Key": { "Group": "BuiltIn", "Name": "Terminal Control" }, "MaxTime": 7200.0 } ], "VoteKick": { "Enabled": true, "PassRatio": 0.6, "MinVotes": 3, "AutoBanThreshold": 3, "VoteDuration": 45.0, "ResolutionDisplayTime": 20.0, "NewVoteLockout": 10.0, "RequesterCooldown": 300.0 } } ``` #### Config Settings **MissionDirectory** The absolute path where the server will look for custom missions (when using `User` or `Workshop` groups). - **Linux example**: `"/home/steam/NuclearOption-Missions"` - **Windows example**: `"C:/Games/NuclearOption-Missions"` ```json "MissionDirectory": "C:/Games/NuclearOption-Missions" ``` **ServerName** The name that will be displayed in the public server list. ```json "ServerName": "My Nuclear Option Server" ``` **MaxPlayers** The maximum number of players allowed on the server. Counts over 16 will display a performance warning to players in the server list. Ensure your server hardware can handle the increased load if setting this higher. ```json "MaxPlayers": 16 ``` **Password** If set, players must enter this password to join the server. Setting this to an empty string (`""`) means No Password will be required. ```json "Password": "" ``` **Port and QueryPort** The server uses an override system for ports. `IsOverride` must be set to `true` for the `Value` to be used; otherwise, the server will use its default ports (7777 and 7778). ```json "Port": { "IsOverride": true, "Value": 7777 }, "QueryPort": { "IsOverride": true, "Value": 7778 } ``` **BanListPaths** A list of file paths (relative to the server executable or absolute) that contain lists of SteamIDs to block from joining. ```json "BanListPaths": [ "ban_list.txt", "global_bans.txt" ] ``` **DisableErrorKick** By default, the server kicks players who cause errors to prevent instability. Set this to `true` to disable this behavior for all players. ```json "DisableErrorKick": true ``` **ErrorKickImmuneListPaths** A list of file paths containing SteamIDs of players who should never be kicked for errors, even if `DisableErrorKick` is `false`. ```json "ErrorKickImmuneListPaths": [ "admins.txt" ] ``` **NoPlayerStopTime** The time in seconds the server will wait after the last player leaves before unloading the current mission. ```json "NoPlayerStopTime": 60.0 ``` **PostMissionDelay** The time in seconds the server waits after a mission ends (via the EndGame outcome in a mission) before loading the next mission in the rotation. ```json "PostMissionDelay": 30.0 ``` **Hidden** If `true`, the server will not appear in the public server list. ```json "Hidden": false ``` **ModdedServer** Should be set to `true` if you are running custom server-side mods that may affect user experience or gameplay. ```json "ModdedServer": false ``` **MissionRotation** A list of missions the server will cycle through. Each entry contains a `Key` (Group and Name) and a `MaxTime` in seconds. - `Group` / `Name`: Identifies the mission to load. For more details on the available groups and how mission names are used, see [Loading Missions](#loading-missions). - `MaxTime`: The maximum duration of the mission in seconds. ```json "MissionRotation": [ { "Key": { "Group": "BuiltIn", "Name": "Escalation" }, "MaxTime": 7200.0 }, { "Key": { "Group": "User", "Name": "Custom Mission" }, "MaxTime": 7200.0 } ] ``` **VoteKick** Configures the vote-kick feature for players on the server. When a player is successfully vote-kicked, they are blocked from rejoining for the duration of the current mission, but are allowed to rejoin when the next mission starts. - **Enabled**: If `true`, players are allowed to start vote-kicks. (Default: `true`) - **PassRatio**: The fraction of voting players required to pass the vote, Not counting the target player (e.g. `0.6` is 60%). (Default: `0.6`) - **MinVotes**: The minimum number of total votes needed for a vote to be valid. (Default: `3`) - **AutoBanThreshold**: The number of times a player can be vote-kicked before they are automatically and permanently banned from the server. (Default: `3`) - **VoteDuration**: Duration of the voting window in seconds. (Default: `45.0`) - **ResolutionDisplayTime**: Time in seconds the result of the vote remains on screen. (Default: `20.0`) - **NewVoteLockout**: Time in seconds after a vote finishes before any player can start a new vote-kick. (Default: `10.0`) - **RequesterCooldown**: Cooldown in seconds before the player who started a vote can initiate another vote-kick. (Default: `300.0`) ```json "VoteKick": { "Enabled": true, "PassRatio": 0.6, "MinVotes": 3, "AutoBanThreshold": 3, "VoteDuration": 45.0, "ResolutionDisplayTime": 20.0, "NewVoteLockout": 10.0, "RequesterCooldown": 300.0 } ``` ### Mission Rotation The `RotationType` field can be changed to tell the server in what order to play the missions. Set the value to one of the following numeric codes: | Value | Rotation Method | Description | | :---: | :--- | :--- | | `0` | **Sequence** | Missions are selected in the order. | | `1` | **Pure Random** | Each missions is selected at random, allowing for immediate repeats. | | `2` | **Random Queue** | Missions are shuffled and selected in that random order, guaranteeing that all missions are played before the shuffle repeats. | ### Loading Missions Mission group options: - `Default` *loads from game files* - `Tutorial` *loads from game files* - `BuiltIn` *loads from game files* - `User` *loads from `MissionDirectory` folder* - `Workshop` *loads from Steam Workshop automatically using the Workshop item ID* when using `MissionDirectory` (User group), mission will be loaded at path `//.json`. For example if `MissionDirectory` is `/home/steam/NuclearOption-Missions` and mission name is `test1` then the path will be `/home/steam/NuclearOption-Missions/test1/test1.json` **note:** MissionDirectory should be a full path **Important:** For the User group, the mission folder name must exactly match the mission JSON file's base name. For example, for a mission named `test1`, the folder must be `.../test1/` and the file must be `.../test1/test1.json`. If these names do not match, the mission will not load. #### Workshop missions The server natively supports downloading and updating public and unlisted Workshop missions automatically. To use a Workshop mission in your rotation: 1. In `DedicatedServerConfig.json`, set the mission's `Group` to `"Workshop"`. 2. Set the `Name` to the Workshop published file ID (e.g., `"3104381984"`). Example configuration: ```json "MissionRotation": [ { "Key": { "Group": "Workshop", "Name": "3104381984" }, "MaxTime": 7200.0 } ] ``` When the server starts or reloads its config, it will automatically download all specified Workshop missions to the `/steamapps/workshop/content/2168680/` folder. It will also query and download updates dynamically in the background. If you need to manually download or host a mission (e.g., private/unlisted files that require specific credentials), you can still use the legacy manual method: 1. Download the workshop items using `steamcmd`: ```sh steamcmd +login anonymous +workshop_download_item 2168680 +quit ``` 2. Move the downloaded folder to your ``. 3. **Rename the folder** from the Workshop ID (e.g., `3669299832`) to exactly match the base name of the mission's `.json` file inside it (e.g., `MyCustomMission`). 4. Reference it under the `User` group in your configuration. ## Troubleshooting ### Check if server started correctly With the default run arguments the server will create log files in the `logs` directory with the timestamp the server was started. (`./logs/server-$(date +%Y-%m-%d-%H-%M-%S).log`). Checking these log files will help tell you if the server started correctly. If you see this line, it is likely the server is running ok: `[DedicatedServerManager] Waiting for Players before loading next map`. ### Steam Server Query To check if your server is accessible on the query point, there are two ways: 1. **Using a Steam server query tool:** Various online tools and applications allow you to query Steam servers directly. Provide your server's IP address and query port (default `7778`) to these tools. (example tool: https://saraserenity.net/steam/server_query.php) 2. **Using the in-game server list:** Attempt to find your server in the game's server browser. If it doesn't appear, check your client-side log files (`%USERPROFILE%\AppData\LocalLow\Shockfront\NuclearOption\Player.log`) for entries like: `[Warn] Request Server List, fail index:, Query Address::` where `` and `` correspond to your server's details. ### NAT Reflection (running server on the same network as client) If you are absolutely sure that your port forwarding settings are correct yet you cannot see your server listed in the game, check if your router has NAT reflection enabled on your port. This issue usually occurs when it's disabled and you're in the same network as the server. However, not all routers will have an option to enable NAT reflection at all.