> For the complete documentation index, see [llms.txt](https://dotsnet.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dotsnet.gitbook.io/docs/user-manual/networkcomponent.md).

# NetworkComponent

**DOTSNET** can automatically sync components for you.&#x20;

For example, let's say we need a **Health** component with:

* **Current** health: this changes when attacked / when recovering.
* **Max** health: this never changes.

We can define a `Health : NetworkComponent` , which **DOTSNET** will automatically:

* Include in **Spawn** messages
* Synchronize every `NetworkServer.snapshotInterval` seconds

## NetworkComponent Interface

First, we need to create a Health struct that implements the `NetworkComponent` interface:

```csharp
public struct Health : NetworkComponent
{
    public int current;
    public int max;

    // server authoritative
    public SyncDirection GetSyncDirection() =>
        SyncDirection.SERVER_TO_CLIENT;

    // only sync current. max is always the same.
    public bool Serialize(ref NetworkWriter128 writer) =>
        writer.WriteInt(current);

    // only sync current. max is always the same.
    public bool Deserialize(ref NetworkReader128 reader) =>
        reader.ReadInt(out current);
}

// need to define a serializer for every NetworkComponent
public class HealthSerializer : NetworkComponentSerializer<Health> {}
```

**Important:** we also need to define a `NetworkComponentSerializer<T>` for every `NetworkComponent` .

{% hint style="success" %}
`NetworkComponent`implements `IComponentData` automatically and is **burstable**.
{% endhint %}

In the above example, **DOTSNET** will automatically serialize `current` health and include it in Snapshots, from client to server. If the client tries to modify it, it will have no effect unless we change sync direction to `CLIENT_TO_SERVER` which would make it client authoritative.

{% hint style="info" %}
We could avoid the Serializer defintion with C# Reflection, but it's too slow.
{% endhint %}

## NetworkComponentSerializer\<T> Fast

The one-liner `NetworkComponentSerializer<T>` uses an `EntityQuery<T>` internally because a generic  `Entites.ForEach<T>` is not supported by ECS.&#x20;

If necessary, feel free to overwrite the Serializer's `SerializeAll` / `DeserializeAll` functions for maximum performance. It's more verbose though:

```csharp
public class HealthSerializer : NetworkComponentSerializer<Health>
{
    public override void SerializeAll(CurrentWorld currentWorld)
    {
        ushort key = Key; // copy for Burst
        Entities.ForEach((ref NetworkComponentsSerialization serialization, in NetworkIdentity identity, in Health component) =>
        {
            Serialize(currentWorld, key, identity, component, ref serialization);
        })
        .Run();
    }

    public override void DeserializeAll(CurrentWorld currentWorld)
    {
        ushort key = Key; // copy for Burst
        Entities.ForEach((ref NetworkComponentsDeserialization deserialization, ref Health component, in NetworkIdentity identity) =>
        {
            Deserialize(currentWorld, key, identity, ref component, ref deserialization);
        })
        .Run();
    }
}
```

For your own components, simply **copy the above** code and replace `Health` with your components type. Put that code right below where you define your component, in the same file. Don't worry about what it does. it just needs to be defined.

{% hint style="info" %}
Defining `NetworkComponentSerializer<T>` might be **automated** in the future.
{% endhint %}
