A labor of love by Hunter Davis. The pages collected here are not the devlog and they are not the docs. The devlog is reverse-chronological, unedited, dated; it is what was in my head on a particular Tuesday. The docs are reference manuals; they tell you what FntFlush does and how the regtest harness loads a BIOS. The Lab is the third thing. It’s where I write down how the work actually gets done — the tools, the habits, the tricks, the things that surprised me, the things that failed.

I’ve been porting Johnny Castaway to one platform or another for years now. Dreamcast, embedded Linux on framebuffer-console boxes, RetroFW handhelds, a receipt-printer text edition. The PS1 port is another expression of an existing practice. What’s changed about the practice in the last six months is mostly the pace — sub-agents draft code and prose in parallel, a Docker farm runs builds and regressions while I sleep, a thirty-cent novelty bird taps a keyboard when I’m not at it. This section is where I write all that down so I’ll remember next time.

A few of these articles were drafted by AI sub-agents and then human-edited, in the same workflow described inside them. That disclosure is part of the methodology, not an apology for it. The voice anchor for the whole site — the four-line drawCredits text in src/pause_menu.c — is hand-written and load-bearing; everything downstream of it gets edited until it sounds like the same person. The voice-anchor article goes into how that pipeline works in practice.

If you want the practical learning path rather than the magazine treatment, start with the Curious Hacker’s Guide. If you want the raw documents behind the essays, use the source library and the resource catalog.

Subscribe via Atom or JSON Feed; both are reverse-chronological with rich summaries (no embedded body — site.html_pages doesn’t pre-render content reliably the way site.posts does, so the feeds are the headline-and-link pattern). Auto-discovery is wired into every page’s <head>, so most feed readers find them automatically. The /docs/feeds/ reference page documents every machine-readable endpoint the site ships, including the matching pair for the devlog.

Contents

Seventeen feature articles, in reverse chronological order. The newest sit on top; the foundational methodology pieces sit underneath. Each card carries the date it landed.

  • 63 heroes

    How every per-scene page on the site got its own captured-on-PS1 hero image, what frame-selection rules of thumb kept reappearing, and the cross-link cluster taxonomy that emerged from writing one figcaption at a time — variant pairs, story-arc sagas, theme threads, engineering-quirk lineages. Plus the one scene the chapter-select grind missed and how the regtest harness filled it in headlessly.

  • The chapter-select grind

    Walking all 63 packs on hardware again to ship custom on-PS1 chapter-select thumbnails — and the surprising number of caption-mismaps the loop caught in the existing scene-page metadata. The validation bar guards pixel drift, not caption drift; this loop reconciled the prose against the discs that play.

  • v0.8.1: what the soak found that the matrix didn't

    The post-v0.8.0 stability fix as a war story. A randomized soak surfaced a MARY 4 scene-load freeze the per-commit matrix never reached. The fix is a clean-rect pressure estimator that mirrors the actual save path; the discipline is the lesson — matrix and soak are not redundant.

  • From 87 to 99.5: the post-validation performance loop

    How the headless-perf battle card moved from +17.4% over target to +0.8% after every scene was already signed off — the single biggest unlock (clean-memory-relief drop-prefetch), the methodology, the accepted experiments, and the rejected ones.

  • The site itself, as a small program

    The path-portable build, the canonical_baseurl trick, the no-plugin Atom feed, the pager pattern shared across catalogs, and the build-stamp coarsening that kills per-commit churn. A handful of decisions that keep the deployment stable and low-noise.

  • The 24/7 build farm

    Docker, multiple branches, headless DuckStation. How a one-person project keeps a build matrix running around the clock.

  • The 63-scene grind

    From five signed off to all 63. What the daily loop looked like on a project of finite scenes and finite evenings, written from inside the grind.

  • The pivot that almost didn't happen

    How the project nearly shipped at "looks similar" before pixel-perfect became the bar. A retrospective on the choice that defined everything else.

  • The two-day SPI bug

    A war story about the PS1 controller pad-poll TX length. DuckStation only delivers button bytes when you send the full five-byte sequence. Spicyjpeg's example is wrong about that.

  • 35 holidays in 4 weeks: a codegen study

    From four shipped holidays to thirty-six in a month, via Meeus, Zeller, and a YAML file that compiles to a C struct array.

  • Why I keep porting Johnny Castaway

    Dreamcast, picture frame, embedded Linux, PS1. The same screensaver, four times. What I'm actually doing when I do it again.

  • Building a fan port in public

    Disclaimers, the original creator, GPL-3.0 inheritance, "if you paid for this, you were cheated." How shipping a fan port works without lawyers in 2026.

  • The dunking bird

    A dumb hack the author wrote that pokes multiple LLM agents in parallel so they keep working instead of going idle. Used a lot during the perf branch's long unattended runs.

  • The LLM pass

    How a one-person fan port uses AI sub-agents without lying about it. The methodology essay; the docs version is at /docs/agents/.

  • Hallucination engineering

    Mitigating LLM-driven dev's specific failure mode: confident wrong answers. War stories, mitigations, what the year of practice teaches.

  • Regression as a lifestyle

    Continuous regtest is not a CI feature. On this project it's a way of working — frame-by-frame screenshot diffs are the heartbeat.

  • The voice anchor problem

    Keeping a project's voice consistent when half the prose was drafted by AI sub-agents. The drawCredits text, the voice guide, the audit pass.

What this section is not

It’s not a contributor onboarding. It’s not a tutorial series. It’s not content marketing for the project. There is no “in this section we’ll explore” framing, no roadmap of future articles, no call to action at the bottom. It is the methodology I would write up if a future me were porting Johnny Castaway again to a fifth platform and wanted to know what worked, and that future me is the primary reader. You’re welcome to read along.

For the live status of the port, see /about/status/. For the day-by-day worklogs, see /devlog/. For reference docs, see /docs/. For a guided path through the codebase, see /hack/.