Mirror Multiplayer Integration for Mobile Games (Unity)
Mirror—open-source network framework for Unity, successor to deprecated UNET. Unlike Photon, Mirror isn't cloud-locked: transport plugged separately (kcp2k, Telepathy, WebSockets, Steam), server self-hosted. For mobile projects, this means full control over latency, traffic, and hosting costs—but also full responsibility for infrastructure.
NetworkManager and Lifecycle
NetworkManager—entry point. Override only what's needed:
public class GameNetworkManager : NetworkManager
{
public override void OnServerAddPlayer(NetworkConnectionToClient conn)
{
var startPos = GetStartPosition();
var player = Instantiate(playerPrefab, startPos.position, startPos.rotation);
NetworkServer.AddPlayerForConnection(conn, player);
}
public override void OnClientDisconnect()
{
base.OnClientDisconnect();
// Reconnect logic for mobile
StartCoroutine(TryReconnect());
}
}
NetworkManager.singleton—static access to instance. Critical mistake: creating multiple NetworkManager in scene. Mirror warns but doesn't crash—unpredictable behavior later.
SyncVar, SyncList, and Commands
[SyncVar] syncs variable from server to all clients automatically on change:
public class PlayerHealth : NetworkBehaviour
{
[SyncVar(hook = nameof(OnHealthChanged))]
public int health = 100;
void OnHealthChanged(int oldVal, int newVal)
{
healthBar.fillAmount = newVal / 100f;
}
[Command]
public void CmdTakeDamage(int amount)
{
// Executes only on server
health = Mathf.Max(0, health - amount);
}
}
[Command]—client calls method on server. [ClientRpc]—server calls on all clients. [TargetRpc]—on specific client. This triple is essential before everything else.
SyncList<T> syncs collections: inventory, buff queue, kill list. OnChange callbacks fire on any list change.
Transport Choice for Mobile
| Transport | Protocol | Mobile |
|---|---|---|
| kcp2k | UDP-based | Recommended, low latency |
| Telepathy | TCP | Reliable, higher latency |
| WebSockets (Mirror) | TCP/WS | Needed for WebGL, not optimal native |
| Ignorance | UDP (ENet) | Good kcp2k alternative |
For mobile native—kcp2k or Ignorance. kcp2k built-in since Mirror 50+. Settings: NoDelay = true, Interval = 10ms, FastResend = 2.
Headless Server and Infrastructure
Mirror server—same Unity build with -batchmode -nographics. For persistent match games, need dedicated server: one Unity instance per room (action games) or several (strategy with few players).
Orchestration: Game Server Hosting (Multiplay) from Unity Gaming Services or self-hosted on Kubernetes with autoscaling. For small projects—VPS on DigitalOcean/Hetzner with systemd management.
Mirror + Telepathy on TCP behind regular load balancer. Mirror + kcp2k (UDP)—needs UDP passthrough, not all load balancers support.
Typical Integration Problems
NetworkIdentity not found. Prefab not registered in NetworkManager.spawnPrefabs. Spawn via NetworkServer.Spawn crashes at runtime.
Authority confusion. isServer, isClient, isLocalPlayer, hasAuthority—four different bools. Code in Update() without isLocalPlayer check runs on all clients, including others' players.
Disconnect on mobile. iOS closes socket ~10 sec in background. Mirror doesn't auto-recover. Implement OnApplicationPause → on pauseStatus = false (return from background) → check NetworkClient.isConnected → reconnect.
Timeline
Basic Mirror integration with position sync, health, basic Command/RPC: 1-2 weeks. Full system with headless server, matchmaking, reconnect, and mobile optimization: 1-2 months. Cost calculated individually.







