When building an online game in Unity, the question is often framed as:
Should I use Photon, Netcode for GameObjects, FishNet, or Mirror?
That question is too small.
In 2026, there is still no single networking product that is optimal for every Unity game. The real decision is a stack: transport, netcode, authority model, session management, server hosting, and backend services.
For a GameObject-based action game that needs client prediction, Photon Fusion 2.1 is a strong first PoC baseline. If your priorities are Unity Gaming Services, DOTS/ECS, self-hosting, source access, or deterministic simulation, the starting point changes.
This article explains how to make that decision in production terms: latency, cheating, reconnection, hosting, bandwidth, operations, and total cost.
This article uses official documentation checked on August 31, 2026 as its factual baseline. SDK versions, pricing, licensing, and service availability can change, so re-check them before committing a production project.
What I mean by a real-time multiplayer game
The target is roughly this class of game:
- 2–32 players in the same session
- continuously synchronized players, enemies, projectiles, or interactable objects
- input latency that directly affects game feel
- reconnects, host loss, and late joining that must be handled
- co-op action, FPS/TPS, racing, or competitive action
If you only need turn-based play, leaderboards, chat, friends, or asynchronous PvP, you may not need a sophisticated state-synchronization netcode at all. A backend such as Nakama, PlayFab, or Unity Gaming Services may be the more important part of the architecture.
Do not treat “networking” as one product
A production multiplayer stack has at least five layers.
| Layer | Responsibility | Examples |
|---|---|---|
| Transport | Packet delivery, reliability, connection path, secure channel integration | Unity Transport, Photon transport, UDP/WebSocket-based transports |
| Netcode | Replication, RPCs, input, prediction, interpolation, rollback | Fusion, NGO, Netcode for Entities, FishNet, Mirror |
| Session | Lobby, matchmaking, relay, connection metadata | Photon Realtime, MPS SDK, UGS Lobby/Relay/Matchmaker |
| Hosting | Dedicated-server allocation, startup, scaling, monitoring | GameLift, PlayFab MPS, Edgegap, Hathora, custom infrastructure |
| Backend | Authentication, persistence, inventory, ranking, result settlement | PlayFab, Nakama, UGS, custom APIs and databases |
This is why “WebSocket or Photon?” is not a useful comparison. WebSocket is an application-layer protocol often used as a transport path in a game stack; Fusion is a netcode with prediction and simulation semantics.
A transport can move packets. It does not automatically give you prediction, snapshot interpolation, authority rules, lag compensation, reconnect restoration, or late-join state reconstruction.
Seven criteria that matter more than brand names
| Criterion | What to decide |
|---|---|
| Prediction | Can local input run ahead and be reconciled against authoritative state? How much is built in? |
| Authority | Who is allowed to decide movement, hits, rewards, inventory, and match results? |
| Topology | Host, client-server, or distributed/shared authority? |
| Replication scale | Tick rate, visible objects, predicted physics, update frequency, interest management |
| Platforms | Mobile suspend/resume, WebGL constraints, console certification and invite flows |
| Team architecture | GameObject or ECS? Do not migrate architecture just because the networking SDK prefers it |
| Total cost | CCU, bandwidth, hosting, observability, operations, migration and maintenance work |
A few terms used below: CCU is concurrent users, RTT is round-trip latency, SLO is a service-level objective, egress is outbound cloud traffic, and p95/p99 are percentile measurements.
Pick the synchronization model before the SDK
Most real-time games are built from three core synchronization models.
Snapshot replication
The authority sends periodic state snapshots, and remote clients interpolate between them. This is a natural fit for remote players, NPCs, doors, and many world objects.
The trade-off is bandwidth: higher update frequency improves responsiveness but increases traffic. Quantization, change detection, and interest management matter quickly.
Input prediction and resimulation
The local player applies input immediately, sends that input to the authority, then reconciles when authoritative state arrives. If needed, the client rewinds to the authoritative tick and resimulates to the present.
This is a strong fit for FPS, TPS, racing, and action games, but it requires simulation code that can be run again safely. External I/O, analytics, rewards, and one-shot side effects must not be mixed into replayable tick logic.
Deterministic lockstep with rollback
Peers advance from the same input stream and rollback when delayed input arrives. This can be excellent for fighting games, RTS, sports, and other deterministic simulations, but it usually requires stricter simulation constraints than ordinary MonoBehaviour/PhysX gameplay.
Real games are hybrids. Your local player may be predicted, remote players interpolated, cosmetic effects local-only, and economic rewards finalized by a backend.
My 2026 decision table
| Option | Best fit | Main strength | Main caution |
|---|---|---|---|
| Photon Fusion | GameObject action, FPS/TPS, co-op | Prediction/resimulation, lag compensation, multiple topologies | Photon dependency, CCU/bandwidth cost, dedicated hosting is separate |
| NGO + MPS SDK | Unity 6, UGS-heavy co-op | Unity-first integration, Sessions/Relay/Lobby ecosystem | MPS Sessions requires Unity 6; advanced action prediction is not a turnkey system |
| Netcode for Entities | DOTS/ECS, many entities, dedicated servers | Ghosts, prediction, lag compensation | ECS commitment, learning curve, resimulation cost |
| FishNet | GameObject, source access, self-hosting | Prediction, server authority, transport flexibility | Custom license; surrounding infrastructure and QA remain your responsibility |
| Mirror | Existing codebases, MIT requirement, self-hosting | Snapshot interpolation, lag compensation, PredictedRigidbody | General prediction is still listed as Researching; PoC the exact physics/use case |
| Photon Quantum | Deterministic competitive games | Deterministic ECS and rollback | Separate simulation model from ordinary Unity physics/MonoBehaviours |
| Nakama | Backend-driven multiplayer | Auth, storage, matchmaking, chat, authoritative match loop | Not a drop-in 3D action-state netcode |
Versions I used as the baseline
These are the specific versions/editor combinations checked for this article.
| Product / stack | Version | Editor / delivery note |
|---|---|---|
| Photon Fusion | 2.1.2 Stable | Unity 2021.3.45, 2022.3.45, 6.0.x, 6.3.x; console access has separate requirements |
| Netcode for GameObjects | 2.13.2 | Unity 6000.3; package manifest minimum is 6000.0 |
| Multiplayer Services SDK | 2.2.1 | Unity 6.0 LTS+; com.unity.services.multiplayer
|
| Netcode for Entities | 1.14.2 | Unity 6000.3 via UPM |
| Netcode for Entities core | 6.5 / 6.6 | Integrated with Unity 6000.5 / 6000.6 editor lines |
| FishNet | 4.7.2R | Verify editor compatibility per release; custom source-available license |
| Mirror | v96.11.2 | MIT; evaluate prediction maturity per feature |
| Photon Quantum | 3.0.13 Stable | Unity 2021.3 LTS+; deterministic simulation environment |
| Nakama | Server v3.40.0 / Unity Client 3.21.1 | Backend, not a transform-prediction netcode |
For NGO and Netcode for Entities, do not confuse the broad product family with a specific package/editor combination. For example, NGO 2.13.2 is not something I would assume can simply be dropped into a Unity 2021/2022 project; older editors have their own package lines. Likewise, Netcode for Entities 6.5+ is tied to the corresponding Unity 6 editor line as a core package.
Primary references: NGO 2.13 changelog, Unity 6000.3 NGO, Unity 6000.3 Netcode for Entities, and the Unity 6000.6.0b9 release page.
When Fusion is a sensible first benchmark
I would start a GameObject action-game PoC with Fusion when all of these are acceptable:
- movement, shooting, or physics needs client prediction;
- Photon Cloud dependency and its pricing model are acceptable;
- Host or client-server topology matches the product;
- full source redistribution or unrestricted middleware reuse is not a hard requirement.
This is a comparison baseline, not an automatic production choice.
Fusion Host Mode is attractive for small PvE games because it can avoid dedicated-server compute cost. Server Mode is a better fit when match integrity matters. Shared Mode can reduce some topology friction for casual/mobile/WebGL use cases, but its authority model must not be treated as equivalent to a trusted dedicated server.
Photon provides Fusion Server Mode and the connection/session runtime. It does not automatically provide the infrastructure that builds, allocates, starts, scales, and monitors your Unity headless server fleet. That is a hosting/orchestration problem. See Photon’s Dedicated Server overview.
Console development also has separate access requirements. Photon’s Console Development Overview describes certification checks, platform-specific documentation, and native socket libraries. Authentication, invites, suspend/resume, cross-play, and platform certification still need device-level PoCs.
NGO + MPS SDK: best when Unity 6 and UGS are deliberate choices
Netcode for GameObjects is Unity’s GameObject/MonoBehaviour-oriented netcode. My current baseline is Unity 6000.3 + NGO 2.13.2.
The Multiplayer Services SDK Sessions requires Unity 6.0 LTS or newer. Sessions can automate host election, player join/leave handling, and network connection establishment. That does not mean it designs your gameplay state, authority model, session lifetime, migration payloads, or failure UX.
For existing Unity 2021/2022 projects, treat “stay on the editor-compatible NGO package” and “migrate to Unity 6 + current NGO + MPS Sessions” as separate estimates.
NGO can be a very good fit for small co-op games where UGS Authentication, Lobby, Relay, and Matchmaker are already part of the product. For highly latency-sensitive competitive action, I would PoC the actual movement and combat loop under 100–200 ms rather than assume anticipation features are equivalent to a complete rollback/resimulation architecture.
Netcode for Entities: use it when ECS is already the product architecture
Netcode for Entities provides Ghost snapshots, command streams, client prediction, rollback/resimulation, interpolation, and lag compensation in an ECS-oriented execution model.
Its strength is not “more players by magic.” You still need to control which ghosts are predicted, how often they update, and which clients receive them. Sending every entity every tick to every client will fail regardless of the framework.
I would choose it when DOTS/ECS and dedicated servers are already strategic decisions: large numbers of players, NPCs, projectiles, or units; data-oriented simulation; and a team that can profile prediction loops and server tick budgets.
I would not move a mature MonoBehaviour/Animator/PhysX/NavMesh project to ECS solely because the networking package looks attractive.
FishNet: strong for self-hosted GameObject stacks, but read the license correctly
FishNet offers server authority, prediction/reconciliation, NetworkTransform, observer systems, and transport choice. It can work well when you want to choose your own hosting and surrounding services.
However, do not describe it simply as “open source.” The current FishNet license permits game/content use and modification, while section 2.b restricts other networking-solution products from using, reverse-engineering, or implementing the FishNet software. Section 2.d explicitly says that exclusion does not apply to games developed with the software.
So separate normal game development from middleware/product reuse. If your plan includes forking, redistribution, an internal shared networking platform, a competing networking product, or FishNet-Pro distribution, get legal review of the current terms.
Self-hosting also means you own more of relay/NAT strategy, allocation, monitoring, DDoS considerations, upgrades, and regression testing.
Mirror: evaluate the current features, not the old reputation
Mirror remains relevant when you value an MIT license, existing assets, and self-hosting.
It has Snapshot Interpolation, Lag Compensation, and PredictedRigidbody. But the official project status still distinguishes feature maturity: snapshot interpolation is Stable, lag compensation is Beta, and general Prediction is Researching.
That does not make Mirror unsuitable for action games. It means the PoC must use the exact Unity version, transport, physics objects, character controller, abilities, knockback, and reconciliation requirements you expect to ship.
Quantum: deterministic does not mean “automatically cheat-proof”
Photon Quantum uses deterministic ECS and rollback. That can be a very good fit for fighting games, RTS, sports, and other simulations where replayability from input history is valuable.
But determinism is not the same as dedicated-server authority. Hidden information, fog of war, input validity, ranking, and reward settlement are separate security problems. Use the official Quantum Cheat Protection guidance to decide what is validated, what checksums can detect, and what must be verified or persisted elsewhere.
Nakama: backend first, not a replacement for action netcode
Nakama provides authentication, storage, matchmaking, chat, leaderboards, realtime sockets, and authoritative match handlers. It can fully own many card, board, or lower-frequency competitive games.
It is not, by itself, a drop-in replacement for a 3D action framework that predicts CharacterControllers, Rigidbodies, projectiles, and hitboxes. For a 60 Hz action game, pair it with a netcode or build a game-specific protocol deliberately.
Unity Multiplay changed: separate matchmaking from hosting
Unity’s directly provided Multiplay Game Server Hosting is marked deprecated as of April 1, 2026 in the Unity status notice.
That does not mean Matchmaker or the Multiplayer Services SDK disappeared. Unity’s game server hosting support documents an architecture where Cloud Code integrates with an external game-server hosting provider for allocation, session creation, and backfill.
A new design should therefore keep these responsibilities separate:
Authentication
↓
Matchmaker
↓
Cloud Code / allocation logic
↓
External game-server hosting
↓
MPS Session
↓
Netcode
The same principle applies to Fusion: netcode is not hosting.
Host Mode: the backend cannot magically make host-reported gameplay trustworthy
For small co-op games, a common design is:
Player-hosted match
↓
Backend
├─ authentication
├─ server-issued mission/reward rules
├─ eligibility and limit validation
└─ capped provisional reward commit
This can be useful, but the participant acting as host owns State Authority and can modify the host process. Sending results to a backend does not prove that reported kills, drops, or clears actually happened.
Server-issued mission tokens, time windows, reward tables, and daily caps can verify eligibility and limit the maximum loss from cheating. They do not prove host-reported gameplay facts inside those limits.
If high-value rewards, ranking, or paid currency require stronger trust, move those facts behind a trusted authority: for example dedicated-server telemetry or another verifiable event source outside the player host’s trust boundary.
Send verifiable input or commands, not authoritative results
A client should not be trusted when it says:
- “my position is X”
- “I dealt 100 damage”
- “this purchase succeeded”
For an action game, send movement, aim, buttons, and fire requests. The authority derives speed, cooldowns, ammo, collisions, and damage.
For a card or board game, raw device input is less useful. Send intent-level commands such as:
PlayCard(cardId, targetId)
UseSkill(skillId, targetId)
BuyItem(sku, quantity)
The authority validates ownership, turn/phase, cost, target, inventory, cooldown, and sequence, then derives the result.
The common principle is simple: the client should submit the minimum input/command that a trusted authority can validate and recompute.
Keep tick simulation replayable
For client-server prediction, gameplay code that affects authoritative results belongs in network ticks, not only in ordinary Update().
This is a conceptual Fusion Host/Server Mode example, not copy-paste production code:
public struct PlayerMoveInput : INetworkInput
{
public Vector2 Move;
}
public sealed class NetworkPlayer : NetworkBehaviour
{
private const byte MaxMoveReuseTicks = 2;
[Networked] public int Hp { get; set; }
[Networked] public NetworkBool IsStunned { get; set; }
[Networked] private Vector2 LastAcceptedMove { get; set; }
[Networked] private byte MissingMoveTicks { get; set; }
public override void FixedUpdateNetwork()
{
if (!HasInputAuthority && !HasStateAuthority)
return;
// State that advances without player input must still tick.
SimulateInputIndependentState(Runner.DeltaTime);
Vector2 move;
if (GetInput(out PlayerMoveInput input))
{
move = Vector2.ClampMagnitude(input.Move, 1f);
LastAcceptedMove = move;
MissingMoveTicks = 0;
}
else
{
MissingMoveTicks++;
move = MissingMoveTicks <= MaxMoveReuseTicks
? LastAcceptedMove
: Vector2.zero;
}
if (Hp <= 0 || IsStunned)
move = Vector2.zero;
SimulateMovement(move, Runner.DeltaTime);
}
}
The important part is not the exact two-tick policy. It is that the policy is deterministic and explicit. Photon documents that GetInput() can occasionally fail even on the State Authority during packet loss or latency spikes.
Held input and edge input should not necessarily use the same missing-packet policy. Reusing a previous held movement state for a bounded number of ticks can be reasonable; inventing a new button-down edge from missing input is not.
Also keep external side effects out of replayable simulation. Do not call databases, HTTP services, anti-cheat services, analytics, or reward settlement directly from resimulatable tick code.
For economic or external effects, use a durable, retry-safe flow:
confirmed authoritative domain event
↓
durable event log / transactional outbox
↓ at-least-once delivery
worker / dispatcher
↓
backend with persistent idempotency key
↓
persisted result / retryable query
↓
apply only if match/player/revision is still valid
An “outbox” stored only in game-server memory or disposable local disk is not crash-safe. If the match state and outbox cannot be committed atomically, you still have a dual-write problem. Either make the durable event the source of truth, use a transactional boundary, or define how the match is invalidated/compensated after unrecoverable failures.
Design session lifetime and reconnection before polishing gameplay
A connection API returning success is not a session design.
Define the state transitions for create, join, ready, start, late join, temporary disconnect, reconnect, leave, result settlement, and destruction. Decide which record is authoritative when lobby, game server, and backend disagree.
Do not use a transient connection ID as the persistent player identity. Reconnect using an authenticated user identity plus match identity, with an expiring token that includes build/version and permissions. Invalidate the old connection when the new one is accepted.
Late joiners should receive scene/assets, current phase, and replicated state in a known order, then acknowledge readiness before spawning and accepting input.
Run a 1–2 week PoC with at most two candidates
Do not choose a multiplayer SDK from documentation alone.
A useful first timebox is one or two engineers, one to two weeks, and no more than two candidates. Build the same minimum slice in each:
- real movement plus one important action such as dash/jump/dodge
- shooting or melee, damage, death
- one moving platform or pushable Rigidbody
- match start/end, late join, disconnect, reconnect
- headless build where relevant
Use the same gameplay and network conditions for every candidate.
Define pass/fail thresholds before testing
Examples:
| Metric | Example acceptance rule |
|---|---|
| Reconciliation | At 100 ms RTT and 3% loss, p95 correction distance stays below your game-specific limit |
| Server tick | p99 tick time remains below 70% of the tick budget |
| Reconnect | p95 reconnect completes within the product target and restores authoritative state correctly |
| Bandwidth | Average billable bytes/sec per connection stays inside the business target |
| Allocation | Dedicated-server allocation success and cold-start p95 meet the SLO |
| Failure handling | Expired tokens, version mismatch, and region exhaustion fail explicitly and recover predictably |
| Result settlement | Crashes and duplicate submissions do not create missing or double-applied match results |
Do not copy arbitrary values like “0.2 m correction” from another game. Derive thresholds from movement speed, match length, reconnect rules, platform constraints, and economic risk.
Network emulation should include not only RTT and random packet loss, but also jitter, burst loss, asymmetric uplink/downlink, packet reordering/duplication, temporary disconnects, host loss, backgrounding, different frame rates, and server tick stalls.
Cost: estimate from average CCU and billable traffic, not DAU alone
A rough average CCU estimate is:
average CCU
≈ DAU × sessions per day × average connected minutes / 1,440
For example, 10,000 DAU × 1.5 sessions × 20 minutes is roughly 208 average CCU.
Bandwidth is roughly:
monthly billable transfer
≈ average CCU × average billable bytes/sec per connection × seconds/month
Use peak CCU for capacity and server-count planning, but average usage for transfer estimates.
Then price each network leg separately:
- client → relay and relay → host/server
- host/server → client
- game server → backend
- cross-region and redundancy traffic
The same packet may be billable by multiple providers, while some hosting plans include certain bandwidth. Only remove a cost after verifying the provider’s pricing model. Relevant references include UGS pricing, Photon Fusion pricing, and Amazon GameLift Servers pricing.
Practical recommendation
In 2026, I would narrow a Unity real-time networking stack in this order:
- decide GameObject vs ECS and the Unity/editor version you can actually ship;
- choose where authority lives: host, dedicated client-server, or distributed/shared;
- separate session, hosting, and backend responsibilities from netcode;
- validate platform access, licensing, CCU/bandwidth, and operational cost;
- compare the real movement/combat/reconnect slice under the same bad-network conditions.
If the game is GameObject-based, you accept Photon dependency and pricing, and you need Host or Client-Server prediction, Fusion 2.1 is a sensible benchmark candidate.
If Unity 6 + UGS integration is the priority, start with NGO 2.13.2 + MPS SDK. If DOTS/ECS is already the architecture, start with Netcode for Entities. If source access and self-hosting matter, compare FishNet and Mirror carefully under their actual licensing and feature-maturity constraints. If determinism is a core requirement, evaluate Quantum. Use Nakama primarily as a backend or authoritative match platform rather than as a drop-in transform prediction layer.
The key point is that “it connected” is not the success condition. Ship only after you have measurable acceptance criteria for 100–200 ms network conditions, reconciliation, authority and cheating, reconnect/late join, server allocation, bandwidth, and crash-safe result settlement.
Primary official references
- Photon Fusion SDK Download
- Photon Fusion topology guide
- Photon Fusion input
- Photon Fusion network simulation loop
- Unity NGO 2.13 changelog
- Unity MPS SDK Sessions
- Unity Multiplay deprecation notice
- Unity Netcode for Entities 1.14 changelog
- FishNet license
- Mirror README / feature status
- Photon Quantum cheat protection
- Nakama authoritative multiplayer
Top comments (0)