the symptom, in your words

"Joining client's singleton claim grabs the host's character"

✓ verified on engine 26.07.15alane: Writing gameplayposted

▸ SYMPTOM

On a joining client, the camera locks onto the host's character instead of the client's own player. Both characters render at their correct spawn positions (physics is fine), but the client sees "two merged characters" because its camera focuses on the host's body. The host sees everything correctly — this is invisible from the host side.

▸ CAUSE

The static Instance singleton is claimed in OnStart behind an if (!IsProxy) guard:

snippet
protected override void OnStart()
{
    if (!IsProxy)
        Instance = this;
}

Components are created before NetworkSpawn(owner) runs. During the joining client's world load, the host's character is momentarily non-proxy on the client (the snapshot hasn't resolved ownership yet), so it passes the !IsProxy check and claims Instance. The client's own character also claims it — but order depends on load sequence, and the host's character often wins or claims last.

The [Sync]-driven proxy flag settles correctly by the first OnUpdate, but the singleton claim in OnStart has already fired with stale data. "IsProxy is settled at OnStart" is only reliable on the spawning peer — never trust it during a joining client's world load.

▸ FIX

Re-resolve the singleton claim at the first OnFixedUpdate — the earliest point where IsProxy is trustworthy on all peers:

snippet
private bool _claimResolved;

protected override void OnFixedUpdate()
{
    if (!_claimResolved)
    {
        _claimResolved = true;
        if (IsProxy && Instance == this)
            Instance = null;           // release mis-claim
        else if (!IsProxy)
            Instance = this;           // re-claim as settled owner
    }
}

A proxy holding the claim releases it; the settled local owner re-claims. After one fixed tick, ownership is authoritative on every peer.

Verification lesson: host-side probes never catch this. Put a client-side assertion in your multiplayer probe ("my camera target matches my character"), or eyeball the client window at least once per milestone.

▸ WHY IT WORKS

The fixed-update re-resolve runs after the networking layer has fully settled ownership flags on the joining client. By deferring the authoritative claim to this point, you guarantee IsProxy reflects the real owner, not the transient pre-NetworkSpawn state. The one-tick delay is imperceptible — the camera settles on the correct character before the first rendered frame.

Verified on engine 26.07.15a: seen in a real project.
s&box moves fast; an undated fix is a liability. Spot a stale detail?

Want to know when new guides or fixes drop? Join the community to help build this out. Report gotchas, flag outdated fixes, or just lurk.

Join the Discord