Skip to main content

Usage

Add NetCluster Plugin

  • Clone the NetClusterPlugin from GitHub and place it in [ProjectFolder]/Plugins/NetCluster.
  • Configure Project.uproject to use the NetCluster Plugin only when compiling the Server or Editor.
    "Plugins": [
...
​{
"Name": "NetCluster",
"Enabled": true,
"PlatformAllowList": [
"Win64",
"Linux"
],
"TargetAllowList": [
"Server",
"Editor"
]
},
...
]
  • Configure the tags provided by NetCluster Plugin:

Directly added to DefaultGameplayTags.ini

[/Script/GameplayTags.GameplayTagsSettings]
...
+GameplayTagTableList=/NetCluster/DT_NetClusterTags.DT_NetClusterTags
...

Update Plugin Binaries

To update the plugin binaries for Unreal Engine, follow these steps:

  • Open your project folder and navigate to [YourProjectFolder]/Plugins/NetCluster/.

  • In Releases under this directory, you will find three versions of binaries for Unreal Engine: 5.0.3, 5.1.1, and 5.2.1.

  • Choose the appropriate version of Unreal Engine that you are using (either 5.0, 5.1, or 5.2).

  • Run the following command in your command prompt or terminal:

    [YourProjectFolder]/Plugins/NetCluster/InstallPlugin.bat [Your engine version]

    Replace [Your engine version] with the version number you chose in step 3 (e.g., 5.0, 5.1, or 5.2).

  • The script will update the plugin binaries for the selected Unreal Engine version.

By following these steps, you will successfully update the plugin binaries for the specific Unreal Engine version you are using. This ensures compatibility and the latest features and improvements provided by the plugin.

Configuring NetDriver and GameEngine

To make the NetCluster Plugin work, custom NetDriver and GameEngine configurations need to be added to the configuration files.

Adding NetDriver for communication between clients and servers

tip

You can directly copy ClusterServerNetDriver.[h,cpp] from the provided sample.

Alternatively, create a class that inherits from UNetDriver and override the interfaces UNetDriver::ShouldReplicateFunction, UNetDriver::ShouldReplicateActor, and UNetDriver::ShouldCallRemoteFunction using the interfaces provided in the NetClusterLibrary. These interfaces only need to be overridden on the server side (can be limited using WITH_SERVER_CODE).

Afterward, add the configuration in the appropriate configuration file.

[/Script/Engine.Engine]
!NetDriverDefinitions=ClearArray
+NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="/Script/YourProjectModule.ClusterServerNetDriver",DriverClassNameFallback="/Script/OnlineSubsystemUtils.IpNetDriver")

Add the ClusterServerNetDriver configuration:

[/Script/YourProjectModule.ClusterServerNetDriver]
AllowPeerConnections=False
AllowPeerVoice=False
ConnectionTimeout=60.0
InitialConnectTimeout=60.0
RecentlyDisconnectedTrackingTime=120
TimeoutMultiplierForUnoptimizedBuilds=1
KeepAliveTime=0.2
MaxClientRate=100000
MaxInternetClientRate=100000
RelevantTimeout=5.0
SpawnPrioritySeconds=1.0
ServerTravelPause=4.0
NetServerMaxTickRate=30
MaxNetTickRate=120
MaxPortCountToTry=512
MaxPortCountToTry=512
ResolutionConnectionTimeout=20.0
ReplicationDriverClassName="/Script/ReplicationGraph.BasicReplicationGraph"

Adding GameEngine

tip

You can also directly copy ClusterServerGameEngine.[h,cpp] from the provided sample.

Alternatively, create a class that inherits from UGameEngine and override the interface UGameEngine::NetworkRemapPath using the interface provided in the NetClusterLibrary. (Again, this only needs to be overridden on the server side).

Use this class in the configuration file:

[/Script/Engine.Engine]
...
GameEngine=/Script/YourProjectModule.ClusterServerGameEngine
...

Configuring NetCluster

NetCluster can be configured at runtime or in configuration files.

For runtime configuration, you can simply use code similar to the following:

    auto Settings = GetMutableDefault<UNetClusterSettings>();

Settings->AccountID = YOUR_ACCOUNT_ID;
Settings->SignatureSeed = YOUR_PASSWORD_BASE64;

Settings->LicenseServerHostName = FString(TEXT("license.netcluster.clustech.com.au"));
Settings->LicenseServerListenPort = 32734;
Settings->LicenseServerCurvePubKey = FString(TEXT("NTFEQFotTyNyfXhmYkAhP0J4dHVVaTA/PyFRPTdTW2VPdnJVZVFuRw=="));

Account Registration

To use the placeholders YOUR_ACCOUNT_ID and YOUR_PASSWORD_BASE64 mentioned above, you need to register an account beforehand.

