RemoteCall (old syntax)

Jump to: navigation, search
Note: This is an older version of RemoteCall, which is no longer used as much. For the newer version of RemoteCall which allows the arguments to be used directly in the statement itself, see RemoteCall2


RemoteCall(variableData as Class RemoteCallOut)

RemoteCallClient(variableData as Class RemoteCallClientOut)

RemoteCallServer(variableData as Class RemoteCallServerOut)


These functions allow for Inter-Process Communication between different parts of HeroEngine engine, such as from one server to another, or between a client and server.

Note: There are two methods of performing a RemoteCall. This page documents the method that involves setting the details in a separate variable. To perform a remote call where the details are directly in the function call, use RemoteCall2 instead.


To make a RemoteCall, a variable of a particular class must be initialized with the data necessary. It contains different fields that specify things such as the destination of the call, the function to be called, and fallback data such as what function to call if the initial attempt does not work.

The destination function that is being called must also be a special function that is prepared to work with a remote call. If it is being called by a server, it must be prepended with the modifier keyword REMOTE. If it is being called by a client, it must be prepended with the modifier UNTRUSTED. This is a reminder that all calls originating from a client must be suspect as potentially hacked, so an extra level of verification should be used to protect the game from malicious actions.

Data is initially generated via an "out" class variable, but is received in the destination function via a different variable, of a particular "in" class. Please see the below table to ensure that the proper class is being used.

Direction Function Name Destination Function Modifier Fail Function Modifier Outgoing Data Class Incoming Data Class
Server to server RemoteCall() REMOTE REMOTE RemoteCallOut RemoteCallIn
Server to client RemoteCallClient() REMOTE UNTRUSTED RemoteCallClientOut RemoteCallServerIn
Client to server RemoteCallServer() UNTRUSTED REMOTE RemoteCallServerOut RemoteCallClientIn

Field definitions for the Remote Call classes

Important: Never add new fields to any of the RemoteCall classes

Fields common to all six classes:

Scope Field Name Description
All classes toScript A script ref which specifies the script that is being sought. In the case of a script calling a script of the same name (a version of itself) that is in a different location, it is acceptable to simply declare this as SYSTEM.EXEC.THISSCRIPT
All classes toFunction The function that is being sought
All classes failScript A script reference which contains the function which will handle things if the call does not work.
All classes failFunction The function which handles things if the call does not work, or if it generates a script error. This function must be in a script which is in the calling location (so for a call from a client to the server, this function must exist on the client). The function must be remote-callable, with the REMOTE (on the client) or UNTRUSTED (on the server) modifier, as appropriate. The incoming data class for the failure function will be the same as it would be for any other receiving function. In other words, RemoteCallServerIn if it is on a client, or RemoteCallClientIn (or RemoteCallIn) if it is on a server.
All classes args A lookup list indexed by string of string which contains the data that is being passed to the remote function. If it is desired to use complex or non-string data, then Serialization and the SplitBy() function can be used. See the Code Snippets page for examples.

And two of the classes have a special additional data structure:

Scope Field Name Description
RemoteCallOut toInstance Structure to hold the AreaID and AreaInstanceNumber of the area that is being called. An AreaID of 0 refers to the World Server.
RemoteCallClientOut toPlayer An account node, which specifies which client gets the call

Note: The toInstance fields are not required for Client calls, since for security reasons, a client is only allowed to talk to the specific instance of the area that it is connected to, via a function that is clearly labeled with the UNTRUSTED modifier.

At the receiving end

If the remote call is successful, data is passed to the destination function, in a different "in" class.

The "in" classes have the following fields:

Scope Field Name Description
All classes fromScript The script that generated the call
All classes fromFunction The function which generated the call
All classes toScript The script that was called
All classes toFunction The function that was being sought
All classes args A lookup list indexed by string of string which contains the data that is being passed
RemoteCallIn fromInstance Structure to hold the AreaID and AreaInstanceNumber of the server that made the original call
RemoteCallIn toInstance Structure to hold the AreaID and AreaInstanceNumber of the server that was being called

The reason that the RemoteCallIn class has additional fields, is to allow for calls between servers, or for such things as an Area Server communicating between two different instances. Client communications, however, do not use these fields because for security reasons, a client can only communicate with the specific instance of the Area Server that it is connected to.

In the event of an error

If an error occurs, the field RemoteError will include a string which lists the error.


Making a call from a script in one instance, to the function MyRemoteCalledFunc in a script of the same name on Area 1, Instance 0.

public function makeRemoteCall()   // This initializes the data for the call
  myid as id = me
  rmc as class RemoteCallOut
  rmc.toFunction = "MyRemoteCalledFunc"
  rmc.failFunction = "MyRCFailHandler"
  rmc.args["myid"] = myid
  remoteCall(rmc)                 // This makes the call
remote function MyRemoteCalledFunc ( rmc as class RemoteCallIn)   // This would be the destination function being called
  myid as id = rmc.args["myid"]
  msgplayer(myid, "rc got script="+rmc.fromFunction+" area="+rmc.fromInstance.AreaID+":"+rmc.fromInstance.AreaInstanceNumber)
remote function MyRCFailHandler(rmc as class RemoteCallIn)    // This is the function on the calling server,
  myid as id = rmc.args["myid"]                               //  that would handle a fail condition
  msgplayer(myid, "rc fail script="+rmc.fromScript+" func="+rmc.fromFunction+" area="+rmc.fromInstance.AreaID+":"rmc.fromInstance.AreaInstanceNumber)

// variable initialization of RemoteCallServerOut, for a call from a client, to a server:
  rout as Class RemoteCallServerOut
  rout.toScript = "CommandHandler"
  rout.toFunction = "OrderPizza"
  rout.failScript = SYSTEM.EXEC.THISSCRIPT           
  rout.failFunction = "PizzaNoAnswer"
  rout.args["kind"] = "cheese"
  // a server-side handler for calls from the client
untrusted function OrderPizza( rin as class RemoteCallClientIn)
  s as string = "The server got your call from script "+rin.fromScript
  s = s + " function "+rin.fromFunction
  MsgPlayer(me, "", s)    // "me" is the node of the character whose client sent the call

// a client-side handler for calls from the server
remote function ShowAcceptCoinDialog( rin as class RemoteCallServerIn) 
  // your code here

See also

Personal tools