Lab · Infrastructure
The 24/7 Build Farm
Docker builds, headless DuckStation, and the boring machinery that lets one person test a PS1 port continuously.
Published
~1 min read · 279 words
The build farm is not a rack of machines. It is a repeatable loop: Dockerized PS1 builds, generated CD images, headless DuckStation runs, log parsing, and a rule that every accepted performance change becomes the next baseline.
The useful part is discipline. A candidate optimization is not “faster” because it feels faster once. It is faster when the headless harness shows fewer VBlanks, no new blocking reads, no worse scene-end metrics, and no visual regression when the human pass catches up. Rejected tests still get logged because a failed idea can become valid after a later pack-format or scheduler change.
Current Loop
- Build the PS1 executable and CD image in the Docker toolchain.
- Run headless DuckStation against the selected scene or scene matrix.
- Parse
JCPERFandJCPERF2logs into VBlank, CD, compose, upload, wait, and blocking counters. - Promote only changes that beat the current baseline without violating deterministic playback.
- Commit accepted changes separately, and record rejected experiments in the log.
Pointers
- The dev environment, photographed — the farm’s bottom-monitor panel in the same field of view as the rest of the workflow.
- Scene ledger — visual signoff (the FISHING 1 bar).
- Performance battle card — second ledger; per-scene timing against the target frame budget, sortable + color-coded.
- Performance plan
- Regression testing —
the headless DuckStation runner the farm orchestrates around
every commit; the harness produces frame PNGs, state hashes,
and
JCPERFlogs the loop above parses. - Performance experiment log
- Scene performance matrix
- From 87 to 99.5: the post-validation performance loop — retrospective on the optimization arc this farm fed.
- v0.8.1: what the soak found that the matrix didn’t — the soak loop the farm runs alongside the per-commit matrix.