Much like other events in 2020, our annual internal hackathon took a remote format this year, sporting over 120 hackers from across the globe. We had many challenges available during the conference which included a password cracking challenge, a discord bot challenge and a programming challenge. This post will talk about the programming challenge called sconwar. You can get the source code for it here.
Admittedly I was really nervous about the idea for a hacker hackathon in general, but we can only become better hackers by understanding technologies better, more specifically, understanding them by using them. I often hear people say they want to get into programming, for which there are many options, but more often that not the drive ends with “well, what do I code?”.
REST-ful API’s are an incredibly common and easy to understand RPC, and most languages have have either a baked in HTTP client or a popular package for one. To this end, I decided I’d give some people a reason to code up something while having some fun by building a programming challenge in the form of a game that exposes a JSON API.
I played with many ideas, bouncing some of them off Jameel, but finally settled on an idea that became sconwar. The name itself is short for SenseConWar. Spawning a 20 by 20 tiled board, players were to battle it out to reach a top score in a turned based game filled with creeps, other players (optional) and some fun power ups to give you a small advantage. The only method of interaction with the game was to be via a JSON serialised HTTP API. This is where the “bring your own client” idea came from.
I decided to write the server in Golang, using the Gin web framework for the API and a custom, home-grown game engine written from scratch. The Gin router served as the blocking call keeping the game alive, while games that were being played all ran in separate goroutines. As for API documentation, I decided on using Swagger, but autogenerated them with code annotations and swag. This way, whenever an API call/model changes, updating documentation was a cinch. While a game was running, logs and other stats would be persisted to a simple SQLite database for record keeping purposes.
To help accelerate client development, Jameel and Martin helped build a view-only web UI. They used Svelte for the frontend that consumed exactly the same API as players would for their clients. Players could use the client as a reference for their own, or to focus on Action submissions instead.
As an example, I built my own sconwar client. It served primarily as a way for me to test game server logic, but also as inspiration for other ideas. A day after releasing the challenge, I teased, using a video, what an example client could look like.
After playing that game , the score board was as follows (which did not last very long with me on top as others starting racking up some points!)
I was blown away by what other people were able to come up with in a really, really short amount of time. Of course you could use the SwaggerUI to play a game, but that would not have been the most efficient way to get a high score. Some players clients showed early signs of automated decision making based on their surroundings which was super cool to see. Some screenshots of other clients as they were being built looked like this:
Some people continued playing even after SenseCon had wrapped up, with two more clients surfacing.
statistics & monitoring
Jameel played an instrumental role in the observability built for sconwar. Using prometheus, metrics relating to how games were played, as well as how the server was performing, were realised via Grafana. It was a lot of fun watching these as the various clients were being built. Some example metrics are shown below.
A super big thanks to Jameel and Martin for their help in making it happen, I think it was a great success!