This document is about: FUSION 2
SWITCH TO

Remote Procedure Calls

Introduction

Remote Procedure Calls, simply referred to as RPCs, are ideal for sharing punctual game events; in contrast the Input Struct and [Networked] properties are the go-to solutions for sharing state between network clients that are undergoing continuous change.

For example when a player wants to perform a rare complex interaction with an object that it does not have Input Authority over such as using a specific key from their inventory to open a locked door. Although the actions can technically be achieved by including additional fields as part of the input, it would clutter the Input Struct and make it unwieldy.

Furthermore, Input Structs are sent as unreliable messages, i.e. packets may be lost. This is rarely noticeable for things requiring continuous input (e.g. character movement), but will be harmful to player experience when this affects single one-time actions which players expect to be guaranteed. In this situation a Remote Procedure Call is the best practice.

Setup

Fusion has a simple yet powerful syntax for RPCs. There are generally speaking 3 types of RPCs:

  1. Instance RPCs;
  2. Static RPCs; and,
  3. Targeted RPCs.

Each one of these types will be presented in the following sections.

Instance RPC

To define an RPC on any NetworkBehaviour on a NetworkObject simply follow these steps:

  1. Declare a regular CSharp method of return type void or RpcInvokeInfo (Documented below);
  2. Pre- or post-fix the method name with "RPC" (case insensitive);
  3. Add the [Rpc] attribute in front of the method declaration; and,
  4. Configure the RpcSources and RpcTargets parameters to control where the RPC may be called from and where it gets executed.

C#

[Rpc(sources: RpcSources.InputAuthority, targets: RpcTargets.StateAuthority)]
public void RPC_Configure(string name, Color color){
    playerName = name;
    playerColor = color;
}

Note: RPCs must have a "rpc" pre- or post-fix in the method name (not case-sensitive).

Static RPC

Static RPCs follow slightly different rules, they:

  • ignore the RpcSources and RpcTargets parameters; and
  • require the first parameter of the method to be NetworkRunner.
  • can be implemented on any SimulationBehaviour (not just NetworkBehaviour), as the callback receiver is not bound to a particular NetworkObject.

Because there is no source and target filter, static RPCs can be called from any client and will be sent to all clients. Do note that you can still target the RPC to a specific PlayerRef (See "Targeted RPC") to control who will receive the call.

C#

[Rpc]
public static void Rpc_MyStaticRpc(NetworkRunner runner, int a) { }

RPC Attribute Parameters

Sources and Targets

RpcSources and RpcTargets are filters. The RpcSources define which peers can send the RPC, whereas the RpcTargets define on which it is executed.

  • All: can be sent / is executed by all peers in the session (including the server).
  • Proxies: can be sent / is executed by a peer who does not have either Input Authority or State Authority over the object.
  • InputAuthority: can be sent / is executed by the peer with Input Authority over the object.
  • StateAuthority: can be sent / is executed by the peer with State Authority over the object.

IMPORTANT: RPCs do not have an explicit state. Clients who late-join and clients who disconnect & reconnect will forget it ever happened. It is therefore crucial to ensure an RPC is either:

  • truly transient without any state (e.g. a chat message); or,
  • has its effect indirectly recorded in a [Networked] property.

C#

public class Player : NetworkBehaviour {
    [Networked] public string playerName { get; set; }
    [Networked] public Color playerColor { get; set; }
    
    [Rpc(RpcSources.InputAuthority, RpcTargets.StateAuthority)]
    public void RPC_Configure(string name, Color color)    {
        playerName = name;
        playerColor = color;
    }
}

Optional RPC Attribute Parameters

In addition to the RpcSources and RpcTargets properties, the [Rpc] attribute offers several optional parameters.

  • Channel (default Reliable): Set to Unreliable if the RPC can be lost in transmission.
  • InvokeLocal (default true): True indicates that the RPC will be invoked on the local client.
  • TickAligned (default true): Set to false if you do not want the receiving end to delay execution of the RPC until at or after the tick in which in was sent.

C#

[Rpc (RpcSources.All, RpcTargets.All, InvokeLocal = true, TickAligned = false )]
void RpcStartBoost(){
    m_BoostAnim.StartBoostAnimation();
}

RPC Method Parameters

RPC are serialized at runtime. It is therefore recommended to use the regular CLR types (e.g.: bool) over the Fusion specific ones (e.g. NetworkBool).

