A minimal Debian-based Docker container for running Love2D games in headless/CI environments without requiring a graphics card or audio card.
- ๐ง Debian-based: Built on
debian:bookworm-slimfor minimal size - ๐ฎ Headless Love2D: Runs Love2D games without GPU/audio hardware using Xvfb
- ๐ง Development tools: Includes LuaJIT and Luarocks
- ๐ฆ Minimal size: Optimized for small container size
- ๐ CI/CD ready: Perfect for automated testing and continuous integration
- ๐ธ Screenshot support: Capture and extract screenshots for visual regression testing
- ๐ฌ Video recording: Record game execution as MP4 and animated GIF
- ๐ค Copilot integration: Built-in instructions for automated visual PR reviews
- ๐ Audio testing: Dummy audio driver for testing audio-enabled games
docker pull ghcr.io/jeduden/love2d-ci-container:latestdocker run --rm -v /path/to/your/game:/game ghcr.io/jeduden/love2d-ci-container:latestThe container expects your Love2D game to be mounted at /game.
docker build -t love2d-ci:local .Run the included test game:
docker run --rm -v $(pwd)/test-game:/game love2d-ci:localCapture screenshots and video recordings from your game for visual testing or documentation:
# Run game and extract screenshots in one command
docker run --rm \
-v $(pwd)/your-game:/game \
-v $(pwd)/screenshots:/output \
ghcr.io/jeduden/love2d-ci-container:latest \
/run-and-screenshot.sh
# Run game and record video (includes screenshots)
docker run --rm \
-v $(pwd)/your-game:/game \
-v $(pwd)/output:/output \
ghcr.io/jeduden/love2d-ci-container:latest \
/run-and-record.shYour screenshots and video will be available in the output directory.
In your Love2D game, save screenshots using love.graphics.captureScreenshot:
function love.draw()
-- Your drawing code here
love.graphics.print("Hello World", 10, 10)
-- Capture screenshot (must be called from love.draw)
if needScreenshot then
love.graphics.captureScreenshot(function(imageData)
local data = imageData:encode("png")
love.filesystem.write("screenshots/my_screenshot.png", data)
print("Screenshot saved!")
end)
needScreenshot = false
end
endScreenshots are saved to Love2D's save directory and can be extracted using the helper scripts.
The container includes ffmpeg for recording your game as it runs. The video recording:
- Captures the full game window at 30 FPS
- Outputs in MP4 format (H.264, compatible with GitHub)
- Generates animated GIF - Embedded directly in GitHub Actions Summary
- Records the actual visual output, perfect for PR reviews
- GIF preview inline - See the game in action without downloading
- Full video available in artifacts for detailed review
jobs:
test-game:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Test Love2D game
run: |
docker run --rm -v ${{ github.workspace }}:/game \
ghcr.io/jeduden/love2d-ci-container:latestCapture video and screenshots, upload as artifacts:
jobs:
test-game:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run game and record video
run: |
mkdir -p output
docker run --rm \
-v ${{ github.workspace }}:/game \
-v ${{ github.workspace }}/output:/output \
ghcr.io/jeduden/love2d-ci-container:latest \
/run-and-record.sh
- name: Upload video and screenshots
uses: actions/upload-artifact@v4
if: always()
with:
name: game-recording
path: output/This captures both video (MP4) and screenshots (PNG) in one step.
This displays screenshots and audio test results directly in the GitHub Actions summary page.
Screenshots can be automatically posted to pull requests for review:
jobs:
test-game:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
- name: Run game and capture screenshots
run: |
mkdir -p screenshots
docker run --rm \
-v ${{ github.workspace }}:/game \
-v ${{ github.workspace }}/screenshots:/output \
ghcr.io/jeduden/love2d-ci-container:latest \
/run-and-screenshot.sh
- name: Post screenshots to PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const files = fs.readdirSync('screenshots').filter(f => f.endsWith('.png'));
if (files.length === 0) return;
let comment = '## ๐ฎ Game Screenshots\n\n';
for (const file of files) {
const content = fs.readFileSync(`screenshots/${file}`);
comment += `### ${file}\n})\n\n`;
}
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: comment
});This workflow makes screenshots immediately visible to reviewers and AI agents like GitHub Copilot, enabling visual feedback on game changes.
This repository includes comprehensive instructions for GitHub Copilot in .github/copilot-instructions.md. These instructions guide Copilot to:
- ๐ฌ Automatically capture video and animated GIFs when reviewing Love2D game PRs
- ๐ธ Post screenshots inline in PR comments for immediate visual feedback
- ๐๏ธ Embed animated GIFs directly in PR reviews showing complete game execution
- ๐ Provide structured visual feedback with observations and comparisons
- ๐ค Enable AI-powered visual review without manual intervention
When GitHub Copilot reviews a PR with Love2D game changes, it will:
- Run the container with
/run-and-record.shto capture video, GIF, and screenshots - Post the animated GIF inline in the PR comment for immediate visual feedback
- Include individual screenshot images at key frames
- Provide observations about visual behavior and rendering
- Reference the full MP4 video in artifacts for detailed analysis
This enables comprehensive visual regression testing and automated PR reviews with rich visual context.
When Copilot reviews your PR, you'll see comments like:
## ๐ฎ Love2D Game Test Results
I've tested the game changes using the Love2D CI container. Here's what I observed:
### Game Recording

The animated GIF shows the complete game execution (~3 seconds at 10 FPS).
### Key Observations
- Circle animation works smoothly with radius changing based on frame count
- Rectangles render correctly on left and right sides
- Text displays frame counter and test status properly
- No rendering glitches observed
### Screenshots at Key Frames
[Individual screenshots embedded inline]
Full quality MP4 video available in artifacts.See .github/copilot-instructions.md for complete integration details.
docker run --rm love2d-ci:local luarocks --versiondocker run --rm love2d-ci:local luajit -vThe container supports audio testing using SDL's dummy audio driver (SDL_AUDIODRIVER=dummy). Audio works out of the box without requiring actual audio hardware. Games can play sounds and music normally, output is just not heard.
If you've already run your game and want to extract screenshots separately:
docker run --rm \
-v $(pwd)/your-game:/game \
-v $(pwd)/output:/output \
ghcr.io/jeduden/love2d-ci-container:latest \
/extract-screenshots.shThe container includes:
- Love2D game engine (version 11.4)
- LuaJIT for high-performance Lua execution
- Luarocks for Lua package management
- Xvfb for headless display
- PulseAudio with null sink for audio testing
- ImageMagick for image processing
MIT License - see LICENSE file for details.