"FromHost field on a runtime singleton does not replicate without NetworkSpawn"
▸ SYMPTOM
A host-authored [Sync(SyncFlags.FromHost)] field on a bootstrap-created singleton does not replicate to joiners. The host has the data (e.g. a serialized world spec), but a joining client that waits for that value hangs forever — the loading overlay never clears, and a host-side probe confirms GameObject.Network.Active == false on the carrier object even though NetworkMode is set to Snapshot.
▸ CAUSE
The assumption "if both peers create the same singleton identically at bootstrap, NetworkMode.Snapshot will converge the FromHost field with no NetworkSpawn" is only true for baked-scene objects. Every peer loads a baked-scene object with the same scene-assigned network identity.
A runtime Scene.CreateObject() singleton has no cross-peer identity. Without NetworkSpawn, GameObject.Network.Active is false, and the FromHost field never crosses the wire. This is the same failure family as instance RPCs on non-networked objects running local-only — the FromHost field has the identical failure mode.
▸ FIX
Host-NetworkSpawn() the singleton, owned by the host, exactly like other host-authored session objects:
var go = Scene.CreateObject();
var session = go.Components.Create<MySession>();
if ( Networking.IsHost )
{
go.NetworkSpawn(); // host-owned — gives it a network identity
}The joining client must not create its own competing local placeholder of the same singleton. A local copy would never receive the FromHost value and, worse, its own OnUpdate could fight the host's replicated version. Instead, the client receives and polls the host's networked proxy.
Guard the NetworkSpawn on Networking.IsHost so single-player/authoring mode (never networked) stays unchanged — the determinism and generation paths are untouched.
▸ WHY IT WORKS
NetworkSpawn registers the object with the networking system and assigns it a network identity that all peers can reference. Once spawned, the engine's snapshot replication system picks up the [Sync(SyncFlags.FromHost)] field and delivers it to every connected peer. This also gives any [Rpc.Host] or [Rpc.Broadcast] on that singleton a real network identity to route on.
Verify with a re-fetchable host-side probe reporting GameObject.Network.Active plus the FromHost field's length — do not try to read it on the client (local debug probes may be unreachable on a joining client, and shared log files can be overwritten).