Menu
Lumberyard
Developer Guide (Version 1.11)

RMI Functions

To send remote method invocations (RMIs), use the InvokeRMI function, which has the following syntax:

Copy
void InvokeRMI( IRMIRep& <rep>, ParamsType&& <params>, uint32 <where>, ChannelId <channel> = kInvalidChannelId );

Parameters

<rep>

Represents the remote function to be called (the RMI ID).

<params>

Specifies the parameters to pass into the remote function.

<where>

Specifies a flag that determines the category of clients to which the RMI will be sent. For information, see the RMI Function Flags section later in this document.

<channel>

Specifies specific clients to which the RMI will be sent, or specific clients to exclude. For information, see the RMI Function Flags section later in this document.

Ordering RMI Functions

The IGameObject.h file includes macros for declaring RMI classes (for example, those beginning with DECLARE_SERVER_RMI_<...>). The different declaration types are as follows:

  • PREATTACH – The RMI is attached at the top of the data update for the object. You can use this declaration type to prepare the remote entity for new incoming data.

  • POSTATTACH – The RMI is attached at the bottom of the data update, so it is called after the data is serialized. You can use this declaration type to complete an action with the new data.

  • NOATTACH – The RMI is not attached to a data update, so the RMI cannot rely on the data. You can use this declaration type for calls that don’t rely on data.

Ordering Rules

The order for RMIs is only applicable within an object and attachment type set.

For example, in the following ordered list, PLAYER RMI 1, 2, and 3 will arrive in that order; however, ITEM RMI 1 might arrive before or after the following PLAYER RMIs:

  • PLAYER RMI 1

  • PLAYER RMI 2

  • ITEM RMI 1

  • PLAYER RMI 3

Using declaration types adds a layer of complication to the order of incoming data:

  • PREATTACH – Messages are ordered within themselves.

  • POSTATTACH – Messages are ordered within themselves.

  • NOATTACH – Messages are ordered within themselves; however, NOATTACH can only fall on either side of the following diagram and never in between:

RMI Function Flags

To specify the clients that will receive an RMI, replace the <where> parameter in the InvokeRMI function with one of the following flags.

Server RMIs

eRMI_ToClientChannel

Sends an RMI from the server to a specific client. Specify the destination channel in the <channel> parameter.

eRMI_ToOwningClient

Sends an RMI from the server to the client that owns the actor.

eRMI_ToOtherClients

Sends an RMI from the server to all clients except the client specified. Specify the client to ignore in the <channel> parameter.

eRMI_ToRemoteClients

Sends an RMI from the server to all remote clients. Ignores the local client.

eRMI_ToOtherRemoteClients

Sends an RMI from the server to all remote clients except the remote client specified. Ignores the local client. The remote client to ignore is specified in the <channel> parameter.

eRMI_ToAllClients

Sends an RMI from the server to all clients.

Client RMIs

eRMI_ToServer

Sends an RMI from the client to the server.

Examples

To define a function to be implemented as RMI, use the IMPLEMENT_RMI #define from IGameObject.h.

Copy
#define IMPLEMENT_RMI(cls, name)

The following example implements a new function called Cl_SetAmmoCount in the CInventory class to be used as a client-side RMI, taking one argument of type TRMIInventory_Ammo:

Copy
Class CInventory : public CGameObjectExtensionHelper<CIventory, IInventory> { // … DECLARE_CLIENT_RMI_NOATTACH(Cl_SetAmmoCount, TRMIInventory_Ammo, eNRT_ReliableOrdered); // … }; IMPLEMENT_RMI(CInventory, Cl_SetAmmoCount) { // Game code: TRMIInventory_Ammo Info(params); IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(Info.m_AmmoClass.c_str()); If (pClass) SetAmmoCount(pClass, Info.m_iAmount); return true; // Always return true - false will drop connection } The following line will invoke the function: pInventory->GetGameObject()->InvokeRMI(CInventory::Cl_SetAmmoCount(), TRMIInventory_Ammo(“Pistol”, 10), eRMI_ToAllClients);

The following line will invoke the function:

Copy
pInventory->GetGameObject()->InvokeRMI(CInventory::C1_SetAmmoCount(), TRMIInventory_Ammo("Pistol", 10), eRMI_ToAllClients);