The
enabled
state of a component won’t replicate to other clients by default. Here are three ways to handle this, listed in order of increasing complexity. 1) Force Full Sync with Network.Refresh
This method triggers a complete network update for the GameObject, ensuring the
enabled
state (and all other syncable data) is sent to all clients. It's simple and reliable, but potentially inefficient—especially if used frequently or on many objects—since it resends all networked properties, not just the one you changed. Use it sparingly for low-frequency updates where simplicity matters more than bandwidth. using Sandbox; using System; public class EnabledExample : Component { /// <summary> /// The component we want to toggle `Enabled` on. /// </summary> [Property] private Component Target { get; set; } /// <summary> /// The duration (in seconds) that the component remains enabled or disabled before toggling. /// </summary> [Property] private float Duration { get; set; } = 2; protected override void OnFixedUpdate() { // Only run for the owner of this component if ( IsProxy ) return; var wantsEnabled = Math.Floor(Time.Now / Duration) % 2 == 0; if ( Target.Enabled == wantsEnabled ) return; Target.Enabled = wantsEnabled; // Without this, connected clients won't be made aware of the change to Target.Enabled Target.Network.Refresh(); } }

2) Manual Sync via Rpc.Broadcast
Broadcast the
enabled
state directly using an RPC. It's much more granular than a full sync, using fewer resources by only sending what's needed. using System; using Sandbox; public class EnabledExample_Rpc : Component { /// <summary> /// The component we want to toggle `Enabled` on. /// </summary> [Sync] [Property] private Component Target { get; set; } /// <summary> /// The duration (in seconds) that the component remains enabled or disabled before toggling. /// </summary> [Property] private float Duration { get; set; } = 2; /// <summary> /// Sets the <see cref="Component.Enabled"/> state of the target component across the network. /// Only the host or the authoritative client is allowed to perform this action. /// </summary> /// <param name="enabled">The desired enabled state.</param> [Rpc.Broadcast] private void SetEnabled( bool enabled ) { // Check if we're not the host... if ( !Rpc.Caller.IsHost ) { // ... If we're not, check if we have authority over the Target component // For context, If the caller is allowed to refresh their objects, they can enable it through `Network.Refresh` var hasAuthority = Rpc.Caller.CanRefreshObjects && Rpc.Caller == Target.Network.Owner; if ( !hasAuthority ) return; } if ( Target.Enabled == enabled ) return; Target.Enabled = enabled; } protected override void OnFixedUpdate() { // Only run for the owner of this component if ( IsProxy ) return; var wantsEnabled = Math.Floor(Time.Now / Duration) % 2 == 0; if ( Target.Enabled == wantsEnabled ) return; // Call our Rpc SetEnabled(wantsEnabled); } }
2.5) Singleton Rpc.Broadcast
Utility
Using a singleton utility component to replicate the enabled state centralizes your syncing logic. Instead of writing custom code to sync the enabled state everywhere, you simply call a single method like
EnabledNetworker.SetEnabled(target, true)
from anywhere in your code. using Sandbox; public class EnabledNetworker : Component { /// <summary> /// Holds a static reference to the single instance of the <see cref="EnabledNetworker"/> class. /// </summary> private static EnabledNetworker Instance { get; set; } /// <summary> /// Constructor that assigns the current instance to the static <see cref="Instance"/> property, implementing a singleton pattern. /// </summary> public EnabledNetworker() => Instance = this; /// <summary> /// Determines whether the specified <paramref name="connection"/> has authority to refresh the given <paramref name="component"/>. /// Returns <c>true</c> if the connection is the host or has the required permissions and ownership; otherwise, <c>false</c>. /// </summary> private bool ConnectionHasAuthority( Connection connection, Component component ) { if ( connection.IsHost ) return true; // Check if the caller has permission and ownership to refresh and modify the Enabled state of this component return connection.CanRefreshObjects && connection == component.Network.Owner; } /// <summary> /// Provides networked control over the <see cref="Component.Enabled"/> state of components, /// ensuring that only authorized connections can modify this state across the network. /// </summary> [Rpc.Broadcast] private void InternalSetEnabled( Component component, bool wantsEnabled ) { if ( !ConnectionHasAuthority( Rpc.Caller, component ) ) { // Only log in editor to prevent runtime log spam; authority errors are handled by SetEnabled if ( Game.IsEditor ) Log.Error($"Connection {Rpc.Caller} has no authority to set enabled."); return; } if ( component.Enabled == wantsEnabled ) return; component.Enabled = wantsEnabled; } /// <summary> /// Sets the <see cref="Component.Enabled"/> state of the specified <paramref name="component"/> across the network. /// Ensures that an <see cref="EnabledNetworker"/> instance exists and that the local connection has authority to perform the operation. /// Logs an error and returns if these conditions are not met. /// </summary> /// <param name="component">The component whose enabled state is to be changed.</param> /// <param name="enabled">The desired enabled state.</param> public static void SetEnabled( Component component, bool enabled ) { if ( Instance is not { IsValid: true } ) { Log.Error( "An instance of EnabledNetworker must exist within your Scene" ); return; } if ( !Instance.ConnectionHasAuthority( Connection.Local, component ) ) { Log.Error($"No authority to change enabled state of '{component}'."); return; } Instance.InternalSetEnabled(component, enabled); } }
Here is the version of EnabledExample making use of the Utility
using Sandbox; using System; public class EnabledExample_Utility : Component { /// <summary> /// The component we want to toggle `Enabled` on. /// </summary> [Property] private Component Target { get; set; } /// <summary> /// The duration (in seconds) that the component remains enabled or disabled before toggling. /// </summary> [Property] private float Duration { get; set; } = 2; protected override void OnFixedUpdate() { // Only run for the owner of this component if ( IsProxy ) return; var wantsEnabled = Math.Floor(Time.Now / Duration) % 2 == 0; if ( Target.Enabled == wantsEnabled ) return; // Use the utility to broadcast the change across all connections EnabledNetworker.SetEnabled(Target, wantsEnabled); } }