> For the complete documentation index, see [llms.txt](https://kinematicsoup.gitbook.io/reactor/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kinematicsoup.gitbook.io/reactor/architecture/messaging-rpcs.md).

# Messaging and RPCs

## Summary

How Reactor sends discrete events with remote procedure calls: room RPCs, entity RPCs, and batch entity RPCs, including targeting and delivery. It is part of the [Reactor Technical Overview](/reactor/architecture.md).

## Properties Versus RPCs

Properties sync continuous state and always hold the latest value. RPCs send one-off events: "took damage", "match started", "played a sound". Reach for a property when a client needs the current value at any time, and an RPC when something happens once and the moment matters. Both properties and RPCs carry their data as [`ksMultiType`](/reactor/architecture/ksmultitype.md).

## Defining a Handler

Tag a method with `[ksRPC(id)]` on a room or entity script. The id is a unique number that both sides agree on. A handler can take a `ksMultiType[]`, or it can list specific parameter types that `ksMultiType` converts to:

```csharp
[ksRPC(RPC.DAMAGE)]
public void OnDamage(ksMultiType[] args) { /* ... */ }

[ksRPC(RPC.DAMAGE)]
public void OnDamage(uint attackerId, float damage) { /* ... */ }
```

Handlers run on the main thread.

## Room RPCs

A room RPC invokes methods tagged with `[ksRPC(id)]` in room scripts. Call it on the server to reach clients, or on the client to reach the server:

```csharp
// Server to clients
Room.CallRPC(RPC.MATCH_STARTED, roundNumber);   // all players
Room.CallRPC(player, RPC.MATCH_STARTED, roundNumber);          // one player
Room.CallRPC(players, RPC.MATCH_STARTED, roundNumber);         // a list of players

// Client to server
room.CallRPC(RPC.REQUEST_RESPAWN);
```

Use room RPCs for events that concern the session rather than a single object.

## Entity RPCs

An entity RPC invokes methods tagged with `[ksRPC(id)]` on the targeted entity's scripts. On the server it reaches the players who can see that entity; on the client it reaches the server:

```csharp
// Server to observers of the entity
entity.CallRPC(RPC.PLAY_HIT, power);            // all observers
entity.CallRPC(player, RPC.PLAY_HIT, power);    // one player

// Client to server
entity.CallRPC(RPC.USE);
```

Use entity RPCs for events tied to one object, such as a hit reaction or an animation trigger.

## Batch Entity RPCs

A batch entity RPC calls the same RPC on many entities in one message. It encodes the entity list once with a single id and shared arguments, which costs less than one call per entity:

```csharp
// Server: same RPC across many entities at once
Room.CallBatchRPC(RPC.TAKE_DAMAGE, enemies, 10);

// Client to server
room.CallBatchRPC(enemies, RPC.HIGHLIGHT);
```

Reach for a batch RPC when one thing happens to a group at once, such as every enemy in range taking damage. The receiving client or server unpacks the batch and raises the call on each entity, so a receiving handler looks the same as for a single entity RPC.

## Arguments and Delivery

* **Arguments**: values carried as [`ksMultiType`](/reactor/architecture/ksmultitype.md).
* **Direction**: client to server, and server to client.
* **Delivery**: reliable and in order over the connection.
* **Cluster RPCs**: a separate attribute sends RPCs room to room across a cluster, and these are the only RPCs that may run off the main thread. See [Room-to-Room Data and RPCs](/reactor/tutorials/cluster_data_and_rpcs.md).

> *Targeted server calls skip virtual players, since a bot has no client to receive them.*

## Where to Go Next

* [Automatic Client Data Syncing](/reactor/architecture/data-syncing.md): sync continuous state instead of sending events.
* [Server Object Model](/reactor/architecture/server-object-model.md): the rooms and entities you call RPCs on.
* [Networked Properties and RPCs](/reactor/tutorials/properties_and_rpcs.md): build with properties and RPCs.
