bacommon package

Functionality and data shared by all Ballistica components.

This includes clients, various servers, tools, etc.

Subpackages

Submodules

bacommon.analytics module

Analytics support.

class bacommon.analytics.AnalyticsEvent[source]

Bases: IOMultiType[AnalyticsEventTypeID]

Top level class for our multitype.

classmethod get_type(type_id: AnalyticsEventTypeID) type[AnalyticsEvent][source]

Return the subclass for each of our type-ids.

classmethod get_type_id() AnalyticsEventTypeID[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 an obscure value so that it does not 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 ‘type’ themself.

class bacommon.analytics.AnalyticsEventTypeID(*values)[source]

Bases: Enum

Type ID for each of our subclasses.

CLASSIC = 'c'
class bacommon.analytics.ClassicAnalyticsEvent(eventtype: EventType, extra: str | None = None)[source]

Bases: AnalyticsEvent

Analytics event related to classic.

class EventType(*values)[source]

Bases: Enum

Types of classic events.

JOIN_NEARBY_PARTY = 'jn'
JOIN_PARTY_BY_ADDRESS = 'ja'
JOIN_PRIVATE_PARTY = 'jpr'
JOIN_PUBLIC_PARTY = 'jpb'
START_COOP_SESSION = 'sc'
START_FFA_SESSION = 'sf'
START_TEAMS_SESSION = 'st'
START_TOURNEY_COOP_SESSION = 'stc'
eventtype: EventType
extra: str | None = None
classmethod get_type_id() AnalyticsEventTypeID[source]

Return the type-id for this subclass.

bacommon.app module

Common high level values/functionality related to Ballistica apps.

class bacommon.app.AppArchitecture(*values)[source]

Bases: Enum

Processor architecture an app can be running on.

ARM = 'arm'
ARM64 = 'arm64'
UNKNOWN = 'unknown'
X86 = 'x86'
X86_64 = 'x86_64'
class bacommon.app.AppInterfaceIdiom(*values)[source]

Bases: Enum

A general form-factor or method of experiencing a Ballistica app.

Note that it may be possible for a running app to switch idioms (for instance if a mobile device or computer is connected to a TV).

CONSOLE = 'console'

Screen with medium amount of detail visible; assumed to have game controller(s) as primary input. Note that this covers handheld or arcade cabinet scenarios in addition to tv-connected consoles.

DESKTOP = 'desktop'

Screen with high amount of detail visible; assumed to have keyboard/mouse as primary input.

HEADLESS = 'headless'

The app has no interface (generally is acting as a server).

PHONE = 'phone'

Small screen; assumed to have touch as primary input.

TABLET = 'tablet'

Medium size screen; assumed to have touch as primary input.

XR_HEADSET = 'xr_headset'

Displayed over or in place of of the real world on a headset; assumed to have hand tracking or spatial controllers as primary input.

XR_PHONE = 'xr_phone'

Displayed over or instead of the real world on a small screen; assumed to have device movement augmented by physical or touchscreen controls as primary input.

XR_TABLET = 'xr_tablet'

Displayed over or instead of the real world on a medium size screen; assumed to have device movement augmented by physical or touchscreen controls as primary input.

class bacommon.app.AppPlatform(*values)[source]

Bases: Enum

Overall platform a build can target.

Each distinct flavor of an app has a unique combination of AppPlatform and AppVariant. Generally platform describes a set of hardware, while variant describes a destination or purpose for the build.

ANDROID = 'android'
IOS = 'ios'
LINUX = 'linux'
MACOS = 'macos'
TVOS = 'tvos'
UNKNOWN = 'unknown'
WINDOWS = 'windows'
class bacommon.app.AppVariant(*values)[source]

Bases: Enum

A unique Ballistica build variation within a single platform.

Each distinct permutation of an app has a unique combination of AppPlatform and AppVariant. Generally platform describes a set of hardware, while variant describes a destination or purpose for the build.

AMAZON_APPSTORE = 'amazon_appstore'
APPLE_APP_STORE = 'apple_app_store'
ARCADE = 'arcade'
CARDBOARD = 'cardboard'
DEMO = 'demo'
EPIC_GAMES_STORE = 'epic_games_store'
GENERIC = 'generic'

Default builds.

GOOGLE_PLAY = 'google_play'
META = 'meta'
STEAM = 'steam'
TEST_BUILD = 'test_build'

Particular builds intended for public testing (may have some extra checks or logging enabled).

WINDOWS_STORE = 'windows_store'

bacommon.bacloud module

Functionality related to the bacloud tool.

Warning

This is an internal api and subject to change at any time. Do not use it in mod code.

bacommon.build module

Functionality related to game builds.

Warning

This is an internal api and subject to change at any time. Do not use it in mod code.

bacommon.clienteffect module

ClientEffect related functionality.

Warning

This is an internal api and subject to change at any time. Do not use it in mod code.

bacommon.cloud module

Cloud related functionality.

Warning

This is an internal api and subject to change at any time. Do not use it in mod code.

bacommon.displayitem module

Functionality for displaying currencies, prizes, owned items, etc.

Warning

This is an internal api and subject to change at any time. Do not use it in mod code.

bacommon.locale module

Functionality for wrangling locale info.

class bacommon.locale.Locale(*values)[source]

Bases: Enum

A distinct grouping of language, cultural norms, etc.

This list of locales is considered ‘sacred’ - we assume any values (and associated long values) added here remain in use out in the wild indefinitely. If a locale is superseded by a newer or more specific one, the new locale should be added and both new and old should map to the same LocaleResolved.

ARABIC = 'arabc'
BELARUSSIAN = 'blrs'
CHINESE = 'chn'
CHINESE_SIMPLIFIED = 'chn_sim'
CHINESE_TRADITIONAL = 'chn_tr'
CROATIAN = 'croat'
CZECH = 'czch'
DANISH = 'dnsh'
DUTCH = 'dtch'
ENGLISH = 'eng'
ESPERANTO = 'esprnto'
FILIPINO = 'filp'
FRENCH = 'frnch'
GERMAN = 'grmn'
GIBBERISH = 'gibber'
GREEK = 'greek'
HINDI = 'hndi'
HUNGARIAN = 'hngr'
INDONESIAN = 'indnsn'
ITALIAN = 'italn'
JAPANESE = 'jpn'
KAZAKH = 'kazk'
KOREAN = 'kor'
MALAY = 'mlay'
PERSIAN = 'pers'
PIRATE_SPEAK = 'pirate'
POLISH = 'pol'
PORTUGUESE = 'prtg'
PORTUGUESE_BRAZIL = 'prtg_brz'
PORTUGUESE_PORTUGAL = 'prtg_pr'
ROMANIAN = 'rom'
RUSSIAN = 'rusn'
SERBIAN = 'srbn'
SLOVAK = 'slvk'
SPANISH = 'spn'
SPANISH_LATIN_AMERICA = 'spn_lat'
SPANISH_SPAIN = 'spn_spn'
SWEDISH = 'swed'
TAMIL = 'taml'
THAI = 'thai'
TURKISH = 'turk'
UKRAINIAN = 'ukrn'
VENETIAN = 'venetn'
VIETNAMESE = 'viet'
property description: str[source]

A human readable description for the locale.

Intended as instructions to humans or AI for translating. For most locales this is simply the language name, but for special ones like pirate-speak it may include instructions.

classmethod from_long_value(value: str) Locale[source]

Given a long value, return a Locale.

property long_value: str[source]

A longer more human readable alternative to value.

Like the regular enum values, these values will never change and can be used for persistent storage/etc.

property resolved: LocaleResolved[source]

Return the associated resolved locale.

class bacommon.locale.LocaleResolved(*values)[source]

Bases: Enum

A resolved Locale for use in logic.

These values should never be stored or transmitted and should always come from resolving a Locale which can be stored/transmitted. This gives us the freedom to revise this list as needed to keep our actual list of implemented resolved-locales as trim as possible.

ARABIC = 'arabc'
BELARUSSIAN = 'blrs'
CHINESE_SIMPLIFIED = 'chn_sim'
CHINESE_TRADITIONAL = 'chn_tr'
CROATIAN = 'croat'
CZECH = 'czch'
DANISH = 'dnsh'
DUTCH = 'dtch'
ENGLISH = 'eng'
ESPERANTO = 'esprnto'
FILIPINO = 'filp'
FRENCH = 'frnch'
GERMAN = 'grmn'
GIBBERISH = 'gibber'
GREEK = 'greek'
HINDI = 'hndi'
HUNGARIAN = 'hngr'
INDONESIAN = 'indnsn'
ITALIAN = 'italn'
JAPANESE = 'jpn'
KAZAKH = 'kazk'
KOREAN = 'kor'
MALAY = 'mlay'
PERSIAN = 'pers'
PIRATE_SPEAK = 'pirate'
POLISH = 'pol'
PORTUGUESE_BRAZIL = 'prtg_brz'
PORTUGUESE_PORTUGAL = 'prtg_pr'
ROMANIAN = 'rom'
RUSSIAN = 'rusn'
SERBIAN = 'srbn'
SLOVAK = 'slvk'
SPANISH_LATIN_AMERICA = 'spn_lat'
SPANISH_SPAIN = 'spn_spn'
SWEDISH = 'swed'
TAMIL = 'taml'
THAI = 'thai'
TURKISH = 'turk'
UKRAINIAN = 'ukrn'
VENETIAN = 'venetn'
VIETNAMESE = 'viet'
static from_tag(tag: str) LocaleResolved[source]

Return a locale for a given string tag.

Tags can be provided in BCP 47 form (‘en-US’) or POSIX locale string form (‘en_US.UTF-8’).

property locale: Locale[source]

Return a locale that resolves to this resolved locale.

In some cases, such as when presenting locale options to the user, it makes sense to iterate over resolved locale values, as regular locales may include obsolete or redundant values. When storing locale values to disk or transmitting them, however, it is important to use plain locales. This method can be used to get back to a plain locale from a resolved one.

property tag: str[source]

An IETF BCP 47 tag for this locale.

This is often simply a language code (‘en’) but may in some cases include the country (‘pt-BR’) or script (‘zh-Hans’). Locales which are not “real” will include an ‘x’ in the middle (‘en-x-pirate’).

bacommon.loggercontrol module

System for managing loggers.

class bacommon.loggercontrol.LoggerControlConfig(levels: dict[str, int]=<factory>)[source]

Bases: object

A logging level configuration that applies to all loggers.

Any loggers not explicitly contained in the configuration will be set to NOTSET.

apply(*, warn_unexpected_loggers: bool = False, warn_missing_loggers: bool = False, ignore_log_prefixes: list[str] | None = None) None[source]

Apply the config to all Python loggers.

If ‘warn_unexpected_loggers’ is True, warnings will be issues for any loggers not explicitly covered by the config. This is useful to help ensure controls for all possible loggers are present in a UI/etc.

If ‘warn_missing_loggers’ is True, warnings will be issued for any loggers present in the config that are not found at apply time. This can be useful for pruning settings for no longer used loggers.

Warnings for any log names beginning with any strings in ‘ignore_log_prefixes’ will be suppressed. This can allow ignoring loggers associated with submodules for a given package and instead presenting only a top level logger (or none at all).

apply_diff(diffconfig: LoggerControlConfig) LoggerControlConfig[source]

Apply a diff config to ourself.

Note that values that resolve to NOTSET are left intact in the output config. This is so all loggers expected by either the base or diff config to exist can be created if desired/etc.

diff(baseconfig: LoggerControlConfig) LoggerControlConfig[source]

Return a config containing only changes compared to a base config.

Note that this omits all NOTSET values that resolve to NOTSET in the base config.

This diffed config can later be used with apply_diff() against the base config to recreate the state represented by self.

classmethod from_current_loggers() Self[source]

Build a config from the current set of loggers.

get_effective_level(logname: str) int[source]

Given a log name, predict its level if this config is applied.

levels: dict[str, int]
sanity_check_effective_levels() None[source]

Checks existing loggers to make sure they line up with us.

This can be called periodically to ensure that a control-config is properly driving log levels and that nothing else is changing them behind our back.

would_make_changes() bool[source]

Return whether calling apply would change anything.

bacommon.logging module

Logging functionality.

class bacommon.logging.ClientLoggerName(*values)[source]

Bases: Enum

Logger names used on the Ballistica client.

ACCOUNT = 'ba.account'
ACCOUNT_CLIENT_V2 = 'ba.accountclientv2'
APP = 'ba.app'
ASSETS = 'ba.assets'
AUDIO = 'ba.audio'
BA = 'ba'
CACHE = 'ba.cache'
CLOUD_SUBSCRIPTION = 'ba.cloudsub'
CONNECTIVITY = 'ba.connectivity'
DISCORD = 'ba.discord'
DISPLAYTIME = 'ba.displaytime'
ENV = 'ba.env'
GARBAGE_COLLECTION = 'ba.gc'
GRAPHICS = 'ba.gfx'
INPUT = 'ba.input'
LIFECYCLE = 'ba.lifecycle'
LOGIN_ADAPTER = 'ba.loginadapter'
NETWORKING = 'ba.net'
PERFORMANCE = 'ba.perf'
UI = 'ba.ui'
V2TRANSPORT = 'ba.v2transport'
WORKSPACE = 'ba.workspace'
property description: str

Return a short description for the logger.

bacommon.logging.get_base_logger_control_config_client() LoggerControlConfig[source]

Return the logger-control-config used by the Ballistica client.

This should remain consistent since local logger configurations are stored relative to this.

bacommon.login module

Functionality related to cloud based assets.

class bacommon.login.LoginType(*values)[source]

Bases: Enum

Types of logins available.

DISCORD = 'discord'

Discord (OAuth2 via Discord Social SDK)

EMAIL = 'email'

Email/password

GAME_CENTER = 'game_center'

Apple’s Game Center

GPGS = 'gpgs'

Google Play Game Services

property displayname: str

A human readable name for this value.

property displaynameshort: str

A short human readable name for this value.

bacommon.metascan module

Scanner for # ba_meta directives in Python source.

Recognized directive shapes:

  • # ba_meta require api <N> — module-level API version requirement. When expected_api_version is supplied, modules whose value doesn’t match are skipped (and listed in ScanResults.incorrect_api_modules). When it is None the line is parsed for validity but no filtering occurs.

  • # ba_meta export <TYPE> — export the class defined on the next non-blank source line under the export-type <TYPE>.

  • # ba_meta require asset-package <ID> — module declares that it needs the named asset-package at runtime.

Other shapes are reported as malformed.

This module has no dependencies beyond the standard library so it can run anywhere — in the game runtime (wrapped by babase._meta.MetadataSubsystem), in build/tooling contexts (e.g. tools/pcommand assetpins), or in tests.

Higher-level concerns — background-thread scheduling, UI feedback, expansion of legacy export-type shortcuts, deprecation warnings — live in the consumer.

class bacommon.metascan.DirectoryScan(paths: list[str], expected_api_version: int | None = None, deprecated_export_shortcuts: dict[str, str] | None = None, *, expects_extras: bool = False)[source]

Bases: object

Scans directories for # ba_meta directives.

Pure-Python; no runtime dependencies. Construct with a list of paths (which must already be on PYTHONPATH if discovered modules will be imported by the consumer), then call run(). Results land in results.

If expected_api_version is set, modules whose # ba_meta require api value doesn’t match are skipped and listed in ScanResults.incorrect_api_modules. Pass None to scan regardless of api version (the typical tooling-side mode).

If deprecated_export_shortcuts is provided, export-type strings that appear as keys are substituted with the corresponding canonical class path and a deprecation warning is emitted with file:line context. Pass None to perform no substitution.

If expects_extras is True, run() will block after finishing the base paths until set_extras() is called from another thread. This supports the runtime pattern of kicking off the scan immediately and providing extra paths (workspace dirs, etc.) once they are known. Synchronous tooling callers should leave it at the default False; run() will then finish after the base paths.

run() None[source]

Do the thing.

set_extras(paths: list[str]) None[source]

Set extra portion.

class bacommon.metascan.ScanResults(exports: dict[str, list[str]]=<factory>, asset_packages: dict[str, list[str]]=<factory>, incorrect_api_modules: list[str] = <factory>, announce_errors_occurred: bool = False)[source]

Bases: object

Final results from a meta-scan.

announce_errors_occurred: bool = False
asset_packages: dict[str, list[str]]
exports: dict[str, list[str]]
exports_by_name(name: str) list[str][source]

Return exports matching a given name.

incorrect_api_modules: list[str]

bacommon.net module

Network related data and functionality.

Warning

This is an internal api and subject to change at any time. Do not use it in mod code.

bacommon.securedata module

Functionality related to verifying server generated data.

Warning

This is an internal api and subject to change at any time. Do not use it in mod code.

class bacommon.securedata.Archive(data: bytes, signature: bytes, cert: Cert | None = None)[source]

Bases: object

Self-contained signed payload — verifiable on its own.

Produced by Writer.write() (delegate-signed) or make_master_archive() (master-signed; cert is None). Verified via Reader.read(), which returns the payload bytes on success.

Embed directly as a field on dataclassio messages and responses (Annotated[Archive, IOAttrs('x')]); dataclassio nests the bytes-typed fields into the outer JSON without the extra base64-of-base64 round trip a bytes-blob field would incur. For the rare case that genuinely needs bytes (filesystem storage, etc.), serialize explicitly with efro.dataclassio.dataclass_to_json().

Per-field IOAttrs short keys are stable; new optional fields get soft_default rather than reusing or renaming existing ones — same as anywhere else dataclassio types travel.

cert: Cert | None = None
data: bytes
signature: bytes
class bacommon.securedata.Cert(payload: bytes, signature: bytes)[source]

Bases: object

Master-signed delegation certificate.

Asserts that the public key embedded in payload is authorized to sign on the master’s behalf for the validity window in the payload. Verifiable by anyone holding a current Reader (server-side) or the static public keys baked into the client binary (client-side, once a future client version supports the cert path).

Carries an opaque payload (canonical JSON of CertPayload) plus the master signature over those bytes. Mirrors the InsecureDirective pattern — re-encoding the dataclass on every verify would risk canonicalization drift.

decoded_payload() CertPayload[source]

Decode payload to a CertPayload.

Does not verify the signature. Callers are expected to be operating on a cert that’s already been chain-verified via Reader.check().

payload: bytes

Canonical JSON encoding of CertPayload. Signed as-is and re-decoded by recipients via decoded_payload().

signature: bytes

Signature of payload made with the master signing key.

class bacommon.securedata.CertPayload(publickey: bytes, starttime: datetime, endtime: datetime, issuer: str)[source]

Bases: object

Unsigned content of a Cert.

Master signs the canonical JSON encoding of this; recipients re-decode after signature verification to access the fields.

endtime: datetime
issuer: str

Identifier of the delegate (e.g. basn node id) for accountability and debugging. Not used for verification.

publickey: bytes

Public half of the keypair this cert authorizes.

starttime: datetime

Validity window during which signatures made by the matching private key should be honored.

exception bacommon.securedata.Invalid[source]

Bases: Exception

Raised by Reader.read() and Writer.write() when an operation cannot complete safely.

For read: the archive bytes are malformed, the master signature does not validate, the cert is expired or signed by an unknown master, or the delegate signature does not match.

For write: the writer’s cert is past its validity window and would produce a signed archive a verifier would refuse.

str(exc) carries a short reason suitable for logging.

bacommon.securedata.MIN_CLIENT_BUILD_FOR_DELEGATE_VERIFY: int = 22843

Minimum ballistica-internal client build number known to support cert-bearing verification via Reader.check(). Older clients only have the legacy check(data, signature) path and would silently fail to verify (data, signature, cert) triples — server code must therefore skip the delegate-signed path for clients reporting a build below this threshold.

Bump in lockstep with the ballistica-internal release that ships the matching client code. Tracks the build at the moment the cert path was added; ratchets upward only when a protocol change requires it.

class bacommon.securedata.Reader(starttime: datetime, endtime: datetime, publickeys: list[bytes])[source]

Bases: object

Verifies data as being signed by our master server.

check(data: bytes, signature: bytes, cert: Cert | None = None) bool[source]

Verify data, returning True if successful.

When cert is None (the default), signature is verified directly against the master public keys — used for anything bamaster signed itself.

When cert is given, the chain is verified end-to-end:

  1. The cert’s signature must validate against a master public key (proving the master authorized this delegate).

  2. The cert’s validity window must include now.

  3. signature must then validate against the delegate public key embedded in the cert.

Used for data signed by a delegate (typically a basn node) acting on the master’s behalf. Older clients that predate the delegate-signing rollout will only ever be sent cert=None triples; see bacommon/securedata.py design notes for the rollout discipline.

Uses the ballistica native _babase.verify_ed25519 when available (inside the app binary). On contexts without it (server, pytest, tools scripts) falls back to the cryptography package, which those contexts already have.

endtime: datetime
publickeys: list[bytes]
read(archive: Archive) bytes[source]

Verify archive and return its data on success.

archive is the Archive produced by Writer.write() or make_master_archive(). Routes automatically: an archive without a cert is verified directly against this reader’s master public keys; an archive with a cert is chain-verified (cert against master keys, then data against the cert’s delegate pubkey).

Raises Invalid for any failure — expired/forged cert, bad signature.

starttime: datetime
bacommon.securedata.STATIC_DATA_PUBLIC_KEYS: tuple[bytes, ...] = (b'\x98\xc0\xb3{\xea\n\t\x0f\xfb\xcbN\x1c\x03A\xd7\xd6d\x95{.\xdc\xda\x9b\xf6\xe0\x7f\x0bM\x84^\x15b',)

Public halves of long-lived Ed25519 keypairs the master server uses to sign static data that clients must verify offline — without any network round trip to fetch a Reader. Compiled into the client binary, so a MITM cannot swap them.

Multiple entries let us rotate: add the new key (as a second entry) in a client release, wait for that release to propagate to the installed base, switch the server to sign with the new key, then later drop the old key in a subsequent client release. On verify, a signature is considered valid if ANY listed key verifies it.

The matching private halves live on the master server in svals under static_data_private_key (current signing key). basn nodes fetch the current private key from the master at startup over the secure inter-node channel.

class bacommon.securedata.Writer(starttime: datetime, endtime: datetime, privatekey: bytes, cert: Cert)[source]

Bases: object

Delegated signing capability.

Issued by the master to a delegate (typically a basn node) over a secure channel. The delegate calls write() on data and distributes the resulting archive bytes; recipients chain-verify and recover the original bytes via Reader.read().

Sensitive: contains a private key. Never traverses untrusted channels and should not be persisted to disk.

The top-level starttime / endtime mirror the cert’s validity window for ergonomic refresh-decision code (see basn’s _update_secure_data_signer). They are NOT authoritative for verification — cert is.

Servers must consult MIN_CLIENT_BUILD_FOR_DELEGATE_VERIFY before sending delegate-signed archives to a client; clients below the threshold do not understand the cert path and would reject the archive.

cert: Cert

Master-signed cert authorizing the public counterpart of privatekey.

endtime: datetime
privatekey: bytes

Raw Ed25519 private key bytes.

sign(data: bytes) bytes[source]

Low-level: produce a raw signature over data.

Most callers should use write() instead — it returns a self-contained archive that includes the signature, the cert, and the data, all verifiable in a single Reader.read() call.

starttime: datetime
write(data: bytes) Archive[source]

Sign data and return an Archive.

The archive carries the signature + the writer’s cert; recipients pass it to Reader.read() to verify and recover the original bytes.

Raises Invalid if the writer’s cert has expired — an archive produced past expiry would be rejected by every verifier, so we fail fast at write time rather than at verify time.

bacommon.securedata.make_master_archive(data: bytes, master_priv_bytes: bytes) Archive[source]

Pack data + a master-key signature into an Archive.

Server-only — clients do not have access to a master private key. Verifiers (with master public keys) accept the resulting archive via Reader.read() exactly the same way they accept Writer-produced archives, except the master path carries no cert.

master_priv_bytes is the raw 32-byte Ed25519 seed. On bamaster, prefer UniversalGlobals.secure_data_archive_master which sources the key from svals.

bacommon.servermanager module

Functionality related to the server manager script.

class bacommon.servermanager.ChatMessageCommand(message: str, clients: list[int] | None)[source]

Bases: ServerCommand

Chat message from the server.

clients: list[int] | None
message: str
class bacommon.servermanager.ClientListCommand[source]

Bases: ServerCommand

Print a list of clients.

class bacommon.servermanager.KickCommand(client_id: int, ban_time: int | None)[source]

Bases: ServerCommand

Kick a client.

ban_time: int | None
client_id: int
class bacommon.servermanager.ScreenMessageCommand(message: str, color: tuple[float, float, float] | None, clients: list[int] | None)[source]

Bases: ServerCommand

Screen-message from the server.

clients: list[int] | None
color: tuple[float, float, float] | None
message: str
class bacommon.servermanager.ServerCommand[source]

Bases: object

Base class for commands that can be sent to the server.

class bacommon.servermanager.ServerConfig(party_name: str = 'FFA', party_is_public: bool = True, authenticate_clients: bool = True, admins: list[str] = <factory>, enable_default_kick_voting: bool = True, public_ipv4_address: str | None = None, public_ipv6_address: str | None = None, port: int = 43210, max_party_size: int = 6, session_max_players_override: int | None = None, session_type: str = 'ffa', playlist_code: int | None = None, playlist_inline: list[dict[str, ~typing.Any]] | None = None, playlist_shuffle: bool = True, auto_balance_teams: bool = True, coop_campaign: str = 'Easy', coop_level: str = 'Onslaught Training', enable_telnet: bool = False, teams_series_length: int = 7, ffa_series_length: int = 24, stats_url: str | None = None, clean_exit_minutes: float | None = None, unclean_exit_minutes: float | None = None, idle_exit_minutes: float | None = None, show_tutorial: bool = False, team_names: tuple[str, str] | None = None, team_colors: tuple[tuple[float, float, float], tuple[float, float, float]] | None = None, enable_queue: bool = True, protocol_version: int | None = None, stress_test_players: int | None = None, player_rejoin_cooldown: float = 10.0, log_levels: dict[str, str] | None = None, dont_write_bytecode: bool = False)[source]

Bases: object

Configuration for the server manager app (<appname>_server).

admins: list[str]
authenticate_clients: bool = True
auto_balance_teams: bool = True
clean_exit_minutes: float | None = None
coop_campaign: str = 'Easy'
coop_level: str = 'Onslaught Training'
dont_write_bytecode: bool = False
enable_default_kick_voting: bool = True
enable_queue: bool = True
enable_telnet: bool = False
ffa_series_length: int = 24
idle_exit_minutes: float | None = None
log_levels: dict[str, str] | None = None
max_party_size: int = 6
party_is_public: bool = True
party_name: str = 'FFA'
player_rejoin_cooldown: float = 10.0
playlist_code: int | None = None
playlist_inline: list[dict[str, Any]] | None = None
playlist_shuffle: bool = True
port: int = 43210
protocol_version: int | None = None
public_ipv4_address: str | None = None
public_ipv6_address: str | None = None
session_max_players_override: int | None = None
session_type: str = 'ffa'
show_tutorial: bool = False
stats_url: str | None = None
stress_test_players: int | None = None
team_colors: tuple[tuple[float, float, float], tuple[float, float, float]] | None = None
team_names: tuple[str, str] | None = None
teams_series_length: int = 7
unclean_exit_minutes: float | None = None
class bacommon.servermanager.ShutdownCommand(reason: ShutdownReason, immediate: bool)[source]

Bases: ServerCommand

Tells the server to shut down.

immediate: bool
reason: ShutdownReason
class bacommon.servermanager.ShutdownReason(*values)[source]

Bases: Enum

Reason a server is shutting down.

NONE = 'none'
RESTARTING = 'restarting'
class bacommon.servermanager.StartServerModeCommand(config: ServerConfig)[source]

Bases: ServerCommand

Tells the app to switch into ‘server’ mode.

config: ServerConfig

bacommon.text module

Text related bits.

class bacommon.text.SpecialChar(*values)[source]

Bases: Enum

Custom unicode characters the engine can display.

Keep this in sync with babase._generated.enums.SpecialChar.

BACK = '\ue00b'
BOTTOM_BUTTON = '\ue008'
BOXING_GLOVE = '\ue067'
CLOSE = '\ue017'
CROWN = '\ue043'
DELETE = '\ue009'
DICE_BUTTON1 = '\ue022'
DICE_BUTTON2 = '\ue023'
DICE_BUTTON3 = '\ue024'
DICE_BUTTON4 = '\ue025'
DOWN_ARROW = '\ue004'
DPAD_CENTER_BUTTON = '\ue010'
DRAGON = '\ue048'
EYE_BALL = '\ue045'
FAST_FORWARD_BUTTON = '\ue00f'
FEDORA = '\ue041'
FIREBALL = '\ue04f'
FLAG_ALGERIA = '\ue054'
FLAG_ARGENTINA = '\ue05f'
FLAG_AUSTRALIA = '\ue058'
FLAG_BRAZIL = '\ue035'
FLAG_CANADA = '\ue039'
FLAG_CHILE = '\ue061'
FLAG_CHINA = '\ue037'
FLAG_CZECH_REPUBLIC = '\ue057'
FLAG_EGYPT = '\ue052'
FLAG_FRANCE = '\ue03c'
FLAG_GERMANY = '\ue034'
FLAG_INDIA = '\ue03a'
FLAG_INDONESIA = '\ue03d'
FLAG_IRAN = '\ue05d'
FLAG_ITALY = '\ue03e'
FLAG_JAPAN = '\ue03b'
FLAG_KUWAIT = '\ue053'
FLAG_MALAYSIA = '\ue056'
FLAG_MEXICO = '\ue033'
FLAG_NETHERLANDS = '\ue040'
FLAG_PHILIPPINES = '\ue060'
FLAG_POLAND = '\ue05e'
FLAG_QATAR = '\ue051'
FLAG_RUSSIA = '\ue036'
FLAG_SAUDI_ARABIA = '\ue055'
FLAG_SINGAPORE = '\ue059'
FLAG_SOUTH_KOREA = '\ue03f'
FLAG_UNITED_ARAB_EMIRATES = '\ue050'
FLAG_UNITED_KINGDOM = '\ue038'
FLAG_UNITED_STATES = '\ue032'
HAL = '\ue042'
HEART = '\ue047'
HELMET = '\ue049'
LEFT_ARROW = '\ue001'
LEFT_BUTTON = '\ue005'
LOCAL_ACCOUNT = '\ue030'
LOGO_FLAT = '\ue00c'
MIKIROG = '\ue062'
MOON = '\ue04d'
MUSHROOM = '\ue04a'
NINJA_STAR = '\ue04b'
OUYA_BUTTON_A = '\ue01c'
OUYA_BUTTON_O = '\ue019'
OUYA_BUTTON_U = '\ue01a'
OUYA_BUTTON_Y = '\ue01b'
PALM_TREE = '\ue066'
PARTY_ICON = '\ue027'
PAUSE_BUTTON = '\ue016'
PLAY_BUTTON = '\ue015'
PLAY_PAUSE_BUTTON = '\ue00e'
PLAY_STATION_CIRCLE_BUTTON = '\ue012'
PLAY_STATION_CROSS_BUTTON = '\ue011'
PLAY_STATION_SQUARE_BUTTON = '\ue014'
PLAY_STATION_TRIANGLE_BUTTON = '\ue013'
POTATO = '\ue065'
REWIND_BUTTON = '\ue00d'
RIGHT_ARROW = '\ue002'
RIGHT_BUTTON = '\ue007'
SANTA_HAT = '\ue064'
SHIFT = '\ue00a'
SKULL = '\ue046'
SPIDER = '\ue04e'
TEST_ACCOUNT = '\ue028'
TICKET = '\ue01f'
TICKET_BACKING = '\ue029'
TOKEN = '\ue01d'
TOP_BUTTON = '\ue006'
TROPHY0A = '\ue02d'
TROPHY0B = '\ue02e'
TROPHY1 = '\ue02a'
TROPHY2 = '\ue02b'
TROPHY3 = '\ue02c'
TROPHY4 = '\ue02f'
UP_ARROW = '\ue003'
VIKING_HELMET = '\ue04c'
YIN_YANG = '\ue044'

bacommon.transfer module

Functionality related to transferring files/data.

Warning

This is an internal api and subject to change at any time. Do not use it in mod code.