Projects & Experience

Projects I designed and built, from low-level performance to GitOps in production, shown oldest to newest. The thread across all of them: I dig to the bottom of the system, deeper than the task asked for, and own the technical foundation. It ends at MyFoodBudget, a whole SaaS I built and run in production, solo.

HorrorMaze - 3D Horror Game in MonoGame

Datamatiker 1st-year exam | 2023 | 2 person team | grade 12

A first-person 3D horror game made in MonoGame, a 2D framework with no built-in 3D camera, no model tooling, and no shaders. When we asked around if 3D was even doable in it, people said it was too hard or impossible. We did it anyway. Procedurally generated maze, a monster that hunts you with A-star pathfinding on its own thread, sprint mechanics, and spatial audio tied to game state. Released on itch.io.

What I built

I built the part that makes the 3D work: the camera and the matrix math that projects a 3D world onto a 2D screen (view and projection transforms, FOV, rotation), plus the procedural maze generation with depth-first search and the audio system. My teammate built the layer on top: the component architecture, player controller, monster movement, collision, and the 3D models.

Key technical decision

MonoGame gives you nothing for 3D, so I had to build the pipeline by hand: a custom camera with explicit world-view-projection matrices. This is where I learned that when the engine does not do it for you, you can still do it yourself if you understand the math underneath. That stuck with me.

MonoGame C# 3D rendering Performance
GitHub

TrashyShooter - Networked 3D Multiplayer FPS

Datamatiker | 2023 | 2 person team (50/50) | 11 day sprint

A 3D multiplayer first-person shooter in MonoGame, with a dedicated authoritative game server, multiple clients, and a scoreboard API. The hard part is the networking: keeping a fast game in sync across clients without it feeling laggy or letting players cheat. We built the full set of techniques for that in 11 days.

What I built

I worked mostly in the netcode layer: the authoritative UDP server, snapshot broadcasting at 30Hz, and the lag compensation that rewinds the world to the moment a shot was fired before checking the hit. The client side has prediction and reconciliation, so the player moves instantly and then corrects against the server, plus snapshot interpolation so other players move smoothly.

Key technical decision

We made the server authoritative: it owns the game state, clients only send input. That stops cheating at the source, but it creates a lag problem, so we added server-side lag compensation, rewinding to historical snapshots to judge shots fairly. It is an 11 day prototype, so some parts like acknowledgement and error handling are partial. The core netcode works.

MonoGame C# .NET Multiplayer Lag compensation Snapshot interpolation
GitHub

Fresh Tracks (CDM Vancouver) - Runtime Level Editor Tools

Datamatiker exchange, Centre for Digital Media | 2024 | international team

A semester abroad in Vancouver, enrolled through Simon Fraser University, working at the Centre for Digital Media. CDM puts students from different backgrounds into teams that build for real clients. Our client was Buffalo Buffalo, a Vancouver game studio, and we worked on an early version of Fresh Tracks, a game that has since been released.

What I built

Our group of six split into two tracks. Zimo and I were the code team, working on the game's runtime level editor. The editor is part of the game itself, so it has to work in play mode. Zimo built a runtime gizmo for moving objects; I built multi-selection and grouping, so a designer could work on many objects at once. Together those two pieces cut level design time in half in the first test. We agreed I would take lead on our small code team.

Working with the client

A real client with real users, so I ran user interviews and usability tests and built the features around that feedback. Patrick Owens, the studio's founder, wrote afterward: "His work on introducing multi-selection and grouping functionality has been particularly noteworthy, as it directly responded to user feedback and significantly improved the level design process."

Unity C# Runtime tooling Level editor User testing
Under NDA

SuperSkole - Educational Game (Internship)

PBA internship | 2024 | Scrum Master and technical lead

An educational game built in Unity during my internship. I was Scrum Master and technical lead, and I also coded. My job was to lead the team, mentor where it was needed, and get the project shipped. It ended up about 40% over its original scope.

What I built and led

This is the one project where I led more than I built, though I did both. I ran the Scrum process, planned the work, and mentored people so they could do real work and see how it fit the whole. The skill here is getting a team to deliver together and still ship the thing. We did, and then some.

Key takeaway

I already knew I step into the lead role naturally. This was the version of it that matters: getting good work out of a whole team, supporting the people who needed it, without lowering the bar on what we delivered.

Unity C# Scrum Master Team leadership
Under NDA

