menu_bookDocumentation
NetworkObject: Ownership, Proxy State, and Automatic Culling
NetworkObject Ownership, Proxy State, and Culling
Derived from NetworkObject.cs in the s&box engine source.
Ownership Model
Every networked GameObject has a NetworkObject (internal) that tracks:
- Owner — The Guid of the Connection that owns this object. Guid.Empty means unowned.
- Creator — The Guid of the Connection that originally created this object.
- IsOwner — True if Owner == Connection.Local.Id.
- IsUnowned — True if Owner == Guid.Empty.
- IsProxy — True if we don't own this object AND it's not unowned-with-host-control.
Proxy Logic
CODE
IsProxy = true when:
- Not spawning (_isNetworkSpawning == false)
- AND not the owner (IsOwner == false)
- AND NOT (IsUnowned AND Networking.IsHost)This means: the host controls all unowned objects — they are NOT proxies for the host.
Control
HasControl(Connection c) returns true if:- Object is unowned AND c.IsHost
- OR c.Id == Owner
Orphaned Behavior
When the owner disconnects, NetworkOrphaned determines what happens:
| Value | Behavior |
|---|---|
| Destroy | GameObject.Destroy() is called |
| Host | Host becomes the new owner |
| Random | Host picks a random connected client as owner |
| ClearOwner | Owner is set to Guid.Empty (unowned) |
Network Culling
Objects are automatically culled from connections that can't see them:
- Culling uses INetworkVisible.IsVisibleToConnection() if present on the GameObject.
- Falls back to Scene.IsBBoxVisibleToConnection() for global culling.
- Objects are only culled after being invisible for 2 seconds (CullDelay = 2f).
- Set GameObject.Network.AlwaysTransmit = true to disable culling entirely.
- When culled, GameObject.Network.SetCullState(target, true) is called.
Owner Change Events
When ownership changes, the engine fires:
- IGameObjectNetworkEvents.NetworkOwnerChanged(newOwner, previousOwner) on all components
- IGameObjectNetworkEvents.StartControl() when we gain ownership
- IGameObjectNetworkEvents.StopControl() when we lose ownership
- Transform interpolation is cleared on ownership change.
Was this helpful?