Skip to content
Adam Probert
Projects

A series of successful stumbles.

Things I’ve built, paid and unpaid, roughly newest first. Each one comes with the lesson I actually took from it, and quite often that’s a mistake.

Some of these are finished, some are paused. At least one sat in a box for a year.

25 projects

Sheet 1 of 25

2026

For myself

Web

Personal project, live at dilectus.app.

I've been into 40k for a few years now. When 11th edition came out the official app dropped support for 10th, which I still wanted to play, so I started building Dilectus. It now covers every army in both editions. You choose a faction and detachment, add units and wargear, attach Leaders to their bodyguards and put units in Transports. The rules engine checks the list as you go. At the table you can track wounds and Command Points, or link your battle with another player's using a 4-digit code. Lists work without an account too, signing in just lets you keep them across devices. BSData and Wahapedia provide the game data. The app checks for updates every morning. Hosting runs on free tiers.

Lesson learned

The free tiers have sent me down quite a few rabbit holes. The import outgrew a Vercel function, so it moved to GitHub Actions. Keeping every old import used too much storage, so now I keep the active one for each edition and record the source versions needed to rebuild the others. The live battles took more work. Polling every 5 seconds kept the database awake even when nobody changed anything. Most people only had one device open anyway. Now those people make no background requests, and devices sharing a battle talk directly over WebRTC. I had to deal with phones sleeping and connections surviving page reloads along the way. There's a hidden connections page for seeing what each device is doing, I wish I'd built that earlier.

RULE GATE BLOCKS UNKNOWN DATASOURCESBSDATA · WAHAPEDIAGITHUB ACTIONSDAILY SYNC · 7 GB RAMNEON0.5 GB · ONE LIVE IMPORTVERCELSTATELESS FUNCTIONSOLDER IMPORTS ARE DELETED,REBUILT FROM THEIR SOURCE VERSIONSIF EVER NEEDEDSIGNALLING ONLYPHONETABLETWEBRTC · DEVICE TO DEVICE

Sheet 2 of 25

2026

For myself

Game

A personal Unity game project, currently paused.

ScrapKings is a top-down wasteland roguelike. You drive out, fight, salvage parts and bolt them onto your vehicle, then head somewhere nastier to get better ones. I wanted the upgrades to change how you play. A new part might let you drift, ram something or slam into the ground. It clips onto a visible socket, so by the end of a run the machine should look very different from the one you started with.

Lesson learned

This one's paused. The scope got ahead of me and the summer of 2026 was a glorious one. I did write the design pillars down early though, which helped when the ideas started piling up. Driving has to be fun before you get any upgrades. Parts should give you a new move. You also need to be able to tell what's happening when the screen gets busy. If an idea didn't fit those, I could leave it out before spending time building it.

Sheet 3 of 25

2025-26

For myself

Robotics

Just because it looked cool.

Cheddar can crab sideways, spin on the spot and climb stairs. It has a 3D-printed rocker-bogie chassis with a drive motor and steering servo for every wheel, so there's quite a lot going on underneath it. The Raspberry Pi runs the video and web controls. An ESP32 handles the motors and servos, and I drive it from a browser with a gamepad over WebRTC. It's finished and alive and well. I'd still like to give it an arm and have it dispense dog treats at some point.

Lesson learned

I shelved this for the best part of a year over a serial connection. I was set on using the Pi's GPIO pins to talk to the ESP32. It worked perfectly in isolation, Pi to ESP32 to drivers to motors and servos, then fell apart every time I put it all together. When I came back to it I tried a USB cable instead. It worked immediately. I'd spent weeks trying to get the GPIO version working and hadn't even tried USB.

Sheet 4 of 25

2025

For myself

AI / Web

Magic has over 27,000 unique cards. I wanted an easier way to find the one I meant.

You can know what you want a Magic card to do and still have no idea what it's called. Grimoire ML lets you describe it in ordinary language, then turns that description into a Scryfall query. The model produces a structured representation first. I can look at that to see what it understood, then build and test the actual search separately. There's a Next.js frontend, a FastAPI backend and a separate card-image proxy, with Redis caches between the services. It's a prototype.

Lesson learned

Having the model write search syntax directly made a bad result difficult to work out. Had it misunderstood the request, or was the query wrong? Putting a structured representation in the middle let me look at those separately. I could also test the whole query layer without making a model call. I put that in late, I'd start there if I built it again.

