Skip to main content

Agones Headless Allocation API

Overview

Since we have a fleet of warm game servers, we need a way to request one of them for usage, and mark that it has players accessing it (and therefore, it should not be deleted until they are finished with it).

https://agones.dev/site/docs/getting-started/create-fleet/#4-allocate-a-game-server-from-the-fleet

SampleAPI

In the sample project, we also prepared a sample API project for accessing Agones API

Build SampleAPI Docker Image

Open another terminal or command prompt and cd to the SampleAPI directory

run

& minikube -p agones docker-env | Invoke-Expression
docker build -t agones-api .

result

Sending build context to Docker daemon  39.94kB
Step 1/19 : FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
6.0: Pulling from dotnet/aspnet
1efc276f4ff9: Pull complete
e5aeae5c9ad4: Pull complete
9d8b4edc672a: Pull complete
67bb3a123350: Pull complete
4b31f33ff8ee: Pull complete
Digest: sha256:6ca5c440d36869d4b83059cf16f111bb4dec371c08b6e935186cc696e89cc0ba
Status: Downloaded newer image for mcr.microsoft.com/dotnet/aspnet:6.0
 ---> f7c23c3cf6cf
Step 2/19 : WORKDIR /app
 ---> Running in 9aa3d7dd7cac
Removing intermediate container 9aa3d7dd7cac
 ---> c028801102ce   
Step 3/19 : EXPOSE 80
 ---> Running in 01945617296e
Removing intermediate container 01945617296e
 ---> 28b7439055eb
Step 4/19 : FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
6.0: Pulling from dotnet/sdk
1efc276f4ff9: Already exists
e5aeae5c9ad4: Already exists
9d8b4edc672a: Already exists
67bb3a123350: Already exists
4b31f33ff8ee: Already exists
c8d14979ed53: Pull complete
67e9673ecfe7: Pull complete
67d70801a7e7: Pull complete
Digest: sha256:dd19f6aa2774de9fde18c78970bc4fdebc695bd824c73371b6faec306a18b230
Status: Downloaded newer image for mcr.microsoft.com/dotnet/sdk:6.0
 ---> 56ae586b64e8
Step 5/19 : WORKDIR /src
 ---> Running in d214d0107d22
Removing intermediate container d214d0107d22
 ---> 82640c645d4e
Step 6/19 : COPY ["API/API.csproj", "API/"]
 ---> 415fda16d2d5
Step 7/19 : COPY ["Agones/Agones.csproj", "Agones/"]
 ---> f6ae638ec9a4
Step 8/19 : RUN dotnet restore "API/API.csproj"
 ---> Running in 014886163fe1
  Determining projects to restore...
  Restored /src/API/API.csproj (in 9.4 sec).
  Restored /src/Agones/Agones.csproj (in 9.4 sec).
Removing intermediate container 014886163fe1
 ---> d64310344275
Step 9/19 : COPY . .
 ---> 15fe17bc89d6
Step 10/19 : WORKDIR "/src/API"
 ---> Running in db60d5ac3967
Removing intermediate container db60d5ac3967
 ---> a27efd97b4f0
Step 11/19 : RUN dotnet build "API.csproj" -c Release -o /app/build
 ---> Running in bed9c5c71072
MSBuild version 17.3.0+92e077650 for .NET
  Determining projects to restore...
  All projects are up-to-date for restore.
  Agones -> /app/build/Agones.dll
  API -> /app/build/API.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:03.13
Removing intermediate container bed9c5c71072
 ---> 634b5a3fb78b
Step 12/19 : FROM build AS publish
 ---> 634b5a3fb78b
Step 13/19 : RUN dotnet publish "API.csproj" -c Release -o /app/publish /p:UseAppHost=false       
 ---> Running in b42d1ba8e008
MSBuild version 17.3.0+92e077650 for .NET
  Determining projects to restore...
  All projects are up-to-date for restore.
  Agones -> /src/Agones/bin/Release/net6.0/Agones.dll
  API -> /src/API/bin/Release/net6.0/API.dll
  API -> /app/publish/
Removing intermediate container b42d1ba8e008
 ---> 44083efde237
Step 14/19 : FROM base AS final
 ---> 28b7439055eb
Step 15/19 : ARG PROJECT_NAMESPACE=default
 ---> Running in c5254b8d9d7d
Removing intermediate container c5254b8d9d7d
 ---> 4d19a4bc7d3a
Step 16/19 : WORKDIR /app
 ---> Running in f6e0111d9b59
Removing intermediate container f6e0111d9b59
 ---> 47ca10364e13
Step 17/19 : COPY --from=publish /app/publish .
 ---> ae22460a1167
