S&box Wiki

Networking Basics

Networking Basics

There are two realms in networking on S&box. The client, and the server:

Client: Each person playing in your game.

Server: The process that is responsible for orchestrating your game with all of the clients in it.

By default, both sides will know nothing about each other. But with networking it allows either side to communicate and keep each other in sync. While the same code will be run on both the client and server. No variables and state information you make are shared between them. Due to this, all variables you create whether they are created the exact same way or not will become out of sync when something is done on only one realm. This is where networking comes in. This allows you to share information between both the client and the server.

Example

using Sandbox; namespace Networking { public class NetworkingExampleOne : Game { public int NumClients = 0; public override void ClientJoined( Client cl ) { base.ClientJoined( cl ); NumClients++; } public override void Simulate( Client cl ) { base.Simulate( cl ); Log.Info( $"{(Host.IsServer ? "Server:" : "Client:")} {NumClients} clients added." ); } } }
NetworkingExampleOneResult.png

Upon a client joining you will find the above in your console. Notice how they are not the same.

"But why?"

The ClientJoined method is only called on the server. Because of this, only the server adds one to the NumClients field. Since this integer is not networked the clients will never get an up-to-date NumClients field.

"How can I fix this?"

With a small edit to the code like so:

using Sandbox; namespace Networking { public partial class NetworkingExampleTwo : Game { [Net] public int NumClients { get; set; } public override void ClientJoined( Client cl ) { base.ClientJoined( cl ); NumClients++; } public override void Simulate( Client cl ) { base.Simulate( cl ); Log.Info( $"{(Host.IsServer ? "Server:" : "Client:")} {NumClients} clients added." ); } } }
NetworkingExampleTwoResult.png

Now when a client joins you will find the above in your console.

"What changed?"

Three things were changed:

  1. The partial keyword was added to the class. The S&box code generator will attach more code to the class in a separate file to support networking types and so partial is required for the code to compile.
  2. The field was turned into a property. This is because S&box networking cannot work with fields. It requires a property. (What's the difference?)
  3. The Net attribute was applied to the NumClients property. This is to mark the property for networking.

"What is the catch?"

  1. Not all classes are capable of networking. Only Entity, EntityComponent, BaseNetworkable classes, and anything derived from those are networking capable.
  2. Not all types can be networked, see this list for available types.
  3. Properties marked with the Net attribute cannot be edited by the client. It will not produce an error, just nothing will happen. If you have code that requires updating on the client-side then you need prediction.

"How will I know when my variable gets updated?"

You can add the Change attribute to your networked property and it will call On[Property]Changed on your class in the client-side.

[Net, Change] public int MyNumber { get; set; } // This will be called once MyNumber is edited on the server. private void OnMyNumberChanged( int oldValue, int newValue ) { Log.Info( $"MyNumber used to be {oldValue}, now it is {newValue}" ); }

You can read the dedicated page for network callbacks here

Useful Links

  • For information on networking types. See here
  • For information on what can be networked. See here
  • For information on prediction. See here
  • For information on Remote Procedure Calls(RPCs). See here
  • For information on network variable callbacks. See here

Special Pages


Wikis

?

Render Time: 16ms

DB GetPage 3
Generate Html 3
SaveChanges (1) 5
Render Body 0
Render Sidebar 1