Skip to content
HY Devlog
Go back

Mirror Prerequisites: The Asset Store Build Is Over a Year Behind GitHub

I was already using Mirror in a multiplayer game project and went looking to re-check the fundamentals, which is how I ended up saving this write-up. It puts server/client/host, NetworkBehaviour, NetworkIdentity, and NetworkManager on a single page, which makes it a good sweep.

The conceptual material holds up against the current docs even though it’s from January 2025. But the first item — where to install from — is a problem, and several things the source passes over in one line have their justification sitting in Mirror’s own code.

Table of contents

Table of contents

Where to get it

The source’s first item is an Asset Store link. Mirror’s official site points its Download menu at the same place, so it isn’t bad advice. The problem is the age of that build.

SourceVersionLast updated
Asset Store96.0.12025-02-27
GitHub releasesv96.10.22026-06-20

Sixteen months, ten minor versions apart. The Asset Store page still lists Unity 2021.3.35 or later and it’s still free — only the updates stopped.

Mirror’s Deprecations page carries this line.

Some changes in this document may apply to an upcoming release to the Asset Store

That means the docs can run ahead of the Asset Store build. In practice this shows up as following the documentation and finding the API isn’t in your project. Before suspecting your own code, check the build version.

The gap isn’t only about features. Security fixes ship in releases too — like the secure cookie backport for the KCP transport I covered in an earlier post. Skipping a year of releases means skipping that as well.

None of this is the author’s fault. In January 2025 the Asset Store build was two months old. The lesson here is closer to this: an installation pointer you saved is only as current as the day you saved it.

Server, client, host

The source gets this right. The server holds authority over game state, the client sends input and draws what it receives, and the host does both in one process. There are only three ways to start.

NetworkManager.singleton.StartServer();
NetworkManager.singleton.StartClient();
NetworkManager.singleton.StartHost();

The source classifies the host as being for “small-scale multiplayer, local testing” but doesn’t say why it gets pushed into that role. Two reasons.

Host mode does have one good property in exchange. ClientRpc is invoked on the host’s local client too, which makes it hard to write code that only works on the host. I wrote that part up separately in the Commands and RPCs post.

NetworkBehaviour and NetworkIdentity

The source puts it this way.

If an object has a class inheriting from NetworkBehaviour, then either the parent object or that object must have a Network Identity component.

That’s correct, and why the “parent” case is allowed is written as a comment in Mirror’s source.

// [RequireComponent(typeof(NetworkIdentity))] disabled to allow child NetworkBehaviours
[AddComponentMenu("")]
[HelpURL("https://mirror-networking.gitbook.io/docs/guides/networkbehaviour")]
public abstract class NetworkBehaviour : MonoBehaviour

RequireComponent was deliberately turned off. With it on, every NetworkBehaviour you add to a child object would drag a NetworkIdentity along. The use case is in the NetworkIdentity source comments: “Some users need NetworkTransform on child bones, etc.”

The reverse direction is blocked. NetworkIdentity cannot be nested.

Mirror does not support Network Identities on nested GameObjects. … ensure your parent GameObject is the only GameObject in the stack with a Network Identity.

One NetworkIdentity at the root, as many NetworkBehaviours as you like down the children. That one line is the whole rule for laying out a hierarchy. The docs also say that a child needing the identifier should reach up with GetComponentInParent.

One parenthetical in the source is wrong. Its Network Identity section adds “(you may also inherit it in your class)” — but NetworkIdentity cannot be inherited.

[DisallowMultipleComponent]
[DefaultExecutionOrder(-1)]
[AddComponentMenu("Network/Network Identity")]
[HelpURL("https://mirror-networking.gitbook.io/docs/components/network-identity")]
public sealed class NetworkIdentity : MonoBehaviour

It’s sealed. Putting two on one object is blocked by [DisallowMultipleComponent] as well. It isn’t something to extend — it’s closer to a marker you attach and nothing else.

netId is unique only at runtime

The source writes:

Because every Network Identity has a unique netId on the network, different clients can use the netId to tell whether they’re looking at the same object.

Correct. The source comment adds one more qualifier, though.

The unique network Id of this object (unique at runtime).

It’s unique within a session only. The server hands them out incrementing from 1, and bringing the server down and back up restarts at 1 via ResetNextNetworkId(). So don’t persist a netId or use it as a database key — a different object in the next session will get that number.

It also helps to know there are three identifiers with different jobs.

IdentifierWhat it points atWhen it’s decided
netIdthis live instance on the networkissued by the server on spawn
sceneIdan object placed in the scene ahead of timewhen the scene is saved
assetIdthe prefab to spawnat prefab registration

This is also why GameObject works as a remote action argument and Transform doesn’t. What crosses is the netId, and a component doesn’t have one.

Network Manager and the HUD

The source lists “provides a test HUD UI” as a NetworkManager feature. The docs are blunter.

It is not, however, intended to be included in finished games. … you should create your own UI later on, to allow your players to find and join games

The HUD is just those three methods turned into three buttons. Better to start out knowing you’ll be building the connection UI yourself.

There’s one item the source skips that you will hit early.

You should normally make sure the Network Manager persists between Scenes, otherwise the network connection is broken upon a scene change. To do this, ensure the Don’t Destroy On Load checkbox is ticked.

If the connection drops the moment you move from the lobby to the game scene, it’s usually this checkbox.

Network Room Manager

The source lists “separating the lobby and game scenes” as a NetworkRoomManager feature, and its comparison table marks scene separation as required. “Required” is not an overstatement. The source code checks it at server start.

NetworkRoomManager RoomScene is empty. Set the RoomScene in the inspector for the NetworkRoomManager

NetworkRoomManager PlayScene is empty. Set the PlayScene in the inspector for the NetworkRoomManager

It trips in OnStartServer(). Leave the inspector fields empty and you haven’t broken a recommendation — the server doesn’t start. The room player prefab gets checked in OnValidate too.

if (roomPlayerPrefab != null)
{
    NetworkIdentity identity = roomPlayerPrefab.GetComponent<NetworkIdentity>();
    if (identity == null)
    {
        roomPlayerPrefab = null;
        Debug.LogError("RoomPlayer prefab must have a NetworkIdentity component.");
    }
}

The same OnValidate clamps minPlayers to at most maxConnections and at least 0. Type a big number into the inspector and it quietly shrinks, so if the value doesn’t match what you set, look here.

ItemNetworkManagerNetworkRoomManager
Lobbybuild it yourselfbuilt in
Scenesa single scene worksRoom and Gameplay both required
Ready statenoneCmdChangeReadyState, allPlayersReady
Minimum playersnoneminPlayers (clamped to maxConnections)

Running more than one editor

The source links ParrelSync under helpful pages. It’s still a live option (latest release 1.5.3, 2024-06-16). Its README describes it as “another Unity editor window opened and mirror the changes from the original project” — a second editor reflecting the original project.

Since January 2025 there’s one more option: Unity’s Multiplayer Play Mode package. It creates virtual players inside a single project, supporting up to four editor players including the main one, plus up to four local builds. It requires Unity 6000.0.50f1 or later.

That said, neither Mirror’s docs nor Unity’s state that the two work together — not as far as I could find. So don’t jump to “on Unity 6, just use MPPM.” Verify it in your project first and decide from there.

Wrapping up

That’s what re-checking the fundamentals mid-project turned up. The concepts were still the concepts; what had changed was where you get the thing. In a prerequisites write-up, the first part to spoil isn’t the explanation — it’s the installation pointer. Twenty months on, the explanations were fine and only the link in the first line had fallen sixteen months of releases behind.

References


Share this post:

Previous Post
Re-reading the Mirror NetworkManager Inspector: The Server Doesn't Use Network Address
Next Post
Why the Example in a Mirror Design-Patterns Guide Breaks on Scene Change