Multiplay Hosting SDK for Unity
Integrate Multiplay Hosting functionality into your Unity game server.
Read time 8 minutesLast updated 3 days ago
The Multiplay Hosting SDK for Unity has all the functionality necessary to use Multiplay Hosting scaling and game server services in your game.
Unity.Services.MultiplayRequirements and limitations
The Multiplay Hosting SDK for Unity works with Unity Editor version 2020.3 and later.Initialize the SDK
Use the Instance method to create a singleton of theIMultiplayServiceasync void Example_InitSDK(){ try { await UnityServices.InitializeAsync(); } catch (Exception e) { Debug.Log(e); }}
Configure the game server
TheServerConfigServerConfigServerConfigServerConfigServerConfigParameter | Type | Description |
|---|---|---|
| long | The server ID. |
| string | The allocation ID. |
| ushort | The Server Query Protocol port number. |
| ushort | The connection port for the game session. This is the port number game clients can use to connect to the game session. |
| string | The directory in which the game server saves log files. |
ServerConfigusing System.Collections;using System.Collections.Generic;using Unity.Services.Multiplay;using UnityEngine;public class Example_ServerConfiguration{ /// <summary> /// A simple example of accessing each of the server config's fields and printing them to the debug console. /// </summary> public static void LogServerConfig() { var serverConfig = MultiplayService.Instance.ServerConfig; Debug.Log($"Server ID[{serverConfig.ServerId}]"); Debug.Log($"AllocationID[{serverConfig.AllocationId}]"); Debug.Log($"Port[{serverConfig.Port}]"); Debug.Log($"QueryPort[{serverConfig.QueryPort}"); Debug.Log($"LogDirectory[{serverConfig.ServerLogDirectory}]"); }}
Ready the game server
Use theReadyServerForPlayersAsyncusing System.Threading.Tasks;using Unity.Services.Multiplay;/// <summary>/// Ready the server. This is to indicate that the server is ready to accept players./// Readiness is the server's way of saying it's ready for players to join the server./// You must wait until you have been Allocated before you can call ReadyServerForPlayersAsync./// </summary>private async void Example_ReadyingServer(){ // After the server is back to a blank slate and ready to accept new players await MultiplayService.Instance.ReadyServerForPlayersAsync();}
Unready the game server
Use theUnreadyServerAsyncusing System.Threading.Tasks;using Unity.Services.Multiplay;/// <summary>/// Unready the server. This is to indicate that the server is in some condition which means it can't accept players./// For example, after a game has ended and you need to reset the server to prepare for a new match./// </summary>private async void Example_UnreadyingServer(){ // The match has ended and players are disconnected from the server await MultiplayService.Instance.UnreadyServerAsync();}
Start server query handler
Use theStartServerQueryHandlerAsyncParameter | Type | Description |
|---|---|---|
| ushort | The maximum number of players on the server. |
| string | The name for the server. |
| string | The name or identifier of the game type the server is running. |
| string | The version of the game. |
| string | The map or world the server is running for the game. |
| ushort | The port number of the game server that the game client can use to connect. |
StartServerQueryHandlerAsyncparametersIServerCheckManagerUpdateServerCheck()UpdateServerCheck()
The following example shows how to start the server query handler.
using System.Collections;using System.Collections.Generic;using UnityEngine;using Unity.Services.Multiplay;/// <summary>/// An example of how to use SQP from the server using the Multiplay SDK./// The ServerQueryHandler reports the given information to the Multiplay Service./// </summary>public class Example_ServerQueryHandler : MonoBehaviour{ private const ushort k_DefaultMaxPlayers = 10; private const string k_DefaultServerName = "MyServerExample"; private const string k_DefaultGameType = "MyGameType"; private const string k_DefaultBuildId = "MyBuildId"; private const string k_DefaultMap = "MyMap"; public ushort currentPlayers; private IServerQueryHandler m_ServerQueryHandler; private async void Start() { m_ServerQueryHandler = await MultiplayService.Instance.StartServerQueryHandlerAsync(k_DefaultMaxPlayers, k_DefaultServerName, k_DefaultGameType, k_DefaultBuildId, k_DefaultMap); } private void Update() { m_ServerQueryHandler.UpdateServerCheck(); } public void ChangeQueryResponseValues(ushort maxPlayers, string serverName, string gameType, string buildId) { m_ServerQueryHandler.MaxPlayers = maxPlayers; m_ServerQueryHandler.ServerName = serverName; m_ServerQueryHandler.GameType = gameType; m_ServerQueryHandler.BuildId = buildId; } public void PlayerCountChanged(ushort newPlayerCount) { m_ServerQueryHandler.CurrentPlayers = newPlayerCount; }}
Subscribe to server events
Use theSubscribeToServerEventsAsyncOnAllocateOnDeallocateOnErrorusing System;using System.Collections;using System.Collections.Generic;using Unity.Services.Multiplay;using UnityEngine;/// <summary>/// An example of how to access and react to multiplay server events./// </summary>public class Example_ServerEvents : MonoBehaviour{ private MultiplayEventCallbacks m_MultiplayEventCallbacks; private IServerEvents m_ServerEvents; /// <summary> /// This should be done early in the server's lifecycle, as you'll want to receive events as soon as possible. /// </summary> private async void Start() { // We must first prepare our callbacks like so: m_MultiplayEventCallbacks = new MultiplayEventCallbacks(); m_MultiplayEventCallbacks.Allocate += OnAllocate; m_MultiplayEventCallbacks.Deallocate += OnDeallocate; m_MultiplayEventCallbacks.Error += OnError; m_MultiplayEventCallbacks.SubscriptionStateChanged += OnSubscriptionStateChanged; // We must then subscribe. m_ServerEvents = await MultiplayService.Instance.SubscribeToServerEventsAsync(m_MultiplayEventCallbacks); }// Handle Multiplay events.}
Handle Multiplay Hosting events
TheMultiplayEventCallbacksOnAllocateOnDeallocateOnErrorusing System;using System.Collections;using System.Collections.Generic;using Unity.Services.Multiplay;using UnityEngine;/// <summary>/// An example of how to access and react to multiplay server events./// </summary>public class Example_ServerEvents : MonoBehaviour{ private MultiplayEventCallbacks m_MultiplayEventCallbacks; private IServerEvents m_ServerEvents; /// <summary> /// This should be done early in the server's lifecycle, as you'll want to receive events as soon as possible. /// </summary> private async void Start() { // We must first prepare our callbacks like so: m_MultiplayEventCallbacks = new MultiplayEventCallbacks(); m_MultiplayEventCallbacks.Allocate += OnAllocate; m_MultiplayEventCallbacks.Deallocate += OnDeallocate; m_MultiplayEventCallbacks.Error += OnError; m_MultiplayEventCallbacks.SubscriptionStateChanged += OnSubscriptionStateChanged; // We must then subscribe. m_ServerEvents = await MultiplayService.Instance.SubscribeToServerEventsAsync(m_MultiplayEventCallbacks); } /// <summary> /// Handler for receiving the allocation multiplay server event. /// </summary> /// <param name="allocation">The allocation received from the event.</param> private void OnAllocate(MultiplayAllocation allocation) { // Here is where you handle the allocation. // This is highly dependent on your game, however this would typically be some sort of setup process. // Whereby, you spawn NPCs, setup the map, log to a file, or otherwise prepare for players. // After you the allocation has been handled, you can then call ReadyServerForPlayersAsync()! } /// <summary> /// Handler for receiving the deallocation multiplay server event. /// </summary> /// <param name="deallocation">The deallocation received from the event.</param> private void OnDeallocate(MultiplayDeallocation deallocation) { // Here is where you handle the deallocation. // This is highly dependent on your game, however this would typically be some sort of teardown process. // You might want to deactivate unnecessary NPCs, log to a file, or perform any other cleanup actions. } /// <summary> /// Handler for receiving the error multiplay server event. /// </summary> /// <param name="error">The error received from the event.</param> private void OnError(MultiplayError error) { // Here is where you handle the error. // This is highly dependent on your game. You can inspect the error by accessing the error.Reason and error.Detail fields. // You can change on the error.Reason field, log the error, or otherwise handle it as you need to. } /// <summary> /// /// </summary> /// <param name="state"></param> private void OnSubscriptionStateChanged(MultiplayServerSubscriptionState state) { switch (state) { case MultiplayServerSubscriptionState.Unsubscribed: /* The Server Events subscription has been unsubscribed from. */ break; case MultiplayServerSubscriptionState.Synced: /* The Server Events subscription is up to date and active. */ break; case MultiplayServerSubscriptionState.Unsynced: /* The Server Events subscription has fallen out of sync, the subscription tries to automatically recover. */ break; case MultiplayServerSubscriptionState.Error: /* The Server Events subscription has fallen into an errored state and won't recover automatically. */ break; case MultiplayServerSubscriptionState.Subscribing: /* The Server Events subscription is trying to sync. */ break; } }}
Allocate
Use thepublic event Action<MultiplayAllocation> Allocate;
AllocateMultiplayAllocationDeallocate
Use thepublic event Action<MultiplayDeallocation> Deallocate;
DeallocateMultiplayDeallocationError
Use thepublic event Action<MultiplayError> Error;
ErrorMultiplayErrorSubscriptionStateChange
Use thepublic event Action<MultiplayServerSubscriptionState> SubscriptionStateChanged;
SubscriptionStateChangedMultiplayServerSubscriptionStateDeploying resources with Unity Editor
The Multiplay Authoring module (installed with the Multiplay package) allows you to optionally author and modify resources directly within the Unity Editor. You can then upload resources from the Unity Editor to the Dashboard by using the Deployment package. Multiplay configurations existing in the Unity Editor allow users to treat their source control as the single source of truth (instead of the version in the cloud), simplifying actions such as rollbacks, bisection, and other common operations.Set up Multiplay
To use Multiplay in the Unity Editor:Install required packages
To create Multiplay configurations within the Editor, install the following packages:- Deployment
- Multiplay:
- For Unity 2022 LTS and later: Multiplayer
- For earlier versions of Unity: Multiplay
- In the Unity Editor's Package Manager, select Unity Registry.
- Enter .
com.unity.services.deployment - Select Install.
- Repeat these steps for Multiplay:
- For Unity 2022 LTS and later:
com.unity.services.multiplayer - For earlier versions of Unity:
com.unity.services.multiplay
- For Unity 2022 LTS and later:
Link project
Link your Unity Gaming Services project with the Unity Editor. You can find your UGS project ID in the Unity Dashboard.- In Unity Editor, select Edit > Project Settings > Services.
- Link your project.
-
If your project doesn't have a Unity project ID:
- Select Create a Unity Project ID > Organizations, then select an organization from the dropdown menu.
- Select Create project ID.
-
If you have an existing Unity project ID:
- Select Use an existing Unity project ID.
- Select an organization and a project from the dropdown menus.
- Select Link project ID.
UnityEditor.CloudProjectSettings.projectIdAuthoring within Unity Editor
The Multiplay Authoring module allows you to create, edit, and deploy Multiplay configurations directly within the Unity Editor.Create a configuration
Follow these steps to create an Multiplay configuration using the Multiplay Authoring module:- In the Unity Editor, right-click (macOS: Ctrl+click) in the Project window, then select Create > Services > Multiplay Config.
- Give the resource file a name.
- Press Enter.
Edit a configuration
There is currently one method to edit an existing configuration:- In the Project tab, double-click the existing resource, then choose any text editor to edit the configuration.
Resource file content
The deployment window finds resources and assigns their type according to their file extension. The configuration uses theyaml.gshnew_multiplay_config.gshThe configuration describes 3 components within the file:version: 1.0builds: my build: # replace with the name for your build executableName: Build.x86_64 # the name of your build executable buildPath: Builds/Multiplay # the location of the build filesbuildConfigurations: my build configuration: # replace with the name for your build configuration build: my build # replace with the name for your build queryType: sqp # sqp or a2s, delete if you do not have logs to query binaryPath: Build.x86_64 # the name of your build executable commandLine: -port $$port$$ -queryport $$query_port$$ -log $$log_dir$$/Engine.log # launch parameters for your server variables: {} cores: 1 # number of cores per server speedMhz: 750 # launch parameters for your server memoryMiB: 800 # launch parameters for your serverfleets: my fleet: # replace with the name for your fleet buildConfigurations: - my build configuration # replace with the names of your build configuration regions: North America: # North America, Europe, Asia, South America, Australia minAvailable: 0 # minimum number of servers running in the region maxServers: 1 # maximum number of servers running in the region