PROMETHEUS · /metricsIR CACHEREDISPOSTGRESBROWSERWEBAPP:3000 · NEXT.JSQUERY:8080 · NL → IRCARD-DB:8081 · IMAGESBACKEND:8000 · DECKSOPENAIGPT-5-MINISCRYFALLSEARCH + IMAGES

Sheet 5 of 25

2026

For myself

Platform

A take-home technical test.

This validates a Unity project, builds it for several platforms in parallel and gathers the results into a report. I used Temporal and .NET 8, with a simulation mode so you can run the whole workflow without having Unity installed. Temporal handles most of the orchestration. Getting several Unity builds to coexist on one machine took more work, because they want to use the same Library folder and the licensing setup assumes a single instance. Each build gets its own copy of the parts of the project it needs.

Lesson learned

I wrote architecture decision records alongside this. Trying to explain why I'd chosen something changed a few of the decisions, which I hadn't expected when I started writing them. They also leave the rejected options in the repo, so someone reading it can see what I considered. I didn't get the role. Still, it gave me a week to get into Unity's build tooling and licensing, both of which had rather more going on than I'd realised.

Sheet 6 of 25

2025

For myself

Hardware

ESP32 Servo Tester

I needed to set Cheddar's steering servos before fitting them to the chassis.

Turn the dial and the servo moves, with its angle shown on the little OLED. Tap the encoder to change the size of each adjustment. It's built around an ESP32-C3 and an EC11 rotary encoder, with eased motion and a printed enclosure. I made it while building Cheddar, where I was otherwise going back and forth adjusting the same servos.

Lesson learned

The dial from the enclosure design didn't fit my encoder shaft, so I remodelled it. Now I can plug a servo in and set it before assembly. It's a little jig for the robotics bench, really.

Sheet 7 of 25

2023

Professional work

Data

  • employerRocket Science Group
  • client · under nda

    A large games studio with a long-lived live-service title and millions of players transacting in it.

Migrating a fraud-detection data source

Rocket Science Group, for a long-running live-service game.

We replaced Kount with SEON as the game's fraud-detection provider. We rebuilt the Snowflake ETL pipelines and the Periscope reporting that depended on them. Several teams used the data, including people making decisions about the live game, so we had to work through what the new provider's outputs meant for each of them.

Lesson learned

I underestimated the time we'd need with those teams. The ETL changes were manageable, agreeing what 'the same number' meant after the switch took much longer. Different people were using the outputs to answer different questions. I'd bring those definitions into the planning much earlier next time.

Sheet 8 of 25

2025

For myself

Teaching

Pokemon SQL Trainer

A small teaching project for someone starting with no SQL knowledge.

A set of SQL challenges built around a Pokédex. You start with your first SELECT and work up to queries Professor Oak would be proud of. It runs against Postgres in Docker, so you've got a real database to experiment with as you go.

Lesson learned

Writing the exercises made me go back over things I'd stopped thinking about. If somebody has only just learnt SELECT, what do they need before they can try a join? I had to work through that order while putting the challenges together.

Sheet 9 of 25

2024

Professional work

Data

  • employerRocket Science Group
  • client · under nda

    An independent US games publisher, behind a free-to-play mobile fighting RPG that has run as a live service since 2017 and passed ten million downloads.

Rocket Science Group, for a free-to-play mobile fighting game.

One of the reports said somebody had bought a $40,000 battle pass. The pass had never cost anything close to that, a currency conversion had gone wrong. There were other discrepancies too, spread across the game's attribution, transaction and user data. I reconciled the sources and rebuilt the reporting in BigQuery, keeping the raw events, cleaned transactions and reporting views separate. There was also a 70 TB backlog to correct. We delivered it in two weeks, with daily demos as we worked through the data.

Lesson learned

By this point the teams had seen the numbers disagree often enough that they were hesitant to use them. Fixing a conversion didn't answer all their questions about the rest of the report. I spent about as long making the corrections traceable as I did making them, so somebody could follow a figure back through the pipeline and see how we'd arrived at it.

DAILY FX RATESSOURCESFIREBASE GA4 · ATTRBRONZERAW EVENTSSILVERCLEANED · FXGOLDTRUSTEDREPORTINGLOOKEROBSERVABILITY · ANOMALIES CAUGHT BEFORE THE DASHBOARD

Sheet 10 of 25

2026

For myself

Game

A weekend project combining genetic algorithms and games.

I made a genome that Unity can turn into a car, then sent a field of them racing over procedural terrain. The ones that get furthest breed into the next generation, with mutations changing the chassis, wheels, suspension and drive strength. You watch the races and bet on a car. That's as far as the player interaction goes at the moment, which leaves me with quite a few game-design questions.

Lesson learned

The chassis started as one random polygon. That gave me plenty of numerical variation, but on screen it was mostly the same lumpy blob with wheels. I want to try joined parts instead, so you can actually see a child inheriting an arm or a counterweight. Then there's what you do between races. Choose the parents? Protect a trait you like? Change the mutation rate? I haven't settled on it yet.

Sheet 11 of 25

2025

Professional work

Distributed systems

  • employerRocket Science Group
  • client · under nda

    A VR studio whose multiplayer title became a viral hit and now runs as a live service.

A four-week workstream in a Rocket Science Group engagement for a VR game studio.

Players needed to hear about friends coming online, invites and account or session warnings while they were in the game. I built the pipeline inside the backend, using a Redis Stream to hold the work and AWS API Gateway's WebSocket API to deliver it. The code raising an event writes a message and carries on. Consumers on the backend instances handle sending it. API Gateway keeps the sockets open, so the application only needs to track connection ids.

Lesson learned

The recovery loop is the thing I'd change. A consumer reclaimed old pending messages when it started, but didn't keep checking for them after that. If another instance crashed while holding a message, that message could sit there until the next deployment. I'd add periodic reclaim and a dead-letter stream for deliveries that keep failing. I'd also prune a connection as soon as API Gateway reports that it's gone.

AT-LEAST-ONCE · AUTO-CLAIM AFTER 30sTRIGGERSWEBHOOKS · EVENTSREDISSTREAM · BUFFERCONSUMERSGROUP ×NAPI GATEWAYWEBSOCKET APICLIENTSIN SESSIONCONNECTION IDS IN REDIS SORTED SETS · STATELESS APP

Sheet 12 of 25

2024

Professional work

Platform

Rocket Science Group, working with Amazon GameLift Servers.

A game server running at 60 Hz has about 16 ms for each tick. Adding metrics code takes some of that time, and if the collector occasionally spikes then you've introduced the sort of problem you're trying to measure. I worked on the observability system across C#, C++ and Go, including the metric definitions, OpenTelemetry pipeline and default dashboards. I built the Unity SDK end to end and wrote the public metrics documentation. The wider work covered Unity and Unreal servers on Windows and Linux.

Lesson learned

Moving timings to histograms and percentiles showed bad frames that the averages had hidden. We had to be just as careful with the collector's own timings, including the occasional slow tick. There was a lot to agree across the three SDKs too. A metric with the same name needs the same units and behaviour in each language, or a studio looking at the shared dashboard can end up comparing different things.

Sheet 13 of 25

2023

Professional work

Platform

  • employerRocket Science Group
  • client · under nda

    A live-service game studio with tens of millions of players, launching its first paid title.

Rocket Science Group, for a games studio releasing its first premium title.

Every download path in the studio's launcher assumed the game was free. Their first paid title needed ownership checks across the launcher, backend and CDN. I worked on the Lambda entitlement checks, Akamai's gating around the files and the TypeScript and React launcher. We also added single-use vouchers for developers and beta testers. Launch day was an important part of the design, because almost no traffic could become the whole player base arriving within a few minutes.

Lesson learned

I initially went looking for one place to enforce access. The launcher is on the player's machine though, so they can change what it does. A backend check doesn't stop somebody going straight to the file URL. And if the CDN refuses a request, the player still needs to understand why their download didn't start. There was some pushback on repeating the checks. Explaining the job of each one helped us get past that, particularly the difference between telling a player they can download and actually protecting the file.

Sheet 14 of 25

2023

For myself

Game

Ludum Dare 53, with Sam Neale, Daniel Neenan, Luke Berry and Amber Hornsby.

