# Basics

To create a mod in the Creator Kit, refer to the official documentation, we only address HogWarp specifics here.

{% hint style="info" %}
The Creator Kit is where you define the networking interface between Blueprint and C#
{% endhint %}

HogWarp will synchronize specific functions from selected Actors. We do not synchronize Blueprints that are not derived from the Actor class!

## Creating a Network Actor

When you create a new Blueprint that needs networking functionality, ensure you pick `Actor` as the parent class as shown below.

<figure><img src="/files/5FgTgOTdcZfgvhYTj7a0" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Only Blueprints with `Actor` as the parent class can be synchronized
{% endhint %}

Once you have created your Blueprint, you can add it to the HogWarp generator, by clicking on the "HogWarp" button in the tool bar. It will open a window

<figure><img src="/files/mdUZr1AVgmVEJUQuUvAV" alt=""><figcaption></figcaption></figure>

This window will be the main tool you use to make your server mod aware of everything that can be synchronized. The first step will be to set the output directory to the location of your server C# mod by clicking on the three dots to open the file explorer (See [Creating a Plugin](/hogwarp/scripting/server-side/plugin/creating-a-plugin.md) if you don't have a server mod yet).

<figure><img src="/files/pJ81HBmiq53oweXvdBWl" alt=""><figcaption></figcaption></figure>

You can now click on `Add Network Blueprint` to add your newly creator Blueprint. Note that you can add as many as you want, but do not add the same one multiple times. A new empty entry will appear. You can either browse directly from the entry to find your Blueprint, or drag and drop from the content browser the Blueprint as shown below.

<figure><img src="/files/DHxm9zcNMiatK47QtGCy" alt=""><figcaption></figcaption></figure>

You are all set! Now just click on "Generate". Nothing special should happen, but if you browse to the output directory, you should see a new `.cs` file named like your Blueprint.

<figure><img src="/files/weqWyhuCQuzJUk8uAo7P" alt=""><figcaption></figcaption></figure>

If you open the file you will see something an empty class with some attributes.

```csharp
// This file is automatically generated

#pragma warning disable CS8618
#pragma warning disable CS0219

using HogWarpSdk;
using HogWarpSdk.Game;
using HogWarpSdk.Systems;
using HogWarpSdk.Internal;

namespace HogWarp.Replicated
{
    [Replicated(Class = "/HogWarpTest/TestMultiActor.TestMultiActor", Hash = 15294942688974238979)]
    public partial class TestMultiActor : Actor
    {
    }
}
```

That's it, your server now knows about this Actor and can spawn/destroy these actors on the client. You may think that this is great but a bit limited and you would be right, now let's add networked functions!

## Rpc

A Remote Procedure Call (Rpc) is a way to call a function from the client on the server or from the server on the client. The mapping is done automatically by HogWarp.

In HogWarp, a Rpc is declared from the Blueprint class. There are two types of Rpcs:

* `Server` which is a function that runs on the server and gets triggered by the client in Blueprint.
* `Client` which is a function that runs on the game client in Blueprint but is triggered by the server in C#.

Let's start by creating a very simple "Ping" mod that logs the player's latency in the server console every 5 seconds. The latency is the time it takes for a roundtrip message, meaning the time between the moment the server sends a message until it receives a response.

We can model this as two Rpcs:

* `Ping`: a function called by the server
* `Pong`: a function called by the client to respond to the Ping request.

Let's create these two functions in our Blueprint class.

<figure><img src="/files/dez9aBU52don75O72gDW" alt=""><figcaption></figcaption></figure>

If we were to Generate the C# code again, nothing would change. That is because we need to categorize the functions, otherwise HogWarp wouldn't know which functions are Rpcs and which are Client or Server.

We therefore need to put our functions in the correct Category, and it is very simple, Client Rpcs go in the `Client` category and Server Rpcs go in the `Server` category.

<figure><img src="/files/jGlWJx3zseS2XC0Y32uZ" alt=""><figcaption><p>Category for "Pong"</p></figcaption></figure>

After we have set `Pong` to the Server category and `Ping` to the Client category we should see our functions like so:

