Show / Hide Table of Contents

RPCs

An RPC (Remote procedure call) is the Slipe representation of server to client & client to server communication.

RPCs are sent and received through the RpcManager (Server documentation, Client documentation)

RPCs work somewhat similar to how client & server events do in MTA, where you will register a function to be called when an RPC is triggered.

RPC payload classes

In an RPC you can send a single object / instance of a class (or enum) along with any trigger. This means you will have to define a class to encapsulate the values you want to transmit from server to client, or the other way around.

An RPC payload is a simple class which implements the IRpc interface. Any RPC payload class will have 3 methods:

  • A (parameterless) default constructor
    This constructor is used internally, when it's missing Visual Studio will show an error
  • A constructor for passing in data
    This is the constructor used by your code to populate the RPC payload (this is optional)
  • A Parse method This is the method which parses a single Lua table value back to the payload class

Here's an example:

public class ElementRpc: BaseRpc
{
    public Element Element { get; set; }

    public ElementRpc()
    {

    }

    public ElementRpc(Element element)
    {
        this.Element = element;
    }

    public override void Parse(dynamic value)
    {
        this.Element = GetElement<Element>(value.Element);
    }
}

It is import that you cast the data in value to the appropriate types when using incoming RPCs. Because when transferring over the network all metatable data (which class / datatype something is) is lost.
The abstract BaseRpc class has several methods to make this process easier.

Registering an RPC

In order to register an RPC you have to call the RegisterRPC method on the singleton Instance of the RpcManager. The RegisterRPC method is a generic method, meaning you need to supply a type argument, this type argument is the IRpc payload class type you wish to receive.

RpcManager.Instance.RegisterRPC<ElementRpc>("announce", HandleAnnouncement);

public void HandleAnnouncement(Player player, ElementRpc rpc)
{
    ChatBox.WriteLine(rpc.Element.Type);
}

Triggering an RPC

Trigger RPCs is quite easy. You use the TriggerRpc method on the RpcManager.

Client:

RpcManager.Instance.TriggerRPC("announce", new ElementRpc(Player.Local));

Server:

// send to a specific player
Player nano = (Player)Player.GetFromName("SAES>Nanobob");
RpcManager.Instance.TriggerRPC(nano, "testRPC", new ElementRpc(someElement));

// send to everyone
RpcManager.Instance.TriggerRPC(Element.Root, "testRPC", new ElementRpc(someElement));

Async RPCs

Async RPCs allow you to return a value over an RPC, and use async / await in order to use it. You will no longer need to bounce RPCs back and forth to get a value from the server to the client or vice versa.

Example: Server:

RpcManager.Instance.RegisterAsyncRPC<SingleCastRpc<string>, EmptyRpc>("Async.RequestMapName", (player, request) =>
{
    return new SingleCastRpc<string>(GameServer.Announcement.MapName);
});

Client:

Task.Run(async () =>
{
    string name = (await RpcManager.Instance.TriggerAsyncRpc<SingleCastRpc<string>>("Async.RequestMapName", new EmptyRpc())).Value;
    ChatBox.WriteLine($"Map name: {name}");
});
``
  • Improve this Doc
Back to top Generated by DocFX