Skip to content

Transfers

Tsu edited this page Jun 10, 2026 · 1 revision

Nimbus supports one transfer mode officially.

Redirect (default)

Redirect works with every vanilla VS client. No client mod required beyond RedirectFix.

How it works

  1. The proxy pre-mints a reservation for the player on the target backend.
  2. It stages a sticky reconnect route keyed by the player's UID (5-minute TTL).
  3. It forges a vanilla Packet_Server { Id = 29, Redirect } and sends it to the client.
  4. The client receives the redirect packet and reconnects to the proxy address.
  5. The proxy reads the sticky route, connects the new session directly to the target backend, and the player lands there.

The player sees the standard VS "Connecting to server..." loading screen.

RedirectFix required. The vanilla VS client crashes in ClientMain.ExitAndSwitchServer when receiving a redirect from a non-vanilla server. Distribute the RedirectFix client mod to all players, this bug is fixed and RedirectFix will no longer be required in the next update of Vintagestory.


Initiating a transfer

From the backend server (operator command)

/nimbus send <playerName> <serverId>

Posts a transfer intent to the registry. The proxy picks it up within transfer_intent_poll_ms (default 1000ms).

From a backend mod (code)

var nimbus = api.ModLoader.GetModSystem<NimbusServerModSystem>();
var result = await nimbus.RequestTransferAsync(player, "factions", reason: "event starting", requestedBy: "system");
if (!result.Ok)
    api.Logger.Warning("[MyMod] Transfer failed: " + result.Error);

From a Nimbus proxy plugin

// Resolve by server ID (checks registry, falls back to static pool)
var target = await api.ResolveServerAsync("factions", cancellationToken);
if (target != null)
{
    var fail = await player.TransferAsync(target, mode: "redirect", reason: "moving to factions");
    if (fail != null) api.LogWarn("transfer failed: " + fail);
}

From the admin socket (nimctl)

nimctl swap --player PlayerName --server factions
nimctl swap --player PlayerName --server factions --seamless

Failover on initial connect

When a player first connects, Nimbus tries backends in the order defined in the try list. If the first backend is unreachable, it tries the next. If all fail, the player receives a No backend available right now disconnect message.

You can override backend selection per-connection from a plugin using PlayerChooseInitialServerEvent. See Plugin Development.


Drain (maintenance)

Take a backend out of rotation without bringing it down:

nimctl drain hub

Draining removes a backend from the failover pool. Existing sessions continue undisturbed; no new players are routed there. Restore it with:

nimctl undrain hub

Drain state persists across proxy restarts by default (persist_drain_flags = true). You can also set Maintenance = true in the backend's nimbus-server.json - this signals the registry and the router skips it for new connects automatically.


Transfer log

Every completed transfer is logged to the proxy console:

12:34:56 [nimbus] [s1] PlayerName: hub -> factions (redirect, 42ms)

You can capture all transfers in a plugin using PlayerTransferredEvent. See Plugin Examples.

Clone this wiki locally