---
title: "Choosing a netcode stack & Netcode for GameObjects"
slug: /workflows/networking-overview/
markdown: /workflows/networking-overview.md
section: netcode
tier: 2
summary: "Pick the stack per project, verify connections, and NGO spawning and serialization rules."
sources: ['unity/networking.md', 'unity/netcode-gameobjects.md']
canonical: https://unityworkflowlibrary.dev/workflows/networking-overview/
read_first: /read-first.md
---

> Read first, on every prompt: [non-destructive rules](/read-first.md).

# Choosing a netcode stack & Netcode for GameObjects

> Pick the stack per project, verify connections, and NGO spawning and serialization rules.

## UNITY-NETWORKING-IS-PROJECT-SELECTED (HARD — project policy)

Record the actual project's
multiplayer requirements and selected stack; never make one project's NGO/DOTS/Mirror choice,
transport, topology or service set the default for all Unity projects.

### Select and record the network design

- Reconcile developer-confirmed choices before asking anything. Record player count, supported
  platforms, online/local modes, join/start/leave flow, topology, authority, stack, transport,
  backend dependencies and the phase in which each must work. Preserve undecided rows explicitly.
- Distinguish real networked peers from local bots, pass-and-play and vendor-owned competitions.
  A single-player prototype can be a visual/rules reference for a multiplayer product; absence
  of networking in the reference does not cancel the developer's multiplayer requirement.

| Choice | Meaning | Rules to open |
| --- | --- | --- |
| No networked multiplayer | No gameplay transport/replication requirement | Project requirements and relevant local gameplay rules |
| Netcode for GameObjects | GameObject/MonoBehaviour networking selected by this project | The NGO sections below; services: [Unity Multiplayer Services](/workflows/unity-multiplayer-services/) |
| DOTS NetCode | ECS networking selected by this project | [DOTS NetCode: ghosts & prediction](/workflows/dots-netcode/), [DOTS NetCode at scale](/workflows/dots-netcode-scale/) |
| Mirror/vendor/custom | Selected alternative with its own authority and lifecycle contracts | [Mirror networking](/workflows/mirror/); FishNet and Photon: [Networking stacks by game size](/workflows/netcode-stack-choice/) |

- Record transport and reachability separately: direct/LAN, relay, dedicated server or other
  selected deployment. Use the chosen stack's compatible transport; adding a package is not
  proof peers can connect. Internet/Relay, hosting and identity-provider choices are not inferred
  solely from selecting a netcode framework.
- Separate backend responsibilities. Auth identifies players; Lobby groups/configures players;
  matchmaking finds a group; transport/Relay moves network traffic; netcode replicates gameplay.
  Install only project-selected services and their required dependencies. For UGS, follow
  the [Unity Gaming Services ops](/workflows/ugs-ops/) page and the compatible SDK guidance for the chosen Editor.

### Define authority, state and presentation before implementation

- Declare one authoritative owner for every action and state transition. Validate player identity,
  permissions, turn/order, legal inputs, timing and rate at that owner. Non-authoritative peers
  request actions rather than authoring outcomes. The selected stack/topology may vary, but
  trust and ownership must be explicit before code.
- Record which state is shared, owner-private or server-only; choose audience, precision and
  frequency by actual consumers. Do not replicate a hidden hand or secret RNG state to everyone
  and attempt to hide it only in UI. Apply the selected stack's security/replication rules.
- Keep deterministic/domain rules independent of UI and transport where practical. Define the
  action/state/event boundary that netcode adapts; preserve the reference's visible behavior and
  animation timings without making client animation completion own authority.
- Specify spawning/despawning, ownership, object registration, scene synchronization, late join,
  reconnect, disconnect, host loss and session cleanup. Required recovery is project-selected;
  do not imply lobby host migration also migrates the authoritative game session.
- For NGO projects, verify the installed `com.unity.netcode.gameobjects` API and compatible
  transport, explicitly author NetworkManager/transport/network prefabs, choose scene-management
  ownership, and use network lifecycle callbacks and correctly owned RPC/state replication.
  Follow the NGO sections below; do not add a second network stack to solve a wiring gap.

### Connect the actual product flow

- Map reference/product actions to network/service operations: identify, discover/create/join,
  readiness, connection approval, synchronized match start, gameplay, results, leave/rejoin.
  Use the same production flow the player operates, with one owner per transition.
