We Did Not Set Out to Build a CI/CD Company

We wanted to build a game.
We started Ayelet Studio to make Son of Thanjai — an action adventure built in Unreal Engine 5. Ten-plus years in enterprise software and DevOps, finally doing the thing we actually wanted to do.
We knew how to build software. We knew how to ship it. We figured CI/CD would be the easy part.
It was not the easy part.
The Duct Tape Phase
We started with Jenkins. Everyone starts with Jenkins. It’s free, it’s flexible, and there are a thousand tutorials on how to set it up for “any project.”
The tutorials don’t mention Unreal.
Within weeks, we were duct-taping. Calling BuildGraph as a shell command. Passing state through environment variables and shared folders. Duplicating pipeline stages because one machine couldn’t hold the entire build. Adding flags to work around failures we didn’t fully understand.
Our Jenkins pipeline worked — in the way that a car with three spare tires and a bungee cord holding the hood down “works.” You could technically drive it. You just couldn’t trust it.
Builds took over three hours. A single texture change triggered a full rebuild. Failures were monolithic — the whole build failed, and the logs told you something broke somewhere in a 200-step process. Good luck.
The worst part wasn’t the time. It was the anxiety.
Every build gave our team an anxiety attack. Artists pushed assets and went home, not knowing if the overnight build would survive. Engineers avoided committing late in the day because a broken nightly meant a wasted tomorrow. We had standup meetings about the pipeline more often than we had standup meetings about the game.
We were building Son of Thanjai. But half our energy was going into keeping Jenkins alive.
The Moment
It hit us on a Monday morning. The weekend build had failed. Again. Nobody was sure why. The one person who could debug the pipeline was out sick. Three artists had committed work on Friday that was now sitting in limbo. The producer was calculating whether we’d make our milestone.
We’d been through this before. Every studio has. The sacred build PC that only one person understands. The Groovy scripts held together by hope. The Slack message: “Don’t restart that job yet — wait for the cook to finish on the other machine.”
That Monday, we didn’t fix the pipeline. We sat down and asked a different question: Why are we teaching Jenkins what Unreal is?
Jenkins doesn’t know what a .uproject file is. It doesn’t know that cooking, compiling, and packaging are separate stages with different dependencies. It doesn’t know that a code change needs recompilation but not a full re-cook. It doesn’t know that shader compilation can run in parallel with packaging.
Jenkins doesn’t know any of this. And that’s not really Jenkins’ fault. Jenkins was built for web applications. Small artifacts. Linear pipelines. Fast feedback loops. It’s genuinely good at that job.
But an Unreal build is not a web deploy. It’s a distributed system — parallelism, dependency graphs, shared state, massive artifacts, multi-platform targets. Treating it like a shell script is the problem.
We weren’t going to fix that with more Groovy.
Building the Thing That Should Have Existed
We didn’t plan to build a CI/CD company. We planned to build an internal tool.
Something that reads the .uproject file and actually understands it. That knows what changed and what needs to rebuild — not “everything,” but the specific stages affected. That runs cook on one machine, compile on another, and packaging on a third, orchestrated by dependency, not by sequence.
We wanted failures that were precise. Not “the build failed” but “this step failed, here’s the log, here’s the commit that triggered it, and the rest of the build is still valid.” Boring failures. The kind you fix in minutes, not hours.
We wanted the whole team to see what was happening — not just the engineer who wrote the pipeline. Artists should know if their textures broke the cook. Producers should see whether we’re on track for the nightly without asking anyone.
We built it for ourselves. And it worked.
The same project, the same hardware, the same repo — Jenkins took 3 hours and 32 minutes. Our tool took 27 minutes.
Not because we’re faster at running commands. Because we stopped running commands that didn’t need to run. Because we cached what Jenkins couldn’t cache — cooked assets, compiled code, engine state. Because we parallelized what Jenkins ran in sequence. Because we understood the build graph instead of flattening it into a line.
From Internal Tool to Speedrun
We used it every day at Ayelet. And we started noticing changes that had nothing to do with build times.
Artists committed more often. Smaller batches, faster feedback, fewer overnight surprises. Engineers stopped doing local builds “just to be safe.” The producer stopped asking about the pipeline in standup — because the dashboard already told them everything. Nobody talked about the build anymore. It just worked.
That’s when other studios started asking what we were using.
Every conversation was the same. “We have Jenkins.” Long pause. “It’s… fine.” Longer pause. “Actually, it takes four hours and only two people can fix it, and we lose a day every time it breaks, and the artists have no idea what’s going on, and we tried GitHub Actions but ran into disk limits, and —”
Yeah. We know.
We heard that story from two indies and three mid-size studios before we decided to open it up. We called it Speedrun.
What Speedrun Actually Is
Speedrun is CI/CD purpose-built for Unreal Engine.
It reads your .uproject. It understands your dependency graph. It caches cooked assets, compiled code, and engine snapshots. It runs build stages in parallel across machines, orchestrated by actual dependencies — not by the order someone wrote them in a Jenkinsfile.
It’s not a plugin. It’s a platform designed from the ground up for the way Unreal builds actually work.
When a build fails, the failure is precise — one step, one log, one commit. The rest of the build is still valid. When a build succeeds, it deploys to Steam or Epic Games Store and notifies the team on Slack or Discord.
Producers can see build status without asking an engineer. Artists can see if their assets broke the cook. The whole team has visibility — not just the person who wrote the pipeline.
And nobody needs to be a “build wizard” to keep it running.
What We’re Not
We’re not CI people who learned about games. We’re gamedevs who built a CI tool because the one we needed didn’t exist.
We still build Son of Thanjai. We still use Speedrun every day. When something doesn’t work for our own studio, we fix it — and every Speedrun user gets that fix too.
We’re not here to tell you Jenkins is bad. Jenkins is great at what it was designed for. We’re here because Unreal builds need something that was designed for them.
Generic CI breaks game studios. Not because it’s bad software — because it’s the wrong software. Configuration isn’t the answer. Game-aware orchestration is.
If your studio is duct-taping a generic CI tool onto Unreal builds, we’ve been exactly where you are. We built Speedrun so you don’t have to build your own.
Let me know if you want to try it — abrahamk@speedrun.ci
Never miss a ue5-main update.
Get them delivered straight to your inbox.