Five of us made Post Haste over a weekend. You play a package that realises it isn't on the delivery truck, then rolls and jumps across the warehouse to reach it. There are planks to cross, puddles to avoid and a few objects that turn out to be friendly. We made three levels in Unity and put the WebGL build on itch. It's the most successful thing we've submitted to a jam, it ranked well and people came back to compete over the best times.

Lesson learned

We had the box rolling and jumping within a few hours. Two inputs, no grabbing things or inventory to build, so we had the rest of the weekend to play it and make levels. The jump became more interesting as we did that. It adds to the force you've already built up, so timing it well carries speed and mistiming it can kill your run. We found that while playing the first version, then built around it.

Sheet 15 of 25

2022-23

Professional work

Developer experience

An internal developer platform for a siloed engineering team

In-house developer experience work at Cazoo.

Cazoo's teams had developed different ways of building and running their services. We worked on shared CI/CD conventions, observability and alerting, with infrastructure as code across the environments. The internal developer platform launched within a quarter. Alongside it we helped set up a Champions Network, with engineers inside the teams advocating for the standards and helping people use them.

Lesson learned

I'd assumed the platform would get adopted once it made the common jobs easier. Teams still needed to see how it fitted their own services though. The Champions Network gave them a colleague to ask, someone who could work through the standards in the context of that team's code.

Sheet 16 of 25

2022

Professional work

Data

Made Tech, working with Skills for Care's Workforce Intelligence team in 2022.

When I arrived there wasn't an AWS account yet. The analysts were moving data around as flat files in Dropbox. They knew the adult social care data inside out, and they were good with Excel and SQL. Software development was new to them. We built the AWS infrastructure in Terraform and wrote Python and Spark pipelines for the workforce models. Models could be explored in Jupyter, then moved into tested jobs when they were ready to run in production. The three analysts ended up running and changing those pipelines themselves.

Lesson learned

About half of this work was teaching. I needed to build the relationship and earn some credibility before turning up with a different way of doing everything. We started with the SQL the analysts already knew, moved into Python that felt familiar and brought in the command line when they had a reason to use it. The setup had to work well too. An experienced engineer might work around a strange error, somebody learning can lose an afternoon to it. We spent time on the development environment and put the tests and quality checks into the normal workflow. The repository is public and still being developed years later. It includes tooling choices the team made after our engagement.

Sheet 17 of 25

2021

Professional work

Web

The DVLA's first fully digital provisional licence service

Made Tech, working with the DVLA across several Nexus Scrum squads.

I worked on digitising the DVLA's first provisional licence service. Applicants used a Ruby on Rails frontend built to GOV.UK standards, and staff processed the applications through a React portal. The backend used AWS Step Functions and Lambda with DynamoDB and queues, plus Elasticsearch for reads and reporting.

Lesson learned

The public sector design and style guides are rock solid. They're intuitive and straightforward to build against, I came away with a lot of respect for them. The risk culture was harder going though. End-to-end tests took 90 minutes and the rollback path was cumbersome enough that people were reluctant to use it. Mistakes still got through. I wanted us to be able to deploy a fix in ten minutes when that happened.

Sheet 18 of 25

2020

For myself

Game

A personal Unity game project.

Exhausted is an apocalyptic vehicle combat game. The cars use PhysX, tuned to keep some weight in the handling while still being fun to throw around an arena. There are different cars, weapons and environments, with an arcade mode for getting straight into it. I built behaviour-tree AI and a custom navmesh agent for the enemy vehicles. And a lot of explosions.

Lesson learned

Unity's navmesh agent assumes something that walks. It can stop, strafe or turn on the spot, all fairly unhelpful assumptions for a car. I used the navmesh to find the route and wrote a separate layer for how the vehicle would drive along it.

Sheet 19 of 25

2020

For myself

Game

The Road

A personal Unity RTS project.

The Road is a squad-based RTS about survivors banding together through a zombie apocalypse. The feature I liked most was overwatch. You put a survivor on watch and they automatically target zombies moving through their cone, with line of sight accounted for. You can position the squad around that coverage.

Lesson learned

The overwatch mechanic only became understandable once I drew the cone on screen. Before that, players couldn't see where the rule applied. Showing it gave them something they could plan around.

Sheet 20 of 25

2020-22

For myself

Game

OfficeTanks

A small personal Unity game.