Currently, registration is supported only through email. Please follow these steps:

  • First, customize an account name. The Account ID should not exceed 128 characters in length.
  • Download KeyGenerator and run .\KeyGenerator.exe -o test gen_signature_key -s "YOUR_PLAIN_PASSWORD". This command will generate test.pub and test.seed files in the current directory. The content of test.seed is your YOUR_PASSWORD_BASE64.
  • Send an email for registration:
    • Title: "Account Registration Request: your game project name"
    • To: registration@clustech.com.au
    • The body of the email should include:
      • Your github account
        • Your account ID
        • Test.pub
        • Your company name/ID
        • A brief description of your game

Initializing the NetCluster Plugin

NetClusterLibrary provides four interfaces for the initialization and launch of NetCluster:

  • UNetClusterLibrary::InitializeCluster: Typically called once when the game server is launched.
  • UNetClusterLibrary::StartLevel: Usually called when a level is started.
  • UNetClusterLibrary::StopLevel: Typically called when a level is completed or finished.
  • UNetClusterLibrary::DestroyContext: Generally called once when the game server is shutting down.
note

All four interfaces are asynchronous and provide completion callbacks. NetCluster expects that each interface's callback delegate is executed before calling other interfaces.

NetClusterLibrary provides the following Delegates:

  • OnReplicatedActorAdded and OnReplicatedActorRemoved: These are used to listen for the creation and destruction events of regular RealActors that require synchronization between servers. When the Delegate is executed, the corresponding Actor can be added to or removed from the respective VisibilityServer.

  • OnVisibilityServerUp and OnVisibilityServerDown: These are used to monitor the status of VisibilityServers.

  • OnActorActivated: This Delegate is used to listen for the events of RealActor and GhostActor creation.

  • OnActorReplicating: This Delegate is used to monitor the events when a RealActor is synchronized with other servers. When the Delegate is called, a list of Actors to be synchronized with the target server needs to be provided. Using this Delegate, you can control the visibility of Actors to other servers.

For specific details, please refer to the comments in the UNetClusterLibrary.h header file.

To streamline the task, you have the option to directly copy and utilize the following files from the sample project:

  • ClusterServerSubsystem.[h,cpp]
  • ClusterServerLibrary.[h,cpp]
  • ClusterServerActorActivationInterface.[h,cpp]
  • ClusterServerCustomizeReplicationInterface.[h,cpp] These files encapsulate the interfaces provided by the NetClusterLibrary and ensure that clients can still work without NetCluster.

After using these files, NetCluster will be automatically initialized during game startup. You just need to call UClusterServerLibrary::StartLevel and UClusterServerLibrary::StopLevel at the appropriate time.

Please check code/comments for their details.

Synchronizing Actors for Inter-Server Communication

When using the NetCluster Plugin to synchronize Actors between servers, it is crucial to ensure that these Actors can be synchronized between the server and clients through Unreal Network.

To enable Actor synchronization between servers, follow these steps:

  • Add NetClusterActor or the appropriate Tag from its subclasses to the AActor:Tags.

  • Identify all the RPCs that interact with this Actor and add the UFUNCTION(Server, reliable) decorator. Since the Actor may be Interserver-owned and running on multiple servers, RPCs need to be executed on the Real Actor's server.

note

For simplicity in design, a Real Actor and all the Actors it owns must reside on the same server. For example, if a character picks up a weapon from another server, the server where the character is located should spawn the Actor for that weapon and then perform the Attach operation.

Defining the Server Structure

NetCluster offers dynamic grouping capabilities. However, the server network requires at least the following components:

  • One LevelServer
  • One VisibilityServer
  • One LoadServer

:::hint After calling StartLevel, the server should determine the readiness of the server network and begin accepting and processing client connections. :::

Compilation and Packaging

Currently, the assumed workflow is on Windows. Compiling the Editor, Server, and Client is all done on Windows. The last two targets require using the Unreal Engine compiled from source code.

Packaging can be accomplished by following the standard process through the Editor.

Running the Server

A game instance requires a DomainServer to be operational. Before starting the server, ensure that the DomainServer is running smoothly, as any issues could prevent the server from connecting properly.

Starting the DomainServer

To start the DomainServer, use the DomainManager: DomainManager.exe -s test.seed -a YOUR_ACCOUNT_ID initiate_domain -d YOUR_DOMAIN_ID

Here, test.seed represents the seed file generated earlier with KeyGenerator. YOUR_DOMAIN_ID is an ID with a maximum length of 128 characters and must be unique within an ACCOUNT_ID. Currently, an Account supports only one Domain.

You can use DomainManager.exe -s test.seed -a YOUR_ACCOUNT_ID list_domains to query the running DomainServers. Additionally, you can stop a DomainServer using DomainManager.exe -s test.seed -a YOUR_ACCOUNT_ID destroy_domain -d YOUR_DOMAIN_ID.

Starting the Servers

NetCluster does not have any specific requirements regarding the startup order of servers. You simply need to start the game server programs following your custom-defined rules.