<figure><img src="/files/pzwfT44WUwbQ2P24ZWPv" alt=""><figcaption></figcaption></figure>

If we now compile and save the Blueprint, we can click `Generate` again and we will see brand new code in the C# file.

```csharp
// This file is automatically generated

#pragma warning disable CS8618
#pragma warning disable CS0219

using HogWarpSdk;
using HogWarpSdk.Game;
using HogWarpSdk.Systems;
using HogWarpSdk.Internal;

namespace HogWarp.Replicated
{
    [Replicated(Class = "/HogWarpTest/TestMultiActor.TestMultiActor", Hash = 15294942688974238979)]
    public partial class TestMultiActor : Actor
    {
        public partial void Pong(Player player);

        [ServerRpc(Function = "Pong", Hash = 12918253484382636919)]
        public void Pong_Impl(Player player, IBuffer data)
        {
            ushort length = 0;
            
            Pong(player);
        }
        
        [ClientRpc(Function = "Ping", Hash = 16843147157235268489)]
        public void Ping(Player player)
        {
            ushort length = 0;
            var data = IBuffer.Create();
            try
            {
                
                IRpc.Get().Call(player.InternalPlayer, Id, 15294942688974238979, 16843147157235268489, data);
            }
            finally
            {
                IBuffer.Release(data);
            }
        }
    }
}
```

At this point we could call the Ping function from the server, the `Pong` function from the client, and implement the `Pong` function on the server. But we need to know when the `Ping` function was called so we should pass a number that represents the time at which it was called to both the `Ping` and `Pong` functions.

Let's add the parameter to both functions as input, called `time` and of type `Integer64`:

<figure><img src="/files/bxQwLmrABxJRUNSSzv6z" alt=""><figcaption></figcaption></figure>

Now we can save and generate the code again.

```csharp
// This file is automatically generated

#pragma warning disable CS8618
#pragma warning disable CS0219

using HogWarpSdk;
using HogWarpSdk.Game;
using HogWarpSdk.Systems;
using HogWarpSdk.Internal;

namespace HogWarp.Replicated
{
    [Replicated(Class = "/HogWarpTest/TestMultiActor.TestMultiActor", Hash = 15294942688974238979)]
    public partial class TestMultiActor : Actor
    {
        public partial void Pong(Player player, long time);

        [ServerRpc(Function = "Pong", Hash = 12918253484382636919)]
        public void Pong_Impl(Player player, IBuffer data)
        {
            ushort length = 0;
            var time = data.ReadInt64();
            
            Pong(player, time);
        }
        
        [ClientRpc(Function = "Ping", Hash = 16843147157235268489)]
        public void Ping(Player player, long time)
        {
            ushort length = 0;
            var data = IBuffer.Create();
            try
            {
                data.WriteInt64(time);
                
                IRpc.Get().Call(player.InternalPlayer, Id, 15294942688974238979, 16843147157235268489, data);
            }
            finally
            {
                IBuffer.Release(data);
            }
        }
    }
}

```

Great! Now we see our functions `Pong` and `Ping`, both have a `long time` parameter.

At this point you should take some time to play around, add more parameters, more functions, and see how this affects the generated code.

## Putting it all together

We now have our Rpcs properly setup but if we were to launch the game with this mod nothing would happen.

### Client

First let's wire the Blueprint `Ping` function to call `Pong` , you may notice that we never explictly call `Ping` anywhere, this is completely normal as remember the server will call it! Also, the `Pong` function is empty, this is expected, HogWarp will intercept calls to `Pong` and replace with the necessary code to call the server function on the correct instance.

<figure><img src="/files/OlYRCJi4dpZ0MwFULwby" alt=""><figcaption></figcaption></figure>

That's all! Nothing more is required!

Let's recap, the flow:

1. The server will trigger a call to `Ping` with the current time.
2. The client will receive the `Ping` call and execute our `Ping` function
3. The `Ping` function which we just implemented in Blueprint triggers a call to `Pong` with the time it received
4. The server receives the `Pong` call and executes the `Pong` function (which we will implement next)

{% hint style="info" %}
In Blueprint you only implement the Client Rpcs, the Server Rpcs are just declarations and HogWarp will replace them with the appropriate code to execute on the server!
{% endhint %}

