Single-player NetworkRole trap¶
Single-player runs with NetworkRole.None: all three of NetworkManager.IsActive, NetworkManager.IsServer, and NetworkManager.IsClient are false. Guards written as "skip remote clients" using !IsServer accidentally also skip single-player, breaking mod features for solo players.
Problem¶
F0029g (Mods/SprayPaintPlus/RESEARCH.md:189-191):
Single-player runs with
NetworkRole.None:IsActive,IsServer, andIsClientare all false. Guards that check!IsServerto skip remote clients will also skip single-player. The correct remote-client check isIsActive && !IsServer.
A naive guard of the form
means "skip if we are not the server." In multiplayer, server = host = authoritative. In single-player, the game is ALSO the authority, but IsServer is false. The guard skips legitimate work.
Conversely a guard "skip remote clients only" written as
also traps single-player because single-player doesn't match IsServer = true either.
Solution / recipe¶
The authoritative NetworkRole flag matrix lives on ../GameSystems/NetworkRoles.md. Consult it for the exact IsActive / IsServer / IsClient values across single-player, multiplayer host, multiplayer client, and dedicated server modes.
The correct filter for "remote client only" is IsActive && !IsServer. The correct filter for "authoritative (host or single-player)" is IsServer || !IsActive.
F0324 (code comment, SprayCanUsePatch.cs:18-23):
// Skip only on multiplayer remote clients. Their authoritative
// quantity is broadcast by the server, so running this locally
// would briefly show paint consumed before the sync corrects it.
// Single-player has NetworkRole.None (IsActive=false, IsServer=false),
// which the earlier `!IsServer` guard conflated with remote clients
// and accidentally disabled infinite spray in solo play.
Rule of thumb when writing any network-aware guard:
- Name the intent: "remote clients only," "server-authoritative work," "any connected node."
- Map the intent through the
NetworkRolematrix including single-player. - If a plain
!IsServeror!IsClienthandles single-player incorrectly, addIsActiveto the conjunction.
Cited verifications¶
- F0029g: primary rule statement and the correct
IsActive && !IsServerform. - F0324: patch code comment documenting the concrete regression (infinite-spray broken in solo) that motivated the fix.
Verification history¶
- 2026-04-20: page created from the Research migration; F0029g primary, F0324 confirming with a regression narrative.
- 2026-04-20: removed derivative NetworkRole matrix that had drifted (said multiplayer host IsClient=false; authoritative F0017 says true). Replaced with link to GameSystems/NetworkRoles.md per Phase 6 Pass B flag.
Open questions¶
None at creation.