メインコンテンツまでスキップ

Use AccelByte Unity SDK to integrate AMS to game server - Game server integration - (Unity module)

Last updated on March 12, 2025

Game server with AMS flow

Before you begin, let's understand how game server is managed by AccelByte Multiplayer Servers (AMS). Take a look at the following state diagram showing the states that the server will go through and how to transition between each of them:

As the game server starts, it connects to AMS via WebSocket. Once the connection is established, the game server sends a message indicating that the server is ready. Once ready, the game server can be claimed by your backend service to serve game sessions for your game clients. If the gameplay is over, the game server must shut down and disconnect from the AMS WebSocket.

AMS also able to send drain event to your game server to remove unused servers. When this event happen, if your game server is not serving any game session (e.g. there is no player in your server) you should shutdown your game server to avoid unneeded cost.

Unwrap the wrapper

This tutorial shows how to integrate AccelByte Multiplayer Servers (AMS) with the game server using the AccelByte Unity SDK. In Byte Wars, there is a completed wrapper defined in the AMSModuleWrapper_Starter class. In this tutorial, you use the starter version of that wrapper to integrate the functionalities from scratch.

What's in the Starter Pack

To follow this tutorial, you use the starter wrapper class called AMSModuleWrapper_Starter. This wrapper is defined in the file below:

  • CS file: Assets/Resources/Modules/AMSModule/Scripts/AMSModuleWrapper_Starter.cs.

Integrate AMS to game server

  1. First of all, open the project in the Unity Editor. Go to the Assets/Resources/Modules/AMSModule folder and open the AMSModuleAssetConfig.asset. Then, make sure to activate the module in starter mode by ticking the Is Active checkbox and the Is Starter Active checkbox. This setting activates the AMSModuleWrapper_Starter wrapper file when the game server started.

  2. Next, open the AMSModuleWrapper_Starter class and declare the AMS interface variable below.

    private ServerAMS ams;
  3. Create a new function below to connect your game server to AMS when the game server started. The code below also binds AMS events to callback functions which you will create later.

    private void OnEnable()
    {
    BytewarsLogger.Log("AMS Module wrapper initialized.");

    // Get AMS interface from SDK with auto create and auto connect to AMS WebSocket enabled.
    ams = AccelByteSDK.GetServerRegistry().GetAMS(autoCreate: true, autoConnect: true);
    if (ams == null)
    {
    BytewarsLogger.LogWarning("AMS interface is null. You might run the instance in Unity Editor. Try to package the game server as executable.");
    return;
    }
    ams.OnOpen += OnConnected;
    ams.Disconnected += OnDisconnected;
    ams.OnDrainReceived += OnDrainReceived;

    // On-server deregister (e.g. game over), disconnect from AMS.
    GameManager.Instance.OnDeregisterServer += Disconnect;
    }
  4. Next, create a new function below to unbind AMS events when the game server deinitialized.

    private void OnDisable()
    {
    BytewarsLogger.Log("AMS Module wrapper deinitialized.");

    if (ams == null)
    {
    BytewarsLogger.LogWarning("AMS interface is null. You might run the instance in Unity Editor. Try to package the game server as executable.");
    return;
    }

    // Unbind events.
    ams.OnOpen -= OnConnected;
    ams.Disconnected -= OnDisconnected;
    ams.OnDrainReceived -= OnDrainReceived;
    GameManager.Instance.OnDeregisterServer -= Disconnect;
    }
  5. Create a new function to send a message to AMS WebSocket indicating the game server is ready to serve game session. You should call this function when your game server is setup properly (e.g. load the correct scene, load the correct gameplay config).

    private void SendServerReady()
    {
    if (!ams.IsConnected)
    {
    BytewarsLogger.LogWarning("Cannot set server ready. The AMS websocket connection is not established.");
    return;
    }

    BytewarsLogger.Log("Send server ready message to AMS.");
    ams.SendReadyMessage();
    }
  6. Next, create a new callback function to handle when AMS WebSocket connection is established. This function call the SendServerReady() to mark the server as ready. However, this is just an example for Byte Wars. If your game server requires to setup something else before it can welcome players (e.g. load the correct scene, load the correct gameplay config), then you should call the SendServerReady() function after those setup are complete.

    private void OnConnected() 
    {
    BytewarsLogger.Log("Success to connect to AMS websocket.");

    /* It is not required to set the server as ready immediately after the AMS websocket connection is established.
    * If the server needs to perform setup tasks before welcoming the player, the server ready message should be sent afterward.
    * Since Byte Wars does not require such setup, the server ready message is sent immediately here. */
    SendServerReady();
    }
  7. Create a new function to disconnect your game server from AMS WebSocket.

        private void Disconnect() 
    {
    if (!ams.IsConnected)
    {
    BytewarsLogger.LogWarning("Cannot disconnect AMS websocket. The AMS websocket connection is not established.");
    return;
    }

    BytewarsLogger.Log("Disconnecting from AMS websocket.");
    ams.Disconnect();
    }
  8. Next, create a new callback function to handle when your game server is disconnected from AMS WebSocket. In the code below, if the disconnection is normal, the game server shuts down. You can also handle this event however you want to suit your needs.

    private void OnDisconnected(WsCloseCode wsCloseCode) 
    {
    BytewarsLogger.Log($"Disconnected from AMS websocket. Ws Code: {wsCloseCode}");

    if (wsCloseCode == WsCloseCode.Normal)
    {
    #if UNITY_EDITOR
    UnityEditor.EditorApplication.ExitPlaymode();
    #else
    Application.Quit();
    #endif
    }
    }
  9. Finally, create a new callback function to handle when an AMS drain event is received. In this function, if the game server is currently not serving a game session, it disconnects from AMS WebSocket and shuts down. Otherwise, the drain event is ignored. This is just an example for Byte Wars, and you can handle the drain event however you want to suit your needs.

    private void OnDrainReceived() 
    {
    BytewarsLogger.Log("Drain event received.");

    /* When a drain event occurs, the server may perform some clean-up tasks.
    * Drain behavior on Byte Wars:
    * If the server is not serving any game session, then disconnect the server from AMS and shut it down.
    * Otherwise, keep it running as normal. */
    if (GameManager.Instance.InGameMode == InGameMode.None && GameManager.Instance.ConnectedPlayerStates.Count <= 0)
    {
    BytewarsLogger.Log("There is no game is in progress. Handle drain event to shut down the server.");
    Disconnect();
    return;
    }

    BytewarsLogger.Log("The game is in progress. Ignore drain event.");
    }

Resources