Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding GSDK related documentation #315

Merged
merged 2 commits into from
Jul 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/_config-development.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ aux_links_new_tab: true
plugins:
- jekyll-seo-tag
- jekyll-sitemap
- jekyll-relative-links
- jemoji

kramdown:
Expand Down
1 change: 1 addition & 0 deletions docs/_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ ga_tracking_anonymize_ip: true # Use GDPR compliant Google Analytics settings (t
plugins:
- jekyll-seo-tag
- jekyll-sitemap
- jekyll-relative-links
- jemoji

kramdown:
Expand Down
2 changes: 1 addition & 1 deletion docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ We use [GitHub Pages](https://docs.github.com/en/pages) to host Thundernetes doc
- Run `bundle exec jekyll serve --config _config-development.yml`
- Browse the site on http://localhost:4000/thundernetes

Alternatively, you can use [this container image](https://github.com/BretFisher/jekyll-serve) with a command similar to the following:
Alternatively, you can use [this container image](https://github.com/BretFisher/jekyll-serve) with a command similar to the following, once you are in the `docs` directory:

```bash
docker run -p 4000:4000 --env JEKYLL_ENV=production --rm -v $(pwd):/site bretfisher/jekyll-serve bundle exec jekyll serve --force-polling --config _config-development.yml --host 0.0.0.0
Expand Down
Binary file added docs/favicon.ico
Binary file not shown.
28 changes: 28 additions & 0 deletions docs/gameserverbuild.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,31 @@ Ports that are to be exposed are assigned a number in the port range 10000-12000
## CrashesToMarkUnhealthy

CrashesToMarkUnhealthy (integer) is the number of crashes that you want to trigger the GameServerBuild to become Unhealthy. Once this happens, no other operation will take place on the GameServerBuild. To allow Thundernetes to continue performing reconciliations on the GameServerBuild after it has become Unhealthy, you can increase the value of the CrashesToMarkUnhealthy field. The GameServerBuild will be marked as Healthy again till the number of crashes reaches the value of CrashesToMarkUnhealthy.

## Game server image upgrades

You should **not** change the container image of your GameServerBuild. The best practice to upgrade your game server version is to

- spin up a separate GameServerBuild
- configure your matchmaker to allocate against this new GameServerBuild
- configure the original GameServerBuild to 0 standingBy
- when all the active games in the original GameServerBuild end, you can safely delete it

At this point, Thundernetes does not do anything to prevent you from changing the container image on the GameServerBuild YAML file, but you should consider the GameServerBuild as immutable (apart from changing the standingBy and max numbers, of course).

## Using host networking

Thundernetes supports running your GameServer Pods with host networking. To do that, you need to provide a GameServerBuild YAML like [this](http://github.com/playfab/thundernetes/tree/main/samples/netcore/sample-hostnetwork.yaml), setting the `hostNetwork` value to true on PodSpec template. During Pod creation, thundernetes controllers will override the containerPort with the same value that will be assigned in the hostPort.

You **have to** use the generated port when you instantiate your game server process. To grab the port number, you should use GSDK.

```csharp
string ListeningPortKey = "nameOfThePortInTheGameServerBuild";
IDictionary<string, string> initialConfig = GameserverSDK.getConfigSettings();
if (initialConfig?.ContainsKey(ListeningPortKey) == true)
{
int listeningPort = int.Parse(initialConfig[ListeningPortKey]);
// instantiate your game server with the value of the listeningPort
```

> _**NOTE**_: Unfortunately, it is necessary to provide a `containerPort` value in the GameServerBuild YAML, since it is required for GameServerBuild validation (specifically, the way the PodTemplate is validated). However, as mentioned, this provided value is not used since it's overwritten by the `hostPort` value.
75 changes: 75 additions & 0 deletions docs/gsdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
layout: default
title: GSDK integration
nav_order: 5
has_children: true
---

# How to run your game server on Thundernetes?

Once you [install Thundernetes](quickstart/installing-thundernetes.md) (either on [kind](quickstart/installing-kind.md) or [AKS](quickstart/installing-aks.md)) and verify it's working as intended, you can prepare your game server for Thundernetes by integrating with the open source [Game Server SDK (GSDK)](https://github.com/playfab/gsdk). GSDK library is also used by [Azure PlayFab Multiplayer Servers (MPS)](https://docs.microsoft.com/gaming/playfab/features/multiplayer/servers/) service. In this way, you can easily migrate your game servers from MPS to Thundernetes and vice versa.

Integrating with GSDK is required for your game server to run on Thundernetes. Integration serves two purposes:
- allows your game server process to communicate its state to Thundernetes (Initializing, StandingBy, Terminated)
- allows Thundernetes to allocate your game server for a game session

To integrate with GSDK, follow the guide for the programming language/environment you are using.

- [Unity GSDK](unity.md)
- [Unreal GSDK](unreal.md)

> **_NOTE_**: For experimenting with Thundernetes, you can use our [wrapper sample](../howtos/usingwrapper.md). This sample takes care of calling the GSDK for you and launching your game server as a separate process.

## Run your game server on Thundernetes

To run your game server on Thundernetes, you need to create a [GameServerBuild](../gameserverbuild.md).

```yaml
apiVersion: mps.playfab.com/v1alpha1
kind: GameServerBuild
metadata:
name: gameserverbuild-sample
spec:
titleID: "1E03" # required
buildID: "85ffe8da-c82f-4035-86c5-9d2b5f42d6f6" # must be a GUID
standingBy: 2 # required
max: 4 # required
crashesToMarkUnhealthy: 5 # optional, recommended
portsToExpose:
- 80
template:
spec:
containers:
- image: <containerRegistryUrl>/<containerImage>:<tag>
name: <containerName>
ports:
- containerPort: <portName> # your game server port
protocol: <TCP or UDP> # your game server port protocol
name: gameport # required field
```

You can call this file `gameserverbuild.yaml`.

- To configure this GameServerBuild to run on your cluster, you should run the following command:

```bash
kubectl apply -f /path/to/gameserverbuild.yaml
```

- Running `kubectl get gsb` and `kubectl get gs` should show something like this:

```bash
dgkanatsios@desktopdigkanat:digkanat$ kubectl get gsb
NAME STANDBY ACTIVE CRASHES HEALTH
gameserverbuild-sample 2/2 0 0 Healthy
dgkanatsios@desktopdigkanat:digkanat$ kubectl get gs
NAME HEALTH STATE PUBLICIP PORTS SESSIONID
gameserverbuild-sample-rtgnm Healthy StandingBy 172.18.0.2 80:14913
gameserverbuild-sample-spdob Healthy StandingBy 172.18.0.2 80:14208
```

Congratulations, your game server is up and running on Thundernetes!

### Run your game server on Azure Kubernetes Service with Azure Container Registry

As soon as you build your container image, you should publish it to a container registry. If you are using Azure Kubernetes Service, we recommend publishing your image to [Azure Container Registry](https://docs.microsoft.com/azure/container-registry/). To integrate your Azure Container Registry with your Azure Kubernetes Service cluster, check the instructions [here](https://docs.microsoft.com/azure/aks/cluster-container-registry-integration).
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
---
layout: default
title: Game Server lifecycle
nav_order: 6
parent: GSDK integration
nav_order: 1
---

# Game Server lifecycle
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
layout: default
title: Using LocalMultiplayerAgent
parent: How to's
parent: GSDK integration
nav_order: 8
---

Expand Down
43 changes: 43 additions & 0 deletions docs/gsdk/unity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
layout: default
title: Unity
parent: GSDK integration
nav_order: 1
---

# Integrating GSDK with Unity

You can find the Unity GSDK [here](https://github.com/PlayFab/gsdk/tree/main/UnityGsdk). This folder contains the Game Server SDK for the [Unity game engine](https://unity.com/). The GSDK files are in the `Assets/PlayFabSdk/MultiplayerAgent` folder. The entire GSDK is usable by class `PlayFabMultiplayerAgentAPI`.

### What do I need to do in order to use the Unity GSDK in a new project?

You can drag the `PlayFabSDK` folder to your Unity project or you can use the provided `unitypackage` file. After that, you need to enable the scripting directive `ENABLE_PLAYFABSERVER_API` on your Build settings, like in [this screenshot](https://user-images.githubusercontent.com/8256138/81462605-a6d7ac80-9168-11ea-9748-110ed01095c2.png). This is useful if your game server and client share the same project files.

### Usage

The minimum work you need to is call the `PlayFabMultiplayerAgentAPI.Start()` when your server is initializing and then call the `PlayFabMultiplayerAgentAPI.ReadyForPlayers();` when your server is ready for players to connect.

```csharp
StartCoroutine(ReadyForPlayers());
...
}

IEnumerator ReadyForPlayers()
{
yield return new WaitForSeconds(.5f);
PlayFabMultiplayerAgentAPI.ReadyForPlayers();
}
```

To create your container image to use on Kubernetes, you should build a "Linux Dedicated Server" and then use a Dockerfile similar to the following:

```
FROM ubuntu:18.04
WORKDIR /game
ADD . .
CMD ["/game/UnityServer.x86_64", "-nographics", "-batchmode", "-logfile"]
```

### Samples

For a more robust sample integrating Unity with the popular [Mirror](https://mirror-networking.com/) networking library, check the `MpsSamples` repository [here](https://github.com/PlayFab/MpsSamples/tree/main/UnityMirror).
55 changes: 55 additions & 0 deletions docs/gsdk/unreal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
layout: default
title: Unreal
parent: GSDK integration
nav_order: 2
---

# Integrating GSDK with Unreal

You can find the Unreal GSDK [here](https://github.com/PlayFab/gsdk/tree/main/UnrealPlugin). This folder contains the Game Server SDK for the [Unreal game engine](https://unrealengine.com/).

### What do I need to do in order to use the Unreal GSDK in a new project?

The Unreal server project needs to be a network-enabled multiplayer Unreal project with a dedicated-server mode. If you don't have a project that meets these prerequisites, follow our [Unreal prerequisite](https://github.com/PlayFab/gsdk/blob/main/UnrealPlugin/ThirdPersonMPSetup.md) set up guide to set one up. Once you have a network-enabled, multiplayer game, with a dedicated server, return to this step and continue.

When ready, open your network-enabled multiplayer Unreal server project, and continue to the [next step](https://github.com/PlayFab/gsdk/tree/main/UnrealPlugin), specifically to the part about [building for the cloud](https://github.com/PlayFab/gsdk/blob/main/UnrealPlugin/ThirdPersonMPCloudDeploy.md).

At a minimum, you would need to call the `SetDefaultServerHostPort()` to get the port your server should listen to and `ReadyForPlayers()` method to transition your server to the StandingBy state.

```cpp
#if UE_SERVER
UGSDKUtils::SetDefaultServerHostPort();
#endif

// ...

void U[YourGameInstanceClassName]::OnStart()
{
UE_LOG(LogPlayFabGSDKGameInstance, Warning, TEXT("Reached onStart!"));
UGSDKUtils::ReadyForPlayers();
}
```

To create your container image to use on Kubernetes, you should build a "Linux Dedicated Server" and then use a Dockerfile similar to the following:

```
FROM ubuntu:18.04

# Unreal refuses to run as root user, so we must create a user to run as
# Docker uses root by default
RUN useradd --system ue
USER ue

EXPOSE 7777/udp

WORKDIR /server

COPY --chown=ue:ue . /server
USER root
CMD su ue -c ./ShooterServer.sh
```

### Samples

Check [this guide](https://github.com/PlayFab/MpsSamples/tree/main/UnrealThirdPersonMP) on how to integrate the [Unreal Third Person template](https://docs.unrealengine.com/4.27/en-US/Resources/Templates/ThirdPerson/) with the Unreal GSDK.
2 changes: 1 addition & 1 deletion docs/quickstart/installing-thundernetes.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ thundernetes-nodeagent-6x8c4 1/1 Running 0
thundernetes-nodeagent-eabgh 1/1 Running 0 17s
```

At this point, you are ready to run a test game server on Thundernetes to verify that the system is working as expected. If you want to run one of our sample game servers, check our [samples](samples.md). Otherwise, if you want to run your own game server, go to [this document](../developertool.md).
At this point, you are ready to run a test game server on Thundernetes to verify that the system is working as expected. If you want to run one of our sample game servers, check our [samples](samples.md). Otherwise, if you want to run your own game server, go to [this document](../gsdk/README.md).

The aforementioned scripts install Thundernetes with unauthenticated access to the allocation API service. This is fine for development scenarios, but for production environments you would need to secure the service. There are a couple of options you can use. Thundernetes offers a way to configure mTLS authentication to the allocation API service, you can read the next section. Alternatively, you can use a [Kubernetes Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) service, like [nginx-ingress](https://github.com/kubernetes/ingress-nginx). To lean how to secure your service, read our ["Protect your Services using an Ingress"](../howtos/serviceingress.md) document.

Expand Down
105 changes: 0 additions & 105 deletions docs/yourgameserver.md

This file was deleted.