Skip to content

Handle host migration

Host migration applies only to persistent reserved rooms. When the active host disconnects, the relay selects the client with the earliest join order and gives it 10 seconds to acknowledge, reconnect, and claim the host role.

The Fish-Networking transport performs the transition automatically:

  1. The transport receives HostPromoted and acknowledges the claim.
  2. The relay disconnects the promoted client.
  3. The transport waits until both local client and server states are stopped.
  4. It starts the server using the pending claim token.
  5. After the server claims the room, it starts the local client.

Use OnRelayHostAvailabilityChanged to pause host-dependent game actions while migration is in progress:

private void OnEnable()
{
transport.OnRelayHostAvailabilityChanged += HandleHostAvailability;
}
private void OnDisable()
{
transport.OnRelayHostAvailabilityChanged -= HandleHostAvailability;
}
private void HandleHostAvailability(bool available)
{
matchmakingOverlay.SetActive(!available);
}

NGO owns its NetworkManager lifecycle, so the NGO transport exposes the promotion and waits for game code to switch roles.

  1. Subscribe to OnHostPromotionReceived before starting the client.
  2. When invoked, call NetworkManager.Shutdown().
  3. Wait until NetworkManager.ShutdownInProgress is false and neither client nor server is listening.
  4. Call NetworkManager.StartHost() or StartServer().
  5. The transport uses its pending claim automatically and clears it after RoomCreated arrives.
using System.Collections;
using BlitzRelay.Ngo;
using Unity.Netcode;
using UnityEngine;
public sealed class NgoHostMigration : MonoBehaviour
{
[SerializeField] private NetworkManager networkManager;
[SerializeField] private BlitzRelayTransport transport;
private void OnEnable()
{
transport.OnHostPromotionReceived += HandlePromotion;
}
private void OnDisable()
{
transport.OnHostPromotionReceived -= HandlePromotion;
}
private void HandlePromotion(HostPromotion promotion)
{
StartCoroutine(BecomingHost());
}
private IEnumerator BecomingHost()
{
networkManager.Shutdown();
while (networkManager.ShutdownInProgress ||
networkManager.IsClient ||
networkManager.IsServer)
{
yield return null;
}
networkManager.StartHost();
}
}

Clients receive HostUnavailable while a persistent room has no active host and HostAvailable after a claim succeeds. These events describe relay availability; they do not migrate your game state. Your networking framework still needs its own authoritative state-transfer strategy.