S&box Wiki

Revision Difference

Networked_Types#543952

<cat>Code.Network</cat> <title>Networked Types</title> ⤶ Networked types allow you to synchronize class members between client and server, this is most commonly used for entities but can be used on any class that is derived from `NetworkClass`⤶ ⤶ #Creating a networked member⤶ ⤶ Adding the `[Net]` or any of the other attributes listed below to a property will mark it to be networked.⤶ ⤶ Any property on your entity can be networked (synced from server to client).⤶ ⤶ ⤶ ⤶ # Making a property networked⤶ ⤶ Adding the `[Net]` attribute makes it networked.⤶ ``` [Net] public float HeadSize { get; set; }⤶ ```⤶ ⤶ Classes containing networked members have to be marked as `partial` in order to work properly. This is because codegen adds a supporting class in another file.⤶ ⤶ ## Predicted⤶ ⤶ The properties can also be predicted.⤶ ⤶ ```⤶ [Net, Predicted]⤶ public float HeadSize { get; set; } ``` ⤶ <warning>Classes containing networked members have to be marked as `partial` in order to work properly.</warning>⤶ ⤶ There are several different attributes you can use instead of `[Net]` that each behave slightly differently:⤶ ⤶ * `[Net]` - Networks to everyone⤶ * `[NetPredicted]` - Same as `[Net]` but allows the value to be predicted⤶ * `[NetLocal]` - Only networks to the player it's set on or `Entity.Owner`⤶ * `[NetLocalPredicted]` - Same as `[NetLocal]` but allows the value to be predicted⤶ ⤶ This changes two things⤶ ⤶ * The variable is backed up and restored properly by the prediction system⤶ * You can change the value clientside⤶ ⤶ ## Local⤶ ⤶ You can make your networked property Local too, meaning it'll only be sent to the owner of the entity. This is useful if the data is only useful to the controlling client, or for anti-cheat reasons you wouldn't want other players to see the value.⤶ ```⤶ [Net, Local]⤶ public int Money { get; set; }⤶ ```⤶ ⤶ # Networkable Types⤶ #Custom types⤶ ⤶ Before you can start networking your own types you have to make sure they're supported. Entities are supported by default and you don't have to worry about them.⤶ ⤶ For non-entity classes the easiest method is to have it inherit from `NetworkClass` but if you want to you can do it the manual way as well.⤶ ⤶ #The manual way (Serialization)⤶ ⤶ This method is mainly used for structs but you can use it for classes as well if you'd like.⤶ ⤶ ##Structs⤶ ⤶ Structs are fairly simple to set up as you just have to add two member functions, one for writing and one for reading the serialized data.| Type Name | Support |⤶ |-|-|⤶ | float, int, bool, byte, long, short | Any [built in value type](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/built-in-types) will work |⤶ | string | Supported |⤶ | Enum | Supported |⤶ | Vector2, Vector3, Rotation, Angles, Transform | Supported |⤶ | Custom Struct | Supported (must contain [only unmanaged types](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/unmanaged-types)) |⤶ | Custom Classes | Must be derived from NetworkClass |⤶ | Entity | Supported |⤶ | List<float>, List<bool> | Supported - any built in value type |⤶ | List<Entity> | Supported - any type of entity |⤶ | List<string> | Supported |⤶ | Dictionary<x, y> | Planned |⤶ ⤶ ## Custom Structs⤶ ⤶ If you want to transmit a struct it needs to be plain old data. It should contain no strings, no classes, no lists, no entities.⤶ ``` public void Write( BinaryWriter writer )⤶ public struct AnotherStruct⤶ { writer.Write( (float)x ); writer.Write( (float)y ); writer.Write( (float)z ); public int A; public int B; public Vector3 C; } public Vector3 Read( BinaryReader reader )⤶ public struct CustomStruct⤶ { return new Vector3( reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() ); public float Delta; public AnotherStruct Data;⤶ public ulong Dump;⤶ } ```⤶ ⤶ Either of the above are valid⤶ ⤶ ## NetworkClass⤶ ⤶ By deriving a class from NetworkClass you'll be able to sync that using `[Net]` too. It has a few characteristics that you should know about.⤶ ⤶ * You can derive from the class and it'll create the right class on the client.⤶ * You can only send variables, entities and structs. No classes, no Lists.⤶ * [Predicted] and [Local] attributes won't change anything, these things are dictated by the original [Net].⤶ ⤶ An example usage of NetworkClass is to provide things like Camera. By networking a Camera class on a var, we allow the server to set the camera class directly and configure its variables. The server can set the `Pawn.Camera` to a `new FirstPersonCamera` and the client will receive that variable and create that class, like magic. This adds a lot of versatility to these kinds of systems.⤶ ⤶ ⤶ ``` ⤶ ##Classes⤶ ⤶ For classes you have to be a bit more crafty, members don't work here since a class can be `null` and we have to handle updating existing instances. Static functions work just fine for this.⤶ ⤶ ```⤶ public static class MyClassExtension⤶ public partial class NetworkClassTest : NetworkClass⤶ { public static void Write( this MyClass self, System.IO.BinaryWriter writer ) { if ( self == null )⤶ {⤶ writer.Write( false );⤶ return;⤶ }⤶ ⤶ writer.Write( true );⤶ ⤶ writer.Write( self.Age );⤶ writer.Write( self.Sex );⤶ writer.Write( self.Location );⤶ }⤶ ⤶ public static MyClass Read( this MyClass self, System.IO.BinaryReader reader )⤶ {⤶ int notNull = reader.ReadBoolean();⤶ if ( notNull == 0 ) return null;⤶ ⤶ if ( self == null ) self = new MyClass();⤶ ⤶ self.Age = self.Age.Read( reader );⤶ self.Sex = self.Sex.Read( reader );⤶ self.Location = self.Location.Read( reader );⤶ ⤶ return self;⤶ }⤶ [Net] public int IntValue { get; set; } [Net] public Vector3 VectorValue { get; set; } } ```⤶ ⤶ [Extension methods](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods) can also be used here (and are used in the example) to let you add support to classes you're unable to access for some reason.```