User Tools

Site Tools


This is an old revision of the document!


The networking API can be used to make a mod multiplayer-compatible.

Note: It is possible to write multiplayer-compatible mods without using the networking API because certain things (for example placing blocks, triggering logic chains) are networked automatically by the game. For many mods it may however be necessary to transmit additional information over the network connection in multiplayer. That is what the networking API is for.

Using the networking API is generally done in three steps:

  • Creating message types
  • Sending messages
  • Acting on received messages

Message Types

Every message sent must conform to a pre-defined type. These are created using the ModNetworking.CreateMessageType function, which returns a MessageType object.

Message types are global in your mod and it is important that they are always created by the mod in the same order. The recommended way is to create them in OnLoad or OnPrefabCreation and then store them in static variables to access throughout the mod.

Example of creating and storing a message type:

using Modding;
using Modding.Blocks;
public static class Messages {
    public static MessageType Example;
public class YourEntryPoint : ModEntryPoint {
    public override void OnLoad() {
        Messages.Example = ModNetworking.CreateMessageType(DataType.Single, DataType.Block);

As you can see, you can pass a list of DataType values to the CreateMessageType method. This is necessary for sending any kind of data along with the message and determines what types of objects and in what order they can be sent and received.

List of available DataTypes and their corresponding types:

DataType Type Other accepted types
Boolean bool
Color UnityEngine.Color
Integer int
IntegerArray int[]
Single float
SingleArray float[]
String string
StringArray string[]
ByteArray byte[]
Vector3 UnityEngine.Vector3 Modding.Serialization.Vector3
Block Modding.Blocks.Block BlockBehaviour
Entity Modding.Levels.Entity LevelEntity
Machine Modding.Blocks.PlayerMachine Machine

Types in the “Other accepted types” column can be passed when sending a message but, regardless of what type was passed in, you will always receive objects from the “Type” column.

Every mod may register at most 255 message types.

Sending Messages

The first step of sending a message is to create a Message object. This is done by calling the CreateMessage method of a previously-created MessageType. The method must be passed one object for each of the DataTypes passed to CreateMessageType. These must also appear in the same order as in CreateMessageType.

To send the created message, call the appropriate Send method in ModNetworking:

  • SendToAll(Message) sends the given message to all connected instances.
  • SendTo(Player, Message) sends the given message only to the given player.
  • SendInSimulation(Message) sends the message to all instance participating in the current simulation. This may mean no player (not in simulation, in local simulation) or all players that are currently not in local simulation (in global simulation).

Continuing the example from above:

float x = <compute some float>;
Block b = <get some block>;
Message message = Messages.Example.CreateMessage(x, b);

Receiving Messages

To receive messages, a mod must register a callback to at least one of two events: ModNetworking.MessageReceived or ModNetworking.Callbacks[MessageType]. Both events require callbacks that take exactly one argument: a Message object.

The first event is fired for every message sent by the mod.

Using the second form, it is possible to register different callbacks for different message types. If exampleType was a MessageType instance, callbacks registered to ModNetworking.Callbacks[exampleType] will be called for every message with the given type that is received. (Registering callbacks works the same way it does for normal events, i.e. ModNetworking.Callbacks[exampleType] += MyCallbackMethod; or += (msg) ⇒ {<code>};)

Either way, a callback receives a Message object.

The Message object exposes who sent the message with the Sender property (of type Player) and the data attached to it with the GetData(int) method.

Indices passed to GetData correspond to the position of the objects in the CreateMessage (or, equivalently, CreateMessageType) call.

Concluding the example:

public override void OnLoad() {
    Messages.Example = ...;
    ModNetworking.Callbacks[Messages.Example] = msg => {
        Debug.Log($"Received a message from {msg.Sender.Name}, x = {(float)msg.GetData(0)}, b = {((Block)msg.GetData(1)).Guid}!");
besiege/modding/networking.1532440832.txt.gz · Last modified: 2018/07/24 16:00 by spaar