diff --git a/.efrocachemap b/.efrocachemap
index 85ec4410..478002a4 100644
--- a/.efrocachemap
+++ b/.efrocachemap
@@ -4064,50 +4064,50 @@
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
- "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "d3d9fb45a4c9b2d03c3d8d92b21e391c",
- "build/prefab/full/linux_arm64_gui/release/ballisticakit": "4046514b27b8de5eec099669270e760a",
- "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "1eb01901da8e4e6a9aae10d93e75f669",
- "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "b2bc222a442085ae9e77c4736c1a47c2",
- "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "98cc6c34ae3baf9f03483ecf718f0860",
- "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "f55ff138c57aeb6d3b5061b6e5289c89",
- "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "47b4af4d42c6ab169bb33d9b1016a321",
- "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "37b2fd64034132fef6a8f202760fc833",
- "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "b4c9e97df51d5cc4f4086c20f75fadea",
- "build/prefab/full/mac_arm64_gui/release/ballisticakit": "017b34a328d86dc83a975504c3228a23",
- "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "f3f4e7aac95d70d36f1458f793df846a",
- "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "5e0c95b6088822a1a8dbb11d889832e3",
- "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "adb8dfd68d6aea6f450b2ad5ccad3d67",
- "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "951745d14df5d233952a002468b37efa",
- "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "bdd54abe7304f4458867692c28ad1d35",
- "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "6585700cc49deb2c42c4119042648ebd",
- "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "aae37dce0c102274289663de0ac083d5",
- "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "3c30cbf4fb4bde6ce99f0f287052a4a2",
- "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "63bf6d378e6af7f7c02837d201d06a17",
- "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "85aaa5262f488e0a411d8ca8ec6e8987",
- "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "56ebc8c31e020e515395d3a81d2bb766",
- "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "b9aabf060ca52f9957e5c0c68975dd0d",
- "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "56ebc8c31e020e515395d3a81d2bb766",
- "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "b9aabf060ca52f9957e5c0c68975dd0d",
- "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "21b01b868f38182cbe30dead5e6f6688",
- "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "5bafa4627b87a3cfc6558d51c2760560",
- "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "21b01b868f38182cbe30dead5e6f6688",
- "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "5bafa4627b87a3cfc6558d51c2760560",
- "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "9ba592d991ebb8724de8cab368bd1ac7",
- "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "79630364e1f71cedf87140c40b913785",
- "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "9ba592d991ebb8724de8cab368bd1ac7",
- "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "79630364e1f71cedf87140c40b913785",
- "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "7e3d1a1c0bdb8a814f7227f71862fa1d",
- "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "5bfe717b5f30a67822130299b7342bcf",
- "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "6c7d4caaad12d39c61b291fe33eef2af",
- "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "5bfe717b5f30a67822130299b7342bcf",
- "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "facd9669de199a464287b985d9373c0f",
- "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "deff82055a269fa905dd0cd7622adb64",
- "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "e5ebf7e622ff126bc6b91dd7148fac4f",
- "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "ad8c2bae99b72b48a510cdf1ce849358",
- "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "a5302ab082d0555788b32e7485e07620",
- "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "0376b9a3e88c8c7305b33160f11a3de9",
- "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "1260620b96e0615fd993bfa19d5368c8",
- "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "2ab0357736b91e5be4cd03c153f92c36",
+ "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "d17c2ee21e1fb7845763e9ccc9e7966d",
+ "build/prefab/full/linux_arm64_gui/release/ballisticakit": "742d02168b023ef812b53fed2e581f7d",
+ "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "b41cfcdd17a4ce3a85707426c62144ee",
+ "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "a799400fd4b28b724a5cd7022c016a1c",
+ "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "0651c8caba1b5258acf06cf515829e94",
+ "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "c67d36bac8c20c59cf58fe67ff5aab6f",
+ "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "a932c27c89add5dd0b0b5054ccbc9c30",
+ "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "bcccf5b9506727ae7339d172946e9cba",
+ "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "ad79f1fb9a69488395dcb8e9909b18e2",
+ "build/prefab/full/mac_arm64_gui/release/ballisticakit": "1c4c72504904d6ac6003401cffef8550",
+ "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "3be75ed39f701ea673fdf4c41cc85fee",
+ "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "b6caf556a041fd297a42d022dd28bbbd",
+ "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "32bce4f3dc1068d13c7a8c13f6f65d39",
+ "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "633069c441e56f01cbe5a15d2a3202d4",
+ "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "02350d3de51cd2056d3144ff34fe24d2",
+ "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "562c39ba329fcd64b23d86a56cd5f7bb",
+ "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "a173972be3a16bc2637dabbe124aaea6",
+ "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "f0b9f9514c4da093c8720a89e54c069c",
+ "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "f7df321426c7add9f4ea31e266ed5c66",
+ "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "72435cbb4e1b80f31652950f32021464",
+ "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "cbb5ca4147284608ee43aaefe1f9bcfb",
+ "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "788b336518c767880ce7392d7f595852",
+ "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "cbb5ca4147284608ee43aaefe1f9bcfb",
+ "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "788b336518c767880ce7392d7f595852",
+ "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "cccb7895ed8f412f72ce04c676eae235",
+ "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "f792c55164f95f8b33f00e7d809c90f7",
+ "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "cccb7895ed8f412f72ce04c676eae235",
+ "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "f792c55164f95f8b33f00e7d809c90f7",
+ "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "460f8c445f95f1789820ab1d4556c03a",
+ "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "911f93f977b96774cfa3c82f5e5a4cc8",
+ "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "460f8c445f95f1789820ab1d4556c03a",
+ "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "911f93f977b96774cfa3c82f5e5a4cc8",
+ "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "8d7077f5e2b9ed0cf9dcf8cbb75ef696",
+ "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "016af4cf5eea1232e05db579bda8ee4b",
+ "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "5d848f38d9a8056de078a26f78538051",
+ "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "016af4cf5eea1232e05db579bda8ee4b",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "3dd5639a27b74c03e77e3ef706889466",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "c374e1187e51a6c7af83b3158e9ece34",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "92888461dc4f86381cfade96b43ca944",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "95c4b8c64bcfb62f782a4b3b74189b80",
+ "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "bb99cd26d290a01a90f538fc9dcc4af6",
+ "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "eb5316cfd1213ed4eb61f780ea9ad5ef",
+ "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "1c436928b8fdae376046661097a85851",
+ "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "b5e3f67b28943b3afe6e8d62811f2844",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "f8cd3af311ac63147882590123b78318",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "ad347097a38e0d7ede9eb6dec6a80ee9",
diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml
index 8aef2757..351a93cf 100644
--- a/.idea/dictionaries/ericf.xml
+++ b/.idea/dictionaries/ericf.xml
@@ -1088,6 +1088,7 @@
fnames
fnmatch
fnode
+ fnsu
fnum
fobjc
foof
@@ -1335,6 +1336,7 @@
hdpi
headercheckline
headerregistry
+ headlessly
heapqmodule
hehe
heldfile
@@ -1393,7 +1395,6 @@
ignorevar
iiarcade
iiiiisssi
- iircade
ilang
ilck
ilogput
@@ -3377,4 +3378,4 @@
zval
-
\ No newline at end of file
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d8d10600..658f9967 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,4 @@
-### 1.7.27 (build 21272, api 8, 2023-08-30)
+### 1.7.27 (build 21281, api 8, 2023-08-30)
- Fixed a rare crash that could occur if the app shuts down while a background
thread is making a web request. The app will now try to wait for any such
@@ -29,9 +29,9 @@
thinking I'll have to bite the bullet and implement something that asks the
user what the thing is to solve cases like that.
- Added tags allowing easily stripping code out of spinoff projects when a
- specific feature-set is not present. For example, for feature-set 'foo', one
- can strip lines out by adding `__SPINOFF_REQUIRE_FOO_BEGIN__` and
- `__SPINOFF_REQUIRE_FOO_END__` tags.
+ specific feature-set is not present. For example, to strip lines out when
+ feature-set 'foo' is not present, surround them by lines containing
+ `__SPINOFF_REQUIRE_FOO_BEGIN__` and `__SPINOFF_REQUIRE_FOO_END__`.
### 1.7.26 (build 21259, api 8, 2023-08-29)
diff --git a/ballisticakit-cmake/.idea/dictionaries/ericf.xml b/ballisticakit-cmake/.idea/dictionaries/ericf.xml
index d2ef27e7..6d3915be 100644
--- a/ballisticakit-cmake/.idea/dictionaries/ericf.xml
+++ b/ballisticakit-cmake/.idea/dictionaries/ericf.xml
@@ -662,6 +662,7 @@
flushhhhh
fname
fnode
+ fnsu
fnumc
fobjc
focuswindow
@@ -805,6 +806,7 @@
havn't
havnt
hdiutil
+ headlessly
healthcare
heldfile
hexval
@@ -843,7 +845,6 @@
ignorevar
iiiiisss
iiiiisssi
- iircade
illum
ilock
imagewidget
@@ -1980,4 +1981,4 @@
zrot
-
\ No newline at end of file
+
diff --git a/ballisticakit-cmake/.idea/misc.xml b/ballisticakit-cmake/.idea/misc.xml
index 22a51356..17581663 100644
--- a/ballisticakit-cmake/.idea/misc.xml
+++ b/ballisticakit-cmake/.idea/misc.xml
@@ -29,7 +29,6 @@
-
diff --git a/src/assets/ba_data/python/babase/_app.py b/src/assets/ba_data/python/babase/_app.py
index e73e45a3..093d3dda 100644
--- a/src/assets/ba_data/python/babase/_app.py
+++ b/src/assets/ba_data/python/babase/_app.py
@@ -4,7 +4,6 @@
# pylint: disable=too-many-lines
from __future__ import annotations
-import os
import logging
from enum import Enum
@@ -144,12 +143,34 @@ class App:
the single shared instance.
"""
- if os.environ.get('BA_RUNNING_WITH_DUMMY_MODULES') == '1':
+ self.env: babase.Env = _babase.Env()
+ if self.env.running_with_dummy_modules:
return
self.state = self.State.NOT_RUNNING
- self.env: babase.Env = _babase.Env()
+ # Controls which app-modes we use for handling given
+ # app-intents. Plugins can override this to change high level
+ # app behavior and spinoff projects can change the default
+ # implementation for the same effect.
+ self.mode_selector: babase.AppModeSelector | None = None
+
+ # Default executor which can be used for misc background
+ # processing. It should also be passed to any additional asyncio
+ # loops we create so that everything shares the same single set
+ # of worker threads.
+ self.threadpool = ThreadPoolExecutor(thread_name_prefix='baworker')
+
+ self.meta = MetadataSubsystem()
+ self.net = NetworkSubsystem()
+ self.workspaces = WorkspaceSubsystem()
+ self.components = AppComponentSubsystem()
+
+ # This is incremented any time the app is backgrounded or
+ # foregrounded; can be a simple way to determine if network data
+ # should be refreshed/etc.
+ self.fg_state = 0
+ self.config_file_healthy: bool = False
self._subsystems: list[AppSubsystem] = []
self._native_bootstrapping_completed = False
@@ -164,43 +185,9 @@ class App:
self._called_on_running = False
self._subsystem_registration_ended = False
self._pending_apply_app_config = False
-
- self.config_file_healthy: bool = False
-
- # This is incremented any time the app is backgrounded or
- # foregrounded; can be a simple way to determine if network data
- # should be refreshed/etc.
- self.fg_state = 0
-
self._aioloop: asyncio.AbstractEventLoop | None = None
-
- self._env = _babase.env()
- self.protocol_version: int = self._env['protocol_version']
- assert isinstance(self.protocol_version, int)
- # self.toolbar_test: bool = self._env['toolbar_test']
- # assert isinstance(self.toolbar_test, bool)
- self.demo_mode: bool = self._env['demo_mode']
- assert isinstance(self.demo_mode, bool)
- self.arcade_mode: bool = self._env['arcade_mode']
- assert isinstance(self.arcade_mode, bool)
- self.headless_mode: bool = self._env['headless_mode']
- assert isinstance(self.headless_mode, bool)
-
- # Default executor which can be used for misc background
- # processing. It should also be passed to any additional asyncio
- # loops we create so that everything shares the same single set
- # of worker threads.
- self.threadpool = ThreadPoolExecutor(thread_name_prefix='baworker')
-
+ self._asyncio_timer: babase.AppTimer | None = None
self._config: babase.AppConfig | None = None
-
- self.components = AppComponentSubsystem()
-
- # Testing this.
- self.meta = MetadataSubsystem()
-
- self.net = NetworkSubsystem()
- self.workspaces = WorkspaceSubsystem()
self._pending_intent: AppIntent | None = None
self._intent: AppIntent | None = None
self._mode: AppMode | None = None
@@ -209,18 +196,10 @@ class App:
self._wait_for_shutdown_suppressions()
]
- # Controls which app-modes we use for handling given
- # app-intents. Plugins can override this to change high level
- # app behavior and spinoff projects can change the default
- # implementation for the same effect.
- self.mode_selector: babase.AppModeSelector | None = None
-
- self._asyncio_timer: babase.AppTimer | None = None
-
def postinit(self) -> None:
"""Called after we've been inited and assigned to babase.app."""
- if os.environ.get('BA_RUNNING_WITH_DUMMY_MODULES') == '1':
+ if self.env.running_with_dummy_modules:
return
# NOTE: the reason we need a postinit here is that
@@ -1011,3 +990,50 @@ class App:
return self.ui_v1.use_toolbars
# __SPINOFF_REQUIRE_UI_V1_END__
+
+ @property
+ def arcade_mode(self) -> bool:
+ """Whether the app is currently running on arcade hardware."""
+ warnings.warn(
+ 'app.arcade_mode is deprecated; use app.env.arcade',
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.env.arcade
+
+ @property
+ def headless_mode(self) -> bool:
+ """Whether the app is running headlessly."""
+ warnings.warn(
+ 'app.headless_mode is deprecated; use app.env.headless',
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.env.headless
+
+ @property
+ def demo_mode(self) -> bool:
+ """Whether the app is targeting a demo experience."""
+ warnings.warn(
+ 'app.demo_mode is deprecated; use app.env.demo',
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.env.demo
+
+ # __SPINOFF_REQUIRE_SCENE_V1_BEGIN__
+
+ @property
+ def protocol_version(self) -> int:
+ """(internal)."""
+ import bascenev1
+
+ warnings.warn(
+ 'app.protocol_version is deprecated;'
+ ' use bascenev1.protocol_version()',
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return bascenev1.protocol_version()
+
+ # __SPINOFF_REQUIRE_SCENE_V1_END__
diff --git a/src/assets/ba_data/python/babase/_apputils.py b/src/assets/ba_data/python/babase/_apputils.py
index 4543ca60..73360581 100644
--- a/src/assets/ba_data/python/babase/_apputils.py
+++ b/src/assets/ba_data/python/babase/_apputils.py
@@ -222,8 +222,7 @@ def garbage_collect() -> None:
def print_corrupt_file_error() -> None:
"""Print an error if a corrupt file is found."""
- # FIXME - filter this out for builds without bauiv1.
- if not _babase.app.headless_mode:
+ if _babase.app.env.gui:
_babase.apptimer(
2.0,
lambda: _babase.screenmessage(
diff --git a/src/assets/ba_data/python/babase/_hooks.py b/src/assets/ba_data/python/babase/_hooks.py
index 1bb03363..9d726c9f 100644
--- a/src/assets/ba_data/python/babase/_hooks.py
+++ b/src/assets/ba_data/python/babase/_hooks.py
@@ -92,7 +92,7 @@ def connection_failed_message() -> None:
def temporarily_unavailable_message() -> None:
from babase._language import Lstr
- if not _babase.app.headless_mode:
+ if _babase.app.env.gui:
_babase.getsimplesound('error').play()
_babase.screenmessage(
Lstr(resource='getTicketsWindow.unavailableTemporarilyText'),
@@ -103,7 +103,7 @@ def temporarily_unavailable_message() -> None:
def in_progress_message() -> None:
from babase._language import Lstr
- if not _babase.app.headless_mode:
+ if _babase.app.env.gui:
_babase.getsimplesound('error').play()
_babase.screenmessage(
Lstr(resource='getTicketsWindow.inProgressText'),
@@ -114,7 +114,7 @@ def in_progress_message() -> None:
def error_message() -> None:
from babase._language import Lstr
- if not _babase.app.headless_mode:
+ if _babase.app.env.gui:
_babase.getsimplesound('error').play()
_babase.screenmessage(Lstr(resource='errorText'), color=(1, 0, 0))
@@ -122,7 +122,7 @@ def error_message() -> None:
def purchase_not_valid_error() -> None:
from babase._language import Lstr
- if not _babase.app.headless_mode:
+ if _babase.app.env.gui:
_babase.getsimplesound('error').play()
_babase.screenmessage(
Lstr(
@@ -136,7 +136,7 @@ def purchase_not_valid_error() -> None:
def purchase_already_in_progress_error() -> None:
from babase._language import Lstr
- if not _babase.app.headless_mode:
+ if _babase.app.env.gui:
_babase.getsimplesound('error').play()
_babase.screenmessage(
Lstr(resource='store.purchaseAlreadyInProgressText'),
@@ -195,7 +195,7 @@ def award_dual_wielding_achievement() -> None:
def play_gong_sound() -> None:
- if not _babase.app.headless_mode:
+ if _babase.app.env.gui:
_babase.getsimplesound('gong').play()
@@ -263,7 +263,7 @@ def ui_remote_press() -> None:
"""Handle a press by a remote device that is only usable for nav."""
from babase._language import Lstr
- if _babase.app.headless_mode:
+ if _babase.app.env.headless:
return
# Can be called without a context; need a context for getsound.
@@ -358,7 +358,7 @@ def show_client_too_old_error() -> None:
):
return
- if not _babase.app.headless_mode:
+ if _babase.app.env.gui:
_babase.getsimplesound('error').play()
_babase.screenmessage(
diff --git a/src/assets/ba_data/python/baclassic/_accountv1.py b/src/assets/ba_data/python/baclassic/_accountv1.py
index 9a1cb452..5dab06cd 100644
--- a/src/assets/ba_data/python/baclassic/_accountv1.py
+++ b/src/assets/ba_data/python/baclassic/_accountv1.py
@@ -42,7 +42,7 @@ class AccountV1Subsystem:
if babase.app.plus is None:
return
if (
- babase.app.headless_mode
+ babase.app.env.headless
or babase.app.config.get('Auto Account State') == 'Local'
):
babase.app.plus.sign_in_v1('Local')
diff --git a/src/assets/ba_data/python/baclassic/_store.py b/src/assets/ba_data/python/baclassic/_store.py
index b82f73dc..e239adf9 100644
--- a/src/assets/ba_data/python/baclassic/_store.py
+++ b/src/assets/ba_data/python/baclassic/_store.py
@@ -545,7 +545,7 @@ class StoreSubsystem:
"""
plus = babase.app.plus
unowned_maps: set[str] = set()
- if not babase.app.headless_mode:
+ if babase.app.env.gui:
for map_section in self.get_store_layout()['maps']:
for mapitem in map_section['items']:
if plus is None or not plus.get_purchased(mapitem):
@@ -558,7 +558,7 @@ class StoreSubsystem:
try:
plus = babase.app.plus
unowned_games: set[type[bascenev1.GameActivity]] = set()
- if not babase.app.headless_mode:
+ if babase.app.env.gui:
for section in self.get_store_layout()['minigames']:
for mname in section['items']:
if plus is None or not plus.get_purchased(mname):
diff --git a/src/assets/ba_data/python/baclassic/_subsystem.py b/src/assets/ba_data/python/baclassic/_subsystem.py
index 108d5ca4..620c2ad3 100644
--- a/src/assets/ba_data/python/baclassic/_subsystem.py
+++ b/src/assets/ba_data/python/baclassic/_subsystem.py
@@ -128,6 +128,10 @@ class ClassicSubsystem(babase.AppSubsystem):
assert isinstance(self._env['platform'], str)
return self._env['platform']
+ def scene_v1_protocol_version(self) -> int:
+ """(internal)"""
+ return bascenev1.protocol_version()
+
@property
def subplatform(self) -> str:
"""String for subplatform.
@@ -216,7 +220,7 @@ class ClassicSubsystem(babase.AppSubsystem):
self.special_offer = cfg['pendingSpecialOffer']['o']
show_offer()
- if not babase.app.headless_mode:
+ if babase.app.env.gui:
babase.apptimer(3.0, check_special_offer)
# If there's a leftover log file, attempt to upload it to the
@@ -747,7 +751,7 @@ class ClassicSubsystem(babase.AppSubsystem):
from bauiv1lib.party import PartyWindow
from babase import app
- assert not app.headless_mode
+ assert app.env.gui
bauiv1.getsound('swish').play()
@@ -770,7 +774,7 @@ class ClassicSubsystem(babase.AppSubsystem):
if not in_main_menu:
set_ui_input_device(device_id)
- if not babase.app.headless_mode:
+ if babase.app.env.gui:
bauiv1.getsound('swish').play()
babase.app.ui_v1.set_main_menu_window(
diff --git a/src/assets/ba_data/python/baenv.py b/src/assets/ba_data/python/baenv.py
index c59fa57f..04c61787 100644
--- a/src/assets/ba_data/python/baenv.py
+++ b/src/assets/ba_data/python/baenv.py
@@ -52,7 +52,7 @@ if TYPE_CHECKING:
# Build number and version of the ballistica binary we expect to be
# using.
-TARGET_BALLISTICA_BUILD = 21272
+TARGET_BALLISTICA_BUILD = 21281
TARGET_BALLISTICA_VERSION = '1.7.27'
diff --git a/src/assets/ba_data/python/bascenev1/__init__.py b/src/assets/ba_data/python/bascenev1/__init__.py
index 77cd93e6..605b363c 100644
--- a/src/assets/ba_data/python/bascenev1/__init__.py
+++ b/src/assets/ba_data/python/bascenev1/__init__.py
@@ -112,6 +112,7 @@ from _bascenev1 import (
newnode,
Node,
printnodes,
+ protocol_version,
release_gamepad_input,
release_keyboard_input,
reset_random_player_names,
@@ -383,6 +384,7 @@ __all__ = [
'PowerupMessage',
'print_live_object_warnings',
'printnodes',
+ 'protocol_version',
'pushcall',
'register_map',
'release_gamepad_input',
diff --git a/src/assets/ba_data/python/bascenev1/_coopgame.py b/src/assets/ba_data/python/bascenev1/_coopgame.py
index c7c0d085..2c684f85 100644
--- a/src/assets/ba_data/python/bascenev1/_coopgame.py
+++ b/src/assets/ba_data/python/bascenev1/_coopgame.py
@@ -53,7 +53,8 @@ class CoopGameActivity(GameActivity[PlayerT, TeamT]):
super().on_begin()
# Show achievements remaining.
- if not (babase.app.demo_mode or babase.app.arcade_mode):
+ env = babase.app.env
+ if not (env.demo or env.arcade):
_bascenev1.timer(
3.8, babase.WeakCall(self._show_remaining_achievements)
)
diff --git a/src/assets/ba_data/python/bascenev1/_coopsession.py b/src/assets/ba_data/python/bascenev1/_coopsession.py
index 39d83ab8..72a67919 100644
--- a/src/assets/ba_data/python/bascenev1/_coopsession.py
+++ b/src/assets/ba_data/python/bascenev1/_coopsession.py
@@ -211,7 +211,7 @@ class CoopSession(Session):
# Hmm; no players anywhere. Let's end the entire session if we're
# running a GUI (or just the current game if we're running headless).
else:
- if not babase.app.headless_mode:
+ if babase.app.env.gui:
self.end()
else:
if isinstance(activity, GameActivity):
@@ -277,6 +277,7 @@ class CoopSession(Session):
from bascenev1._score import ScoreType
app = babase.app
+ env = app.env
classic = app.classic
assert classic is not None
@@ -291,7 +292,7 @@ class CoopSession(Session):
# If we're running with a gui and at any point we have no
# in-game players, quit out of the session (this can happen if
# someone leaves in the tutorial for instance).
- if not babase.app.headless_mode:
+ if env.gui:
active_players = [p for p in self.sessionplayers if p.in_game]
if not active_players:
self.end()
@@ -317,7 +318,7 @@ class CoopSession(Session):
if (
isinstance(activity, JoinActivity)
and self.campaign_level_name == 'Onslaught Training'
- and not (app.demo_mode or app.arcade_mode)
+ and not (env.demo or env.arcade)
):
if self._tutorial_activity is None:
raise RuntimeError('Tutorial not preloaded properly.')
@@ -339,7 +340,7 @@ class CoopSession(Session):
# Now flip the current activity..
self.setactivity(next_game)
- if not (app.demo_mode or app.arcade_mode):
+ if not (env.demo or env.arcade):
if self.tournament_id is not None:
self._custom_menu_ui = [
{
diff --git a/src/assets/ba_data/python/bascenev1/_lobby.py b/src/assets/ba_data/python/bascenev1/_lobby.py
index 3bc9b894..9422a4e4 100644
--- a/src/assets/ba_data/python/bascenev1/_lobby.py
+++ b/src/assets/ba_data/python/bascenev1/_lobby.py
@@ -65,7 +65,7 @@ class JoinInfo:
)
)
- if babase.app.demo_mode or babase.app.arcade_mode:
+ if babase.app.env.demo or babase.app.env.arcade:
self._messages = [self._joinmsg]
else:
msg1 = babase.Lstr(
@@ -434,6 +434,7 @@ class Chooser:
"""Reload all player profiles."""
app = babase.app
+ env = app.env
assert app.classic is not None
# Re-construct our profile index and other stuff since the profile
@@ -475,17 +476,13 @@ class Chooser:
self._profiles['_random'] = {}
# In kiosk mode we disable account profiles to force random.
- if app.demo_mode or app.arcade_mode:
+ if env.demo or env.arcade:
if '__account__' in self._profiles:
del self._profiles['__account__']
# For local devices, add it an 'edit' option which will pop up
# the profile window.
- if (
- not is_remote
- and not is_test_input
- and not (app.demo_mode or app.arcade_mode)
- ):
+ if not is_remote and not is_test_input and not (env.demo or env.arcade):
self._profiles['_edit'] = {}
# Build a sorted name list we can iterate through.
diff --git a/src/assets/ba_data/python/bascenev1/_profile.py b/src/assets/ba_data/python/bascenev1/_profile.py
index dd142935..bef7c71e 100644
--- a/src/assets/ba_data/python/bascenev1/_profile.py
+++ b/src/assets/ba_data/python/bascenev1/_profile.py
@@ -69,7 +69,7 @@ def get_player_profile_colors(
# Special case: when being asked for a random color in kiosk mode,
# always return default purple.
- if (babase.app.demo_mode or babase.app.arcade_mode) and profilename is None:
+ if (babase.app.env.demo or babase.app.env.arcade) and profilename is None:
color = (0.5, 0.4, 1.0)
highlight = (0.4, 0.4, 0.5)
else:
diff --git a/src/assets/ba_data/python/bascenev1lib/activity/coopjoin.py b/src/assets/ba_data/python/bascenev1lib/activity/coopjoin.py
index f0cdf5ec..0777e8f1 100644
--- a/src/assets/ba_data/python/bascenev1lib/activity/coopjoin.py
+++ b/src/assets/ba_data/python/bascenev1lib/activity/coopjoin.py
@@ -45,6 +45,9 @@ class CoopJoinActivity(bs.JoinActivity):
def _show_remaining_achievements(self) -> None:
from bascenev1lib.actor.text import Text
+ app = bs.app
+ env = app.env
+
# We only show achievements and challenges for CoopGameActivities.
session = self.session
assert isinstance(session, bs.CoopSession)
@@ -64,19 +67,15 @@ class CoopJoinActivity(bs.JoinActivity):
ts_h_offs = 60
# Show remaining achievements in some cases.
- if bs.app.classic is not None and not (
- bs.app.demo_mode or bs.app.arcade_mode
- ):
+ if app.classic is not None and not (env.demo or env.arcade):
achievements = [
a
- for a in bs.app.classic.ach.achievements_for_coop_level(
- levelname
- )
+ for a in app.classic.ach.achievements_for_coop_level(levelname)
if not a.complete
]
have_achievements = bool(achievements)
achievements = [a for a in achievements if not a.complete]
- vrmode = bs.app.env.vr
+ vrmode = env.vr
if have_achievements:
Text(
bs.Lstr(resource='achievementsRemainingText'),
diff --git a/src/assets/ba_data/python/bascenev1lib/activity/coopscore.py b/src/assets/ba_data/python/bascenev1lib/activity/coopscore.py
index 1f2af3f9..ce226cfb 100644
--- a/src/assets/ba_data/python/bascenev1lib/activity/coopscore.py
+++ b/src/assets/ba_data/python/bascenev1lib/activity/coopscore.py
@@ -351,6 +351,8 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
assert bui.app.classic is not None
+ env = bui.app.env
+
delay = 0.7 if (self._score is not None) else 0.0
# If there's no players left in the game, lets not show the UI
@@ -406,9 +408,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
else:
pass
- show_next_button = self._is_more_levels and not (
- bui.app.demo_mode or bui.app.arcade_mode
- )
+ show_next_button = self._is_more_levels and not (env.demo or env.arcade)
if not show_next_button:
h_offs += 70
@@ -486,7 +486,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
v_offs + 560.0,
)
- if bui.app.demo_mode or bui.app.arcade_mode:
+ if env.demo or env.arcade:
self._league_rank_button = None
self._store_button_instance = None
else:
@@ -595,7 +595,9 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
# pylint: disable=too-many-locals
super().on_begin()
- plus = bs.app.plus
+ app = bs.app
+ env = app.env
+ plus = app.plus
assert plus is not None
self._begin_time = bs.time()
@@ -624,7 +626,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
# If this is the first time we completed it, set the next one
# as current.
if self._newly_complete:
- cfg = bs.app.config
+ cfg = app.config
cfg['Selected Coop Game'] = (
self._campaign.name + ':' + self._next_level_name
)
@@ -637,7 +639,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
self._is_complete
and self._victory
and self._is_more_levels
- and not (bs.app.demo_mode or bs.app.arcade_mode)
+ and not (env.demo or env.arcade)
):
Text(
bs.Lstr(
@@ -715,7 +717,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
position=(0, 230),
).autoretain()
- if bs.app.classic is not None and bs.app.classic.server is None:
+ if app.classic is not None and app.classic.server is None:
# If we're running in normal non-headless build, show this text
# because only host can continue the game.
adisp = plus.get_v1_account_display_string()
@@ -828,7 +830,7 @@ class CoopScoreScreen(bs.Activity[bs.Player, bs.Team]):
)
if plus.get_v1_account_state() != 'signed_in':
# We expect this only in kiosk mode; complain otherwise.
- if not (bs.app.demo_mode or bs.app.arcade_mode):
+ if not (env.demo or env.arcade):
logging.error('got not-signed-in at score-submit; unexpected')
bs.pushcall(bs.WeakCall(self._got_score_results, None))
else:
diff --git a/src/assets/ba_data/python/bascenev1lib/game/football.py b/src/assets/ba_data/python/bascenev1lib/game/football.py
index 5f3fd6f7..5a286a63 100644
--- a/src/assets/ba_data/python/bascenev1lib/game/football.py
+++ b/src/assets/ba_data/python/bascenev1lib/game/football.py
@@ -487,8 +487,8 @@ class FootballCoopGame(bs.CoopGameActivity[Player, Team]):
super().on_begin()
- # Show controls help in kiosk mode.
- if bs.app.demo_mode or bs.app.arcade_mode:
+ # Show controls help in demo or arcade mode.
+ if bs.app.env.demo or bs.app.env.arcade:
controlsguide.ControlsGuide(
delay=3.0, lifespan=10.0, bright=True
).autoretain()
diff --git a/src/assets/ba_data/python/bascenev1lib/game/onslaught.py b/src/assets/ba_data/python/bascenev1lib/game/onslaught.py
index f79ca59f..2e8f98e4 100644
--- a/src/assets/ba_data/python/bascenev1lib/game/onslaught.py
+++ b/src/assets/ba_data/python/bascenev1lib/game/onslaught.py
@@ -550,8 +550,9 @@ class OnslaughtGame(bs.CoopGameActivity[Player, Team]):
]
elif self._preset in {Preset.UBER, Preset.UBER_EASY}:
- # Show controls help in demo/arcade modes.
- if bs.app.demo_mode or bs.app.arcade_mode:
+ # Show controls help in demo or arcade modes.
+ env = bs.app.env
+ if env.demo or env.arcade:
ControlsGuide(
delay=3.0, lifespan=10.0, bright=True
).autoretain()
diff --git a/src/assets/ba_data/python/bascenev1lib/mainmenu.py b/src/assets/ba_data/python/bascenev1lib/mainmenu.py
index 94794cba..b697a6b1 100644
--- a/src/assets/ba_data/python/bascenev1lib/mainmenu.py
+++ b/src/assets/ba_data/python/bascenev1lib/mainmenu.py
@@ -171,7 +171,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
# Throw in test build info.
self.beta_info = self.beta_info_2 = None
- if env.test and not (app.demo_mode or app.arcade_mode):
+ if env.test and not (env.demo or env.arcade):
pos = (230, 35)
self.beta_info = bs.NodeActor(
bs.newnode(
@@ -292,10 +292,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
random.seed()
- if (
- not (app.demo_mode or app.arcade_mode)
- and not app.ui_v1.use_toolbars
- ):
+ if not (env.demo or env.arcade) and not app.ui_v1.use_toolbars:
self._news = NewsDisplay(self)
# Bring up the last place we were, or start at the main menu otherwise.
@@ -312,7 +309,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
# When coming back from a kiosk-mode game, jump to
# the kiosk start screen.
- if bs.app.demo_mode or bs.app.arcade_mode:
+ if env.demo or env.arcade:
# pylint: disable=cyclic-import
from bauiv1lib.kiosk import KioskWindow
@@ -399,6 +396,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
# pylint: disable=too-many-locals
# pylint: disable=too-many-statements
app = bs.app
+ env = app.env
assert app.classic is not None
# Update logo in case it changes.
@@ -442,7 +440,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
base_x = -270.0
x = base_x - 20.0
spacing = 85.0 * base_scale
- y_extra = 0.0 if (app.demo_mode or app.arcade_mode) else 0.0
+ y_extra = 0.0 if (env.demo or env.arcade) else 0.0
self._make_logo(
x - 110 + 50,
113 + y + 1.2 * y_extra,
@@ -507,7 +505,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]):
base_x = -170
x = base_x - 20
spacing = 55 * base_scale
- y_extra = 0 if (app.demo_mode or app.arcade_mode) else 0
+ y_extra = 0 if (env.demo or env.arcade) else 0
xv1 = x
delay1 = delay
for shadow in (True, False):
diff --git a/src/assets/ba_data/python/bauiv1lib/gather/publictab.py b/src/assets/ba_data/python/bauiv1lib/gather/publictab.py
index fa592372..0a9ef110 100644
--- a/src/assets/ba_data/python/bauiv1lib/gather/publictab.py
+++ b/src/assets/ba_data/python/bauiv1lib/gather/publictab.py
@@ -1169,7 +1169,7 @@ class PublicGatherTab(GatherTab):
plus.add_v1_account_transaction(
{
'type': 'PUBLIC_PARTY_QUERY',
- 'proto': bui.app.protocol_version,
+ 'proto': bs.protocol_version(),
'lang': bui.app.lang.language,
},
callback=bui.WeakCall(self._on_public_party_query_result),
diff --git a/src/assets/ba_data/python/bauiv1lib/kiosk.py b/src/assets/ba_data/python/bauiv1lib/kiosk.py
index 335ea69d..f3a03696 100644
--- a/src/assets/ba_data/python/bauiv1lib/kiosk.py
+++ b/src/assets/ba_data/python/bauiv1lib/kiosk.py
@@ -88,7 +88,7 @@ class KioskWindow(bui.Window):
resource='demoText',
fallback_resource='mainMenu.demoMenuText',
)
- if bui.app.demo_mode
+ if bui.app.env.demo
else 'ARCADE'
),
flatness=1.0,
@@ -332,7 +332,7 @@ class KioskWindow(bui.Window):
self._b4 = self._b5 = self._b6 = None
self._b7: bui.Widget | None
- if bui.app.arcade_mode:
+ if bui.app.env.arcade:
self._b7 = bui.buttonwidget(
parent=self._root_widget,
autoselect=True,
diff --git a/src/assets/ba_data/python/bauiv1lib/mainmenu.py b/src/assets/ba_data/python/bauiv1lib/mainmenu.py
index 1ec449f9..69f5406c 100644
--- a/src/assets/ba_data/python/bauiv1lib/mainmenu.py
+++ b/src/assets/ba_data/python/bauiv1lib/mainmenu.py
@@ -50,8 +50,8 @@ class MainMenuWindow(bui.Window):
)
# Grab this stuff in case it changes.
- self._is_demo = bui.app.demo_mode
- self._is_arcade = bui.app.arcade_mode
+ self._is_demo = bui.app.env.demo
+ self._is_arcade = bui.app.env.arcade
self._tdelay = 0.0
self._t_delay_inc = 0.02
@@ -617,7 +617,7 @@ class MainMenuWindow(bui.Window):
)
)
# In kiosk mode, provide a button to get back to the kiosk menu.
- if bui.app.demo_mode or bui.app.arcade_mode:
+ if bui.app.env.demo or bui.app.env.arcade:
h, v, scale = positions[self._p_index]
this_b_width = self._button_width * 0.4 * scale
demo_menu_delay = (
@@ -634,7 +634,7 @@ class MainMenuWindow(bui.Window):
textcolor=(0.7, 0.8, 0.7),
label=bui.Lstr(
resource='modeArcadeText'
- if bui.app.arcade_mode
+ if bui.app.env.arcade
else 'modeDemoText'
),
transition_delay=demo_menu_delay,
diff --git a/src/ballistica/base/assets/assets_server.cc b/src/ballistica/base/assets/assets_server.cc
index d918dd9d..447e8776 100644
--- a/src/ballistica/base/assets/assets_server.cc
+++ b/src/ballistica/base/assets/assets_server.cc
@@ -43,8 +43,8 @@ void AssetsServer::PushPendingPreload(Object::Ref* asset_ref_ptr) {
});
}
-void AssetsServer::PushBeginWriteReplayCall() {
- event_loop()->PushCall([this] {
+void AssetsServer::PushBeginWriteReplayCall(uint16_t protocol_version) {
+ event_loop()->PushCall([this, protocol_version] {
if (replays_broken_) {
return;
}
@@ -79,7 +79,7 @@ void AssetsServer::PushBeginWriteReplayCall() {
// NOTE: We always write replays in our host protocol version
// no matter what the client stream is.
uint32_t file_id = kBrpFileID;
- uint16_t version = kProtocolVersion;
+ uint16_t version = protocol_version;
if ((fwrite(&file_id, sizeof(file_id), 1, replay_out_file_) != 1)
|| (fwrite(&version, sizeof(version), 1, replay_out_file_) != 1)) {
fclose(replay_out_file_);
diff --git a/src/ballistica/base/assets/assets_server.h b/src/ballistica/base/assets/assets_server.h
index 4a8772ff..65853ecf 100644
--- a/src/ballistica/base/assets/assets_server.h
+++ b/src/ballistica/base/assets/assets_server.h
@@ -15,7 +15,7 @@ class AssetsServer {
public:
AssetsServer();
void OnMainThreadStartApp();
- void PushBeginWriteReplayCall();
+ void PushBeginWriteReplayCall(uint16_t protocol_version);
void PushEndWriteReplayCall();
void PushAddMessageToReplayCall(const std::vector& data);
void PushPendingPreload(Object::Ref* asset_ref_ptr);
diff --git a/src/ballistica/base/input/device/joystick_input.cc b/src/ballistica/base/input/device/joystick_input.cc
index 531e72a5..d7f348a5 100644
--- a/src/ballistica/base/input/device/joystick_input.cc
+++ b/src/ballistica/base/input/device/joystick_input.cc
@@ -1526,9 +1526,6 @@ auto JoystickInput::GetDeviceIdentifier() -> std::string {
}
auto JoystickInput::GetPartyButtonName() const -> std::string {
- if (g_buildconfig.iircade_build()) {
- return "X";
- }
return g_base->assets->CharStr(SpecialChar::kTopButton);
}
diff --git a/src/ballistica/base/python/class/python_class_env.cc b/src/ballistica/base/python/class/python_class_env.cc
index 4af103ee..666d50ff 100644
--- a/src/ballistica/base/python/class/python_class_env.cc
+++ b/src/ballistica/base/python/class/python_class_env.cc
@@ -145,12 +145,35 @@ void PythonClassEnv::SetupType(PyTypeObject* cls) {
"a non-standard environment, and that python-path modifications may\n"
"cause modules to be loaded from other locations.");
- envs["tv"] = BoolEntry_(g_core->platform->IsRunningOnTV(),
- "Whether the app is currently running on a TV.");
+ envs["tv"] =
+ BoolEntry_(g_core->platform->IsRunningOnTV(),
+ "Whether the app is targeting a TV-centric experience.");
envs["vr"] = BoolEntry_(g_core->IsVRMode(),
"Whether the app is currently running in VR.");
+ envs["arcade"] =
+ BoolEntry_(g_buildconfig.arcade_build(),
+ "Whether the app is targeting an arcade-centric experience.");
+
+ envs["headless"] =
+ BoolEntry_(g_buildconfig.headless_build(),
+ "Whether the app is running headlessly (without a gui).\n"
+ "\n"
+ "This is the opposite of `gui`.");
+
+ envs["gui"] = BoolEntry_(!g_buildconfig.headless_build(),
+ "Whether the app is running with a gui.\n"
+ "\n"
+ "This is the opposite of `headless`.");
+
+ envs["demo"] = BoolEntry_(g_buildconfig.demo_build(),
+ "Whether the app is targeting a demo experience.");
+
+ auto* envval = getenv("BA_RUNNING_WITH_DUMMY_MODULES");
+ envs["running_with_dummy_modules"] =
+ BoolEntry_(envval && !strcmp(envval, "1"), "(internal)");
+
bool first = true;
for (auto&& entry : envs) {
if (!first) {
diff --git a/src/ballistica/base/python/methods/python_methods_app.cc b/src/ballistica/base/python/methods/python_methods_app.cc
index 56628c81..e6f40764 100644
--- a/src/ballistica/base/python/methods/python_methods_app.cc
+++ b/src/ballistica/base/python/methods/python_methods_app.cc
@@ -756,8 +756,8 @@ static auto PyEnv(PyObject* self) -> PyObject* {
// "sO" // toolbar_test
"sO" // demo_mode
"sO" // arcade_mode
- "sO" // iircade_mode
- "si" // protocol_version
+ // "sO" // iircade_mode
+ // "si" // protocol_version
"sO" // headless_mode
"sO" // python_directory_app_site
"ss" // device_name
@@ -779,11 +779,10 @@ static auto PyEnv(PyObject* self) -> PyObject* {
"ui_scale", ui_scale,
"on_tv", g_core->platform->IsRunningOnTV() ? Py_True : Py_False,
"vr_mode", g_core->IsVRMode() ? Py_True : Py_False,
- // "toolbar_test", BA_TOOLBAR_TEST ? Py_True : Py_False,
"demo_mode", g_buildconfig.demo_build() ? Py_True : Py_False,
"arcade_mode", g_buildconfig.arcade_build() ? Py_True : Py_False,
- "iircade_mode", g_buildconfig.iircade_build() ? Py_True: Py_False,
- "protocol_version", kProtocolVersion,
+ // "iircade_mode", g_buildconfig.iircade_build() ? Py_True: Py_False,
+ // "protocol_version", kProtocolVersion,
"headless_mode", g_core->HeadlessMode() ? Py_True : Py_False,
"python_directory_app_site",
site_py_dir ? *PythonRef::FromString(*site_py_dir) : Py_None,
diff --git a/src/ballistica/base/support/app_config.cc b/src/ballistica/base/support/app_config.cc
index e52dc466..df3f85de 100644
--- a/src/ballistica/base/support/app_config.cc
+++ b/src/ballistica/base/support/app_config.cc
@@ -214,9 +214,8 @@ void AppConfig::SetupEntries() {
bool_entries_[BoolID::kKickIdlePlayers] =
BoolEntry("Kick Idle Players", false);
- // (default to internal keyboard on iircade; not elsewhere)
bool_entries_[BoolID::kAlwaysUseInternalKeyboard] =
- BoolEntry("Always Use Internal Keyboard", g_buildconfig.iircade_build());
+ BoolEntry("Always Use Internal Keyboard", false);
bool_entries_[BoolID::kShowFPS] = BoolEntry("Show FPS", false);
bool_entries_[BoolID::kShowPing] = BoolEntry("Show Ping", false);
bool_entries_[BoolID::kEnableTVBorder] =
diff --git a/src/ballistica/base/ui/ui.cc b/src/ballistica/base/ui/ui.cc
index 2f7c4f3c..53801a2f 100644
--- a/src/ballistica/base/ui/ui.cc
+++ b/src/ballistica/base/ui/ui.cc
@@ -36,9 +36,7 @@ UI::UI() {
}
if (!force_scale_) {
// Use automatic val.
- if (g_buildconfig.iircade_build()) { // NOLINT(bugprone-branch-clone)
- scale_ = UIScale::kMedium;
- } else if (g_core->IsVRMode() || g_core->platform->IsRunningOnTV()) {
+ if (g_core->IsVRMode() || g_core->platform->IsRunningOnTV()) {
// VR and tv builds always use medium.
scale_ = UIScale::kMedium;
} else {
diff --git a/src/ballistica/core/platform/core_platform.cc b/src/ballistica/core/platform/core_platform.cc
index 963045ff..52f59169 100644
--- a/src/ballistica/core/platform/core_platform.cc
+++ b/src/ballistica/core/platform/core_platform.cc
@@ -588,8 +588,6 @@ auto CorePlatform::GetLegacyUserAgentString() -> std::string {
subplatform = "DeMo";
} else if (g_buildconfig.arcade_build()) {
subplatform = "ArCd";
- } else if (g_buildconfig.iircade_build()) {
- subplatform = "iiRcd";
} else {
subplatform = "TstB";
}
@@ -699,9 +697,6 @@ auto CorePlatform::GetDeviceV1AccountID() -> std::string {
// Everything else is just considered a 'local' account, though we may
// give unique ids for unique builds..
- if (g_buildconfig.iircade_build()) {
- return "L-iRc" + GetLegacyDeviceUUID();
- }
return "L-" + GetLegacyDeviceUUID();
}
diff --git a/src/ballistica/scene_v1/python/methods/python_methods_scene.cc b/src/ballistica/scene_v1/python/methods/python_methods_scene.cc
index d16a3145..8015cff4 100644
--- a/src/ballistica/scene_v1/python/methods/python_methods_scene.cc
+++ b/src/ballistica/scene_v1/python/methods/python_methods_scene.cc
@@ -1718,6 +1718,24 @@ static PyMethodDef PyHandleAppIntentExecDef = {
"(internal)",
};
+// ----------------------- handle_app_intent_default ---------------------------
+
+static auto PyProtocolVersion(PyObject* self) -> PyObject* {
+ BA_PYTHON_TRY;
+ return PyLong_FromLong(kProtocolVersion);
+ BA_PYTHON_CATCH;
+}
+
+static PyMethodDef PyProtocolVersionDef = {
+ "protocol_version", // name
+ (PyCFunction)PyProtocolVersion, // method
+ METH_NOARGS, // flags
+
+ "protocol_version() -> int\n"
+ "\n"
+ "(internal)\n",
+};
+
// -----------------------------------------------------------------------------
auto PythonMethodsScene::GetMethods() -> std::vector {
@@ -1757,6 +1775,7 @@ auto PythonMethodsScene::GetMethods() -> std::vector {
PyAppModeDeactivateDef,
PyHandleAppIntentDefaultDef,
PyHandleAppIntentExecDef,
+ PyProtocolVersionDef,
};
}
diff --git a/src/ballistica/scene_v1/scene_v1.h b/src/ballistica/scene_v1/scene_v1.h
index 53211a32..f3f21011 100644
--- a/src/ballistica/scene_v1/scene_v1.h
+++ b/src/ballistica/scene_v1/scene_v1.h
@@ -25,6 +25,43 @@ class BaseFeatureSet;
namespace ballistica::scene_v1 {
+// Protocol version we host games with and write replays to.
+// This should be incremented whenever there are changes made to the
+// session-commands layer (new/removed/changed nodes, attrs, data files,
+// behavior, etc.)
+// Note that the packet/gamepacket/message layer can vary more organically based
+// on build-numbers of connected clients/servers since none of that data is
+// stored; this just needs to be observed for all the scene stuff that
+// goes into replays since a single stream can get played/replayed on different
+// builds (as long as they support that protocol version).
+const int kProtocolVersion = 33;
+
+// Oldest protocol version we can act as a client to.
+// This can generally be left as-is as long as only
+// new nodes/attrs/commands are added and existing
+// stuff is unchanged.
+const int kProtocolVersionMin = 24;
+
+// FIXME: We should separate out connection protocol from scene protocol. We
+// want to be able to watch really old replays if possible but being able to
+// connect to old clients is much less important (and slows progress).
+
+// Protocol additions:
+// 25: added a few new achievement graphics and new node attrs for displaying
+// stuff in front of the UI
+// 26: added penguin
+// 27: added templates for LOTS of characters
+// 28: added cyborg and enabled fallback sounds and textures
+// 29: added bunny and eggs
+// 30: added support for resource-strings in text-nodes and screen-messages
+// 31: added support for short-form resource-strings, time-display-node, and
+// string-to-string attr connections
+// 32: added json based player profiles message, added shield
+// alwaysShowHealthBar attr
+// 33: handshake/handshake-response now send json dicts instead of
+// just player-specs
+// 34: new image_node enums, data assets.
+
// Sim step size in milliseconds.
const int kGameStepMilliseconds = 8;
diff --git a/src/ballistica/scene_v1/support/client_session_net.cc b/src/ballistica/scene_v1/support/client_session_net.cc
index a8c40c4b..896fd4ec 100644
--- a/src/ballistica/scene_v1/support/client_session_net.cc
+++ b/src/ballistica/scene_v1/support/client_session_net.cc
@@ -17,7 +17,7 @@ ClientSessionNet::ClientSessionNet() {
"g_replay_open true at netclient start; shouldn't happen.");
}
assert(g_base->assets_server);
- g_base->assets_server->PushBeginWriteReplayCall();
+ g_base->assets_server->PushBeginWriteReplayCall(kProtocolVersion);
writing_replay_ = true;
g_core->replay_open = true;
}
diff --git a/src/ballistica/scene_v1/support/scene_v1_app_mode.cc b/src/ballistica/scene_v1/support/scene_v1_app_mode.cc
index 92b8e5b5..306df4da 100644
--- a/src/ballistica/scene_v1/support/scene_v1_app_mode.cc
+++ b/src/ballistica/scene_v1/support/scene_v1_app_mode.cc
@@ -556,11 +556,6 @@ void SceneV1AppMode::UpdateGameRoster() {
bool include_self = (connections()->GetConnectedClientCount() > 0);
- // Previously were gonna enable this with the UI revision.
- // #if BA_TOOLBAR_TEST
- // include_self = true;
- // #endif // BA_TOOLBAR_TEST
-
if (auto* hs = dynamic_cast(GetForegroundSession())) {
// Add our host-y self.
if (include_self) {
diff --git a/src/ballistica/scene_v1/support/session_stream.cc b/src/ballistica/scene_v1/support/session_stream.cc
index 9ff31248..8c26b8d0 100644
--- a/src/ballistica/scene_v1/support/session_stream.cc
+++ b/src/ballistica/scene_v1/support/session_stream.cc
@@ -32,7 +32,7 @@ SessionStream::SessionStream(HostSession* host_session, bool save_replay)
"g_replay_open true at replay start; shouldn't happen.");
}
assert(g_base->assets_server);
- g_base->assets_server->PushBeginWriteReplayCall();
+ g_base->assets_server->PushBeginWriteReplayCall(kProtocolVersion);
writing_replay_ = true;
g_core->replay_open = true;
}
diff --git a/src/ballistica/shared/ballistica.cc b/src/ballistica/shared/ballistica.cc
index e58f14ab..085df9a2 100644
--- a/src/ballistica/shared/ballistica.cc
+++ b/src/ballistica/shared/ballistica.cc
@@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
namespace ballistica {
// These are set automatically via script; don't modify them here.
-const int kEngineBuildNumber = 21272;
+const int kEngineBuildNumber = 21281;
const char* kEngineVersion = "1.7.27";
const int kEngineApiVersion = 8;
diff --git a/src/ballistica/shared/ballistica.h b/src/ballistica/shared/ballistica.h
index 7d9ef7b3..2944c6db 100644
--- a/src/ballistica/shared/ballistica.h
+++ b/src/ballistica/shared/ballistica.h
@@ -18,9 +18,6 @@
#include "ballistica/shared/foundation/macros.h"
#include "ballistica/shared/foundation/types.h"
-// BA 2.0 UI testing.
-#define BA_TOOLBAR_TEST 0
-
// There are one or two places where we include this from regular C
// or Objective-C code so want to gracefully handle that case.
#ifdef __cplusplus
@@ -31,43 +28,6 @@ extern const int kEngineBuildNumber;
extern const char* kEngineVersion;
extern const int kEngineApiVersion;
-// Protocol version we host games with and write replays to.
-// This should be incremented whenever there are changes made to the
-// session-commands layer (new/removed/changed nodes, attrs, data files,
-// behavior, etc.)
-// Note that the packet/gamepacket/message layer can vary more organically based
-// on build-numbers of connected clients/servers since none of that data is
-// stored; this just needs to be observed for all the scene stuff that
-// goes into replays since a single stream can get played/replayed on different
-// builds (as long as they support that protocol version).
-const int kProtocolVersion = 33;
-
-// Oldest protocol version we can act as a client to.
-// This can generally be left as-is as long as only
-// new nodes/attrs/commands are added and existing
-// stuff is unchanged.
-const int kProtocolVersionMin = 24;
-
-// FIXME: We should separate out connection protocol from scene protocol. We
-// want to be able to watch really old replays if possible but being able to
-// connect to old clients is much less important (and slows progress).
-
-// Protocol additions:
-// 25: added a few new achievement graphics and new node attrs for displaying
-// stuff in front of the UI
-// 26: added penguin
-// 27: added templates for LOTS of characters
-// 28: added cyborg and enabled fallback sounds and textures
-// 29: added bunny and eggs
-// 30: added support for resource-strings in text-nodes and screen-messages
-// 31: added support for short-form resource-strings, time-display-node, and
-// string-to-string attr connections
-// 32: added json based player profiles message, added shield
-// alwaysShowHealthBar attr
-// 33: handshake/handshake-response now send json dicts instead of
-// just player-specs
-// 34: new image_node enums, data assets.
-
const int kDefaultPort = 43210;
const float kTVBorder = 0.075f;
diff --git a/src/ballistica/shared/buildconfig/buildconfig_common.h b/src/ballistica/shared/buildconfig/buildconfig_common.h
index c3691395..cba14ac5 100644
--- a/src/ballistica/shared/buildconfig/buildconfig_common.h
+++ b/src/ballistica/shared/buildconfig/buildconfig_common.h
@@ -84,11 +84,6 @@ namespace ballistica {
#define BA_XCODE_BUILD 0
#endif
-// Is this our android iircade build?
-#ifndef BA_IIRCADE_BUILD
-#define BA_IIRCADE_BUILD 0
-#endif
-
// Does this build use SDL 1.x? (old mac only)
#ifndef BA_SDL_BUILD
#define BA_SDL_BUILD 0
@@ -268,7 +263,6 @@ class BuildConfig {
bool google_build() const { return EXPBOOL_(BA_GOOGLE_BUILD); }
bool demo_build() const { return EXPBOOL_(BA_DEMO_BUILD); }
bool arcade_build() const { return EXPBOOL_(BA_ARCADE_BUILD); }
- bool iircade_build() const { return EXPBOOL_(BA_IIRCADE_BUILD); }
bool contains_python_dist() const {
return EXPBOOL_(BA_CONTAINS_PYTHON_DIST);
}
diff --git a/src/ballistica/ui_v1/python/methods/python_methods_ui_v1.cc b/src/ballistica/ui_v1/python/methods/python_methods_ui_v1.cc
index 06c1c41f..f0147a40 100644
--- a/src/ballistica/ui_v1/python/methods/python_methods_ui_v1.cc
+++ b/src/ballistica/ui_v1/python/methods/python_methods_ui_v1.cc
@@ -2848,7 +2848,7 @@ static PyMethodDef PyIsPartyIconVisibleDef = {
static auto PyToolbarTest(PyObject* self) -> PyObject* {
BA_PYTHON_TRY;
- if (BA_TOOLBAR_TEST) {
+ if (BA_UI_V1_TOOLBAR_TEST) {
Py_RETURN_TRUE;
} else {
Py_RETURN_FALSE;
diff --git a/src/ballistica/ui_v1/support/root_ui.cc b/src/ballistica/ui_v1/support/root_ui.cc
index 55ebb382..cd82b389 100644
--- a/src/ballistica/ui_v1/support/root_ui.cc
+++ b/src/ballistica/ui_v1/support/root_ui.cc
@@ -13,7 +13,7 @@
namespace ballistica::ui_v1 {
// Phasing these out; replaced by buttons in our rootwidget.
-#define DO_OLD_MENU_PARTY_BUTTONS (!BA_TOOLBAR_TEST)
+#define DO_OLD_MENU_PARTY_BUTTONS (!BA_UI_V1_TOOLBAR_TEST)
const float kMenuButtonSize = 40.0f;
const float kMenuButtonDrawDepth = -0.07f;
diff --git a/src/ballistica/ui_v1/ui_v1.h b/src/ballistica/ui_v1/ui_v1.h
index 448fd3fb..f2607e4a 100644
--- a/src/ballistica/ui_v1/ui_v1.h
+++ b/src/ballistica/ui_v1/ui_v1.h
@@ -12,6 +12,9 @@
// It predeclares our feature-set's various types and globals and other
// bits.
+// BA 2.0 UI testing.
+#define BA_UI_V1_TOOLBAR_TEST 0
+
// Predeclared types from other feature sets that we use.
namespace ballistica::core {
class CoreFeatureSet;
diff --git a/src/ballistica/ui_v1/widget/root_widget.cc b/src/ballistica/ui_v1/widget/root_widget.cc
index 92722782..12233ad3 100644
--- a/src/ballistica/ui_v1/widget/root_widget.cc
+++ b/src/ballistica/ui_v1/widget/root_widget.cc
@@ -313,7 +313,7 @@ void RootWidget::AddMeter(float h_align, float x, int type, float r, float g,
#pragma clang diagnostic pop
void RootWidget::Setup() {
- if (!explicit_bool(BA_TOOLBAR_TEST)) {
+ if (!explicit_bool(BA_UI_V1_TOOLBAR_TEST)) {
return;
}
@@ -1096,7 +1096,7 @@ void RootWidget::SetScreenWidget(StackWidget* w) {
void RootWidget::SetOverlayWidget(StackWidget* w) {
// this needs to happen after our buttons and things get added..
- if (explicit_bool(BA_TOOLBAR_TEST)) {
+ if (explicit_bool(BA_UI_V1_TOOLBAR_TEST)) {
assert(!buttons_.empty());
}
AddWidget(w);