← Dev Log
BallOrcs2 min read

The robot playtesters clock in for real

Last week we built AI bots that playtest the game. This week we put them on the payroll.

In plain words

Last week we built AI bots that playtest the game. This week we put them on the payroll. Every weekly build now ends with a shift of eight bots soaking the fresh Linux version for five minutes each, while a camera bot takes the exact same set of screenshots so any surprise change in the graphics shows up side-by-side. If something breaks, the report spells out how to reproduce it — but a bad soak only turns the light yellow, never red, so it can never block a build that already shipped. We also lined up next week's job: automatically picking the best graphics mode your machine can actually run.

Under the hood

  • A new playtest stage runs after weekly-release on every scheduled pipeline (and on-demand from any main pipeline). It has the same single-entry-point contract as the builds — CI runs exactly bash ci/playtest.sh, and so can any developer with docker/podman.
  • The soak needs a display and a GL stack the build containers don't have (ci-shell is musl; the build images ship no X/GL), so it runs in a new pinned IMAGE_PLAYTEST sibling container — Fedora + Xvfb + llvmpipe software GL + Pillow + ffmpeg (infra/toolchain/Dockerfile.playtest). Image built, pushed, and its digest pinned in versions.lock.
  • 8 bots × 300 sim-seconds plus the Xvfb camera probe against the build:linux artifact. The job is allow_failure: true (yellow, never blocks the release), ships playtest-results/ as an 8-week artifact, and persists the screenshot baseline between runs via the job cache (key playtest-baseline) — the very first run only records it.
  • The screenshot diff now compares only stable anchor poses. The path_* shots follow that week's bot trajectory, and since Godot physics is deterministic per build but not across builds, they'd false-flag every single week — so they're kept as visual artifacts, not diffed.
  • Verified end-to-end in WSL docker: 54/54 anchor shots reproduce byte-for-byte under llvmpipe. ci/playtest.sh is shellcheck-clean and the amended .gitlab-ci.yml passed GitLab's CI-lint API.
  • On the board for next week: a best-available renderer that degrades gracefully — Forward+/Vulkan → Mobile → gl_compatibility. Part one is closing our from-source Forward+ shader-compile gap (the build has no runtime SPIR-V compiler, so Forward+ isn't even selectable yet); gl_compatibility stays today's working baseline.
#ci#testing#automation