AdditronK8S is a retro game machine build as a Kubernetes custom controller and implemented in Javascript.
The name
Additron
is a tribute to the great inventor and scientist Josef Kates who invented the first digital playing machine to showcase his Additron tube invention.
I did this as a PoC for a company talk (Video), to demonstrate how powerful can be the Kubernetes APIs when used also to build custom applications.
I chose to use Javascript as it is an officially supported client and also because I didn't find any project a bit more complex than a simple hello world, to implement a custom controller.
Personal note: When developing for Kubernetes, you have to deal with tons of REST APIs and complex relationship between them, this is where the GO ecosystem shines, you have framework and abstractions used to build Kubernetes itself and you are sure to use top-notch quality code; so if you plan to implement something serious with Kubernetes, my advice is to use GO as a first class citizen language of your system.
One of the goal of this project was to use just Kubernetes API without any external dependency (neither the storage),
infact is noteworthy that Configmaps
are (ab)used as a persistent storage layer, using a simple technique
of split/merge parts of files to save the games.
How it works (hand written schematic):
See it in action:
Here you can find the slides of my talk: https://www2.slideshare.net/sparkfabrik/retro-gaming-machine-made-with-javascript-and-kubernetes
This project consists of 3 main components:
WARNING: The code is not even close to be production ready, it is just a quick PoC to build a custom controller in Javascript.
You just need a working k8s cluster, with a working external connection.
To install it from the root, run the following commands:
kubectl apply -f k8s/manifests/namespace.yml
kubectl -n games apply -f k8s/manifests/crd-game-controller.yml
kubectl -n games apply -f k8s/manifests/game-controller-sa.yml
kubectl -n games apply -f k8s/manifests/game-controller-cluster-role.yml
kubectl -n games apply -f k8s/manifests/game-controller-cluster-role-binding.yml
kubectl -n games apply -f k8s/manifests/game-controller.yaml
Now you can run a demo game to test if everything is working as expected:
kubectl -n games apply -f k8s/games/quake.yml
You can also tail the logs of the game-controller to ensure that it was successful in processing the location of your game zip file.
kubectl -n games logs deployment/game-controller -f
Once you have the game up and running, you can access via the web browser by proxying the game service, like this:
kubectl -n games port-forward svc/quake 8080:8080 8081:8081
Finally you can access the game console on: https://localhost:8080
At this stage you will be presented with the dosbox command line and the command to run to execute the game.
IMPORTANT: To start the audio websocket, before to start the game and inside the dosbox cli, you have to press
ALT + s
this will start once the needed websocket, to transport the audio from the pulseaudio server to your browser.
Files can be downloaded from any public http endpoint or from any public GCP cloud storage bucket.
The expect manifest to run a game is this:
apiVersion: retro.sparkfabrik.com/v1
kind: Game
metadata:
name: game-name
spec:
name: "Game name human friendly"
zipUrl: "gs://my-gs-bucket/game.zip"
dir: "GAME"
exe: "GAME.EXE"
Where dir
represent the directory of the unzipped game and exe
the binary to run.
To be clear, this is a structure we expect:
unzip game.zip
> GAME
- GAME.EXE
- SOUND.MOD
- VIDEO.MOD
The development environment is based on k3d
and skaffold
,
by running make dev
you will have end up with: