Skip to main content

RPC & Server-side Game Logic

RPC in PlayServ is a mechanism for running game logic on the game server. Server-side code is authored in the client codebase, marked for discovery, extracted by the code analyser during deployment, and executed on the server runtime.


When to use RPC

Use RPC when you need gameplay logic to execute on the game server in order to reduce cheating risk and avoid exposing important scenarios to the client build.

info

PlayServ does not rely on running a full headless game engine runtime on the server, as is common in some traditional multiplayer architectures. Instead, PlayServ analyses the game code, discovers server-side code, and deploys only that server-side code to the server runtime.

Server logic is described in separate classes from the client gameplay code. This enables local execution and debugging, but requires binding server code where it is used.


Server-side execution model

Server logic is written by client developers in the client codebase, but must be explicitly described so the code analyser can detect it and upload it to the server during deployment.

A minimal example of a server class:

[Server]
public class Domain
{
// May contain state
bool flag = true;

public void RollDice(int dice)
{
flag = dice % 2 > 0;

var player = PlayServ.GetPlayer("a123");
player.Name = "Vasya";
player.Update();
}

public string DoSomethingCool(int dice)
{
return flag ? "Ice!" : "Nice";
}
}

Calling that server code from client code:

class CustomBehaviour : NetworkBehaviour
{
// Allows local debugging and remote execution
private Domain _domain = PlayServ.Remote(Domain);

public void Init(Vector3 velocity, PlayerRef owner)
{
_domain.RollDice(1);
_domain.DoSomethingCool(); // "Ice!"
}
}

Calling SDK from server-side code

Server-side code in PlayServ has access to the SDK, which enables implementing a fully featured game server.

The SDK used to compile server-side code includes the same transport protocol used by SDK service modules to exchange signals with each other. This allows server-side code to act as an SDK client when calling other server-side code or platform modules.

Unlike a regular game client, server-side code does not need to connect to the Proxy Module. Its signals are routed directly to the bus and then delivered to the final recipients.


Server-to-server calls and bundling

warning

If a server class calls another server class, the called server classes may not be included in the server bundle (Archive.zip).

Because of that, the server-side analyser replaces such references with an RPC-facing stub and generates a proxy class with method stubs that perform RPC invocations.

// Instead of:
private RPC_Domain _domain = PlayServ.Remote(RPC_Domain);

// Use:
PlayServ.Remote("Domain").Invoke("DoSomethingCool", params);

Static server classes

An alternative approach is to use static server classes. This removes the need to initialise server domains and allows the analyser to detect calls to [Server] methods and replace them with RPC calls more reliably.


Next step

Continue with Extending SDK Components to understand how to extend SDK behaviour using handlers and middleware-style pipelines.

For related topics: