← Dev Log
BallOrcs1 min read

Hello, Realm: why BallOrcs builds everything from source

BallOrcs is a colourful 3D platformer about round little creatures. Day one went on building the factory that will make the game.

In plain words

BallOrcs is a colourful 3D platformer about round little creatures — think "build your own bouncy ball with eyes, a hat, and superpowers." Before writing any of the fun stuff, we spent day one building the factory that will make the game: our own copy of the game engine, our own build machines, and a rulebook that guarantees the game we ship is exactly the game we tested. It's like pouring the foundations before decorating the house.

Under the hood

The repo opened with a deterministic build pipeline, not gameplay. Choices worth defending:

  • Godot built from pinned source, not downloaded binaries. A single versions.lock is the source of truth for every dependency — engine commit, bindings, SDKs, container images — and check_pins fails closed when a build touches an unpinned value.
  • One entry point: build/build.sh <platform> dispatches to per-platform scripts sharing a common library. C++ gameplay lives in a GDExtension, so the engine stays unmodified upstream code.
  • Self-hosted GitLab CE + CI (localhost, memory-tuned for a 10 GB WSL box) rather than cloud CI: the whole studio runs on one Windows machine with WSL, and nothing about the pipeline should assume internet-hosted services exist.
  • Day-one hygiene that paid off immediately: .gitattributes forces LF repo-wide (the system gitconfig has autocrlf=true, and CRLF scripts break inside Linux build containers and change artifact hashes), and shellcheck runs in CI with a clean exit — several findings were real bugs, like a top-level [[ cond ]] && warn that aborted whole builds under set -e whenever the condition was false.

Pinning surprises from the very first day: upstream publishes build-container Dockerfiles but no images (the ghcr packages don't exist), so we pin their repo commit and build/push images to our own registry; and godot-cpp has no godot-4.7-stable tag because since v10 it versions independently of the engine — more on the fallout from that in the next post.

#kickoff#infrastructure