// HACKER NEWS — CYBERSECURITY
The backend that ran every game we made, ten years and counting
Seven games, eleven platforms, one self-built backend for crash reports, remote config, cloud auth and console ports. One developer, ten years, now in C#.
Every game I worked on in the last ten years talks to the same backend. Marooners, Verdun, Tannenberg, Isonzo, Crash Drive 2 and Crash Drive 3, and since this year a seventh game that another studio built on it. Steam, Epic, the Windows Store, PlayStation 4 and 5, Xbox One and Series, Switch, iOS, Android, WebGL. All of it reports to one Google App Engine project in PHP, backed by Firestore. I called it the GDT, short for Game Development Toolkit. The name sounds generic, but so is the tool: backend, admin, a small player portal for account linking and closed tests, and the Unity package, and it took on a new job with every game. The PHP version ran ten years without an outage a player noticed, and has now been replaced by a C# version. This piece covers the PHP years; the screenshots are from the C# version, and a section near the end covers what is new.
Our hosting bill for all of those games together was between 10 and 50 euros a month, depending on how many people were playing, most of them in the free mobile games. If nobody played, it would cost nothing. For the premium games the cost per paying player was negligible. I built it alone, and there has been almost nothing to maintain: Google kept the old PHP runtimes alive, the few moves to a newer one broke nothing, and it just runs. Keeping it simple, PHP included, has paid off tremendously.
It is also the part of our work nobody sees. Players see the game, reviewers see the game, and the thing that made every launch and every port possible sits behind an admin login. I have wanted to show it around for years. So here it is.
The Crash Drive 3 dashboard, four years after launch. Of the last three hundred players to sign in, four in ten were on Android, a quarter on iPhone, a quarter on Switch. That mix is why we ship everywhere: the people who paid on Steam or Switch always have someone to drive into.
Before this I wrote small PHP scripts for every game, lots of them, whenever a game needed something online: live news in the main menu, a counter, a version check, a little event. They were ugly and I kept writing them again from scratch.
What changed that was the Marooners console release. We were taking a party game made by six friends to PlayStation 4, Xbox One and PC, and I was the porting team, with Matt on testing and UI. Once the game left our hands I had no idea what happened inside it. On PC you get a Steam forum post when something breaks. On console you get silence, and later a certification failure.
The first attempt was Piwik with a Redis backend. I knew the database would be the bottleneck and Redis is very fast, so I had a freelancer set it up, because I had no idea how Redis worked. I never got it running properly. Power tends to bring complexity you did not ask for, and every time something went wrong I was reading someone else’s architecture instead of shipping. That is the one thing I cannot stand in a tool. I want to build a feature in the morning and have it live in the afternoon, and anything that gets in the way of that has to go. So I threw it out and built my own on App Engine and Firestore, in PHP, with no schema and no framework. I applied for WBSO, the Dutch R&D tax credit, for that rebuild. The money was modest, but writing it down as a serious project made me treat it as one.
A lot of it was built over a Christmas holiday. It was already working in Marooners, so dropping it into Verdun after the break took days rather than weeks, and someone on the WW1 team asked whether I had worked straight through the holidays.
From there it grew one game at a time. The WW1 games were made by WW1 Game Series, the company Jos, Matt and I founded, with a team that grew to twenty-five over the years. Crash Drive 2 was me again, with Matt on testing and UI. Crash Drive 3 was four of us. Every release a