KlimaPark - Interactive Learning Prototype

PBA, Scrum course | 2024 | Scrum Master, client contact, developer

An interactive learning game in Unity for an external client, KlimaPark Nordvestjylland, to teach school kids what a climate park is and how it works. This was the Scrum course, so the real point was running proper Scrum, by the book, with a real client. I was Scrum Master, the main client contact, and I coded. We delivered a working alpha within a three week deadline.

What I did

I ran the Scrum process and I was the one who talked to the client. That second part matters more than it sounds. A lot of developers can build but cannot sit across from a customer, understand what they actually need, and turn it into something shippable. I did both: kept the sprints honest and kept the client in the loop.

Key takeaway

Doing Scrum properly with a real client is different from doing it in a classroom exercise. Being the client contact taught me to translate between what a customer says they want and what the team can actually build in three weeks.

Unity C# Scrum Master Client communication
Under NDA

Survive the DOiTS - Boids Performance at Scale (Unity DOTS)

Datamatiker main thesis (hovedopgave) | 2024 | solo | grade 12

My datamatiker main thesis. A first-person shooter built to push Unity DOTS to its limit by simulating huge swarms of flocking boids (separation, alignment, cohesion). The point was the performance: how many agents can you simulate at 60 FPS, and what does it take to get there. I reached 35,000 boids at a stable 60 FPS. The goal was 10,000, so it beat that by more than three times.

What I built

The whole thing, solo. The boid simulation, the spatial hashmap, the job pipeline, the game on top. Finding each boid's neighbours by checking it against every other boid is O(n squared), which falls apart at scale. I built a spatial hashmap that splits the world into grid cells, so each boid only checks the cells next to it, bringing the neighbour search down to roughly O(n) on average. The thesis has the full Big-O analysis in an appendix.

Key technical decision

I went with Unity DOTS instead of normal Unity (MonoBehaviour). DOTS uses an entity component system that stores data tightly together and lets the Job system run work across all CPU cores without locks, and the Burst compiler turns it into native machine code. The move system handled 2,500 boids at 10.26ms without Burst, and 35,000 boids at 0.014ms with it. All of it is CPU work through Jobs and Burst.

Unity DOTS ECS Burst C# Spatial hashing Performance
GitHub Live boids demo

Unity ML Snake - Reinforcement Learning

Datamatiker (Dania) | 2025 | 3 person team

A Unity game where a snake is driven by an AI agent that learns to play through reinforcement learning, using Unity ML-Agents. It runs human against AI, so you can watch the trained agent play next to a person. A two week school project about machine learning with Unity.

What I built

I worked on the ML side. I built the agent itself (its observations, rewards, and actions) and ran the training, including the long training sessions to get it to actually play well. I also fixed the game state so training could run clean. The other two handled more of the game loop and infrastructure.

Key technical decision

The hard part of reinforcement learning is the reward design. The agent only learns what you reward it for, so a bad reward function teaches the wrong behaviour. Most of the work was tuning the rewards and the training setup, then running long sessions and checking what the agent actually learned.

Unity ML-Agents Reinforcement Learning C#
GitHub

YinYang - Real-time 3D Graphics Engine (OpenGL)

PBA, graphics course | 2025 | 2 person team

A custom real-time 3D graphics engine in C# on OpenTK (OpenGL 4.6). The assignment was to pick one graphics topic and implement it. We built a whole engine instead and implemented all of them. It runs a cave scene with a sun, point and spot lights, water, particle systems, god rays, and reflections, all driven by a modular render pipeline. About 9,500 lines of C# and 39 shaders.

What I built

I built the particle systems (a waterfall mist and magic particles, both running on compute shaders), the post-processing effects (god rays and bloom), and most of the scene construction. My teammate did the water surface shader, the shadows, and the general lighting model. The render pipeline and engine core we shared.

Key technical decision

OpenGL gives you the raw API and nothing else, so everything above it we built ourselves. The engine is a chain of render passes you can compose: shadow pass, scene pass, bloom, god rays, reflection capture. Adding a new effect means adding a pass. The harder pieces used geometry shaders (rendering all six faces of a shadow cubemap in one pass) and compute shaders (updating particles on the GPU).

OpenGL GLSL C# Compute shaders Performance
Private repository

NutriFinder - REST API with a Quality Pipeline

PBA, software quality exam | 2025 | 2 person team

A REST API and CLI client for nutrition lookups, built in ASP.NET Core. It checks a MongoDB cache first, then falls back to external sources (the Danish DTU food database and OpenFoodFacts). This was the software quality exam, so the point was how it was built: testing, CI/CD, and an architecture you can actually test.

What I built

My teammate and I split it. I owned the CI/CD and the containerisation: the Azure DevOps pipeline with automated tests on every push and pull request, a coverage gate that blocks a merge below 80%, the Docker setup, and Docker Compose for local and test environments. I also built the client and the integration and end to end tests. My teammate focused more on the server architecture and the testability design.

Key technical decision

We drove the whole thing test first (TDD). The project ended on 44 tests with 96% line coverage, split across unit, integration, and end to end tests. The integration tests run against a real MongoDB using Testcontainers, so they test the actual database. High coverage shows the code was tested, and that is all it shows. The tests are there as protection against regressions.

ASP.NET Core C# MongoDB TDD CI/CD Docker
GitHub

Homelab - Self-hosted from Scratch

Personal project | 2025 | solo

My first self-hosted server, and where DevOps started for me. I took NutriFinder, my exam project, and put it live in production on my own machine, reachable from the internet at api.mtbonde.dev. Self-contained on purpose, so I could focus on what it actually takes to host and run something live.

What I built

The full path from code to a running, public service. Domain and DNS through Cloudflare, multi-stage Dockerfiles, a GitHub Actions pipeline that builds and tests on every push, Docker Compose plus Watchtower on the server, and a Cloudflare Tunnel with a systemd service so it survives a reboot.

Key technical decision

Port forwarding was unreliable, so I switched to a Cloudflare Tunnel. It reaches out from the server, so there are no open inbound ports on my home network. That same pattern (tunnel, Docker, CI/CD, auto-update) became the base I carried into every later infrastructure project, including MyFoodBudget.

Docker Docker Compose GitHub Actions Git CI/CD DevOps Cloudflare Cloudflare Tunnel Linux Bash systemd Self-hosting
GitHub

Offline Bootstrap USB - Hardening Before First Boot

Personal project | 2025 | solo

A USB stick that hardens a fresh Linux server before it ever touches the network. There is a window between installing an OS with network access and finishing the hardening where the machine is exposed. This closes that window by doing the hardening first, offline. You plug in the USB, run one Ansible playbook with no internet, and the server comes up already locked down.

What I built

An Ansible project that runs fully offline. Ansible normally needs to install things from the internet, so I packaged a full Python virtualenv with Ansible onto the USB. The playbook is eight roles: create the user and SSH key, harden SSH, set up a UFW firewall and fail2ban, remove unwanted packages, configure unattended security updates, apply kernel hardening through sysctl, and set up auditd to watch auth and sudo. Secrets handled with SOPS and an age key. The whole thing is idempotent.

Key technical decision

The point is sequence. Most hardening happens after a machine is already online, which leaves a gap. I wanted the machine hardened before it has network access at all, so the hardening had to run offline. That is why Ansible is packaged on the USB instead of pulled from the internet. A small idea with a real security payoff: there is no exposed window, because the box is locked down before it is reachable.

Ansible Linux Security CI/CD
Personal tooling, no public repo

Alexor - GitOps Microservice Backend

PBA, System Integration exam | 2025 | 2 person team | grade 12

A backend platform for an Unreal Engine multiplayer game, built as microservices on Kubernetes with a fully automated GitOps delivery pipeline. Six services (auth, session, registry, relay, chat, and the game server) talk over RabbitMQ and use Redis for caching. The course had two parts: a prep project (HAGI) where we built the backend services for reuse, and the graded exam (Alexor) where I built the GitOps and infrastructure layer on top.

What I built

The whole DevOps and GitOps side, end to end: the Flux setup with Kustomize, sealed-secrets so credentials are safe to commit, and a GitHub Actions pipeline with semantic versioning that builds, tests, and pushes images, then lets Flux promote them through dev, staging, and prod. I also wrote a custom NuGet package (HAGI.Robust) that adds resilience to every service: retries with backoff, circuit breakers, timeouts, and a startup gate. My teammate built the Unreal game server and its separate build pipeline.

Key technical decision

