Skip to content

Building From Source

godgutten edited this page Sep 21, 2026 · 2 revisions

Building From Source

For anyone building the mod themselves. If you just want to fly it, see Installation.

Run the tests

python -m unittest discover -s tests -v

Roughly 940 of them, about two seconds.

Worth understanding what they prove. They are static assertions over the source: they read the SQF and check that specific decisions are still in it. So a green suite means the code still says what it should. It says nothing about how the mod behaves in Arma, because the suite has never started the game. Retuning a constant will break the test that pins it, and that is the test doing its job, not a bug.

Build a release

python tools/build_release.py --version 1.2.3.0 --label my-change

That runs the suite, builds and signs both PBOs, writes the release and source ZIPs, then re-runs the whole suite from a fresh extraction of the source ZIP. It fails rather than shipping something unverified.

Useful flags:

Flag What it does
--deploy <dir> Extracts into a mod folder and re-hashes what landed
--key-dir / --key-name The signing keypair. The private key lives outside the repository
--no-sign Ships unsigned, deliberately
--expect-pbo-sha256 Fails unless the built PBO matches, which is how you prove a rebuild reproduces a known release

Output is deterministic (sorted ZIP entries, fixed timestamps), so identical source produces identical archives.

A release contains two addon files: TLB_CARP_System.pbo, the drop computer, and TLB_CARP_Items.pbo, which carries the CARP Computer item and the launcher logo.

Regenerate assets

python tools/gen_assets.py      # inventory icon and launcher logos
python tools/gen_banners.py     # Steam Workshop banners and preview
python tools/build_config.py    # config.bin, from config.cpp
python tools/gen_dialog.py      # the panel layout, from its spec

Four traps

Each of these has cost somebody a day.

config.cpp is the source; config.bin is built from it. The binary is what ships, so a .cpp edit that is not rebuilt does nothing in game and nothing warns you. Run python tools/build_config.py. It round-trips losslessly through Arma 3 Tools' CfgConvert, verified byte-for-byte.

A new function only reaches the engine through the compile table in addon/functions/fn_postInit.sqf. There is no other registration path for anything added since the config was binarised, and a brand new file also has to be --included in its first release build, because the base PBO defines the entry set.

A compiled .sqfc sibling shadows the .sqf beside it at load. There are none in the tree now and it should stay that way. If a change appears to do nothing in game, look for one before theorising about physics — that exact mistake once produced sixteen runs of garbage that looked like a solver problem.

Never set a control position in the dialog by hand. tools/gen_dialog.py emits the whole panel from a layout spec and refuses to write if any two controls overlap. v0.11.0 did not have that check, put four controls on top of the CARGO row, and shipped it.

The panel is generated

gen_dialog.py walks a cursor down the panel handing out rectangles. It parses the existing handler strings out of the config and re-emits them verbatim, so a rewrite cannot quietly drop one, and --check verifies without writing.

Contributing

Branch, pull request, squash merge, and nothing merges until it has been checked — see CONTRIBUTING.md, which is the whole rulebook.

Clone this wiki locally