Tanks fighting across an office desk. The tanks, projectiles and objects are physically simulated, with a simple enemy AI to fight against. You can play the Unity WebGL build straight in a browser.

Lesson learned

I'd already made games people had to download, and hardly anyone tried them. It took me a couple of goes to learn that. OfficeTanks was on the web, so I could send someone a link and they could play it there and then.

Sheet 21 of 25

2019-20

Professional work

Web

DabApps, working with Agilio Software.

iComply helps dental practices keep their compliance work in order and prepare for CQC inspections. Four of us rebuilt it in Django, PostgreSQL and React over 18 months. We covered the recurring tasks and calendars, policies, dashboards and finance work, with subscriptions and single sign-on across the Agilio products. The old system worked, but people didn't enjoy using it. We redesigned the interface as part of the rebuild and showed the client working software every week.

Lesson learned

The weekly demos made this the best delivery I'd worked on. We gathered feedback and made decisions with the client in the room, and I've kept that habit since. Late on they mentioned wanting a 'dual-ledger' system. We took the phrase at face value and spent six weeks building double-entry accounting, including journals and tax handling. It turned out they'd read the term somewhere and weren't sure what it meant. They wanted a simple finance ledger, about a week's work. The extra accounting machinery stayed in the product. Every later finance feature had to work through it, and we felt that for months. We'd skipped the demo and the questions on this part of the system.

Sheet 22 of 25

2019-20

For myself

Game

Gravitap

A personal mobile game project.

In Gravitap you tap to place stars, then use their gravity to pull a moving ball around the map. Tap a star again to remove it. You can chain the gravity fields together for a higher multiplier, while trying to reach the goals and avoid the hazards. I built it in Unity and released it on Google Play.

Lesson learned

Getting the game working left quite a bit still to do. There was the store listing, signing the build and producing screenshots at seven different resolutions.

Sheet 23 of 25

2017-19

Professional work

Data

  • employerBT

Hermes

In-house at BT Global Services.

We were trying to investigate problems across systems we couldn't see properly. I pushed for Hermes and managed to get room for myself and two others to build it. It collected logs and metrics from across the application stack and made them available in Kibana. The analytics engine scaled on Docker Swarm, with Kafka moving the data and the ELK stack, Hadoop, Sqoop, Hive and Spark doing the processing.

Lesson learned

Hermes started with a gap I wanted fixed. Once we'd got something going, it caught senior management's attention and became part of the official roadmap. Seeing an idea I'd argued for become work the wider team wanted to keep was new to me. I also learnt more on this than on a lot of the projects I'd been assigned. Containers, distributed processing and observability were all things I had to get working together.

Sheet 24 of 25

2017

For myself

Research

Beacon Investigation

My final-year BSc dissertation.

I investigated whether Bluetooth beacons could help people navigate a festival. It's a large site that only exists in that form for a short time, so I was interested in whether proximity information would be useful there. The dissertation included primary research into that question.

Lesson learned

I had to defend the research to people whose job was to question it. I'd been used to checking whether something I'd built worked. This time I had to explain what the evidence supported and where my conclusions were limited.

Sheet 25 of 25

2014

For myself

Mobile

My first proper personal project, with another developer and a graphic designer.

Managercash had wallets, budgets, recurring transactions and savings goals. The expense screen was a grid of category icons, with the running total on each. Tap the category and enter the spend, so logging something didn't take you through a stack of forms. Three of us built it over one university summer. It got far enough that people were entering their real expenses into it.

Lesson learned

Final year started, the funding ran out and we stopped. The app was working, we'd just planned for the summer and given very little thought to how we'd keep it going afterwards.

Where all this happened

  • 2023 - nowRocket Science Group · Lead Software Engineer
  • 2022 - 23Cazoo · Senior Platform Engineer
  • 2021 - 22Made Tech · Senior Data / Software Engineer
  • 2019 - 21DabApps · Senior Software Engineer
  • 2017 - 19BT · Data Engineer
  • 2015 - 17BT · Production Database Administrator
  • 2012 - 15Cardiff University · BSc Computer Science
Contact

Say hello.

If you’re stuck on something or thinking about starting a project, I’m happy to chat it through.

Get in touch
  • Something you're building, or thinking about building
  • A problem you're stuck on and want another pair of eyes on
  • Anything on this site you want to know more about
  • A role or piece of work worth a conversation