- If live service integration is explicitly deferred, build real typed SDK-backed foundations,
  configuration, errors, cancellation and cleanup now as requested. Mark them `built; integration
  pending`; do not manufacture peers, successful login/join responses or online test evidence.
  Deferred Auth/Lobby work does not silently remove the gameplay multiplayer requirement.
- Keep integration status in developer records/tools. Preserve the selected reference UI rather
  than adding implementation explanations or replacing it with a generic networking sample.

### Verify multiplayer at the right tier

- Resolve/pin compatible packages and prove assemblies compile. For runnable multiplayer,
  exercise at least two genuinely separate peers with the required host/server/client roles.
  One process displaying several seats or an Editor-only bot match is not connected-peer evidence.
- Verify the actual join-to-results flow, matching authoritative state, legal-action rejection,
  per-player privacy, scene/spawn readiness and duplicate-action handling. Exercise late join,
  disconnect/rejoin/host loss where required, then confirm complete subscription/session teardown.
- Add latency/loss, reconnect and capacity measurements when they are part of acceptance or the
  reported symptom. Capture exact versions, peer identities/roles, configuration, logs and results.
  Keep direct/LAN proof distinct from Relay/internet/backend proof and target-platform builds.
- Update the project's feature matrix, ledger and canonical evidence. A package install, compile,
  lobby room or local preview never substitutes for required live multiplayer verification.

References (verify against installed package versions when implementing):
- [Unity NGO and Multiplayer Services integration](https://docs.unity.com/en-us/mps-sdk/tutorials/relay-and-ngo).
- [Unity Lobby and Relay responsibilities](https://docs.unity.com/en-us/mps-sdk/advanced-config/relay-vs-lobby).

## Netcode for GameObjects (NGO) — non-DOTS netcode

For DOTS NetCode see [DOTS NetCode: ghosts & prediction](/workflows/dots-netcode/); for Mirror see [Mirror networking](/workflows/mirror/).

## Spawned objects vs app-driven scene flow

See also: [App & scene flow](/workflows/scene-flow/) - the app & scene flow hub (bootstrap -> load -> transitions/additive -> runtime lifecycle -> teardown).

- **With `EnableSceneManagement=false`, a dynamically spawned NetworkObject lives in whatever scene
  was ACTIVE on each peer at spawn time — and dies with it.** A client that spawns the object while
  still in a menu scene, then unloads that scene to follow the match, destroys its own replica:
  `OnNetworkDespawn` runs, statics null out, and the game renders default state with NOTHING logged.
  Replication looks broken; replication was flawless. Fix: `OnNetworkSpawn` moves the object to the
  persistent boot scene on EVERY peer (`SceneManager.MoveGameObjectToScene`) — not
  `DontDestroyOnLoad` if the project uses a named persistent scene. (a card game.)
- With NGO scene sync off, **clients must follow the match themselves**: subscribe to the spawned
  object's first replication and drive your own scene flow from it. The host reaching the game scene
  does nothing for anyone else.

## Serialization for structs outside netcode assemblies

- For an unmanaged struct in an assembly with NO netcode reference (rules kept unit-testable), wrap
  it: `NetworkVariable<ForceNetworkSerializeByMemcpy<T>>` and the same wrapper for RPC parameters.
  Do NOT reach for `[GenerateSerializationForType]` — it emitted an initializer that threw
  `BadImageFormatException` inside NGO's own `InitializeOnLoad` and took down serialization for
  EVERY NetworkVariable in the project. (a card game.)
- **Two NetworkPrefabsLists holding the same prefab UNREGISTER it** — NGO auto-maintains
  `DefaultNetworkPrefabs.asset`; a second list makes a duplicate `GlobalObjectIdHash`, NGO drops the
  registration with two WARNINGS, and `Spawn` silently fails at runtime. Keep only the default list.

## Presentation vs authority

- **Animation never gates authority.** The authority resolves instantly and appends to an event log;
  each client replays the log at human speed while every render stays a function of authoritative
  state MASKED by not-yet-presented events (pending NumberPlaced hides a line card, pending Stay
  holds the stamp and the banked total). Masks beat replaying state — subtracting pending facts from
  truth cannot diverge from the engine, and an event-less reconnecting client renders plain truth
  from cold. Add back-pressure: fast-forward past ~10 queued events, hard-snap past ~25.
- Authority-side pacing is for DECISIONS, not visuals: bot think delay, human turn timeouts. A lone
  human should never be timed out (the table waits, as a real one would); arm timeouts only when a
  rival human is actually waiting.
