batools package¶
Build/tool functionality specific to the Ballistica project.
This stuff can be a bit more sloppy/loosey-goosey since it is not used by the game itself.
Subpackages¶
Submodules¶
batools.android module¶
Functionality related to android builds.
batools.android_messages module¶
Codegen for the typed Android JNI message bus.
Reads a spec module (babasecodegen.android_messages) describing typed messages between Java and C++, and emits:
BallisticaJniBridge.java— JNI sender natives, outbound handler interface, and outbound JNI entry points.android_messages_decl.inc— C++ inbound handler abstract base, outbound sender class, install/setter declarations.android_messages_impl.inc— C++ inbound trampolines, JNI native method table, outbound sender bodies, install/setter definitions.
The two .inc files are #include``d from a hand-written ``.h
and .cc pair under src/ballistica/base/platform/android/.
Adding a new message regenerates these and forces every implementer
of AndroidInboundHandler (C++) / BallisticaJniBridge.OutboundHandler
(Java) to provide the new method — missing implementations are compile
errors.
- class batools.android_messages.Dir(*values)[source]¶
Bases:
EnumMessage direction.
- JAVA_TO_NATIVE = 'j2n'¶
- NATIVE_TO_JAVA = 'n2j'¶
- class batools.android_messages.Field(name: str, type: str)[source]¶
Bases:
objectA single typed payload field on a Message.
- class batools.android_messages.Message(name: str, direction: Dir, fields: list[Field] = <factory>, doc: str = '')[source]¶
Bases:
objectA single typed message between Java and C++.
batools.androidsdkutils module¶
Utilities for wrangling Android SDK bits.
batools.appmodule module¶
Generates parts of babase._app.py.
This includes things like subsystem attributes for all feature-sets that want them and default app-intent handling.
batools.apprun module¶
Utils for wrangling running the app as part of a build.
Manages constructing or downloading it as well as running it.
- batools.apprun.acquire_binary(purpose: str, *, gui: bool = False) str[source]¶
Return path to a runnable binary, building/downloading as needed.
By default this provides a headless-server binary along with the full server asset bundle (Python scripts + fonts + data, but no audio/textures/meshes). That is enough for the binary to fully boot and is the right choice for the vast majority of tool/test workflows (dummy-module generation, import tests, transport tests, etc.).
Pass
gui=Truewhen the caller genuinely needs a GUI binary and the full (including media) asset bundle — e.g. a test that exercises rendering. This only works in environments that have the full asset source tree available; environments like ba-check that strip audio/textures/meshes will fail the asset build in this mode.By default the binary is built locally so the caller’s working-tree edits are reflected in the run. Set
BA_APP_RUN_USE_PREFAB=1to use a prefab binary instead — useful for environments without a full compiler toolchain (public-repo CI, casual contributors). In repos that publish prefabs via efrocache (spinoff/public) the prefab path is a download; in ballistica-internal it falls back to a remote cmake build via cloudshell.
- batools.apprun.python_command(cmd: str, purpose: str, include_project_tools: bool = False, env: Mapping[str, str] | None = None) None[source]¶
Run a cmd with a built bin and PYTHONPATH set to its scripts.
- batools.apprun.run_headless_capture(*, purpose: str, config_dir: str | None = None, exec_code: str | None = None, env: Mapping[str, str] | None = None, timeout: float = 30.0, udp_listener: bool = False, stop_pattern: str | re.Pattern[str] | None = None, sigterm_grace: float = 5.0) subprocess.CompletedProcess[bytes][source]¶
Boot the headless engine, capture stdout+stderr, and return.
Designed for capture-style tests that boot the client, observe a bit of behavior in the logs, and quit. Like
python_command, this goes throughacquire_binary, so build-vs-prefab is controlled byBA_APP_RUN_USE_PREFAB=1(default: build).By default
BA_NO_UDP_LISTENER=1is exported so the binary never opens a UDP socket. That sidesteps Claude Code’s sandbox (which blocks0.0.0.0binds) and avoids port conflicts on shared CI hosts. Passudp_listener=Trueif a test genuinely needs the listener.If
stop_pattern(str or compiled regex) is given, output is streamed and the process is sent SIGTERM as soon as a line matches — much faster than waiting for an apptimer to call_babase.quit. Without it, the binary runs until it exits on its own ortimeoutelapses.Stdout and stderr are merged. Returns a CompletedProcess with bytes
stdout; callers decode as needed. Never raises on timeout — callers assert on the captured output instead.
batools.assetpins module¶
Asset-package pin inspection / update.
assetpins is the single owner of “what asset-package version
are we pinned to” across the source tree. It discovers pins in
two places:
the
"assets"entry inpconfig/projectconfig.json(the construct-mode/bootloader pin),per-wrapper
# ba_meta require asset-package <id>lines inside Python wrapper modules (server-generated; see theGET /api/v1/admin/asset-package-versions/{id}/python-wrapperREST endpoint).
Per the global build-system design, this is the only build-flow
step that talks to the cloud and the only one that mutates
checked-in source as part of normal use (other than make
update, which is purely about regenerating bookkeeping derived
from on-disk source state).
Apverid schema (from the third segment of <account>.<name>.<seg>):
<seg>starts with a digit → PROD (allowed anywhere).<seg>matchesdev(\d.*)?→ DEV (allowed in private/internal-CI only; blocked from public).<seg>matchestest\d.*→ TEST (allowed in private/internal-CI only; blocked from public).
Bare dev (no trailing digit) is an unresolved pseudo-id
meaning “give me the latest dev snapshot”. The build refuses to
consume it; assetpins update resolves it via master and
writes the resolved devN form back to the pin’s source file.
The update operation takes a TARGET and a VERSION:
TARGET:
all, an asset-package name (e.g.bastdassets) matching any pin of that package across accounts, or a file path matching exactly one pin.VERSION:
latest(current track, newest version),prod/test/dev(switch to or stay on that track, newest version), or a full third-segment like260513a(prod),test260512a, ordev260513a(exact pin; account+package come from the pin’s own apverid).
Each pin is independent — moving one pin does not move any other. Track-switching is an explicit, deliberate operation.
- class batools.assetpins.Pin(kind: str, file_path: Path, apverid: str, pin_type: PinType, account: str, package: str, wrapper_type: str | None = None, latest_available: str | None = None)[source]¶
Bases:
objectOne discovered asset-package pin.
- class batools.assetpins.PinType(*values)[source]¶
Bases:
EnumClassification of an apverid by its third-segment shape.
- DEV = 'dev'¶
- PROD = 'prod'¶
- TEST = 'test'¶
- batools.assetpins.classify_apverid(apverid: str) PinType[source]¶
Classify an apverid string by its third segment.
Raises
CleanErrorif the apverid is structurally malformed (wrong segment count, unrecognized third-segment shape).
- batools.assetpins.do_check(projroot: Path) list[Pin][source]¶
Return the list of dev/test pins (empty = clean).
Used by the pre-pubsync gate (and by
make assetpins-check) to refuse before any committed-source dev/test pin can flow to a public artifact.
- batools.assetpins.do_list(projroot: Path) None[source]¶
Print discovered pins + whether master has newer versions.
- batools.assetpins.do_update(projroot: Path, target_str: str, version_str: str) None[source]¶
Update one or more pins to a chosen version.
target_str:all, an asset-package name (e.g.bastdassets), or a file path matching exactly one pin.version_str:latest(track-preserving),prod/test/dev(track-switching), or a full third segment (e.g.260513a,dev260513a,test260512a).
batools.assetsmakefile module¶
Updates src/assets/Makefile based on source assets present.
batools.build module¶
General functionality related to running builds.
- class batools.build.LazyBuildCategory(*values)[source]¶
Bases:
EnumTypes of sources.
- ASSETS = 'assets_src'¶
- CMAKE = 'cmake_src'¶
- CODEGEN = 'codegen_src'¶
- DUMMYMODULES = 'dummymodules_src'¶
- RESOURCES = 'resources_src'¶
- WIN = 'win_src'¶
- class batools.build.PrefabPlatform(*values)[source]¶
Bases:
EnumDistinct os/cpu-arch/etc. combos we support for prefab builds.
- LINUX_ARM64 = 'linux_arm64'¶
- LINUX_X86_64 = 'linux_x86_64'¶
- MAC_ARM64 = 'mac_arm64'¶
- MAC_X86_64 = 'mac_x86_64'¶
- WINDOWS_X86 = 'windows_x86'¶
- WINDOWS_X86_64 = 'windows_x86_64'¶
- static get_current(wsl_targets_windows: bool | None = None) PrefabPlatform[source]¶
Get an identifier for the platform running this build.
Pass a bool wsl_targets_windows value to cause WSL to target either native Windows (True) or Linux (False). If this value is not passed, the env var BA_WSL_TARGETS_WINDOWS is used, and if that is not set, the default is False (Linux builds).
Throws a RuntimeError on unsupported platforms.
- class batools.build.PrefabTarget(*values)[source]¶
Bases:
EnumTypes of prefab builds able to be run.
- GUI_DEBUG = 'gui-debug'¶
- GUI_RELEASE = 'gui-release'¶
- SERVER_DEBUG = 'server-debug'¶
- SERVER_RELEASE = 'server-release'¶
- batools.build.archive_old_builds(ssh_server: str, builds_dir: str, ssh_args: list[str]) None[source]¶
Stuff our old public builds into the ‘old’ dir.
(called after we push newer ones)
- batools.build.cmake_prep_dir(dirname: str, verbose: bool = False) None[source]¶
Create a dir, recreating it when cmake/python/etc. versions change.
Useful to prevent builds from breaking when cmake or other components are updated.
batools.builtinassetids module¶
Generate C++ id-enum + load-block code for the construct asset-package.
Reads the cached bundle manifest at
.cache/asset_bundle/gui/manifest.json, walks each per-bucket CAS
manifest, and splices generated content into two pre-marked autogen
sections in checked-in source files:
src/ballistica/base/base.h— between the// __AUTOGENERATED_BUILTIN_ASSET_IDS_BEGIN__and…_END__markers: the fourBuiltinTextureID/BuiltinCubeMapTextureID/BuiltinSoundID/BuiltinMeshIDenums + thekBuiltinAssetsApveridstring constant.src/ballistica/base/assets/assets.cc— between the// __AUTOGENERATED_BUILTIN_ASSET_LOAD_BEGIN__and…_END__markers insideAssets::StartLoading(): oneLoadBuiltinTexture(BuiltinTextureID::kFooBar, "<apverid>:foo/bar")call per entry.
This runs as part of make update (not codegen): the autogen
sections live in checked-in files, and per the global build-system
doc, anything that touches checked-in files belongs in update.
Idempotent — only writes a target file if the spliced result
differs from what’s on disk, so steady-state make update calls
leave both files (and their mtimes) untouched.
- class batools.builtinassetids.AssetEntry(kind: AssetKind, logical_name: str, full_logical_path: str)[source]¶
Bases:
objectOne asset, post-grouping & validation.
- class batools.builtinassetids.AssetKind(*values)[source]¶
Bases:
EnumWhich of the four C++ enums an entry belongs to.
- CUBE_MAP_TEXTURE = 'cube_map_texture'¶
- MESH = 'mesh'¶
- SOUND = 'sound'¶
- TEXTURE = 'texture'¶
- class batools.builtinassetids.BuildResult(apverid: str, entries: list[AssetEntry] = <factory>)[source]¶
Bases:
objectOutput collected before writing to disk.
- entries: list[AssetEntry]¶
- entries_for(kind: AssetKind) list[AssetEntry][source]¶
Entries of a given asset kind, sorted by enum-entry name.
- batools.builtinassetids.collect(projroot: Path) BuildResult[source]¶
Read cached manifests and produce a validated build result.
The manifest is produced by
asset_bundle_build(invoked via the make rule whose direct dep ispconfig/projectconfig.json), so by the time we’re reading it the file exists and its apverid matches projectconfig’s"assets". Anything else is a build-system bug we want to surface, not paper over.
- batools.builtinassetids.compute_splices(projroot: Path, base_h_existing: str | None = None, assets_cc_existing: str | None = None) dict[str, str][source]¶
Compute spliced contents for both target files.
Returns a dict keyed by project-relative path with the full new file content (existing content + new autogen section). Caller decides whether to write — typical use is “write only if contents differ from on-disk”.
base_h_existing/assets_cc_existinglet the caller pass in already-read content (e.g. when integrated into a project updater that’s already loaded the file); passNoneto read from disk here.
- batools.builtinassetids.generate(projroot: Path, check: bool = False) bool[source]¶
Splice generated content into
base.handassets.cc.Reads each target file, replaces the content between its
// __AUTOGENERATED_*__marker pair, and writes the file only if the resulting content differs from what’s on disk. Idempotent: a run with no changes leaves both files (and their mtimes) untouched.Returns True if anything was (or would be) changed.
- batools.builtinassetids.render_enum_block(result: BuildResult) str[source]¶
Build the autogen-section content for
base.h.Returns the lines that go between
// __AUTOGENERATED_BUILTIN_ASSET_IDS_BEGIN__and// __AUTOGENERATED_BUILTIN_ASSET_IDS_END__in base.h (the markers themselves are NOT included).
- batools.builtinassetids.render_load_block(result: BuildResult) str[source]¶
Build the autogen-section content for
assets.cc.Returns the lines that go between
// __AUTOGENERATED_BUILTIN_ASSET_LOAD_BEGIN__and// __AUTOGENERATED_BUILTIN_ASSET_LOAD_END__insideAssets::StartLoading()(the markers themselves are NOT included). Lines that would exceed the 80-char cpplint limit wrap after the comma.
batools.changelog module¶
Generates a pretty html changelog from our markdown.
batools.codegen module¶
Generate code from input files.
Used for various code-generation applications.
- batools.codegen.gen_pyembed(projroot: str, in_path: str, out_path: str, *, encrypt: bool, ctx_var: str = 'internal_py_context') None[source]¶
Generate a pyembed .inc from a .py file using compiled bytecode.
The emitted .inc embeds two marshaled
CodeTypeblobs — one compiled withoptimize=0(debug) and one withoptimize=1(release) — under#if BA_DEBUG_BUILD/#else, so each C++ build links only the blob matching its own-Olevel. Replaces bothgen_encrypted_python_codeandgen_flat_data_code.The .inc expands to a
PyembedExeccall usingctx_varas the execution context (internal_py_contextby default — most featuresets set up that local variable before the#include). Settingencrypt=TrueXOR-obfuscates the bytecode so casual inspection of the binary doesn’t trivially reveal the source.
batools.codegenbuild module¶
Functionality used in codegen-builds (dynamically generated sources).
batools.codegenmakefile module¶
Procedurally regenerates our code Makefile.
This Makefiles builds our generated code such as encrypted python strings,
node types, etc). Outputs land in generated/ / _generated/ dirs per
feature-set; see docs/design/codegen.md for why that’s the convention.
- class batools.codegenmakefile.CodegenMakefileGenerator(projroot: str, existing_data: str)[source]¶
Bases:
objectThing that does the thing.
batools.docker module¶
General functionality related to docker builds.
- batools.docker.docker_build(platform: str | None = 'linux/amd64', headless_build: bool | str | None = None, build_type: str | None = None) None[source]¶
Build docker image. platform == ‘linux/arm64’ or platform == ‘linux/amd64’
batools.docs module¶
Documentation generation functionality.
- class batools.docs.AttributeInfo(name: str, attr_type: str | None = None, docs: str | None = None)[source]¶
Bases:
objectInfo about an attribute of a class.
- class batools.docs.SphinxSettings(project_name: str, project_author: str, copyright: str, version: str, buildnum: int, logo_small: str, logo_large: str)[source]¶
Bases:
objectOur settings for sphinx stuff.
- batools.docs.get_sphinx_settings(projroot: str) SphinxSettings[source]¶
Settings for our Sphinx runs.
batools.dummymodule module¶
Generates dummy .py modules based on binary modules.
This allows us to use code introspection tools such as pylint without spinning up the engine, and also allows external scripts to import game scripts successfully (albeit with limited functionality).
batools.enumspython module¶
Generate a Python module containing Enum classes from C++ code.
Note that the general strategy moving forward is the opposite of this: to generate C++ code as needed from Python sources. That is generally a better direction to go since introspecting Python objects or source code ast is more foolproof than the text based parsing we are doing here.
batools.featureset module¶
Functionality for working with spinoff feature-sets.
Feature-sets are logical groupings of functionality that can be stripped out of or added in to spinoff dst projects. This allows for more high level dependency management and organization than would be possible through filtering alone.
- class batools.featureset.FeatureSet(name: str)[source]¶
Bases:
objectDefines a feature-set.
- allow_as_soft_requirement: bool¶
If True, feature-set ‘foo_bar’, will be allowed to be listed as a soft-requirement of other feature sets and its python-app-subsystem will be annotated as type ‘bafoobar.FooBarSubsystem | None’ instead of simply ‘bafoobar.FooBarSubsystem’. This forces type-checked code to account for the possibility that it will not be present. Note that this currently requires has_python_app_subsystem to be True (because if a soft-required feature-set is missing we must assume that is the case anyway because there’s no way to know).
- cpp_namespace_check_disable_files: set[str]¶
Paths of files we should disable c++ namespace checks for. (generally external-originating code that doesn’t conform to our ballistica feature-set based namespace scheme)
- dummy_module_def: DummyModuleDef¶
Override this to customize how your dummy module is generated.
- classmethod get_active() FeatureSet[source]¶
Return the FeatureSet currently being defined.
For use by settings scripts.
- classmethod get_all_for_project(project_root: str) list[FeatureSet][source]¶
Return all feature-sets for the current project.
- has_python_app_subsystem: bool¶
If True, for feature-set ‘foo_bar’, the build system will define a ‘ba*.app.foo_bar’ attr which points to a lazy loaded instance of type ‘bafoobar.FooBarSubsystem’.
- has_python_binary_module: bool¶
Whether this featureset defines a native Python module within its C++ code. The build process will try to create dummy modules for all native modules, so to avoid errors you must tell it if you don’t have one.
- property path_native_source: str¶
Project-relative path for this feature-set’s native source.
Note that this does not mean that such source actually exists; this just shows where it would.
- property path_python_package: str¶
Project-relative path for this feature-set’s Python package.
Note that this does not mean that the package actually exists; this just shows where it would.
- property path_python_package_codegen: str¶
Project-relative path for this feature-set’s Python codegen package.
Note that this does not mean that the package actually exists; this just shows where it would.
- property path_python_package_tests: str¶
Project-relative path for this feature-set’s Python tests package.
Note that this does not mean that the package actually exists; this just shows where it would.
- property paths: list[str]¶
Return all file/dir paths associated with this feature-set.
Paths are project relative and may not actually exist; this just gives their theoretical locations.
- python_app_subsystem_dependencies: set[str]¶
By default, Python app subsystems will be created in alphabetical order based on their feature set name. All subsystem callbacks adhere to this ordering. If there are any feature sets whose subsystems should always be created before this one’s, list them here. Note that this does not affect whether or not the feature set is included in the build; only the init order in cases when it is.
- requirements: set[str]¶
Other feature-sets this one requires. Any spinoff project that includes our feature-set will implicitly include our requirements as well. We are allowed to access Python modules of our requirements directly, unlike soft-requirements where we must limit our access to their app subsystem.
- classmethod resolve_requirements(featuresets: list[FeatureSet], reqs: set[str]) set[str][source]¶
Resolve all required feature-sets based on a given set of them.
Throws descriptive CleanErrors if any are missing.
- soft_requirements: set[str]¶
Feature-sets we can use but can survive without. All usage of soft requirements must be through app-subsystems (ba*.app.foo_bar for feature-set foo_bar, etc.). We must be prepared for these subsystems to be missing (set to None) and we must never import their modules directly (since they might not exist). Note that all featuresets we soft-require must have ‘allow_as_soft_requirement’ enabled. While it is possible to programmatically check for the presence of any feature-set, officially listing soft-requirements ensures that any expected app-subsystems are in place even for feature-sets not included in the spinoff project (though be aware their type annotations will be ‘Any | None’ in that case instead of the usual ‘FooBarSubsystem | None’ due to ‘FooBarSubsystem’ not actually existing).
batools.pcommandmain module¶
A collection of commands for use with this project.
All top level functions here can be run by passing them as the first argument on the command line. (or pass no arguments to get a list of them).
batools.pcommands module¶
A nice collection of ready-to-use pcommands for this package.
- batools.pcommands.androidaddr() None[source]¶
Return the source file location for an android program-counter.
command line args: archive_dir architecture addr
- batools.pcommands.archive_old_builds() None[source]¶
Stuff our old public builds into the ‘old’ dir.
(called after we push newer ones)
- batools.pcommands.check_clean_safety() None[source]¶
Ensure all files are are added to git or in gitignore.
Use to avoid losing work if we accidentally do a clean without adding something.
- batools.pcommands.cmake_prep_dir() None[source]¶
Create dir & recreate when cmake/python/etc. version changes.
Useful to prevent builds from breaking when cmake or other components are updated.
- batools.pcommands.efrocache_update() None[source]¶
Build & push files to efrocache for public access.
- batools.pcommands.ensure_prefab_platform() None[source]¶
Ensure we are running on a particular prefab platform.
Note that prefab platform may not exactly match hardware/os. For example, when running in Linux under a WSL environment, the prefab platform may be Windows; not Linux. Also, a 64-bit os may be targeting a 32-bit platform.
- batools.pcommands.gen_python_enums_module() None[source]¶
Update our procedurally generated python enums.
- batools.pcommands.get_master_asset_src_dir() None[source]¶
Print master-asset-source dir for this repo.
- batools.pcommands.lazy_increment_build() None[source]¶
Increment build number only if C++ sources have changed.
This is convenient to place in automatic commit/push scripts. It could make sense to auto update build number when scripts/assets change too, but a build number change requires rebuilding all binaries so I’ll leave that as an explicit choice to save work.
- batools.pcommands.printcolors() None[source]¶
Print all colors available in efro.terminals.TerminalColor.
- batools.pcommands.prune_includes() None[source]¶
Check for unnecessary includes in C++ files.
Pass –commit to actually modify files.
- batools.pcommands.python_android_build() None[source]¶
Build Android Python lib using new in-tree build script.
- batools.pcommands.python_android_build_debug() None[source]¶
Build Android Python lib using new in-tree script (debug).
- batools.pcommands.python_android_patch_old() None[source]¶
Patches Python to prep for building for Android (old pipeline).
- batools.pcommands.python_android_patch_ssl_old() None[source]¶
Patches Python ssl to prep for building for Android (old pipeline).
- batools.pcommands.python_apple_gather() None[source]¶
Gather Apple Python slices into XCFramework and copy to project.
- batools.pcommands.python_build_android_old() None[source]¶
Build an embeddable Python lib for Android (old pipeline).
- batools.pcommands.python_build_android_old_debug() None[source]¶
Build embeddable Android Python lib (old pipeline, debug ver).
- batools.pcommands.python_build_apple() None[source]¶
Build one Apple Python slice using new in-tree script.
- batools.pcommands.python_gather() None[source]¶
Gather build python components into the project.
This assumes all embeddable py builds have been run successfully.
- batools.pcommands.python_gather_android_old() None[source]¶
python_gather but only android bits (old pipeline).
- batools.pcommands.resize_image() None[source]¶
Resize an image and save it to a new location.
args: xres, yres, src, dst
- batools.pcommands.static_dependencies_build_debug() None[source]¶
Build static dependencies for Android and Apple platforms.
- batools.pcommands.update_project() None[source]¶
Update project files.
This command is in charge of generating Makefiles, IDE project files, etc. based on the current structure of the project. It can also perform sanity checks or cleanup tasks.
Updating should be explicitly run by the user through commands such as ‘make update’, ‘make check’ or ‘make preflight’. Other make targets should avoid running this command as it can modify the project structure arbitrarily which is not a good idea in the middle of a build.
If this command is invoked with a –check argument, it should not modify any files but instead fail if any modifications would have been made. (used in CI builds to make sure things are kosher).
batools.pcommands2 module¶
A nice collection of ready-to-use pcommands for this package.
- batools.pcommands2.asset_bundle_build() None[source]¶
Build a bundled-asset variant for the projectconfig pin.
Takes one arg: a variant name (
guiorheadless).gui: real renderable assets (fallback-profile regular-quality textures + English language + constant).headless: same bucket shape as gui, but withnull-profile textures (single shared empty blob) so headless server builds keep the same wrapper-module layout (and same type-checks) without shipping image data.
Reads the apverid from
pconfig/projectconfig.json’s"assets"field. The projectconfig value is expected to be a fully-resolved apverid (<owner>.<name>.<seg>where<seg>is digits,devN, ortestN). If it’s the unresolved pseudo-id<owner>.<name>.dev, the build refuses with a single-tunnel “runmake assetpins-latest” error. Pin-state mutation lives exclusively intools/pcommand assetpins.Writes
.cache/asset_bundle/<variant>/manifest.jsonplus CAS-keyed bucket manifests + data blobs under.cache/assetdata/. Both variants share the same.cache/assetdata/(CAS dedup). Staging picks the right variant to copy into<staged>/ba_data/based on the build target.
- batools.pcommands2.assetpins() None[source]¶
Inspect and update asset-package pins.
Subcommands:
assetpins # default: same as 'list' assetpins list # list pins + master's # latest-available assetpins help # show usage examples assetpins update <TARGET> <VERSION> # mutate matched pins assetpins check # exit non-zero on any # dev/test pin
VERSION can be:
latest— current track, newest version.prod/test/dev— switch (or stay on) the named track, newest version of it.A full version string as seen in the third segment of an apverid:
<digits>for prod (e.g.260513a),test<digits>for test (e.g.test260512a), ordev<digits>for dev (e.g.dev260513a). The track is inferred from the prefix; account and package come from each pin’s own apverid.
TARGET can be:
all— every discovered pin.<package-name>(e.g.bastdassets) — every pin of that asset-package across accounts.A file path (e.g.
pconfig/projectconfig.json) — exactly one pin.
Pins live in
pconfig/projectconfig.json(the construct-mode/bootloader pin) and per-wrapper# ba_meta require asset-package <id>lines in Python wrapper modules undersrc/assets/ba_data/python/. Each pin is independent — moving one pin does not move any other; track-switching is an explicit deliberate operation.assetpinsis the only command that mutates pin state, and the only build-flow phase that talks to the cloud — seeefrohome/docs/global_design/build_system.md.
- batools.pcommands2.clean_orphaned_assets() None[source]¶
Remove asset files that are no longer part of the build.
- batools.pcommands2.gen_builtin_asset_ids() None[source]¶
Splice C++ id-enums / load-block into base.h / assets.cc.
Reads the cached bundle manifest under
.cache/asset_bundle/gui/and splices generated content into the// __AUTOGENERATED_BUILTIN_ASSET_IDS_*__autogen section insrc/ballistica/base/base.hand the// __AUTOGENERATED_BUILTIN_ASSET_LOAD_*__section insideAssets::StartLoading()insrc/ballistica/base/assets/assets.cc. Idempotent — only rewrites a file if its spliced content differs from on-disk.Normally invoked indirectly via
make update(this is the one-phase-that-can-modify-checked-in-files per the build system design); standalone invocation exists for manual regen. Pass--checkto fail (without writing) if either file would change.
- batools.pcommands2.gen_monolithic_register_modules() None[source]¶
Generate .h file for registering py modules.
- batools.pcommands2.py_examine() None[source]¶
Run a python examination at a given point in a given file.
- batools.pcommands2.spinoff_check_submodule_parent() None[source]¶
Make sure this dst proj has a submodule parent.
- batools.pcommands2.tests_warm_start() None[source]¶
Warm-start some stuff needed by tests.
This keeps logs clearer by showing any binary builds/downloads we need to do instead of having those silently happen as part of tests.
- batools.pcommands2.update_cmake_prefab_lib() None[source]¶
Update prefab internal libs; run as part of a build.
batools.pcommands3 module¶
A nice collection of ready-to-use pcommands for this package.
- batools.pcommands3.compose_docker_arm64_gui_debug() None[source]¶
Build the docker image with bombsquad cmake for arm64.
- batools.pcommands3.compose_docker_arm64_gui_release() None[source]¶
Build the docker image with bombsquad cmake for arm64.
- batools.pcommands3.compose_docker_arm64_server_debug() None[source]¶
Build the docker image with bombsquad cmake server for arm64.
- batools.pcommands3.compose_docker_arm64_server_release() None[source]¶
Build the docker image with bombsquad cmake server for arm64.
- batools.pcommands3.compose_docker_gui_debug() None[source]¶
Build the docker image with bombsquad debug cmake gui.
- batools.pcommands3.compose_docker_gui_release() None[source]¶
Build the docker image with bombsquad cmake gui.
- batools.pcommands3.compose_docker_server_debug() None[source]¶
Build the docker image with bombsquad debug cmake server.
- batools.pcommands3.compose_docker_server_release() None[source]¶
Build the docker image with bombsquad cmake server.
- batools.pcommands3.gen_pyembed() None[source]¶
Gen a pyembed .inc file using compiled bytecode.
Args: <in_path> <out_path> [encrypt={0,1}] [ctx=<var_name>]
Replaces gen_encrypted_python_code (encrypt=1) and gen_flat_data_code (encrypt=0) for pyembed modules.
- batools.pcommands3.generate_flathub_manifest() None[source]¶
Generate a Flathub manifest for Ballistica and push to submodule. This function is intended to be run within a GitHub Actions workflow.
This function: 1. Copies files from pconfig/flatpak/ to pconfig/flatpak/flathub 2. Generates the manifest from template using latest GitHub release info
- batools.pcommands3.generate_flatpak_release_manifest(version: str, asset_url: str, checksum: str, github_repo: str, release_date: str) None[source]¶
Generate a Flatpak release manifest for Ballistica.
This function:
Adds a new release entry to net.froemling.bombsquad.releases.xml
Updates the net.froemling.bombsquad.releases.xml file with the new release information
- Parameters:
version – Version string from GitHub release (e.g., ‘1.7.60’)
asset_url – URL to the release asset
checksum – SHA256 checksum of the release asset
github_repo – GitHub repository in format ‘owner/repo’
release_date – Release date in YYYY-MM-DD format
- batools.pcommands3.remove_docker_images() None[source]¶
Remove the bombsquad images loaded in docker.
- batools.pcommands3.test_game_run() None[source]¶
Run the game for testing purposes in a siloed instance dir.
Usage:
tools/pcommand test_game_run [--instance NAME] [--gui] [--port N] [--exec CODE] [--log LEVELS] [--timeout SECONDS] [--fleet FLEET] [--user-data] [--reset-connectivity] [--debug-network-toggle] [--gc-warning-threshold N] [--gc-debug-types TYPE1,TYPE2,...] [--gc-debug-type-limit N]
Always runs in the foreground and blocks until the process exits or
--timeoutelapses. Callers that want to supervise multiple concurrent instances, keep a server alive across sessions, or manage output on their own should wrap their own invocation (e.g. a terminal multiplexer,nohup ... &, or the host automation’s background-task mechanism) rather than relying on backgrounding baked into this command.Default is a headless server build; the headless binary starts faster, pops no window, and is the right fit for the programmatic testing this command is optimized for. Pass
--guiwhen you actually want to interact with the UI.Every run invokes the appropriate
maketarget first so edits to.py/.ccsources land in the binary we launch. Lazybuild makes this a near-noop when nothing changed, so there’s no need to manuallymake cmake-build/make cmake-server-buildbefore running this — the pcommand handles it.Each instance lives under
build/test_run/<name>/with its ownba_root/andconfig.toml(server only). Silos auto-create on first use. Run two instances concurrently by passing different--instancenames; give server instances distinct--portvalues so they don’t fight over UDP 43210.Flags:
--instance NAME: Silo name underbuild/test_run/. Defaults todefault.--gui: Launch the interactive GUI client build instead of the default headless server build.--port N: Only valid at silo creation time for headless instances. Writes the port into the silo’s newconfig.toml. Ignored (with a note) for pre-existing silos.--exec CODE: Python snippet passed via the binary’s--execflag. Works for both GUI and headless builds; for headless,connect_to_partycalls are allowed in developer builds only (shipped builds hard-block this path).--log LEVELS: Comma-separated logger=LEVEL pairs (e.g.ba.net=DEBUG). Passed viaBA_LOG_LEVELS.--timeout SECONDS: Hard timeout before the process is killed (default 10).--fleet FLEET: Override master-server fleet (prod,test,dev).--user-data: GUI only. Drop--config-dirso the binary uses its default per-user data dir — you see the caller’s real signed-in state, saved options, unlocked characters, etc. instead of the silo’s fresh slate. Handy for reproducing user-reported issues that only manifest with real account state. Incompatible with headless (servers have no user data dir in the same sense).--reset-connectivity: SetsBA_CONNECTIVITY_RESET=1for the child process so saved zone-ping warm-start data is discarded on launch. Useful for testing initial-cycle convergence behavior from a clean slate.--debug-network-toggle: SetsBA_NETWORK_AVAILABILITY_DEBUG_TOGGLE=1for the child process so the platform-layer network-availability signal starts in the unavailable state and toggles every 5 seconds thereafter — exercises gating consumers without actually severing the network.--gc-warning-threshold N: SetsBA_GC_WARNING_THRESHOLD. Override the object-count threshold above which a cyclic-gc pass logs a WARNING (default 50). Lower it to surface smaller cycles, raise it to silence known library-internal cycles while iterating.--gc-debug-types TYPE1,TYPE2,...: SetsBA_GC_DEBUG_TYPES. Comma-separated list of type names whose collected instances get extra ref-dump details in the GC summary (overrides the cloud-suppliedgc_debug_types). Use to track down what’s holding a specific type in a cycle without needing a cloud-config push.--gc-debug-type-limit N: SetsBA_GC_DEBUG_TYPE_LIMIT. Max number of instances per debug-type to dump (overrides the cloud-supplied limit).
Env-var-setting flags (
--reset-connectivity,--debug-network-toggle, etc.) exist so that callers don’t need to setBA_*env vars in the command prefix, which changes the wrapper’s command signature and triggers a fresh sandbox permission prompt per invocation. If you find yourself wanting to set a newBA_*debug env var for a test, add a matching flag here rather than passing the env var directly.
batools.pruneincludes module¶
Utility to scan for unnecessary includes in c++ files.
batools.resourcesmakefile module¶
Generate our resources Makefile.
(builds things like icons, banners, images, etc.)
batools.staging module¶
Stage files for builds.
batools.toplevelmakefile module¶
Updates top level Makefile based on project elements present.
batools.version module¶
Util to get ballisticakit versions.
- class batools.version.Mode(*values)[source]¶
Bases:
EnumMode we can run this command in.
- API = 'api'¶
- BUILD = 'build'¶
- INFO = 'info'¶
- VERSION = 'version'¶
batools.xcodeproject module¶
XCode related functionality.