Pin everything: taming a moving engine
Game engines and their helper libraries update constantly, and 'latest version' today is a different program than 'latest version' next month.
In plain words
Game engines and their helper libraries update constantly, and "latest version" today is a different program than "latest version" next month. We locked every ingredient of BallOrcs to an exact, verified version — the way a recipe might specify exactly which brand and batch of flour — so a build next year produces the same game as a build today. We immediately hit a case where the "proper" version was broken and had to pin a newer fix instead, which is exactly why the rulebook exists.
Under the hood
- Engine: Godot
4.7-stable→ commit5b4e0cb0fd27. - Bindings: godot-cpp v10 versions independently of the engine and its
release bundles a 4.6-stable API snapshot. Building our GDExtension
against that would silently target the wrong API, so the pipeline dumps
extension_api.jsonfrom the editor we just built and feeds it to scons viacustom_api_file. - The rc1 landmine: godot-cpp
10.0.0-rc1cannot compile against the 4.7 API at all — 4.7 exports integer-limit global constants (UINT8_MAXet al.) that the rc1 generator emits verbatim, where<cstdint>macros mangle them into syntax errors (upstream #1941). The filter fix exists only on master, so the pin moved to master HEAD, recorded with rationale inversions.lock. - Crash reporting SDK: sentry-godot 2.0.1 vendored from a
sha256-verified release zip. 2.x is a self-registering GDExtension —
the 1.x-era "add an autoload" instruction is obsolete. Windows detail:
Expand-Archivedrops unix exec bits, and sentry-native spawnscrashpad_handleras an external process, so the bits had to be restored explicitly.
The theme: every dependency gets an exact commit or digest, a reason, and a check that fails the build if it drifts — because two of the first four pins we tried were wrong in ways that would have surfaced weeks later otherwise.