Allowed Data Parameters

  • Primitives
    • byte, sbyte
    • Int16, Int32, Int64
    • UInt16, UInt32, UInt64
    • float
    • double
    • float
    • double
  • Unity struct types (defined in ILWeaver.cs)
    • Vector2, Vector3, Vector4
    • Quaternion
    • Matrix4x4
    • Vector2Int, Vector3Int
    • BoundingSphere
    • Bounds
    • Rect
    • BoundsInt
    • RectInt
    • Color, Color32
  • System.Guid
  • User Defined INetworkStructs
  • Fusion Defined INetworkStructs
    • NetworkString<IFixedStorage>
    • NetworkBool
    • Ptr
    • Angle
    • BitSet64, BitSet128, BitSet192, BitSet256
    • PlayerRefSet
    • NetworkId
    • NetworkButtons
    • NetworkRNG
    • NetworkObjectGuid
    • NetworkPrefabRef
    • NetworkObjectHeader
    • NetworkPrefabId
    • SceneRef
    • TickTimer
    • IFixedStorage (_2, _4, _8, _16, _32, _64, _128, _256, _512)
  • Fusion Types
    • NetworkObject (serialized as NetworkId)
    • NetworkBehaviour (serialized as NetworkId and the NetworkBehaviour index)
    • PlayerRef (serialized as PlayerRef.PlayerId)
  • Strings
  • Arrays of any of the types listed above

RpcInfo

RPC method declarations can take a optional parameter of type RpcInfo, which exposes the following meta information about the RPC:

  • Tick: at which tick was it sent.
  • Source: which player (PlayerRef) sent it.
  • Channel: was it sent as an Unreliable or Reliable RPC.
  • IsInvokeLocal: was it the local player who originally invoked this RPC.

C#

[Rpc(sources: RpcSources.InputAuthority, targets: RpcTargets.StateAuthority)]
public void RPC_Configure(string name, Color color, RpcInfo info = default){
    playerName = name;
    playerColor = color;
}

The parameter is always declared as RpcInfo info = default.

Server vs Host Source

When using Fusion in ServerMode, an the RpcInfo.Source included with an RPC sent by the Server will be set to PlayerRef.None as the server is not a player.

When using Fusion in HostMode, however, the host-client runs both a server and a player. By default any RPC sent by the Host will function identically to the Server and set RpcInfo.Source to PlayerRef.None. To include the Host's local PlayerRef instead, the HostMode attribute has to be set to RpcHostMode.SourceIsHostPlayer.

The HostMode can be set to one of two modes:

  • RpcHostMode.SourceIsServer (default): the RpcInfo.Source is set to PlayerRef.None.
  • RpcHostMode.SourceIsHostPlayer: the RpcInfo.Source is set to the local PlayerRef when Fusion is running in HostMode.

To include the host's PlayerRef in the RpcSource.Info the previous snippet can be adjusted as follows:

C#

[Rpc(sources: RpcSources.InputAuthority, targets: RpcTargets.StateAuthority, HostMode = RpcHostMode.SourceIsHostPlayer)]
public void RPC_Configure(string name, Color color, RpcInfo info = default){
    playerName = name;
    playerColor = color;
}

RpcInvokeInfo

RPC methods may optionally define RpcInvokeInfo as a return value. When the RPC method is invoked, the RpcInvokeInfo return value will contain information about the RPC invoke and send operations.

  • LocalInvokeResult: RpcLocalInvokeResult enum value indicating success or cause of failure of the local invoke action.
  • SendCullResult: RpcSendCullResult enum value indicating the success or cause of failure of the RPC invocation for remote peers.
  • SendResult: RpcSendResult struct containing meta information about the RPC send operation.
    • Result: RpcSendMessageResult result flags for this RPC message send operation.
    • MessageSize: Size of RPC package.
    • Receivers: A collection of the PlayerRefs included as receivers for this RPC operation.
    • CulledReceivers: A collection of the PlayerRefs which were culled and excluded as receivers from this RPC send operation.

Note: that this is NOT information about delivery success or failure, but rather only the results of the invoke and send operations.

C#

[Rpc]
public RpcInvokeInfo RpcFoo() {
  // RPC action
  return default;
}
 
public override void FixedUpdateNetwork() {
  var info = RpcFoo();
  Debug.Log(info);
}

Targeted Rpc

When an RPC is meant to be exclusively executed on a specific player's machine, targeted RPCs are used. Both Instance RPCs and Static RPCs can be turned into targeted RPCs by adding a PlayerRef parameter prefaced by the [RpcTarget] attribute. A typical use-case is team chat where a message is only meant for the specific players on one's own team.

Note: Passing PlayerRef.None for the [RpcTarget] parameter will target the server!

C#

[Rpc(sources: RpcSources.InputAuthority, targets: RpcTargets.All)]
public void Rpc_TargetedInstanceMessage([RpcTarget] PlayerRef player, string message){}

Or

C#

[Rpc(sources: RpcSources.InputAuthority, targets: RpcTargets.All)]
public static void Rpc_MyTargetedStaticMessage(NetworkRunner runner, [RpcTarget] PlayerRef player, string message) { };

IMPORTANT: The [RpcTarget] attribute used within the method the declaration is DIFFERENT from the RpcTargets parameter inside the [Rpc] attribute placed in front of the method declaration.

Back to top