You may now upload the mod to CurseForge so that they cloud builds it while we work on the server!

See [Setting up mods](/hogwarp/scripting/client-side/setting-up-mods.md) on how to deploy your Creator Kit mod.

## Server

#### Rpcs

If we try to build our server mod now, we will get an error:

<pre><code><strong>error CS8795: Partial method 'TestMultiActor.Pong(Player, long)' must have an implementation part because it has accessibility modifiers.
</strong></code></pre>

This is because the codegen creates all the boiler plate for the server Rpcs but you must implement the server Rpcs! These errors ensure that you don't forget to implement server Rpcs that you declared in Blueprint.

The error in this example says that `TestMultiActor.Pong(Player, long)` is not implemented, so let's just do that. For simplicity we will keep everything in `Plugin.cs` but feel free to create a new file.

```csharp
namespace Tutorial
{
    public class Plugin : HogWarpSdk.IPlugin
    {
        public string Author => "HogWarp Team";
        public string Name => "My Awesome Plugin";
        public Version Version => new(0, 1);
    
        public Plugin()
        {
            var logger = new HogWarpSdk.Systems.Logger("MyMod!");
            logger.Info("Hello, World!");
        }
        
        public void PostLoad()
        {
        }
        
        public void Shutdown()
        {
        }
    }
}

namespace HogWarp.Replicated
{
    public partial class TestMultiActor
    {
        public partial void Pong(HogWarpSdk.Game.Player player, long time)
        {
            // This is the implementation of the Pong function
        }
    }
}
```

As you can see we added a namespace, a class, and a function that match exactly the generated class  and function for our Blueprint actor. You will notice that now the mod builds!

We can implement a very basic display to give us the ping:

```csharp
namespace HogWarp.Replicated
{
    public partial class TestMultiActor
    {
        public partial void Pong(HogWarpSdk.Game.Player player, long time)
        {
            long elapsedTicks = DateTime.Now.Ticks - time;

            var logger = new HogWarpSdk.Systems.Logger("TestMultiActor");
            logger.Info($"Player {player.Id} has a latency of {elapsedTicks / 100} nanoseconds");
        }
    }
}
```

At this point everything is wired up, all we need is a `TestMultiActor` instance and to call our `Ping` function.

#### Actors

As explained above we need an instance of our Blueprint class, this implies that we need to create it somehow.

To create an Actor we use the `HogWarpSdk.Server.World.Spawn<T>()` function which will return an instance of our actor. We can call this function multiple times if we want to create multiple instances.&#x20;

```csharp
namespace Tutorial
{
    public class Plugin
    {
        public string Author => "HogWarp Team";
        public string Name => "My Awesome Plugin";
        public Version Version => new(0, 1);
        
        TestMultiActor? MyActor;

        public Plugin()
        {
            var logger = new HogWarpSdk.Systems.Logger("MyMod!");
            logger.Info("Hello, World!");
        }

        void SendPings(float Delta)
        {
            foreach (var player in HogWarpSdk.Server.PlayerSystem.Players)
            {
                MyActor!.Ping(player, DateTime.Now.Ticks);
            }
        }
        
        public void PostLoad()
        {
            MyActor = HogWarpSdk.Server.World.Spawn<TestMultiActor>()!;

            HogWarpSdk.Server.Timer.Add(SendPings, 5.0f);
        }
        
        public void Shutdown()
        {
        }
    }
}
```

I have also added a timer, that calls the `SendPings` function every 5 seconds. And as you can see the `SendPings` function will iterate over all connected players and call the Ping function on the instance  `MyActor`.&#x20;

{% hint style="info" %}
The Spawn function will create an instance on the server AND all the clients. If a new player joins the server, all actors that have been spawned will also be spawned for the new player.
{% endhint %}

If we build our server mod now, copy the DLL to the appropriate server directory, launch the server and connect to the server from the game client we will see every 5 seconds the latency of the player in the server console being logged.

<figure><img src="/files/Q2RdgmmDpoVjJo7BIKIp" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hogwarp.com/hogwarp/scripting/client-side/basics.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
