the symptom, in your words

"Networking API facts to check against the installed build before you compile"

✓ verified on 26.07.22
lane Writing gameplayposted

▸ SYMPTOM

You plan multiplayer code against assumptions about the networking API, and the plan looks sound on paper. Then it fails to compile, or a symbol turns out to be unreachable, or a headless build passes but the editor rejects the type.

Each of these is a false pass at the planning stage. The assumption reads as safe until the compiler or the editor disagrees.

▸ CAUSE

The networking API surface in the installed build differs from several common assumptions. The facts below come from the build's own source and XML, checked against the version stamped in verifiedOn.

Two mechanisms drive most of the surprises. SB1000 whitelisting works at assembly level, not per member, so a symbol's accessibility, not the whitelist, is usually what stops game code from reaching it. A headless dotnet build skips the editor's compiler, analyzers, and type registration, so a networked type only fully resolves at the editor's own compile.

▸ FIX

Check each of these against your build before you write the code that depends on it.

  1. LobbyInformation is a struct, not a class. A null guard such as if (info == null) does not compile. Guard against a default-constructed value instead.
  2. Networking.Connections is deprecated. The XML notes it moved to Connection.All, and the compiler emits CS0618. Use Connection.All everywhere.
  3. Connection.MaxChunkSize is internal. Game code cannot reference the symbol, even though its value, 128 KB or 131072, is real and is the documented auto-chunk threshold. Hard-code the number or stay well under it. The symbol is unreachable, the value is not wrong.
  4. NetworkAccessor exposes Owner, OwnerTransfer, and OrphanedMode as get-only. The mutators are methods, called after NetworkSpawn: AssignOwnership, SetOwnerTransfer, and SetOrphanedMode.
  5. Networking.TryConnectSteamId exists and is public. Networking.Connect(ulong) is the shorter equivalent path most code should reach for, but the method exists and the API-surface question is closed.
  6. SB1000 whitelisting is assembly-level, not per member. Sandbox.Compiler permits any reference whose assembly name starts with Sandbox. or Facepunch., and Sandbox.AccessRules whitelists Sandbox.Engine and Sandbox.System outright. Every stock networking API lives in one of those, so the whitelist is not the risk for networking calls. Public versus internal accessibility is, as MaxChunkSize shows.
  7. A green dotnet build is not an editor-green result for networked types. The headless build does not run the editor's compiler, its analyzers, or its type registration. Treat a headless-only pass on networking code as provisional until an editor merge and compile confirm it.

▸ WHY IT WORKS

The accessibility rule follows from where SB1000 draws its line. Because the whitelist admits whole engine assemblies, a stock networking symbol is never blocked for whitelist reasons. What remains is ordinary C# access control, so an API that appears in the engine XML can still be internal and unusable from game code. That is why Connection.MaxChunkSize reads in the XML but will not compile in a reference.

The headless caveat follows from what dotnet build leaves out. Type registration and the editor's analyzers run only at the editor's compile, and networked components resolve there. A headless pass confirms the C# compiles, not that the editor accepts the networked type, so it stays provisional until the editor confirms it.

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

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