Welcome back, readers! In this article, we’ll look at integrating the Agones SDK with a Simple Game Server built using NodeJS.

In a previous article, we learned about Agones and installed it into our Kubernetes cluster. It is necessary to integrate the Agones SDK into the game server to deploy a game server alongside Agones. By doing so, Agones can leverage Kubernetes's scaling and resiliency features.

Agones, an extension of Kubernetes, enhances the capabilities of game server deployment. By integrating the Agones SDK, game servers can use Kubernetes' powerful features, including scaling game server instances based on demand and ensuring high availability and resilience.

Setup

Let's set up our environment for development here; I’m installing Node 18 in my local system!

I'll use fnm a node version manager to set up a nodejs development environment.

To install fnm,

curl -fsSL https://fnm.vercel.app/install | bash

And now, to install node 18,

fnm use 18.12.1

Alternatively, on Mac or Linux systems, you can use brew to install node using the following command:

brew install node@18
PS: Install brew using this command if you don't have it in your system (requires sudo access)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Integrate the SDK

Now let us set up the codebase; I’ve chosen an application that uses WebSocket connections for this article. The process is similar for other types of applications as well.

You can access the application at: https://github.com/nischal-subedi/nodejs-chat-app
git clone https://github.com/nischal-subedi/nodejs-chat-appa
cd nodejs-chat-app

This application requires a few dependencies to be resolved before it can be started; let's install them now,

npm i

If you want, you can update the vulnerable dependencies as well using the command:

npm audit --fix
Sometimes fixing vulnerable packages can cause unknown behaviours in the application.

The application works by storing data in a MongoDB Database. Let's now setup a mongo database using docker.

docker run -d -p 127.0.0.1:27017:27017 mongo:latest

Here,

-d will daemonize the container (runs in the background)

-p will map the host port 27017 with container port 27017 on 127.0.0.1 (localhost)

mongo:latest is the image name and tag, a specific version can also be provided like this mongo:v6

Now, we'll provide the URL for the MongoDB instance in our code,

Replace dbUrl with var dbUrl = mongodb://127.0.0.1:27017. Predefined DBUrls have been placed in the code for different environments, including one for the local dev environment.

Integrating Agones

In the main.js file, we need to perform a few modifications to connect our game server with the Agones SDK. To do so, write the following code snippet into the file:

//AGONES IMPLEMENTATION STARTS -> <-
const AgonesSDK = require('@google-cloud/agones-sdk/src/agonesSDK');
const { clear } = require('console');
const { clearInterval } = require('timers');
const { setTimeout } = require('timers/promises');

const DEFAULT_TIMEOUT = 60;
const MAX_TIMEOUT = 2147483;

const connect = async (timeout, enableAlpha) => {
  let sdk = new AgonesSDK();

  let lifetimeInterval;
  let healthInterval;

  try {
    console.log(`SDK Server connection....`);
    await sdk.connect();
    console.log(`Connection.... Is Successful`);

    let connectTime = Date.now();
    lifetimeInterval = setInterval(() => {
      let limetimeSeconds = Math.floor((Date.now() - connectTime) / 1000);
      console.log(`SDK has been running for ${limetimeSeconds} seconds`);
    }, 1000);
    healthInterval = setInterval(() => {
      sdk.health();
      console.log(`Health Pings are enroute`);
    }, 20000);
    sdk.watchGameServer((result) => {
      let output = `GameServer Update:
            name: ${result.objectMeta.name}
            state: ${result.status.state}
            labels: ${result.objectMeta.labelsMap.join(' & ')}
            annotations: ${result.objectMeta.annotationsMap.join(' & ')}`;
      if (enableAlpha) {
        output += `
                players: ${result.status.players.count}/${result.status.players.capacity} [${result.status.players.idsList}]`;
      }
      console.log(output);
    }, (error) => {
      console.error(`Watch Error`, error);
      clearInterval(healthInterval);
      clearInterval(lifetimeInterval);
      process.exit(0);
    });

    await setTimeout(10000);
    console.log(`Labeling...`);
    await sdk.setLabel(`app-type`, `node-chatapp`);

    await setTimeout(10000);
    console.log(`Annotating resource...`);
    await sdk.setAnnotation('app-is', `volatile`);

    await setTimeout(10000);
    console.log('Marking Server as ready...');
    await sdk.ready();

    await setTimeout(10000);
    console.log('Allocation in Progress...');
    await sdk.allocate();

    if (timeout === 0) {
      do {
        await setTimeout(MAX_TIMEOUT);
      } while (true);
    }

  } catch (error) {
    console.error(error);
    clearInterval(healthInterval);
    clearInterval(lifetimeInterval);
    process.exit(0);
  }
};

connect(1000, false);
Server.js with Agones SDK Integrated

The code snippet above demonstrates the initial steps of connecting with the Agones SDK, conducting health checks, and regularly updating the server's status. While minimal, this implementation serves as a foundation for further enhancements. By enabling alpha features, which are newly introduced to the community and not included in the stable version by default, you can unlock additional capabilities and expand the functionality of your implementation.

To explore the various features available, refer to this comprehensive Agones documentation for more information.

Running the Application

The developers of Agones have provided a binary that can be executed on our system to get similar effects as using it on a cluster. Download the binary file, unzip it and use the binary that matches your system architecture. E.g.:

./sdk-server.darwin.arm64 --local

We can run the application now that the Agones SDK is running locally; run it using the command,

npm start
Starting the Application

The app is running as intended. You can try out different features by referring to the Agones docs.

Conclusion

In this blog post, we explored the seamless integration of Agones into any existing Game Server Application, regardless of the programming language used. By leveraging the Official SDKs provided by Agones, gaming companies can tap into the power of Kubernetes for their scaling requirements. Agones proves to be an invaluable technology, paving the way for gaming companies to achieve an infinitely scalable architecture within the Kubernetes ecosystem.

Please comment below if you have any queries. I try to periodically update my articles to ensure accuracy and relevance.