1 - Tutorial Build and Run a Simple Gameserver (Rust)

This tutorial describes how to use the Code Blind Rust SDK in a simple Rust gameserver.

Objectives

  • Run a simple gameserver
  • Understand how the simple gameserver uses the Code Blind Rust SDK
  • Build a customized version of the simple gameserver
  • Run your customized simple gameserver

Prerequisites

  1. Docker
  2. Code Blind installed on GKE
  3. kubectl properly configured
  4. A local copy of the Code Blind repository
  5. A repository for Docker images, such as Docker Hub or GC Container Registry

To install on GKE, follow the install instructions (if you haven’t already) at Setting up a Google Kubernetes Engine (GKE) cluster. Also complete the “Installing Code Blind” instructions on the same page.

While not required, you may wish to review the Create a Game Server, Create a Game Server Fleet, and/or Edit a Game Server quickstarts.

1. Run the simple gameserver

First, run the pre-built version of the simple gameserver and take note of the name that was created:

kubectl create -f https://raw.githubusercontent.com/googleforgames/agones/release-1.38.0/examples/rust-simple/gameserver.yaml
GAMESERVER_NAME=$(kubectl get gs -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')

The game server sets up the Code Blind SDK, calls sdk.ready() to inform Code Blind that it is ready to serve traffic, prints a message every 10 seconds, and then calls sdk.shutdown() after a minute to indicate that the gameserver is going to exit.

You can follow along with the lifecycle of the gameserver by running

kubectl logs ${GAMESERVER_NAME} rust-simple -f

which should produce output similar to

Rust Game Server has started!
Creating SDK instance
Setting a label
Starting to watch GameServer updates...
Health ping sent
Setting an annotation
Marking server as ready...
...marked Ready
Getting GameServer details...
GameServer name: rust-simple-txsc6
Running for 0 seconds
GameServer Update, name: rust-simple-txsc6
GameServer Update, state: Scheduled
GameServer Update, name: rust-simple-txsc6
GameServer Update, state: Scheduled
GameServer Update, name: rust-simple-txsc6
GameServer Update, state: RequestReady
GameServer Update, name: rust-simple-txsc6
GameServer Update, state: Ready
Health ping sent
Health ping sent
Health ping sent
Health ping sent
Health ping sent
Running for 10 seconds
GameServer Update, name: rust-simple-txsc6
GameServer Update, state: Ready
...
Shutting down after 60 seconds...
...marked for Shutdown
Running for 60 seconds
Health ping sent
GameServer Update, name: rust-simple-txsc6
GameServer Update, state: Shutdown
GameServer Update, name: rust-simple-txsc6
GameServer Update, state: Shutdown
...

If everything goes as expected, the gameserver will exit automatically after about a minute.

In some cases, the gameserver goes into an unhealthy state, in which case it will be restarted indefinitely. If this happens, you can manually remove it by running

kubectl delete gs ${GAMESERVER_NAME}

2. Build a simple gameserver

Change directories to your local agones/examples/rust-simple directory. To experiment with the SDK, open up main.rs in your favorite editor and change the interval at which the gameserver calls sdk.health() from 2 seconds to 20 seconds by modifying the line in the thread assigned to let _health to be

thread::sleep(Duration::from_secs(20));

Next build a new docker image by running

cd examples/rust-simple
REPOSITORY=<your-repository> # e.g. gcr.io/agones-images
make build-image REPOSITORY=${REPOSITORY}

The multi-stage Dockerfile will pull down all of the dependencies needed to build the image. Note that it is normal for this to take several minutes to complete.

Once the container has been built, push it to your repository

docker push ${REPOSITORY}/rust-simple-server:0.4

3. Run the customized gameserver

Now it is time to deploy your newly created gameserver container into your Code Blind cluster.

First, you need to edit examples/rust-simple/gameserver.yaml to point to your new image:

containers:
- name: rust-simple
  image: $(REPOSITORY)/rust-simple-server:0.4
  imagePullPolicy: Always

Then, deploy your gameserver

kubectl create -f gameserver.yaml
GAMESERVER_NAME=$(kubectl get gs -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')

Again, follow along with the lifecycle of the gameserver by running

kubectl logs ${GAMESERVER_NAME} rust-simple -f

which should produce output similar to

Rust Game Server has started!
Creating SDK instance
Setting a label
Starting to watch GameServer updates...
Health ping sent
Setting an annotation
Marking server as ready...
...marked Ready
Getting GameServer details...
GameServer name: rust-simple-z6lz8
Running for 0 seconds
GameServer Update, name: rust-simple-z6lz8
GameServer Update, state: Scheduled
GameServer Update, name: rust-simple-z6lz8
GameServer Update, state: RequestReady
GameServer Update, name: rust-simple-z6lz8
GameServer Update, state: RequestReady
GameServer Update, name: rust-simple-z6lz8
GameServer Update, state: Ready
Running for 10 seconds
GameServer Update, name: rust-simple-z6lz8
GameServer Update, state: Ready
GameServer Update, name: rust-simple-z6lz8
GameServer Update, state: Unhealthy
Health ping sent
Running for 20 seconds
Running for 30 seconds
Health ping sent
Running for 40 seconds
GameServer Update, name: rust-simple-z6lz8
GameServer Update, state: Unhealthy
Running for 50 seconds
Health ping sent
Shutting down after 60 seconds...
...marked for Shutdown
Running for 60 seconds
Running for 70 seconds
GameServer Update, name: rust-simple-z6lz8
GameServer Update, state: Unhealthy
Health ping sent
Running for 80 seconds
Running for 90 seconds
Health ping sent
Rust Game Server finished.

with the slower healthcheck interval, the gameserver gets automatically marked an Unhealthy by Code Blind.

To finish, clean up the gameserver by manually removing it

kubectl delete gs ${GAMESERVER_NAME}

2 - Tutorial Build and Run a Simple Gameserver (node.js)

This tutorial describes how to use the Code Blind node.js SDK in a simple node.js gameserver.

Objectives

  • Run a simple gameserver
  • Understand how the simple gameserver uses the Code Blind node.js SDK
  • Build a customized version of the simple gameserver
  • Run your customized simple gameserver

Prerequisites

  1. Docker
  2. Code Blind installed on GKE
  3. kubectl properly configured
  4. A local copy of the Code Blind repository
  5. A repository for Docker images, such as Docker Hub or GC Container Registry

To install on GKE, follow the install instructions (if you haven’t already) at Setting up a Google Kubernetes Engine (GKE) cluster. Also complete the “Installing Code Blind” instructions on the same page.

While not required, you may wish to review the Create a Game Server, Create a Game Server Fleet, and/or Edit a Game Server quickstarts.

1. Run the simple gameserver

First, run the pre-built version of the simple gameserver and take note of the name that was created:

kubectl create -f https://raw.githubusercontent.com/googleforgames/agones/release-1.38.0/examples/nodejs-simple/gameserver.yaml
GAMESERVER_NAME=$(kubectl get gs -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')

The game server sets up the Code Blind SDK, calls sdk.ready() to inform Code Blind that it is ready to serve traffic, prints a message every 10 seconds, and then calls sdk.shutdown() after a minute to indicate that the gameserver is going to exit.

You can follow along with the lifecycle of the gameserver by running

kubectl logs ${GAMESERVER_NAME} nodejs-simple -f

which should produce output similar to

> @ start /home/server/examples/nodejs-simple
> node src/index.js

node.js Game Server has started!
Setting a label
(node:20) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
Setting an annotation
Marking server as ready...
...marked Ready
GameServer Update:
	name: nodejs-simple-9bw4g 
	state: Scheduled
GameServer Update:
	name: nodejs-simple-9bw4g 
	state: RequestReady
GameServer Update:
	name: nodejs-simple-9bw4g 
	state: RequestReady
GameServer Update:
	name: nodejs-simple-9bw4g 
	state: Ready
Health ping sent
Health ping sent
Health ping sent
Health ping sent
Health ping sent
Running for 10 seconds!
Health ping sent
Health ping sent
Health ping sent
Health ping sent
Running for 20 seconds!
Health ping sent
Health ping sent
Health ping sent
Health ping sent
Health ping sent
GameServer Update:
	name: nodejs-simple-9bw4g 
	state: Ready
Running for 30 seconds!
Health ping sent
Health ping sent
Health ping sent
Health ping sent
Health ping sent
Running for 40 seconds!
Health ping sent
Health ping sent
Health ping sent
Health ping sent
Health ping sent
Running for 50 seconds!
Health ping sent
Health ping sent
Health ping sent
Health ping sent
Health ping sent
GameServer Update:
	name: nodejs-simple-9bw4g 
	state: Ready
Running for 60 seconds!
Shutting down after 60 seconds...
...marked for Shutdown
GameServer Update:
	name: nodejs-simple-9bw4g 
	state: Shutdown
Health ping sent
GameServer Update:
	name: nodejs-simple-9bw4g 
	state: Shutdown
Health ping sent
Health ping sent
Health ping sent
Health ping sent
Running for 70 seconds!
Health ping sent
Health ping sent
Health ping sent
Health ping sent
Health ping sent
Running for 80 seconds!
Health ping sent
Health ping sent
Health ping sent
Health ping sent
Health ping sent
Running for 90 seconds!

If everything goes as expected, the gameserver will exit automatically after about a minute.

In some cases, the gameserver goes into an unhealthy state, in which case it will be restarted indefinitely. If this happens, you can manually remove it by running

kubectl delete gs ${GAMESERVER_NAME}

2. Build a simple gameserver

Change directories to your local agones/examples/nodejs-simple directory. To experiment with the SDK, open up src/index.js in your favorite editor and change the interval at which the gameserver calls sdk.health() from 2 seconds to 20 seconds by modifying the lines in the health ping handler to be

setInterval(() => {
	agonesSDK.health();
	console.log('Health ping sent');
}, 20000);

Next build a new docker image by running

cd examples/nodejs-simple
REPOSITORY=<your-repository> # e.g. gcr.io/agones-images
make build REPOSITORY=${REPOSITORY}

Once the container has been built, push it to your repository

docker push ${REPOSITORY}/nodejs-simple-server:0.1

3. Run the customized gameserver

Now it is time to deploy your newly created gameserver container into your Code Blind cluster.

First, you need to edit examples/nodejs-simple/gameserver.yaml to point to your new image:

containers:
- name: nodejs-simple
  image: $(REPOSITORY)/nodejs-simple-server:0.1
  imagePullPolicy: Always

Then, deploy your gameserver

kubectl create -f gameserver.yaml
GAMESERVER_NAME=$(kubectl get gs -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')

Again, follow along with the lifecycle of the gameserver by running

kubectl logs ${GAMESERVER_NAME} nodejs-simple -f

which should produce output similar to

> @ start /home/server/examples/nodejs-simple
> node src/index.js

node.js Game Server has started!
Setting a label
(node:20) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
Setting an annotation
Marking server as ready...
...marked Ready
GameServer Update:
	name: nodejs-simple-qkpqn 
	state: Scheduled
GameServer Update:
	name: nodejs-simple-qkpqn 
	state: Scheduled
GameServer Update:
	name: nodejs-simple-qkpqn 
	state: RequestReady
GameServer Update:
	name: nodejs-simple-qkpqn 
	state: Ready
Running for 10 seconds!
GameServer Update:
	name: nodejs-simple-qkpqn 
	state: Unhealthy
Health ping sent
Running for 20 seconds!
GameServer Update:
	name: nodejs-simple-qkpqn 
	state: Unhealthy
Running for 30 seconds!
Health ping sent
Running for 40 seconds!
Running for 50 seconds!
GameServer Update:
	name: nodejs-simple-qkpqn 
	state: Unhealthy
Health ping sent
Shutting down after 60 seconds...
...marked for Shutdown
Running for 60 seconds!
Running for 70 seconds!
Health ping sent
Running for 80 seconds!
GameServer Update:
	name: nodejs-simple-qkpqn 
	state: Unhealthy
Running for 90 seconds!

with the slower healthcheck interval, the gameserver gets automatically marked an Unhealthy by Code Blind.

To finish, clean up the gameserver by manually removing it

kubectl delete gs ${GAMESERVER_NAME}

3 - Tutorial Build and Run a Simple Gameserver (C++)

This tutorial describes how to use the Code Blind C++ SDK in a simple C++ gameserver.

Objectives

  • Run a simple gameserver
  • Understand how the simple gameserver uses the Code Blind C++ SDK
  • Build a customized version of the simple gameserver
  • Run your customized simple gameserver

Prerequisites

  1. Docker
  2. Code Blind installed on GKE
  3. kubectl properly configured
  4. A local copy of the Code Blind repository
  5. A repository for Docker images, such as Docker Hub or GC Container Registry

To install on GKE, follow the install instructions (if you haven’t already) at Setting up a Google Kubernetes Engine (GKE) cluster. Also complete the “Installing Code Blind” instructions on the same page.

While not required, you may wish to review the Create a Game Server, Create a Game Server Fleet, and/or Edit a Game Server quickstarts.

1. Run the simple gameserver

First, run the pre-built version of the simple gameserver and take note of the name that was created:

kubectl create -f https://raw.githubusercontent.com/googleforgames/agones/release-1.38.0/examples/cpp-simple/gameserver.yaml
GAMESERVER_NAME=$(kubectl get gs -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')

The game server sets up the Code Blind SDK, calls SDK::Ready() to inform Code Blind that it is ready to serve traffic, prints a message every 10 seconds, and then calls SDK::Shutdown() after a minute to indicate that the gameserver is going to exit.

You can follow along with the lifecycle of the gameserver by running

kubectl logs ${GAMESERVER_NAME} cpp-simple -f

which should produce output similar to

C++ Game Server has started!
Getting the instance of the SDK!
Attempting to connect...
...handshake complete.
Setting a label
Starting to watch GameServer updates...
Health ping sent
Setting an annotation
Marking server as ready...
...marked Ready
Getting GameServer details...
GameServer name: cpp-simple-tlgzp
Running for 0 seconds !
GameServer Update:
	name: cpp-simple-tlgzp
	state: Scheduled
GameServer Update:
	name: cpp-simple-tlgzp
	state: RequestReady
GameServer Update:
	name: cpp-simple-tlgzp
	state: RequestReady
GameServer Update:
	name: cpp-simple-tlgzp
	state: Ready
Health ping sent
Health ping sent
Health ping sent
Health ping sent
Health ping sent
Running for 10 seconds !
Health ping sent
...
GameServer Update:
	name: cpp-simple-2mtdc
	state: Ready
Shutting down after 60 seconds...
...marked for Shutdown
Running for 60 seconds !
Health ping sent
GameServer Update:
	name: cpp-simple-2mtdc
	state: Shutdown
GameServer Update:
	name: cpp-simple-2mtdc
	state: Shutdown
Health ping failed
Health ping failed
Health ping failed
Health ping failed
Running for 70 seconds !
Health ping failed
Health ping failed
Health ping failed
Health ping failed
Health ping failed
Running for 80 seconds !
Health ping failed
Health ping failed
Health ping failed
Health ping failed
Health ping failed

If everything goes as expected, the gameserver will exit automatically after about a minute.

In some cases, the gameserver goes into an unhealthy state, in which case it will be restarted indefinitely. If this happens, you can manually remove it by running

kubectl delete gs ${GAMESERVER_NAME}

2. Run a fleet of simple gameservers

Next, run a fleet of gameservers

kubectl create -f https://raw.githubusercontent.com/googleforgames/agones/release-1.38.0/examples/cpp-simple/fleet.yaml
FLEET_NAME=$(kubectl get fleets -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')

You can again inspect the output of an individual gameserver (which will look the same as above), but what is more interesting is to watch the set of all gameservers over time. Each gameserver exits after about a minute, but a fleet is responsible for keeping a sufficient number of gameservers in the Ready state. So as each gameserver exits, it is replaced by a new one. You can see this in action by running

watch "kubectl get gameservers"

which should show how gameservers are constantly transitioning from Scheduled to Ready to Shutdown before disappearing.

When you are finished watching the fleet produce new gameservers you should remove the fleet by running

kubectl delete fleet ${FLEET_NAME}

3. Build a simple gameserver

Change directories to your local agones/examples/cpp-simple directory. To experiment with the SDK, open up server.cc in your favorite editor and change the interval at which the gameserver calls SDK::Health from 2 seconds to 20 seconds by modifying the line in DoHealth to be

std::this_thread::sleep_for(std::chrono::seconds(20));

Next build a new docker image by running

cd examples/cpp-simple
REPOSITORY=<your-repository> # e.g. gcr.io/agones-images
make build REPOSITORY=${REPOSITORY}

The multi-stage Dockerfile will pull down all of the dependencies needed to build the image. Note that it is normal for this to take several minutes to complete.

Once the container has been built, push it to your repository

docker push ${REPOSITORY}/cpp-simple-server:0.6

4. Run the customized gameserver

Now it is time to deploy your newly created gameserver container into your Code Blind cluster.

First, you need to edit examples/cpp-simple/gameserver.yaml to point to your new image:

containers:
- name: cpp-simple
  image: $(REPOSITORY)/cpp-simple-server:0.6
  imagePullPolicy: Always # add for development

Then, deploy your gameserver

kubectl create -f gameserver.yaml
GAMESERVER_NAME=$(kubectl get gs -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')

Again, follow along with the lifecycle of the gameserver by running

kubectl logs ${GAMESERVER_NAME} cpp-simple -f

which should produce output similar to

C++ Game Server has started!
Getting the instance of the SDK!
Attempting to connect...
...handshake complete.
Setting a label
Health ping sent
Starting to watch GameServer updates...
Setting an annotation
Marking server as ready...
...marked Ready
Getting GameServer details...
GameServer name: cpp-simple-f255n
Running for 0 seconds !
GameServer Update:
	name: cpp-simple-f255n
	state: Scheduled
GameServer Update:
	name: cpp-simple-f255n
	state: Scheduled
GameServer Update:
	name: cpp-simple-f255n
	state: RequestReady
GameServer Update:
	name: cpp-simple-f255n
	state: Ready
Running for 10 seconds !
GameServer Update:
	name: cpp-simple-f255n
	state: Unhealthy
Health ping sent
Running for 20 seconds !
GameServer Update:
	name: cpp-simple-f255n
	state: Unhealthy
Running for 30 seconds !
Health ping sent
Running for 40 seconds !
Running for 50 seconds !
GameServer Update:
	name: cpp-simple-f255n
	state: Unhealthy
Health ping sent
Shutting down after 60 seconds...
...marked for Shutdown
Running for 60 seconds !
Running for 70 seconds !
Health ping sent
Running for 80 seconds !
GameServer Update:
	name: cpp-simple-f255n
	state: Unhealthy
Running for 90 seconds !
Health ping sent

with the slower healthcheck interval, the gameserver gets automatically marked an Unhealthy by Code Blind.

To finish, clean up the gameserver by manually removing it

kubectl delete gs ${GAMESERVER_NAME}