Problem
Integration tests that exercise the generated game code on Linux CI currently need `xvfb` because every existing backend (`backends/raylib`, `backends/sokol`) talks to a real display server via `InitWindow` / `glfwInit` / equivalent. Even hidden windows fail to initialize without an X display.
Concretely: the plugin-controllers example added in #73 runs `xvfb-run timeout 3 ./game` to get past raylib's window init, just so the tick loop can run and assert lifecycle order. The test has nothing to do with rendering — it's checking `setup → game-tick → plugin-tick` log ordering.
This pattern will repeat as more integration tests land. Every one either needs xvfb or has to settle for codegen-only snapshot coverage.
Proposal
Add a new `backends/null/` that generates a main which:
- Does NOT initialize any graphics context
- Runs the engine tick loop for N frames (configurable via `LABELLE_NULL_FRAMES=5` or a project.labelle field), then exits cleanly — letting `deinit` fire
- Provides stub implementations of the render interface (draws become no-ops, input returns zeros)
- Is selected via `.backend = .null` in `project.labelle`
Useful beyond Plugin Controllers — any lifecycle / integration / determinism test that doesn't exercise rendering could adopt it, skip xvfb entirely, and run identically on every platform.
Scope
Priority
Not blocking #73 (ships fine with xvfb). But every new integration test added before this lands inherits the xvfb dependency on Linux — worth cutting off sooner rather than later.
Related
Problem
Integration tests that exercise the generated game code on Linux CI currently need `xvfb` because every existing backend (`backends/raylib`, `backends/sokol`) talks to a real display server via `InitWindow` / `glfwInit` / equivalent. Even hidden windows fail to initialize without an X display.
Concretely: the plugin-controllers example added in #73 runs `xvfb-run timeout 3 ./game` to get past raylib's window init, just so the tick loop can run and assert lifecycle order. The test has nothing to do with rendering — it's checking `setup → game-tick → plugin-tick` log ordering.
This pattern will repeat as more integration tests land. Every one either needs xvfb or has to settle for codegen-only snapshot coverage.
Proposal
Add a new `backends/null/` that generates a main which:
Useful beyond Plugin Controllers — any lifecycle / integration / determinism test that doesn't exercise rendering could adopt it, skip xvfb entirely, and run identically on every platform.
Scope
Priority
Not blocking #73 (ships fine with xvfb). But every new integration test added before this lands inherits the xvfb dependency on Linux — worth cutting off sooner rather than later.
Related