Testing (Headless)
Plume3D can run an app’s Wren test suite headless — no window, no Vulkan surface, no render loop — and exit with a process code the suite controls. This is how a game’s Wren logic is gated in CI, and it works on machines with no display.
plume3d --test <appdir> # alias: --headless ; also --test=<appdir>- Mounts
<appdir>and loads<appdir>/tests/run.wren. - Calls the static method
Tests.main(). - Exits with the code set by
Engine.exit(code)(default0).
The --test path returns before any window or renderer is created, so
renderer/audio/window-dependent API calls are inert in this mode — keep test suites
to game logic. game.toml is not required for --test.
Test-entry convention
Section titled “Test-entry convention”Create <appdir>/tests/run.wren:
import "engine" for Engine// import your game modules and assertions here…
class Tests { static main() { // run assertions; on failure call Engine.exit(1) Engine.exit(0) // 0 = suite passed }}Tests.main() is the whole contract — structure your suite however you like inside
it (many apps build a small assert/test framework in Wren and call it from here).
Prefer calling Engine.exit as the final action of the suite: Engine.exit is
record-and-honor, so code after it still runs — and a Wren runtime error always wins
over a recorded Engine.exit(0) (a crashing suite can never report green).
Exit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
value of Engine.exit(code) | Whatever the suite requested (clamped 0–255). Wins, except a Wren error after a recorded Engine.exit(0) still yields 1. |
0 | Tests.main() returned cleanly without calling Engine.exit (or called Engine.exit(0) and did not error). |
1 | tests/run.wren failed to compile, has no Tests class, or Tests.main() raised a Wren runtime error — and no explicit non-zero Engine.exit was requested. |
2 | Setup error: app dir missing (or no app dir given), tests/run.wren missing/unreadable, mount failure, or --test combined with --tool. |
70 | Filesystem initialization failed. |
CI example
Section titled “CI example”# fails the job if any Wren assertion failsplume3d --test apps/mygame || exit $?Reproducible tests
Section titled “Reproducible tests”Pair headless testing with the seeded Random API: construct
generators from fixed seeds so test runs are deterministic across machines and
platforms.
See Engine.exit for exit semantics in normal
(windowed) runs, and Getting Started for the app layout.