I applied the CAP theorem per service instead of one rule for all: auth and the game server are consistency-first, session and registry are availability-first with eventual consistency. And the resilience: Kubernetes probes heal at the container level, but that does not help a service that is up but talking to a dependency that is down, so HAGI.Robust adds that protection at the application level. Alexor itself is a proof of concept on a single node. The same patterns run in production in MyFoodBudget today.

Kubernetes Flux CD GitOps DevOps Kustomize sealed-secrets GitHub Actions Git .NET C# RabbitMQ Redis
GitOps Repo Workflows

MyFoodBudget - A SaaS in Production, Built Solo

PBA bachelor thesis | 2024 to now | solo, AI-orchestrated | grade 12 | live

A meal planning SaaS that turns recipe choices into store-grouped shopping lists with real deal matching and savings across Danish grocery chains. Guest-first, so the whole core flow works without an account. It started as my internship and bachelor thesis and kept growing into a tool other families could use too. I built it alone and I run it in production on my own infrastructure. It is the full thing, from the database to the running service.

I build it the way I work now: I direct an AI as my lead developer and own every architectural decision myself. The decisions are mine and they are documented in the project's ADRs. The AI does a lot of the typing, I do the design, the review, and the calls. MyFoodBudget is the proof that this way of working ships real, running software.

What I built

Every layer, solo. PostgreSQL with migrations for the data. A Flask backend built as a modular monolith, where each module is a future microservice, with one authoritative compute endpoint so the numbers can never disagree across the app. A mobile-first frontend. Then the operations: two Kubernetes clusters (production and staging) on my own VPS, GitOps with Flux and Kustomize, sealed-secrets, image automation that auto-deploys staging and holds production for a manual promote, a CI pipeline with semantic versioning, full monitoring (Prometheus, Grafana, Alertmanager to Discord, uptime checks), and an encrypted nightly backup pipeline to object storage. The test suite is over 2000 tests.

Key technical decision

The one I lean on most is the single authoritative compute endpoint. Early on, prices and savings could disagree between the recipe view, the shopping list, and the dashboard, because each one computed its own numbers. Instead of fixing those mismatches one bug at a time, I moved all the computation behind one endpoint that every view calls. After that the numbers cannot disagree, because there is only one source for them. Fix the cause in the architecture, not the symptom in the code.

Python Flask PostgreSQL Kubernetes Flux CD GitOps DevOps Kustomize sealed-secrets CI/CD GitHub Actions Git nginx Cloudflare Prometheus Grafana AI-orchestrated
Live at myfoodbudget.dk Private repository

BCS - The System That Makes My AI a Reliable Lead Developer

Personal project | 2026 to now | solo | ongoing

Everyone can use an AI tool now. BCS is the system I built so I can direct one like a reliable lead developer. It is hooks, skills, a memory system, and role-based agents that turn a general AI into a disciplined teammate that follows my rules and ships real work. I own the architecture and the decisions, the AI is a strong pair of hands, and MyFoodBudget is what that collaboration produced: a whole SaaS in production.

What I built

Around 30 working pieces, all running in my real workflow. Permission hooks that hard-block dangerous commands (a database DROP cannot happen by accident). A commit gate so the AI cannot commit on its own without my explicit go. Architecture-enforcement that blocks module-boundary violations at commit time. A structured memory system so context survives across sessions without bloating. A "Kitchen Cabinet" of role-based agents (CTO, finance, legal, and more) I can consult for a decision. And a suite of my own skills for the work I do most: test-driven development, planning, triage, refactoring, release.

Key insight

The principle the whole thing runs on: rules suggest, skills enforce. A rule written in prose gets followed maybe 60 to 70 percent of the time. A mechanical guardrail gets followed 95 percent of the time. So when something actually matters, I stopped writing a rule and started building a hook. Over 100 improvements tracked, around 30 built, each one a small fix to how the AI and I work together.

Where it's heading

Right now I am setting up a self-hosted, always-on version on my own homelab: a Claude that runs around the clock, so it can pick up work, orchestrate specialist sub-agents (one researches, one codes, one tests), and handle routine tasks while I hold the decisions and the quality. I am testing that now, building it the same way I build everything, from the foundation up.

AI-orchestrated Hooks Bash Automation Systems design
Public repo planned

Need someone who builds and runs the whole system?

I'm open to DevOps, platform, and backend roles, ideally remote. I built and run a SaaS solo, so I'm comfortable owning anything from the database to production operations. Let's talk about what you need built.