{"id":17273604,"url":"https://github.com/markmandel/paddle-soccer","last_synced_at":"2025-08-18T13:19:15.764Z","repository":{"id":57557471,"uuid":"83243898","full_name":"markmandel/paddle-soccer","owner":"markmandel","description":"A simple, two player multiplayer game built to show how you can host dedicated game servers on Kubernetes.","archived":false,"fork":false,"pushed_at":"2018-05-22T18:18:41.000Z","size":28638,"stargazers_count":172,"open_issues_count":0,"forks_count":41,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-08-14T22:57:25.111Z","etag":null,"topics":["dedicated-gameservers","game-development","kubernetes","unity3d"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/markmandel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-26T22:03:02.000Z","updated_at":"2025-03-27T08:29:02.000Z","dependencies_parsed_at":"2022-09-08T17:01:43.051Z","dependency_job_id":null,"html_url":"https://github.com/markmandel/paddle-soccer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/markmandel/paddle-soccer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markmandel%2Fpaddle-soccer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markmandel%2Fpaddle-soccer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markmandel%2Fpaddle-soccer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markmandel%2Fpaddle-soccer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/markmandel","download_url":"https://codeload.github.com/markmandel/paddle-soccer/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markmandel%2Fpaddle-soccer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270998265,"owners_count":24682214,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-18T02:00:08.743Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dedicated-gameservers","game-development","kubernetes","unity3d"],"created_at":"2024-10-15T08:51:44.600Z","updated_at":"2025-08-18T13:19:15.739Z","avatar_url":"https://github.com/markmandel.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Paddle Soccer\n\nA simple, two player multiplayer game built to show how you can host dedicated game servers on [Kubernetes](https://kubernetes.io/).\n\nIt has been implemented using [Unity](https://unity.com) for the game client and dedicated game server, and [Go](https://golang.org/) for the backend service components that sit on top of Kubernetes.\n\n![Screenshot](screen.png)\n\n## Overview\n\nGame servers are started up as a [Pod](https://kubernetes.io/docs/user-guide/pods/) on request through the Kubernetes API, and configured to use [Host Networking](https://kubernetes.io/docs/resources-reference/v1.5/#pod-v1), to avoid any network latency issues through a Load Balancer. The Game Servers start on a random port between a given range (defaults to 2000-3000), and then register themselves against a custom API with their Pod name for later lookup.\n\nOnce the game server has started, we use the combination of the Kubernetes API and the aforementioned custom port registry to determine which node in the Kubernetes cluster the Pod has been scheduled on, that node's external IP and what port the game server is open on. This is then pass that back to the game client, through a match maker or otherwise, so that they can connect to it directly.\n\n## Blog Posts\n\n- [Scaling Dedicated Game Servers with Kubernetes: Part 1 - Containerising and Deploying](http://www.compoundtheory.com/scaling-dedicated-game-servers-with-kubernetes-part-1-containerising-and-deploying/)\n- [Scaling Dedicated Game Servers with Kubernetes: Part 2 – Managing CPU and Memory](http://www.compoundtheory.com/scaling-dedicated-game-servers-with-kubernetes-part-2-managing-cpu-and-memory/)\n- [Scaling Dedicated Game Servers with Kubernetes: Part 3 – Scaling Up Nodes](http://www.compoundtheory.com/scaling-dedicated-game-servers-with-kubernetes-part-3-scaling-up-nodes/)\n- [Scaling Dedicated Game Servers with Kubernetes: Part 4 – Scaling Down](https://www.compoundtheory.com/scaling-dedicated-game-servers-with-kubernetes-part-4-scaling-down/)\n\n## Presentations\n[![GCAP Australia](https://img.youtube.com/vi/a08WrvIPKMw/maxresdefault.jpg)](https://www.youtube.com/watch?v=a08WrvIPKMw\u0026feature=youtu.be)   \n[![GDC](gdc.jpg)](http://www.gdcvault.com/play/1024328/)\n\n## Unity Structure\nThe unity source code can be found in the `unity` folder.\n\nIt was built with [Unity 5.6.0](https://store.unity.com/download). It was built on Linux, but the\nclient should run on any OS.\n\nTo quickly make the Client and Server builds (for Linux), you can run the [Build Pipeline](https://docs.unity3d.com/ScriptReference/BuildPipeline.html) under the `Build \u003e Build Game and Server` menu\n\nOnce the server infrastructure has been configured, you can start the game with a `-match` command line argument, to tell it where the matchmaker is. For example:\n\n```bash\n./Game.x86_64 -match \"http://10.32.14.10\" -logFile /dev/stdout\n```\n\n## Server\n\nAll the non-Unity server side code is found in the `server` folder.\n\n### Infrastructure\n\nThis project works on Kubernetes [1.6.0](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG.md#v160) or higher, as it uses Kubernetes [Node Affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#node-affinity-beta-feature).\n\nIf you have a [Google Cloud Platform](https://cloud.google.com/) Project configured and the [Google Cloud SDK](https://cloud.google.com/sdk/) installed, you can cd into the `infrastructure` folder, and run `make deploy` to deploy a 4 node cluster over 2 nodepools, as well as the accompanying firewall rules.  `make auth` will authenticate your local `kubectl` tooling with this cluster.\n\n### Node Pools\n- There are two [Node Pools](https://cloud.google.com/container-engine/docs/node-pools) withing this cluster. \n    - \"apps\" (Node Selector `role=apps`) - which is the area in which Sessons, Matchmaker and Nodescaler all run, so as to keep application separate \n    from the game servers, and not have them impact CPU performance.\n    - \"game-servers\" (Node Selector `role=game-servers`) - for which game servers will be exclusively run on, and for ease of\n    autoscaling.\n\n### Game Server\n\nThe `game-server` folder contains Dockerfile for the Unity dedicated server. To build the server, and the image (on Linux) run `make build` and then `make push` to push the image up to [Container Registry](https://cloud.google.com/container-registry/) for use.\n\n### Sessions\n\nThe `sessions` folder contains the Go application manages the HTTP API that creates new instances of the Unity Game Server within a Pod. It also hosts the HTTP API the that Game Server connects to to register the port that it currently runs on, with the podname is it provided through an Environment variable.\n\nTo build the code for the Docker image and push the image up to the Container Registry, run `make build push`. \nTo deploy, run `make deploy-all` and it will deploy the [Redis](https://redis.io/) Stateful Set, and the \n[Kubernetes Deployment](https://kubernetes.io/docs/user-guide/deployments/) and accompanying [Service](https://kubernetes.io/docs/user-guide/services/).\n\n### Matchmaker\nThe `matchmaker` folder contains a Go application that is a very simple HTTP based matchmaker that pairs the first two players that request a game in FIFO order. It coordinated with the session manager to start game servers, and inspect what IP and port they are running on, so it can be passed back to the client.\n\nTo build the code for the Docker image and push the image up to the Container Registry, run `make build push`. \nTo deploy, run `make deploy-all` and it will deploy the Redis Stateful Set, and the Kubernetes Deployment and accompanying Service.\n\n### NodeScaler\n\nThe `nodescaler` folder contains a Go application that tracks resource usage within the `game-server` node pool and\nincreases the number of nodes if the amount of CPU space available falls below a certain buffer value. Once the buffer is exceeded, the node scaler will first cordon nodes that have game servers\nstill running on them, and then eventually delete them once they are empty of running dedicated game servers.\n\nCurrently only implemented to work on Google Cloud Platform, through its [Container Engine API](https://cloud.google.com/container-engine/reference/rest/) \nand [Compute Engine Instance Group Manager API](https://cloud.google.com/compute/docs/reference/latest/instanceGroupManagers), \nbut has been written for extension if required.\n\nTo build the code for the Docker image and push the image up to the Container Registry, run `make build push`. \nTo deploy, run `make deploy-all` and it will deploy the Kubernetes Deployment for this.\n\n\n## Licence\nApache 2.0\n\nThis is not an official Google product.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkmandel%2Fpaddle-soccer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarkmandel%2Fpaddle-soccer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkmandel%2Fpaddle-soccer/lists"}