Skip to content

chore: Add NetworkObject ownership docs and update related docs#3879

Open
EmandM wants to merge 5 commits intodevelop-2.0.0from
chore/update-ownership-documentation
Open

chore: Add NetworkObject ownership docs and update related docs#3879
EmandM wants to merge 5 commits intodevelop-2.0.0from
chore/update-ownership-documentation

Conversation

@EmandM
Copy link
Member

@EmandM EmandM commented Feb 24, 2026

Purpose of this PR

At long last.... Ownership docs!

Jira ticket

Link to related jira ticket (Use the smart commits). Short version (e.g. MTT-123) also works and gets auto-linked

Changelog

  • Added: The package whose Changelog should be added to should be in the header. Delete the changelog section entirely if it's not needed.
  • Fixed: If you update multiple packages, create a new section with a new header for the other package.
  • Removed/Deprecated/Changed: Each bullet should be prefixed with Added, Fixed, Removed, Deprecated, or Changed to indicate where the entry should go.

Documentation

  • No documentation changes or additions were necessary.
  • Includes documentation for previously-undocumented public API entry points.
  • Includes edits to existing public API documentation.

Testing & QA (How your changes can be verified during release Playtest)

Functional Testing

Manual testing :

  • Manual testing done

Automated tests:

  • Covered by existing automated tests
  • Covered by new automated tests

Does the change require QA team to:

  • Review automated tests?
  • Execute manual tests?
  • Provide feedback about the PR?

If any boxes above are checked the QA team will be automatically added as a PR reviewer.

Backports

Copy link
Member

@NoelStephensUnity NoelStephensUnity left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made a few suggestions... otherwise it looks great (and was definitely needed).

Comment on lines +12 to +14
## Authority ownership

If you're creating a client-server game and you want a client to control more than one NetworkObject, or if you're creating a distributed authority game and the authority/current owner of the object would like to change ownership, use the following ownership methods.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ownership vs authority

The client-server and distributed authority network topologies have slight differences when it comes to ownership and authority.

  • Client-server: A client can own a spawned NetworkObject but the server always maintains spawn authority over the NetworkObject. Ownership only provides the owning client authority over NetworkVariables (with write permissions), any NetworkTransform configured for owner authority, and can be used to send an RPC that targets the owner.
  • Distributed authority: If a client owns a NetworkObject it becomes the "over-all" authority of that NetworkObject. This means the owning client has spawn/de-spawn authority, write permissions to NetworkVariables (associated with the owned NetworkObject), the motion authority (if the NetworkObject has any NetworkTransforms), and the owning client can change the ownership permissions flags.

The following methods change their behavior based on the network topology being used:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This, except one day Noel will learn that it's 'overall' not 'over-all'

Comment on lines +16 to +20
The default `NetworkObject.Spawn` method will set server-side ownership when using a client-server topology. When using a distributed authority topology, this method will set the client who calls the method as the owner.

```csharp
GetComponent<NetworkObject>().Spawn();
```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NetworkObject.Spawn

  • Client-Server: The server defaults as the owner of this spawned object.
  • Distributed authority: The client invoking this method becomes the owner of the spawned object.

```csharp
GetComponent<NetworkObject>().ChangeOwnership(clientId);
```

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NetworkObject.SpawnWithOwnership

  • Client-Server: The client identifier passed in as a parameter defines who the owner will be.
  • Distributed authority: It is not recommended to use this method when using distributed authority if there are initial settings you want applied when spawning the new instance. For this scenario, it is recommended to use NetworkObject.Spawn, allow the settings to be applied locally, and then use NetworkObject.ChangeOwnership.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved SpawnWithOwnership to the bottom of the page. That way ChangeOwnership has a higher prominence than SpawnWithOwnership, hopefully leading to fewer SpawnAuthority issues.

Comment on lines +117 to +135
internal class MyRequestableBehaviour : NetworkBehaviour
{
public override void OnNetworkSpawn()
{
NetworkObject.OnOwnershipRequestResponse = OnOwnershipRequestResponse;
base.OnNetworkSpawn();
}

private void OnOwnershipRequestResponse(NetworkObject.OwnershipRequestResponseStatus ownershipRequestResponseStatus)
{
// Called when the requesting client has gotten a response to their request
}

public override void OnNetworkDespawn()
{
NetworkObject.OnOwnershipRequestResponse = null;
base.OnNetworkDespawn();
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

///


/// When a NetworkObject's permissions includes the
/// flag.
///

public class RequestableOwnershipBehaviour : NetworkBehaviour
{
public override void OnNetworkSpawn()
{
NetworkObject.OnOwnershipRequestResponse += OnOwnershipRequestResponse;
base.OnNetworkSpawn();
}

private void OnOwnershipRequestResponse(NetworkObject.OwnershipRequestResponseStatus ownershipRequestResponseStatus)
{
    switch (ownershipRequestResponseStatus)
    {
        case NetworkObject.OwnershipRequestResponseStatus.Approved:
            {
                // OnOwnershipChanged and OnGainedOwnership is invoked on the client requesting side.
                // OnOwnershipChanged and OnLostOwnership is invoked on the previous owning client side.
                break;
            }
        case NetworkObject.OwnershipRequestResponseStatus.RequestInProgress:
            {
                // Another client already has a request pending.
                break;
            }
        case NetworkObject.OwnershipRequestResponseStatus.CannotRequest:
            {
                // Cannot request means RequestRequired is no longer a permission of this NetworkObject.
                // The owning client changed while the request was being sent.
                break;
            }
        case NetworkObject.OwnershipRequestResponseStatus.Denied:
            {
                // The owning client denied the request.
                break;
            }
        case NetworkObject.OwnershipRequestResponseStatus.Locked:
            {
                // Ownership has been locked by the owning client.
                break;
            }
    }
}

public override void OnNetworkDespawn()
{
    NetworkObject.OnOwnershipRequestResponse -= OnOwnershipRequestResponse;
    base.OnNetworkDespawn();
}

}

Copy link
Contributor

@jabbacakes jabbacakes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of suggestions here, but it's a lot of new doc 😅 Nothing major, just a lot of wording/style/consistency tweaks.

There are a lot of changes here and it's getting a bit hard to see the wood for the trees, but we'll be rereviewing this content as part of the centralisation efforts so I think it's all good for now.

Copy link
Contributor

@jabbacakes jabbacakes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of suggestions here, but it's a lot of new doc 😅 Nothing major, just a lot of wording/style/consistency tweaks.

There are a lot of changes here and it's getting a bit hard to see the wood for the trees, but we'll be rereviewing this content as part of the centralisation efforts so I think it's all good for now.

EmandM and others added 2 commits March 2, 2026 16:18
@EmandM EmandM marked this pull request as ready for review March 5, 2026 19:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants