Client-Server Communication
Multiplayer games usually require the server and client to have communication. This is done by creating a server-side module and client-side scripts that send events to one another.
Overview
Here is a quick overview on setting up client to server communication:
- Create the server module using a TypeScript class extending the
BaseModule
. - Include this module in the list within the
ServerConfig.json
file. - Create a client script using TypeScript and use the
NetworkEventManager
to listen or trigger server events.
Server Code
The Server folder is within the root Unity project folder (outside of the Assets folder) and contains the necessary server code and custom server modules.
Server Module Libraries
Under the Server > src > Core folder, there are multiple server module scripts. These are the essential libraries that custom modules will import.
Server Module Examples
Under the Server > src > Examples folder, there are multiple custom server module scripts that have useful examples with logic such as collectibles, physics, and NPCs.
Updating Server Config
The ServerConfig.json file needs to be updated to include new server modules scripts. Only update the ServerConfig.json file located in the Assets > Experience > Server folder.
See the example below for how to add a custom server module to the ServerConfig.json file.
Updating Server Code
Once a custom server script module is created and added to the server config file, the server code needs to be updated.
If using the localhost server target, then the server code is automatically updated with any changes. If using remote server target, then use the sync and verify server code buttons in the Multiplayer window after changing or adding any server code.
Server Module API
The server module script uses the SFS2X API instead of the Unity API.
SFS2X Namespace
The Smart Fox Server API has its classes in the SFS2X
namespace for the server module scripts to use.
Here is an example line of code to import the SFSUser
class:
type SFSUser = SFS2X.Entities.SFSUser;
Check out the SmartFoxServer 2X C# API documentation for more information.
Server Libraries
One key difference is the server-specific libraries available are all within the Unity project root folder Server > src > Core.
Here is an example line of code to import the BaseModule class:
import { BaseModule } from "Core/Modules/BaseModule";
Open the BaseModule.ts file to see the inherited methods when creating a custom server module such as init
or onUserJoined
.
Trace Method
This method will display a string to the server logs:
trace(message: string)
The server logs are visible using the Multiplayer window section named Remote Server Logs.
Add Request Handler Method
This method will connect a listener function to a specific event:
addRequestHandler(eventName: string, listenerFn: reqHandlerFn)
Send Method
This method will trigger a specific event to certain user recipients with any necessary parameters:
send(eventName: string, params: any, recipients: SFSUser[])
Network Event Manager API
The NetworkEventManager
class manages all the events being sent across the server and the client. Client scripts can use it to listen and trigger server events.
import {NetworkEventManager} from "Genies.Components.Sdk.External.Multiplayer";
let eventManager: NetworkEventManager;
//Listen to server events
eventManager.AddListener();
//Trigger server events
eventManager.SendServerRequestAsync();
TypeScript Example
Here are three example scripts to create client to server communication.
Server Module Script
Here is an example script of a server module communicating with client scripts:
type SFSUser = SFS2X.Entities.SFSUser;
type BaseEvent = SFS2X.BaseEvent;
import { BaseModule } from "Core/Modules/BaseModule";
export class ServerModule extends BaseModule {
public name: string = "ServerModule";
private _usersJoined: SFSUser[] = [];
public constructor() {
super();
trace(`Server Module is created!`);
}
public init(modules: any): void {
//Adding listener method to event
addRequestHandler("start_game", this.onStartGame.bind(this));
trace(`Server Module is initialized!`);
}
public destroy(): void {
trace(`Server Module is destroyed!`);
}
public onUserJoined(event: BaseEvent): void {
var user = event.getParameter(SFSEventParam.USER);
this._usersJoined.push(user);
}
public onUserDisconnected(event: BaseEvent): void {
try {
var user = event.getParameter(SFSEventParam.USER);
this._usersJoined = this._usersJoined.filter(u => u !== user);
trace(`User disconnected: ${user.name} total users: ${this._usersJoined.length}`);
} catch (error) {
trace(`[delayStart] Error: ${error} | ${error.stack}`);
}
}
private onStartGame(params: any, user: SFSUser): void {
trace(`Received start game from client!`);
//Trigger an event
send("on_start_game", new SFSObject(), this._usersJoined);
}
}
Server Config JSON File
Here is the necessary module reference in the ServerConfig.json file for the server module to be recognized:
{
"v": 1,
"sdkVersion": "0.0.4",
"playerEnabled": true,
"itemsEnabled": true,
"inventoryEnabled": true,
"rewardsEnabled": true,
"storeEnabled": true,
"modules": [
{
"modulePath": "Examples/ServerModule.js",
"className": "ServerModule"
}
]
}
The module needs to be referenced as a .js
file in order for it to work with the Smart Fox Server API.
Client Script
Here is an example client script to communicate with the server module:
import { NetworkEventManager, NetworkPlayerManager } from "Genies.Components.Sdk.External.Multiplayer";
import { NetworkPlayer } from "Genies.Components.Sdk.External.Multiplayer.Player";
import { SFSObject } from "Sfs2X.Entities.Data";
import { MonoBehaviour } from "UnityEngine";
export default class ClientScript extends MonoBehaviour {
public playerManager: NetworkPlayerManager;
public eventManager: NetworkEventManager;
private Awake() : void {
this.playerManager.OnLocalPlayerCreated.AddListener(this.OnLocalPlayerCreated);
//Adding listener method to event
this.eventManager.AddListener("on_start_game", this.OnStartGame);
}
private OnStartGame(command: string, data: SFSObject): void {
console.log("Received start game from server!");
}
public OnLocalPlayerCreated(player: NetworkPlayer): void {
console.log("Local player created");
//Triggering an event
this.eventManager.SendServerRequestAsync("start_game", new SFSObject());
}
}