bacommon.workspace package¶
Functionality related to ballistica.net workspaces.
Submodules¶
bacommon.workspace.assetsv1 module¶
Public types for assets-v1 workspaces.
While this module is currently only used server-side, its source code can be useful as reference when setting workspace config data by hand or for use in client-side workspace modification tools. There may be advanced settings that are not accessible through the UI/etc.
- class bacommon.workspace.assetsv1.AssetsV1AprefFile[source]¶
Bases:
IOMultiType[AssetsV1AprefFileTypeID]Top level class for our multitype.
An
<name>.aprefsource in an assets_v1 workspace is an asset-package reference: a pin to a published asset-package version. String briefs can then reference the pinned package’s translations via cross-package term refs ({@<apref-logical-path>:<entry-path>}).- classmethod get_type(type_id: AssetsV1AprefFileTypeID) type[AssetsV1AprefFile][source]¶
Return the subclass for each of our type-ids.
- classmethod get_type_id() AssetsV1AprefFileTypeID[source]¶
Return the type-id for this subclass.
- classmethod get_type_id_storage_name() str[source]¶
Return the key used to store type id in serialized data.
The default is a short obscure value so that it is unlikely to conflict with members of individual type attrs, but in some cases one might prefer to serialize it to something simpler like ‘type’ by overriding this call. One just needs to make sure that no encompassed types serialize anything to that same name themself (dataclassio will error if they do).
- class bacommon.workspace.assetsv1.AssetsV1AprefFileTypeID(*values)[source]¶
Bases:
EnumType ID for each of our subclasses.
- V1 = 'v1'¶
- class bacommon.workspace.assetsv1.AssetsV1AprefFileV1(apverid: str)[source]¶
Bases:
AssetsV1AprefFileOur initial version of asset-package-ref file data.
- apverid: str¶
The pinned asset-package-version id (
<account>.<package>.<version-segment>). Always a concrete version — including on the dev track (a specificdevNsegment, never the baredevpseudo-id); pins only move via the explicit update/switch-track actions in the workspace UI.
- classmethod get_type_id() AssetsV1AprefFileTypeID[source]¶
Return the type-id for this subclass.
- class bacommon.workspace.assetsv1.AssetsV1GlobalVals(base_assets: str | None = None, base_assets_filter: str = '', docs: str = '', dev_team: str | None = None, asset_package_name: str | None = None, conventions: ConventionsMode = ConventionsMode.RELAXED, resolve_access: PackageResolveAccess = PackageResolveAccess.PUBLIC, source_sharing: PackageSourceSharing = PackageSourceSharing.PRIVATE)[source]¶
Bases:
objectGlobal values for an assets_v1 workspace.
- asset_package_name: str | None = None¶
The asset-package name this workspace publishes under. None means it is derived from the workspace’s display name (see
derive_asset_package_name()); set explicitly to decouple the published name from the display name (e.g. to keep a package lineage across a workspace rename, or to have a new workspace take over publishing an existing package name).
- conventions: ConventionsMode = 'relaxed'¶
Conventions-check enforcement level (see
ConventionsMode). First-party workspaces set strict (see the asset-packages design doc). Set by hand inworkspace.json– deliberately not exposed in the UI. Unknown stored values fall back to relaxed so older servers never over-enforce.
- dev_team: str | None = None¶
Dev-team id granting resolve access to this workspace’s dev/test asset-package versions. None (unset) means owner-only access — matching the semantics of the asset-package doc’s
dev_team_id(seeAssetPackage.account_has_access).
- docs: str = ''¶
Optional free-form workspace documentation, appended to the generated wrapper module’s docstring (after the auto-generated summary line). Empty string means none.
- resolve_access: PackageResolveAccess = 'public'¶
Who may resolve this package’s prod versions (see
PackageResolveAccess). Set by hand inworkspace.json– deliberately not exposed in the UI, same asconventions, since its use is limited to server-side packages. Unknown stored values fall back to public: failing closed here would break asset resolves for every client, and private packages are private from birth and reached by their owner (who short-circuits before this is ever consulted).
- source_sharing: PackageSourceSharing = 'private'¶
Who may start a workspace of their own from this package’s source (see
PackageSourceSharing). Package-wide policy, resolved live – it moved here from a per-version field in 2026-07-27, which republishing silently reset each time.
- class bacommon.workspace.assetsv1.AssetsV1PathVals[source]¶
Bases:
IOMultiType[AssetsV1PathValsTypeID]Top level class for path vals classes.
- classmethod get_type(type_id: AssetsV1PathValsTypeID) type[AssetsV1PathVals][source]¶
Return a specific subclass given a type-id.
Should be overridden by child classes. Generally, users of the class should call
get_type_cached()instead of this, as it is more efficient.
- classmethod get_type_id() AssetsV1PathValsTypeID[source]¶
Return the type-id for this subclass.
- classmethod get_type_id_storage_name() str[source]¶
Return the key used to store type id in serialized data.
The default is a short obscure value so that it is unlikely to conflict with members of individual type attrs, but in some cases one might prefer to serialize it to something simpler like ‘type’ by overriding this call. One just needs to make sure that no encompassed types serialize anything to that same name themself (dataclassio will error if they do).
- class bacommon.workspace.assetsv1.AssetsV1PathValsAprefV1(keep_up_to_date: bool = True)[source]¶
Bases:
AssetsV1PathValsPath-specific values for an
.aprefasset-package ref.Keyed in
workspace.json’spathdict by the.apreffile’s path. Carries per-pin settings that are not part of the pin itself – the pinned apverid lives in the.apreffile, since that is content the workspace owns and syncs.NOTE: adding a member to
AssetsV1PathValsTypeIDis a wire change with a cross-repo rollout. Workspace compiles parse this map viaWorkspaceCompileInput.parse_path_config_data, which raisesPermanentBuildErroron an entry it cannot decode – and those compiles run on basn nodes carrying their own copy of this file. So a node that predates this type hard-fails any build of a workspace using it. Rolling one out means: define here ->make efrosync-> deploy basn -> bumpCLOUD_BUILD_MIN_BASN_VERSION-> only then let bamaster start writing it.- classmethod get_type_id() AssetsV1PathValsTypeID[source]¶
Return the type-id for this subclass.
- keep_up_to_date: bool = True¶
Whether pending updates should include bumping this pin to the newest version on its own track. See
docs/initiatives/pin_keep_up_to_date.md.On by default, to encourage modders to keep what they depend on current. With
store_default=Falsethat means the absence of this field reads as enabled, so every existing workspace inherits the behavior with no migration and the common case costs no bytes. The trade is that “never set” and “explicitly enabled” are indistinguishable – fine here, but it does mean an explicit opt-out is the only thing that leaves a trace.
- class bacommon.workspace.assetsv1.AssetsV1PathValsAudioV1(audio_role: AudioRole = AudioRole.DEFAULT, audio_quality: AudioQuality = AudioQuality.DEFAULT, docs: str = '')[source]¶
Bases:
AssetsV1PathValsPath-specific values for an audio source in an assets_v1 workspace.
The per-sound authoring knobs (
AudioRole,AudioQuality) are module-level types in this module.- audio_quality: AudioQuality = 'default'¶
- docs: str = ''¶
Optional free-form documentation for this asset, surfaced as a comment above the asset in generated wrapper modules (and in the Sphinx docs). Empty string means no docs.
- classmethod get_type_id() AssetsV1PathValsTypeID[source]¶
Return the type-id for this subclass.
- class bacommon.workspace.assetsv1.AssetsV1PathValsCubeMapV1(docs: str = '')[source]¶
Bases:
AssetsV1PathValsPath-specific values for a cube map (
.cubemapdir) in a workspace.Cube maps are reflection textures with no Python API (decision #24), so they aren’t wrapper-visible. This currently carries only optional
docs– stored for completeness/consistency with other asset kinds, but not yet consumed by anything (it’ll have a home if/when cube maps gain a Python surface). Keyed inworkspace.json’spathdict by the.cubemapdirectory path.- docs: str = ''¶
Optional free-form documentation for this cube map. Stored but not yet surfaced anywhere (cube maps have no wrapper entry). Empty string means no docs.
- classmethod get_type_id() AssetsV1PathValsTypeID[source]¶
Return the type-id for this subclass.
- class bacommon.workspace.assetsv1.AssetsV1PathValsGroupV1(docs: str = '')[source]¶
Bases:
AssetsV1PathValsPath-specific values for a group (directory) in a workspace.
A group builds no asset of its own; this exists purely to carry optional
docs(decision #28) that become the generated wrapper group class’s docstring. Keyed inworkspace.json’spathdict by the directory path (e.g.texturesormydir/subdir).- docs: str = ''¶
Optional free-form documentation for this group, used as the generated wrapper group class’s docstring (a trailing “See source for the full asset list.” is always appended). Empty string means fall back to the auto-generated docstring.
- classmethod get_type_id() AssetsV1PathValsTypeID[source]¶
Return the type-id for this subclass.
- class bacommon.workspace.assetsv1.AssetsV1PathValsMeshV1(mesh_role: MeshRole = MeshRole.DEFAULT, docs: str = '')[source]¶
Bases:
AssetsV1PathValsPath-specific values for a mesh source in an assets_v1 workspace.
The per-mesh authoring knob (
MeshRole) is a module-level type in this module.- docs: str = ''¶
Optional free-form documentation for this asset, surfaced as a comment above the asset in generated wrapper modules (and in the Sphinx docs). Empty string means no docs.
- classmethod get_type_id() AssetsV1PathValsTypeID[source]¶
Return the type-id for this subclass.
- class bacommon.workspace.assetsv1.AssetsV1PathValsStrV1(up_to_date_state: str | None = None, state: AssetsV1StrState | None = None, wrap: WrapParams | None = None, deps: AssetsV1StrTermDeps | None = None, conv: AssetsV1StrConvCache | None = None)[source]¶
Bases:
AssetsV1PathValsPath-specific values for an assets_v1 workspace path.
- conv: AssetsV1StrConvCache | None = None¶
Retired – cached conventions findings, now held in a content-addressed Valkey group instead (
assetsv1conventions.conv_findings_group). Same reasoning asdepsabove; it was a further ~16%.
- deps: AssetsV1StrTermDeps | None = None¶
Retired – cached term-ref info, now held in a content-addressed Valkey group instead (
assetsv1str.term_deps_group). Kept only so stored records carrying it still parse; never read or written. It moved because a cache keyed by immutable content needs no home in the snapshot – and living here meant only write paths could fill it, since a path-vals write mints a snapshot and races user saves. It was also ~23% of a large workspace’sworkspace.json.
- classmethod get_type_id() AssetsV1PathValsTypeID[source]¶
Return the type-id for this subclass.
- state: AssetsV1StrState | None = None¶
Per-locale up-to-date state (see
AssetsV1StrState). Stamped by the translate / mark-clean paths for exactly the locales they brought current; a locale absent here (or whose stamp no longer matches a fresh calc) needs regenerating.
- up_to_date_state: str | None = None¶
Retired – the single whole-entry up-to-date state, superseded by the per-locale
statebelow. Kept only so stored records carrying it still parse; never read, and cleared on the next stamp. Never populate it.(Historical note: string author docs briefly lived here as a
docspath-val to avoid restaling translations; they moved into the.bstritself once docs began feeding the translation prompt, with the UI’s mark-translations-clean action as the no-regeneration-needed escape hatch.)
- wrap: WrapParams | None = None¶
Optional definition-time line-wrapping hints (decision D-t in the language-string-context initiative): applied automatically at evaluation everywhere this string displays. Locale-invariant. Lives HERE (not in the
.bstr) deliberately: the.bstris by definition the translation input, so its content hash is the translation-staleness key, and display-side metadata like this must not restale translations (the same reasoning as the docs history above, in reverse – wrap does not feed the translation prompt).
- class bacommon.workspace.assetsv1.AssetsV1PathValsTexV1(texture_quality: TextureQuality = TextureQuality.DEFAULT, texture_role: Role = Role.DEFAULT, astc_settings: AstcSettings = <factory>, bc7_settings: Bc7Settings = <factory>, docs: str = '', fallback_high_res: bool = False)[source]¶
Bases:
AssetsV1PathValsPath-specific values for an assets_v1 workspace path.
The per-texture quality knobs (
TextureQuality,Role,AstcSettings,Bc7Settings) are module-level types in this module.- astc_settings: AstcSettings¶
Per-format encode settings, consulted only when
texture_qualityisCUSTOM. Fully defaulted so a texture never has to store them explicitly.
- bc7_settings: Bc7Settings¶
- docs: str = ''¶
Optional free-form documentation for this asset, surfaced as a comment above the asset in generated wrapper modules (and in the Sphinx docs). Empty string means no docs.
- fallback_high_res: bool = False¶
Halve the fallback flavor’s level0 downsize divisor (2 instead of 4) so this asset’s fallback carries a higher-res top mip. For the rare asset whose fallback bytes get consumed directly rather than just serving as a universal render fallback – e.g. the engine cursor texture feeding OS hardware cursors, which wants a retina-res mip. Deliberately not exposed in the workspace web UI (it would be noise there); edit workspace.json directly for the odd asset that needs it.
- classmethod get_type_id() AssetsV1PathValsTypeID[source]¶
Return the type-id for this subclass.
- normalize() None[source]¶
Reset redundant/unused settings to defaults, in place.
A pure tidiness pass to run before storing: it never changes the resolved result, only drops dead data so
store_default=Falsecan strip it from workspace.json. Resolution consults the per-format settings only when the top-leveltexture_qualityisCUSTOM, and a format’s explicitblock_size/rdoonly when that format’s owntexture_qualityisCUSTOM– so anything outside those paths is unused and gets cleared here.
- texture_quality: TextureQuality = 'default'¶
- class bacommon.workspace.assetsv1.AssetsV1PathValsTypeID(*values)[source]¶
Bases:
EnumTypes of vals we can store for paths.
- APREF_V1 = 'apref_v1'¶
- AUDIO_V1 = 'audio_v1'¶
- CUBE_MAP_V1 = 'cube_map_v1'¶
- GROUP_V1 = 'group_v1'¶
- MESH_V1 = 'mesh_v1'¶
- STR_V1 = 'str_v1'¶
- TEX_V1 = 'tex_v1'¶
- class bacommon.workspace.assetsv1.AssetsV1StrConvCache(state: str, findings: list[str] = <factory>)[source]¶
Bases:
objectCached conventions findings for a
.bstr, keyed to its inputs.Per-entry conventions findings are a pure function of the
.bstrfile’s content plus the workspace’s cross-package term environment (its.apreffiles’ content-ids) plus the checks’ own version – all folded intostate. Consumers (the conventions lint) use it to skip reading the file; on mismatch they fall back to reading and re-checking that one entry. Maintained automatically by the string save/translate paths; do not hand-edit (wrongfindingswith a matchingstatewould be trusted).
- class bacommon.workspace.assetsv1.AssetsV1StrState(uniform: str | None = None, per_locale: dict[~bacommon.locale.Locale, str]=<factory>)[source]¶
Bases:
objectA
.bstr’s up-to-date state, resolved per locale.A locale’s output is a pure function of the entry’s own content plus, for each
{@…}term it references, that term’s translated value for that locale in the pinned version. So staleness is per-locale: fixing one locale of a shared term must cost its dependents that one locale, not all ~41.Two shapes, because per-locale resolution is only ever needed by the minority of entries that reference terms:
uniform– one state covering every locale. Used when the entry has no term refs, so nothing about its translation inputs varies by locale.per_locale– one state per locale. Used when it does.
Storing per-locale for everything would be far larger than the rest of
workspace.jsoncombined (BaClassicAssets: 32 of 1128 entries carry refs), hence the split. Read throughfor_locale(), which hides it.
- class bacommon.workspace.assetsv1.AssetsV1StrTermDeps(file_id: str, inputs_digest: str = '', local: list[str] = <factory>, cross: list[str] = <factory>, kinds: list[str] | None = None)[source]¶
Bases:
objectCached term-ref info for a
.bstr, keyed to its content.Term refs (
{@term}/{@pkg:term}in the brief) are a pure function of the.bstrfile’s content, which is pinned by its content-addressedfile_id– so this record stays valid exactly as long asfile_idmatches the entry’s current file. Consumers (dep-aware staleness calcs) use it to skip reading the file; on mismatch they fall back to reading that one file. Maintained automatically by the string save/translate paths; do not hand-edit (a wronglocal/crosslist with a matchingfile_idwould be trusted).- cross: list[str]¶
Term-ref targets, whole (
<apref-path>:<entry-path>, no extensions) – consumers key staleness on the individual referenced term, not just its package. (Historical note: this briefly held bare apref paths; consumers ignore any entry lacking the:half and re-extract from the file.)
- inputs_digest: str = ''¶
Digest of the entry’s translation inputs (brief, docs, style and layout presets) – everything that shapes what the model produces, and nothing else. Notably NOT the entry’s own outputs or modtimes: staleness folds this in per locale, so including outputs would mean writing one locale’s translation restaled every other locale. Empty on records predating the field, which consumers treat as a cache miss.
- kinds: list[str] | None = None¶
Sorted unique display-param kinds this entry’s brief uses (
'bytes'etc.; the union overdisplay_param_kinds_for_brief()). What the master consults to decide which formatter components a package build must embed, without reading the file.Noneon records predating the field, which consumers treat as a cache miss so the record gets repaired (mirroringinputs_digest); an extracted brief using no spec’d params stores[].
- class bacommon.workspace.assetsv1.AssetsV1StringFile[source]¶
Bases:
IOMultiType[AssetsV1StringFileTypeID]Top level class for our multitype.
- classmethod get_type(type_id: AssetsV1StringFileTypeID) type[AssetsV1StringFile][source]¶
Return the subclass for each of our type-ids.
- classmethod get_type_id() AssetsV1StringFileTypeID[source]¶
Return the type-id for this subclass.
- classmethod get_type_id_storage_name() str[source]¶
Return the key used to store type id in serialized data.
The default is a short obscure value so that it is unlikely to conflict with members of individual type attrs, but in some cases one might prefer to serialize it to something simpler like ‘type’ by overriding this call. One just needs to make sure that no encompassed types serialize anything to that same name themself (dataclassio will error if they do).
- class bacommon.workspace.assetsv1.AssetsV1StringFileTypeID(*values)[source]¶
Bases:
EnumType ID for each of our subclasses.
- V1 = 'v1'¶
- class bacommon.workspace.assetsv1.AssetsV1StringFileV1(input: str, input_modtime: datetime.datetime, style_preset: StylePreset = StylePreset.NONE, docs: str = '', layout_preset: LayoutPreset = LayoutPreset.NONE, translation_effort: TranslationEffort = TranslationEffort.AUTO, outputs: dict[Locale, Output]=<factory>)[source]¶
Bases:
AssetsV1StringFileOur initial version of string file data.
- class LayoutPreset(*values)[source]¶
Bases:
EnumWhat kind of slot a string occupies, and how it may size.
(Named
FitPresetuntil 2026-07-27; the stored key staysfit_preset. Renamed because the values describe the slot – a narrow tab, a standard button, a body paragraph – and only some of them are a size constraint at all.)Mirrors
StylePreset: passed to the translator with UI context, so localized output respects both the space available and the register the slot implies. The CHARS_* budgets are display-width in Latin characters – wide-glyph scripts (CJK) target roughly half the character count – and are aims, not hard caps (soft enforcement with generous slack; seechar_budget).- CHARS_20 = 'chars_20'¶
Aim for ~20 characters - narrow buttons, tabs, column headings.
- CHARS_40 = 'chars_40'¶
Aim for ~40 characters - standard buttons and labels.
- CHARS_80 = 'chars_80'¶
Aim for ~80 characters / one concise line - transient messages, status lines, and the like.
- NONE = 'none'¶
Unset – no slot declared and no size constraint. Note this is the absence of a choice, which is why the authoring check nags on a long English string that is still NONE: use PROSE to say “unbounded on purpose”.
- PROSE = 'prose'¶
Body prose - paragraphs in a document or web page. No size constraint, but unlike NONE that is a deliberate statement, and it tells the translator to write flowing multi-sentence text rather than terse UI wording.
- class Output(modtime: datetime, value: str | StringSelector = '')[source]¶
Bases:
objectRepresents a single localized output.
- value: str | StringSelector = ''¶
The localized output – a plain string, or a render-time
StringSelector(plural/select) whose final form is chosen at display time. (A type-disjoint dataclassio union; selectors ride the wire as dicts.)
- class StylePreset(*values)[source]¶
Bases:
EnumPreset for general styling in translated strings.
- LOUD = 'loud'¶
- NONE = 'none'¶
- SOFT = 'soft'¶
- TITLE = 'title'¶
- class TranslationEffort(*values)[source]¶
Bases:
EnumHow much model effort a string’s translations warrant.
Deliberately describes intent, not a model or a vendor setting: the server maps these onto whatever (model, thinking level) pair is current, so retuning that never touches stored
.bstrdata or restales translations.AUTOis the right answer for nearly every string – short UI labels translate identically at any effort. It runs cheap first and escalates on its own when the brief looks structurally hard or when a generated attempt fails validation. Reach forHIGHonly for semantic subtlety no heuristic can see: wordplay, brand voice, a line whose tone has to land.- AUTO = 'auto'¶
Server decides – cheap by default, escalating when warranted.
- HIGH = 'high'¶
Always translate at maximum effort.
- docs: str = ''¶
Optional free-form usage docs describing where this string appears and how it is used. Feeds both the generated wrapper accessor’s docstring and the translation prompt (as usage context). Lives in the
.bstritself so edits restale translations via the file’s content-id; when an edit doesn’t warrant regeneration, use the UI’s mark-translations-clean action.
- classmethod get_type_id() AssetsV1StringFileTypeID[source]¶
Return the type-id for this subclass.
- input_modtime: datetime.datetime¶
- layout_preset: LayoutPreset = 'none'¶
Which kind of slot this string occupies (see
LayoutPreset). The stored key remainsfit_presetfrom before the rename – values on disk must not move. Passed to the translator so localized output respects the UI space available.
- style_preset: StylePreset = 'none'¶
- translation_effort: TranslationEffort = 'auto'¶
How much model effort this string’s translations warrant (see
TranslationEffort). Unlike the other presets this is folded into the translation digest only when it is notAUTO, so adding the field left every existing entry’s digest byte-identical rather than restaling the whole corpus.
- class bacommon.workspace.assetsv1.AstcBlockSize(*values)[source]¶
Bases:
EnumASTC square block size — the mobile bitrate lever.
Smaller block = more bits per texel = higher quality + larger output. Consulted only when an
AstcSettingshas itstexture_qualityset toCUSTOM; otherwise the blanketLOW/DEFAULT/HIGHmap to a value in this range (LOW=TWELVE_BY_TWELVE,HIGH=FOUR_BY_FOUR).- EIGHT_BY_EIGHT = '8x8'¶
- FIVE_BY_FIVE = '5x5'¶
- FOUR_BY_FOUR = '4x4'¶
- SIX_BY_SIX = '6x6'¶
- TEN_BY_TEN = '10x10'¶
- TWELVE_BY_TWELVE = '12x12'¶
- class bacommon.workspace.assetsv1.AstcSettings(texture_quality: TextureQuality = TextureQuality.DEFAULT, block_size: AstcBlockSize = AstcBlockSize.SIX_BY_SIX)[source]¶
Bases:
objectPer-texture ASTC (mobile) encode settings.
Consulted only when the texture’s top-level
texture_qualityisCUSTOM. Its owntexture_qualitymay in turn beCUSTOMto use the explicitblock_size; otherwiseLOW/DEFAULT/HIGHmap to the encoder’s block-size range. Fully defaulted so a texture never has to store it explicitly.- block_size: AstcBlockSize = '6x6'¶
- texture_quality: TextureQuality = 'default'¶
- class bacommon.workspace.assetsv1.AudioQuality(*values)[source]¶
Bases:
EnumPer-sound authoring quality knob (asset-packages decision #25).
Mirrors the texture knob’s LOW/DEFAULT/HIGH pattern. Defined from day one as the escape hatch for content whose default encode budget doesn’t fit (e.g. a short pre-mixed UI sound sharing music’s bitrate), but nothing consumes it yet — the recipe carries it in its cache key only, so wiring it up later rebuilds correctly.
- DEFAULT = 'default'¶
- HIGH = 'high'¶
- LOW = 'low'¶
- class bacommon.workspace.assetsv1.AudioRole(*values)[source]¶
Bases:
EnumA sound’s channel/encode contract (asset-packages decision #25).
Names the technical contract, not a content category — “music” deliberately does not exist as a build-time concept (volume routing stays a runtime play-flag; streaming is a length-derived engine policy).
DEFAULT— spatialization-ready: downmixed to mono at encode (OpenAL only spatializes mono; a hard requirement, not a size optimization). The vast majority of sounds.PRE_MIXED— an authored mix: channels preserved (≤2) and the sound always plays listener-space. The recipe stamps aBA_ROLE=pre_mixedvorbis comment tag so the engine knows at load time (channel count alone can’t carry the bit — a mono pre-mixed source stays mono). Music, plus any intentionally stereo (or otherwise authored-mix) sound.
- DEFAULT = 'default'¶
- PRE_MIXED = 'pre_mixed'¶
- class bacommon.workspace.assetsv1.Bc7Rdo(*values)[source]¶
Bases:
EnumBC7 RDO (rate-distortion optimization) lambda — the desktop lever.
BC7 is a fixed 8bpp block format, so its size lever is RDO: higher lambda steers the encoder toward more zlib/LZ-compressible output (smaller on-disk) at the cost of quality.
OFFdisables RDO (best quality, largest). Consulted only when aBc7Settingshas itstexture_qualityset toCUSTOM; otherwise the blanketLOW/DEFAULT/HIGHmap to a value in this range (LOW=FOUR,HIGH=OFF).- FOUR = '4'¶
- OFF = 'off'¶
- ONE = '1'¶
- TWO = '2'¶
- ZERO_POINT_FIVE = '0.5'¶
- ZERO_POINT_ONE_TWO_FIVE = '0.125'¶
- ZERO_POINT_TWO_FIVE = '0.25'¶
- class bacommon.workspace.assetsv1.Bc7Settings(texture_quality: TextureQuality = TextureQuality.DEFAULT, rdo: Bc7Rdo = Bc7Rdo.ONE)[source]¶
Bases:
objectPer-texture BC7 (desktop) encode settings.
Consulted only when the texture’s top-level
texture_qualityisCUSTOM. Its owntexture_qualitymay in turn beCUSTOMto use the explicitrdolambda; otherwiseLOW/DEFAULT/HIGHmap to the encoder’s RDO range. Fully defaulted so a texture never has to store it explicitly.- texture_quality: TextureQuality = 'default'¶
- class bacommon.workspace.assetsv1.ConventionsMode(*values)[source]¶
Bases:
EnumConventions-check enforcement level for an assets_v1 workspace.
STRICTblocks test/prod publishes while conventions findings exist (dev-track resolves are never gated);RELAXED(the default) surfaces findings as informational hints only.- RELAXED = 'relaxed'¶
- STRICT = 'strict'¶
- class bacommon.workspace.assetsv1.MeshRole(*values)[source]¶
Bases:
EnumWhat a mesh
.objsource builds (asset-packages decision #26).DEFAULT— a display mesh: compiled to the engine’s binary.bobformat (welded/quantized verts, vertex-cache-optimized index order) and served from the flavor-varyingmeshesbucket (headless builds get none).COLLISION— a collision mesh: compiled to the engine’s binary.cobformat (positions + indices for the physics trimesh) and served from the flavor-invariantconstantbucket — every build including headless gets it, and the bytes are identical across all flavors (networked sims/replays must agree on collision geometry).
- COLLISION = 'collision'¶
- DEFAULT = 'default'¶
- class bacommon.workspace.assetsv1.PackageResolveAccess(*values)[source]¶
Bases:
EnumWho may resolve a package’s prod versions.
Orthogonal to the version track: a track says how released a version is, this says who may have it.
PRIVATEapplies the same owner-or-dev-team check that dev/test versions always get, so resolve access only ever adds restriction to prod – it can never make a dev/test version public.PUBLICis the default and what every package had before this existed. Exists for packages nothing fetches at runtime – content the master evaluates itself, or build-time sources embedded into other packages – not as a general publishing control.Gates the resolve, not the content. A private package’s entries can still reach clients verbatim – formatter components are embedded by value into each consuming package’s language blobs at build time – so this says “nothing fetches this package at runtime”, never “these strings are secret”.
- PRIVATE = 'private'¶
- PUBLIC = 'public'¶
- class bacommon.workspace.assetsv1.PackageSourceSharing(*values)[source]¶
Bases:
EnumWho can start a new workspace from a package’s source.
Governs source availability only – who may copy the exporting workspace’s snapshot as the starting point for a workspace of their own. It says nothing about who can use the published assets; that’s the track plus
PackageResolveAccess.Package-wide (not per-version): sharing intent belongs to the package, and a per-version value meant every republish silently reset it.
- DEV_TEAM_ONLY = 'devteam'¶
- PRIVATE = 'private'¶
- PUBLIC = 'public'¶
- class bacommon.workspace.assetsv1.Role(*values)[source]¶
Bases:
EnumWhat a texture is for (its authoring intent).
Drives mip-filtering math and encoder flags (asset-packages initiative decisions #19/#23). Intent-based rather than a bundle of low-level mechanical flags — the recipe maps each role to a concrete filtering/encoding behavior.
normal_map/dataare reserved slots for when such content (and the compressed- profile recipes) land.- DEFAULT = 'default'¶
sRGB color with straight opacity alpha. The pipeline premultiplies it by its alpha for storage (decision #23): premult-weighted, halo-free mip filtering in the requested render_space, premult output bytes,
ALPHA_PREMULTIPLIEDDFD flag set. The common case for color sprites. Renders correctly only with premult-blend (the renderer wiring lands in a later step; until thenDEFAULToutput shows darkened edges under the legacy straight-blend path).
- SOURCE_PREMULTIPLIED = 'source_premultiplied'¶
sRGB color whose SOURCE RGB is already premultiplied by its alpha (e.g. glow sprites — they carry additive
RGB > alphavalues that straight alpha cannot represent). The pipeline does NOT re-multiply; mips filter the premultiplied RGB directly (in the requested render_space) and the flag is set. Renders identically toDEFAULT(both premult-blend); they differ only in whether the pipeline applies the multiply.
- STRAIGHT_ALPHA = 'straight_alpha'¶
sRGB color with straight alpha whose RGB channels carry meaningful color even in transparent regions, so they must be preserved (decision #23). The pipeline does NOT premultiply: mips filter RGB and alpha INDEPENDENTLY (color still filtered in the requested render_space, but with no premult round-trip, which would zero — and fail to recover — the transparent-region color). Straight output bytes;
ALPHA_PREMULTIPLIEDflag clear. Renders with ordinary straight-alpha blending.
- bacommon.workspace.assetsv1.STRING_NOT_TRANSLATED = '<NOT-TRANSLATED>'¶
Placeholder value for a string with no generated output in its own locale or in English. We deliberately do NOT fall back to the brief
inputhere: that’s the author’s description of what the string should say (a translator prompt), often a long-winded sentence – not display text – so rendering it is worse than an obvious “untranslated” marker.
- class bacommon.workspace.assetsv1.TextureQuality(*values)[source]¶
Bases:
EnumPer-texture authoring quality knob (decision #19).
DEFAULTis the normal case (the vast majority of textures);LOWandHIGHare deliberate per-texture overrides for special cases (e.g.HIGHfor a hero texture that must stay crisp,LOWfor one that can afford to be cheap). NamedDEFAULTrather thanMEDIUMto communicate that — it’s the baseline, not a middle setting you’d routinely reach past.LOW/DEFAULT/HIGHare blanket settings that map to a sensible value for whichever encoder a profile uses (ASTC block size on mobile, BC7 RDO lambda on desktop).CUSTOMinstead defers to the per-formatAstcSettings/Bc7Settingsso a texture can be tuned independently per encoder (e.g. ASTCHIGHwhile BC7DEFAULT). Distinct from the bucket-levelTextureTier.- CUSTOM = 'custom'¶
- DEFAULT = 'default'¶
- HIGH = 'high'¶
- LOW = 'low'¶
- class bacommon.workspace.assetsv1.WrapperType(*values)[source]¶
Bases:
EnumPython wrapper-module flavor for an asset-package version.
Selects which feature-set’s loader API the generated wrapper delegates to. Members today correspond 1:1 with feature-sets, but the type is deliberately named
WrapperType(notWrapperFeatureset) to leave room for non-featureset-shaped variants (e.g. tooling-only or future loader APIs) without a rename.- BABASE = 'babase'¶
Strings-and-sounds wrapper for the babase layer. String leaves emit the same native
babase.LangStraccessors as the featureset forms; sound leaves emitSimpleSoundHandle, whose.get()loads ababase.SimpleSound– the one classic asset loader API babase has (there is no babase texture or mesh equivalent, so those kinds are skipped). Exists so pre-featureset machinery (e.g. construct-mode’s bring-up UI, and the app/plugin/account paths that play ui feedback sounds before any feature-set is up) can consume package strings and sounds.
- BASCENEV1 = 'bascenev1'¶
- BAUIV1 = 'bauiv1'¶
- bacommon.workspace.assetsv1.complete_locale_values(string_files: dict[str, AssetsV1StringFileV1], locale: Locale) dict[str, str | StringSelector][source]¶
English-completed per-locale values for a set of string files.
Maps each string’s logical name to its value for
locale: the locale’s own output, else the English output, else theSTRING_NOT_TRANSLATEDplaceholder. So every locale’s map carries the complete key set with graceful English fallback – an untranslated string still renders (in English where available, else an obvious<NOT-TRANSLATED>marker) rather than failing, and every locale’s key set is identical. The briefinputis intentionally never used as a value: it’s the author’s prompt/description, not display text.The shared value-selection both the asset-build string recipe and the langstr vendor command route through (paired with
serialize_language_blob()) so the built and vendored blobs can’t drift.
- bacommon.workspace.assetsv1.derive_asset_package_name(workspace_name: str) str[source]¶
Derive a default asset-package name from a workspace name.
Lowercases and strips spaces (‘My Awesome Assets’ -> ‘myawesomeassets’). The single source for this rule — publish paths, collision checks, and UI previews must all route through it. Note the result is not guaranteed to be a valid asset-package name (the workspace name may contain characters with no valid mapping); consumers validate at point of use.
- bacommon.workspace.assetsv1.display_param_kinds(string_files: dict[str, AssetsV1StringFileV1]) dict[str, dict[str, str]][source]¶
Per-string
{param: kind}for params the display side must know.A spec’d brief param (
{size|data_size}) renders through logic the translated text cannot describe – the text holds only a{size}token – so its kind has to travel to the evaluator in the language blob. Plain text subs and the plural pivot are omitted: text is the default, and the pivot is not a named output token at all (it renders as the ICU#count placeholder inside each form).Entries with nothing to declare are absent, so a package using no spec’d params serializes byte-identically to before this existed.
The shared derivation both the asset-build string recipe and the langstr vendor command route through, alongside
complete_locale_values(), so the built and vendored blobs can’t drift on this either. Briefs that don’t parse contribute nothing rather than failing the build – consistent with how broken briefs degrade everywhere else.
- bacommon.workspace.assetsv1.display_param_kinds_for_brief(brief: str) dict[str, str][source]¶
Per-param display kinds for a single brief.
The one-entry unit
display_param_kinds()aggregates; see it for what qualifies as a display kind. Values are display-kind expressions: the bare kind for an argless spec, else the kind plus its spec args in canonical form ('bytes(compact=true)') – seedisplay_kind. Raises on a malformed brief – callers that must degrade softly (listing renders, builds) wrap it, matching how broken briefs degrade everywhere else.