Skip to content

Server Mod

Tsu edited this page Jun 10, 2026 · 1 revision

Nimbus.ServerMod is a standard Vintage Story server-side code mod. It must be installed on every backend server that connects to Nimbus. It works with vanilla VS.

Installation

  1. Copy Nimbus.ServerMod into your VS server's Data/Mods/ folder.
  2. Start the server once to generate ModConfig/nimbus-server.json.
  3. Edit the config (see below).
  4. Restart.

Configuration - nimbus-server.json

{
  "Enabled": true,
  "ServerId": "hub",
  "DisplayName": "Hub",
  "PublicHost": "play.example.com",
  "PublicPort": 42420,
  "RegistryUrl": "http://127.0.0.1:8765",
  "SharedSecret": "change-me-and-keep-secret",
  "HeartbeatIntervalSeconds": 5,
  "RegistryHttpTimeoutSeconds": 5,
  "Maintenance": false,
  "ReservationRequired": true,
  "AllowPlayerServerCommand": true,
  "TransferMode": "redirect",
  "Tags": []
}

Field reference

Field Default Description
Enabled true Set false to disable the mod without removing it. The mod loads but does nothing.
ServerId "" Required. Unique ID for this backend. Must exactly match the key in the proxy's [servers] table.
DisplayName "" Human-readable name shown in /nimbus servers output. Defaults to ServerId if empty.
PublicHost "" The hostname players use to reach the network, the proxy address. Used in registry listings.
PublicPort 42420 The port players use, the proxy port, not this backend's port.
RegistryUrl "" URL of the Nimbus registry. For embedded mode: http://127.0.0.1:8765 (or wherever embedded_bind is set).
SharedSecret "" HMAC secret. Must match embedded_shared_secret (or shared_secret for remote) in the proxy config.
HeartbeatIntervalSeconds 5 How often to send heartbeats. The registry marks backends stale after 20 seconds, so keep this well below that.
RegistryHttpTimeoutSeconds 5 HTTP timeout for all registry API calls.
Maintenance false When true, marks this backend as in maintenance. The proxy router skips it for new connections.
ReservationRequired true When true, players who join without a valid proxy reservation are kicked. Use this to enforce that all players arrive through the proxy.
AllowPlayerServerCommand true When true, players can use /server <id> and /join <id> to switch backends.
TransferMode redirect Transfer mode used for player-initiated switches. redirect or seamless.
Tags [] Arbitrary string tags sent with heartbeats. Readable by plugins via the registry snapshot.

Minimum working config

The mod stays idle (logging a warning) until ServerId, RegistryUrl, PublicHost, and SharedSecret are all set. Enabled = true is the default - you just need to fill in these four fields:

{
  "ServerId": "hub",
  "PublicHost": "play.example.com",
  "RegistryUrl": "http://127.0.0.1:8765",
  "SharedSecret": "your-shared-secret-here"
}

In-game commands (backend server)

These commands run on the backend game server (not the proxy). They require the controlserver privilege by default.

Command Description
/nimbus status Shows mod status, registry connection state, last heartbeat result, cached player count.
/nimbus servers Lists all backends from the last registry snapshot with player counts, TPS, and maintenance flag.
/nimbus send <player> <serverId> Posts a transfer intent to move a player to another backend.
/nimbus reload Hot-reloads nimbus-server.json. Note: RegistryUrl and SharedSecret changes require a full VS server restart to take effect.

Player-facing commands (require AllowPlayerServerCommand = true):

Command Description
/server <serverId> Move yourself to another backend.
/join <serverId> Alias for /server.

Forwarding

When a player arrives via the proxy, the mod automatically consumes their reservation on join and stores the forwarding data for that session. This gives you access to the player's real IP as seen by the proxy - not the proxy's internal IP.

From another mod:

var nimbus = api.ModLoader.GetModSystem<NimbusServerModSystem>();
var forwarded = nimbus?.GetForwardedPlayer(player.PlayerUID);
if (forwarded != null)
{
    string realIp  = forwarded.RealRemoteIp;   // player's actual IP
    string source  = forwarded.SourceServerId; // backend they transferred from (null for first join)
}

GetForwardedPlayer returns null if:

  • The player connected directly (no proxy)
  • The registry is not configured on this backend
  • The reservation had already expired when they joined

See Forwarding for more detail on the trust model.

ReservationRequired

ReservationRequired = true (the default) blocks any player who does not have a valid proxy reservation. This enforces that all players connect through Nimbus, preventing direct backend access.

When a blocked player is kicked they receive the message: Direct connections are not permitted. Please connect via the Nimbus proxy.

Fail-open guarantee: if the registry is unreachable when a player joins, the check is skipped and the player is allowed through. A registry outage never locks players out.

Clone this wiki locally