Step 18/19 : ENV PROJECT_NAMESPACE="${PROJECT_NAMESPACE}"
 ---> Running in 2081d6073fab
Removing intermediate container 2081d6073fab
 ---> f2f0c75eb2a8
Step 19/19 : ENTRYPOINT ["dotnet", "API.dll"]
 ---> Running in c3f0fb52cf9c
Removing intermediate container c3f0fb52cf9c
 ---> 26f99d472126
Successfully built 26f99d472126
Successfully tagged agones-api:latest
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. 
All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

Deploy SampleAPI Docker Image

After successfully creating your image, you now can deploy your SampleAPI image into your local cluster

run

kubectl delete serviceaccount agones-api-account
kubectl delete role agones-api-role
kubectl delete rolebinding agones-api-rolebind
kubectl delete service agones-api
kubectl delete pod agones-api
kubectl apply -f Deployment\service-account.yaml
kubectl apply -f Deployment\api.yaml
kubectl wait --for=condition=Ready pod/agones-api
kubectl port-forward --address 0.0.0.0 pod/agones-api 80:80

result

Error from server (NotFound): serviceaccounts "agones-api-account" not found
Error from server (NotFound): roles.rbac.authorization.k8s.io "agones-api-role" not found
Error from server (NotFound): rolebindings.rbac.authorization.k8s.io "agones-api-rolebind" not found
Error from server (NotFound): services "agones-api" not found
Error from server (NotFound): pods "agones-api" not found
serviceaccount/agones-api-account created
role.rbac.authorization.k8s.io/agones-api-role created
rolebinding.rbac.authorization.k8s.io/agones-api-rolebind created
service/agones-api created
pod/agones-api created
pod/agones-api condition met
Forwarding from 0.0.0.0:80 -> 80

don’t worry if you see an error saying Error from server (NotFound), that’s normal if you never deployed the SampleAPI before

After deploying, you will see

Forwarding from 0.0.0.0:80 -> 80

these are port forward because we are using local kubernetes so that you can access the container directly from localhost, in the production environment, these are not needed

After finished using the API you need to press ctrl+c in the terminal to stop the port forward

Now you can access the API from http://localhost/swagger/index.html

Photon Fusion Mechanic Integration Example

In photon fusion, you can’t really connect directly to a game server using IP and PORT, you can only connect to a game server using sessionId

If you open the SampleAPI project solution, there are 2 projects inside Agones and API

Untitled

Inside MatchController.cs there are 3 sample endpoints that use provided methods from /API/Controller/AgonesControllerBase.cs to help you call agones API

  • GetGameServers - get all running game servers and return directly
  • FindGameSession - get all running game servers, and get one game server with state Ready, then return the label value of “agones.dev/sdk-session-name“ as sessionId. This label is set by each game server (FusionDedicatedServer)
  • AllocateGameSession(sessionId) - receive a sessionId and use it as required match labels to allocate the game server with that sessionId and return the allocation result
  • AllocateGameSession() - basic allocation for agones

The sessionId in FindGameSession and AllocateGameSession is a fusion mechanic, you don’t really need sessionId if your game server does not use Photon Fusion

Chanel System Example

Some multiplayer games like an MMORPG might have some kind of channel system to spread out the players, there are multiple reasons for this, for example, to spread the network load for each headless or to increase the area for players to play so there is no fighting over a hunting spots or monsters

Channels are just multiple instances of the same area or map running in multiple headless players can connect to or select from the game menu

We provided an example implementation of the channel system inside SampleAPI

Inside /API/Controller/ChannelController.cs there is a single endpoint called GetChannels, what this does is

  • get all game servers
  • get previously generated channel data if exist
  • filters the game servers by label “app=unity-headless-lobby”, so that only the channel game server is selected
  • filters only game servers with state Ready, Reserved or Allocated
  • generate channel data, in this example, we set the channel name using a random country name, set the max players and player count of the channel (the max players and connected players are also get from the game server label)
  • next, we save the channel data so that for the next request we will have the same name for the channels, unless there is a new channel then it will be given a new name
  • we also removed unused channel data because sometimes the headless will be shut down to scale down empty headless to save costs
  • then all channel data get returned to the client

Untitled

Label

The label is a key value pair type of information for each headless container, you can use the label either for filtering or getting information about the headless

We are using label to filter the headless game server and to get the max players and the player count of the channel, the label is set from the deployment configuration, and the channel headless

“app” is set from /SampleHeadless/Deployment/lobby-fleet.yaml

“agones.dev/sdk-max-players” and “agones.dev/sdk-active-players” is set from /SampleHeadless/LobbyFusionUnityExample/Assets/Scripts/ServerEventsInfo.cs

more about labels: