MigrationGuidePart03RemoteProcedureCalls

Why Alteruna RPCs aren't split into client-to-server and server-to-client directions, and what to call instead.

Remote procedure calls

Netcode and FishNet split RPCs by direction - a client can only call [ServerRpc], the server can only call [ClientRpc]/[ObserversRpc] - because both frameworks assume a real client/server split exists. Alteruna doesn't assume that, so [SynchronizableMethod] has no direction baked in: it's one call shape, and you choose the audience instead. Fusion's newer unified [Rpc] attribute (RpcSources/RpcTargets) is the closest thing to Alteruna's model here - it also replaced Photon's own older direction-based [PunRPC] for the same reason.

C#
[SynchronizableMethod]
void TakeDamage(int amount) => hp -= amount;
void Fire() => BroadcastRemoteMethod(nameof(TakeDamage), 10);
C#
[PunRPC]
void TakeDamage(int amount) => hp -= amount;
void Fire() => photonView.RPC(nameof(TakeDamage), RpcTarget.All, 10);
C#
[Rpc(RpcSources.All, RpcTargets.All)]
void TakeDamage(int amount) => hp -= amount;
void Fire() => TakeDamage(10);
C#
NetworkVariable<int> hp = new(100);

// Netcode requires ServerRpc methods to end in "ServerRpc".
[ServerRpc]
void TakeDamageServerRpc(int amount) => hp.Value -= amount;
void Fire() => TakeDamageServerRpc(10);
C#
readonly SyncVar<int> hp = new(100);

// FishNet has no naming rule for RPC methods.
[ServerRpc]
void TakeDamage(int amount) => hp.Value -= amount;
void Fire() => TakeDamage(10);

Need a single target instead of everyone? Swap BroadcastRemoteMethod (always includes the sender) for InvokeRemoteMethod, which takes a UserId or a List<ushort> - the audience argument does the job Photon's RpcTarget enum, Fusion's RpcTargets, and Netcode's Server/Client split do separately.

Watch the difference between the two "everyone" targets, since it's easy to get backwards:

  • UserId.All (the default) sends to every other client and skips the sender - the equivalent of Photon's RpcTarget.Others.
  • UserId.AllInclusive sends to everyone, the sender included - the same audience as BroadcastRemoteMethod, and the equivalent of Photon's RpcTarget.All.
C#
InvokeRemoteMethod(nameof(TakeDamage), UserId.All, 10);          // everyone except me
InvokeRemoteMethod(nameof(TakeDamage), UserId.AllInclusive, 10); // everyone, me included

This guide only covers the mapping from other frameworks. For the full breakdown of InvokeRemoteMethod vs BroadcastRemoteMethod, targeting specific users, and speeding up repeated calls with GetMethodAttributeId, see Developer Guide Part 02 - Remote Procedure Calls.



← Back | Next →

See Also