Buildkite Doom Example
Now you can play Doom on Buildkite — or have AI play it for you!
How it works
This project runs Doom interactively in a Buildkite pipeline. It’s playable in three modes:
- Manual: You choose each move in the Buildkite dashboard, one step at a time
- Random: The pipeline chooses the next move for you at random
- AI: Claude Code analyzes the game to determine the best next move
Each new move adds a step to the running pipeline, and the game interface (a PNG animation) is updated in place in the Buildkite dashboard. Canceling the build ends the game.
See it in action
https://github.com/user-attachments/assets/5890f5e4-46ec-4bc9-a2dc-beda3fd48624
The pipeline for this project is also fully public. Have a look at a few recent plays.
Create your own
To create a playable Doom pipeline of your own, you’ll need:
- A Buildkite account — you can grab a free trial here
- Docker installed locally to run the Buildkite agent (under Ubuntu, for easier setup of ffmpeg and Chocolate Doom)
- Optionally, an Anthropic API key to play in AI mode with Claude (the game falls back to manual mode by default). You can get an API key by visiting the Anthropic console.
Follow these steps to get going:
-
Fork this repository into your GitHub account.
-
Create a new Buildkite pipeline and configure it to use your newly forked repo. Be sure to choose a self-hosted agent agent cluster, as you’ll be running the Buildkite agent locally on your computer.
-
If you’re prompted to set up a GitHub webhook, click Skip Webhook Setup. (You’ll be running these builds on demand.)
-
Navigate to Agents » Your Cluster » Agent Tokens.
-
Create a new agent token and copy it to your clipboard.
-
Export your
BUILDKITE_AGENT_TOKEN
andANTHROPIC_API_KEY
as environment variables:export BUILDKITE_AGENT_TOKEN="${your_new_buildkite_agent_token}" export ANTHROPIC_API_KEY="${your_anthropic_api_key}"
Again, don’t worry if you don’t have an Anthropic token; the pipeline defaults to manual mode automatically.
-
Start the Buildkite agent with Docker, passing these two environment variables:
docker run -it --rm -e "ANTHROPIC_API_KEY" buildkite/agent:3-ubuntu start \ --token "$BUILDKITE_AGENT_TOKEN" \ --spawn 2
Note that this spawns two Buildkite agent processes — one for the Doom server (it’s a long-running process), another to trigger each move step.
-
Navigate to Pipelines » Doom Example, trigger a build with the New Build button, and start playing!
What’s interesting about this?
Aside from just being a fun — if slightly weird (and potentially expensive — watch those tokens!) — way to play Doom, this project demonstrates a few key Buildkite features:
-
Dynamic pipelines: It uses Buildkite dynamic pipelines to capture player input at runtime, adding a step to the running pipeline for each move. Dynamic pipelines enable you to define flexible, reactive workflows that adjust to the conditions of your build environment.
-
AI-driven CI/CD workflows: In AI mode, it uses Claude to analyze the state of the game and build the pipeline accordingly. This shows how LLMs like Claude can be used to drive more intelligent software-delivery workflows.
How it works
The pipeline starts by prompting you with a Buildkite input step to set the desired gameplay mode — manual, random, or AI-driven.
Once the mode is selected, the pipeline moves on to the next step, spawning a Ruby program (doom.rb
) that starts the server, captures the first few frames of the game, and uploads the frames as a PNG animation with a Buildkite build annotation. It then loops indefinitely, waiting for “keypress events”:
-
In manual mode, it prompts with another input step that lets you choose what to do next — move forward, turn, fire, etc.
-
In random mode, it chooses the next move for you.
-
In AI mode, it reads the last few frames of the game, then has Claude analyze them and decide how to move next, attaching a brief explanation as to why.
The selected move is recorded as a Buildkite agent metadata key-value pair. On the next iteration, the most recent move is fetched and sent to the running game, and the process continues until the build is canceled (or the user runs out of Anthropic credits!).
Contributing
Contributions welcome! As you’ll see, Claude needs all the help it can get to up its Doom game.
Special thanks
Extra special thanks to @rianmcguire, who created the original version of this project. :raised_hands: :green_heart: