Made game settings type safe

This commit is contained in:
Eric Froemling 2020-06-02 18:46:38 -07:00
parent 546ad7848f
commit 5b4282eb11
33 changed files with 764 additions and 423 deletions

View File

@ -4132,16 +4132,16 @@
"assets/build/windows/x64/python.exe": "https://files.ballistica.net/cache/ba1/25/a7/dc87c1be41605eb6fefd0145144c",
"assets/build/windows/x64/python37.dll": "https://files.ballistica.net/cache/ba1/b9/e4/d912f56e42e9991bcbb4c804cfcb",
"assets/build/windows/x64/pythonw.exe": "https://files.ballistica.net/cache/ba1/6c/bb/b6f52c306aa4e88061510e96cefe",
"build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2e/aa/9bcdf166975aa5295669df48f641",
"build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d8/44/091ec27299abfb3e4a12efbb4016",
"build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/1b/2f/99bcfa67fb5a77d9d80883fcc9a4",
"build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/f6/f5/fbd4514b7ca4663f917ee848acc5",
"build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/8b/3c/7f4895731a58ab99c8deb2caa563",
"build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ba/d5/5a51c250695ce84b0cf2d59ef447",
"build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/44/e9/33f406d3ff1a7a5ec5c0d7f185e6",
"build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/53/55/1f3e23b7c6e975056854005de9aa",
"build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/c5/5d/56272619667b1fcd87b759d8688d",
"build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/8b/d0/24e71e25ac40fbd513e21c318ba4",
"build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/8a/6a/ba53af1a84abfa764213f1791ea2",
"build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/d8/7b/b32727ec4d7e899d54ebe83e1203"
"build/prefab/linux-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1f/1d/c3e431b8c9116fb76eb10c7c3351",
"build/prefab/linux-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/66/b8/9cb66184745ef1d783af3f7d3f22",
"build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/52/e8/4826278e2030d629a682a8de070f",
"build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/a5/8a/9e07236256d006f0357d5d1aa887",
"build/prefab/mac-server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/81/38/985294f68973344e2f012fe93c45",
"build/prefab/mac-server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d3/57/2cdf16147cdd25263ba76aa40198",
"build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/a7/ec/1d64c0c31d58ef530b6894fabf2a",
"build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/4c/ea/c136ba4360d210842915c2f6c55e",
"build/prefab/windows-server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/35/06/d5ae11c90f89d1c10ca62a2b2f66",
"build/prefab/windows-server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/a1/e9/960e434759c45b623fba34725e64",
"build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/dd/d0/f85582938a539d2d677d3e36b61b",
"build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/8d/e9/3685ecf7b07f3e3568867da5536f"
}

View File

@ -746,6 +746,7 @@
<w>gameplayer</w>
<w>gameport</w>
<w>gameresults</w>
<w>gamesettings</w>
<w>gameteam</w>
<w>gametype</w>
<w>gametypes</w>
@ -783,6 +784,7 @@
<w>getpt</w>
<w>getremote</w>
<w>getscanresults</w>
<w>getscoreconfig</w>
<w>getsession</w>
<w>getsockname</w>
<w>getsound</w>
@ -1444,6 +1446,7 @@
<w>prevstate</w>
<w>priceraw</w>
<w>printcolors</w>
<w>printf</w>
<w>printnodes</w>
<w>printobjects</w>
<w>printpaths</w>
@ -1640,6 +1643,7 @@
<w>sched</w>
<w>sclx</w>
<w>scly</w>
<w>scoreconfig</w>
<w>scorescreen</w>
<w>scoreteam</w>
<w>scoretxt</w>

View File

@ -24,6 +24,7 @@
"ba_data/python/ba/__pycache__/_freeforallsession.cpython-37.opt-1.pyc",
"ba_data/python/ba/__pycache__/_gameactivity.cpython-37.opt-1.pyc",
"ba_data/python/ba/__pycache__/_gameresults.cpython-37.opt-1.pyc",
"ba_data/python/ba/__pycache__/_gamesettings.cpython-37.opt-1.pyc",
"ba_data/python/ba/__pycache__/_gameutils.cpython-37.opt-1.pyc",
"ba_data/python/ba/__pycache__/_general.cpython-37.opt-1.pyc",
"ba_data/python/ba/__pycache__/_hooks.cpython-37.opt-1.pyc",
@ -80,6 +81,7 @@
"ba_data/python/ba/_freeforallsession.py",
"ba_data/python/ba/_gameactivity.py",
"ba_data/python/ba/_gameresults.py",
"ba_data/python/ba/_gamesettings.py",
"ba_data/python/ba/_gameutils.py",
"ba_data/python/ba/_general.py",
"ba_data/python/ba/_hooks.py",

View File

@ -166,6 +166,7 @@ SCRIPT_TARGETS_PY_PUBLIC = \
build/ba_data/python/ba/_freeforallsession.py \
build/ba_data/python/ba/_gameactivity.py \
build/ba_data/python/ba/_gameresults.py \
build/ba_data/python/ba/_gamesettings.py \
build/ba_data/python/ba/_gameutils.py \
build/ba_data/python/ba/_general.py \
build/ba_data/python/ba/_hooks.py \
@ -396,6 +397,7 @@ SCRIPT_TARGETS_PYC_PUBLIC = \
build/ba_data/python/ba/__pycache__/_freeforallsession.cpython-37.opt-1.pyc \
build/ba_data/python/ba/__pycache__/_gameactivity.cpython-37.opt-1.pyc \
build/ba_data/python/ba/__pycache__/_gameresults.cpython-37.opt-1.pyc \
build/ba_data/python/ba/__pycache__/_gamesettings.cpython-37.opt-1.pyc \
build/ba_data/python/ba/__pycache__/_gameutils.cpython-37.opt-1.pyc \
build/ba_data/python/ba/__pycache__/_general.cpython-37.opt-1.pyc \
build/ba_data/python/ba/__pycache__/_hooks.cpython-37.opt-1.pyc \
@ -734,6 +736,11 @@ build/ba_data/python/ba/__pycache__/_gameresults.cpython-37.opt-1.pyc: \
@echo Compiling script: $^
@rm -rf $@ && $(TOOLS_DIR)/snippets compile_python_files $^ && chmod 444 $@
build/ba_data/python/ba/__pycache__/_gamesettings.cpython-37.opt-1.pyc: \
build/ba_data/python/ba/_gamesettings.py
@echo Compiling script: $^
@rm -rf $@ && $(TOOLS_DIR)/snippets compile_python_files $^ && chmod 444 $@
build/ba_data/python/ba/__pycache__/_gameutils.cpython-37.opt-1.pyc: \
build/ba_data/python/ba/_gameutils.py
@echo Compiling script: $^

View File

@ -34,7 +34,7 @@ NOTE: This file was autogenerated by gendummymodule; do not edit by hand.
"""
# (hash we can use to see if this file is out of date)
# SOURCES_HASH=78832523659898286100096175148597852751
# SOURCES_HASH=48988468250135652281791058794704714718
# I'm sorry Pylint. I know this file saddens you. Be strong.
# pylint: disable=useless-suppression

View File

@ -56,11 +56,14 @@ from ba._error import (
from ba._freeforallsession import FreeForAllSession
from ba._gameactivity import GameActivity
from ba._gameresults import TeamGameResults
from ba._gamesettings import (Setting, IntSetting, FloatSetting, ChoiceSetting,
BoolSetting, IntChoiceSetting,
FloatChoiceSetting)
from ba._lang import Lstr, setlanguage, get_valid_languages
from ba._map import Map, getmaps
from ba._session import Session
from ba._servermode import ServerController
from ba._score import ScoreType, ScoreInfo
from ba._score import ScoreType, ScoreConfig
from ba._stats import PlayerScoredMessage, PlayerRecord, Stats
from ba._team import SessionTeam, Team, EmptyTeam
from ba._teamgame import TeamGameActivity

View File

@ -36,9 +36,8 @@ class AppDelegate:
def create_default_game_settings_ui(
self, gameclass: Type[ba.GameActivity],
sessionclass: Type[ba.Session], config: Optional[Dict[str, Any]],
completion_call: Callable[[Optional[Dict[str, Any]]],
None]) -> None:
sessionclass: Type[ba.Session], config: Optional[dict],
completion_call: Callable[[Optional[dict]], None]) -> None:
"""Launch a UI to configure the given game config.
It should manipulate the contents of config and call completion_call

View File

@ -121,7 +121,7 @@ class CoopGameActivity(GameActivity[PlayerType, TeamType]):
animate(txt.node, 'scale', {1.0: 0.0, 1.1: 0.7, 1.2: 0.6})
break
# FIXME: this is now redundant with activityutils.get_score_info();
# FIXME: this is now redundant with activityutils.getscoreconfig();
# need to kill this.
def get_score_type(self) -> str:
"""

View File

@ -121,10 +121,10 @@ class CoopSession(Session):
settings = level.get_settings()
# Make sure all settings the game expects are present.
neededsettings = gametype.get_game_settings(type(self))
for settingname, setting in neededsettings:
if settingname not in settings:
settings[settingname] = setting['default']
neededsettings = gametype.get_available_settings(type(self))
for setting in neededsettings:
if setting.name not in settings:
settings[setting.name] = setting.default
newactivity = _ba.new_activity(gametype, settings)
assert isinstance(newactivity, GameActivity)
@ -144,10 +144,10 @@ class CoopSession(Session):
settings = nextlevel.get_settings()
# Make sure all settings the game expects are present.
neededsettings = gametype.get_game_settings(type(self))
for settingname, setting in neededsettings:
if settingname not in settings:
settings[settingname] = setting['default']
neededsettings = gametype.get_available_settings(type(self))
for setting in neededsettings:
if setting.name not in settings:
settings[setting.name] = setting.default
# We wanna be in the activity's context while taking it down.
newactivity = _ba.new_activity(gametype, settings)

View File

@ -27,7 +27,7 @@ import random
from typing import TYPE_CHECKING, TypeVar
from ba._activity import Activity
from ba._score import ScoreInfo
from ba._score import ScoreConfig
from ba._lang import Lstr
from ba._messages import PlayerDiedMessage, StandMessage
from ba._error import NotFoundError, print_error, print_exception
@ -62,11 +62,11 @@ class GameActivity(Activity[PlayerType, TeamType]):
# Default get_description() will return this if not None.
description: Optional[str] = None
# Default get_game_settings() will return this if not None.
game_settings: Optional[List[Tuple[str, Dict[str, Any]]]] = None
# Default get_available_settings() will return this if not None.
available_settings: Optional[List[ba.Setting]] = None
# Default get_score_info() will return this if not None.
score_info: Optional[ba.ScoreInfo] = None
# Default getscoreconfig() will return this if not None.
scoreconfig: Optional[ba.ScoreConfig] = None
# Override some defaults.
allow_pausing = True
@ -83,8 +83,8 @@ class GameActivity(Activity[PlayerType, TeamType]):
def create_settings_ui(
cls,
sessionclass: Type[ba.Session],
settings: Optional[Dict[str, Any]],
completion_call: Callable[[Optional[Dict[str, Any]]], None],
settings: Optional[dict],
completion_call: Callable[[Optional[dict]], None],
) -> None:
"""Launch an in-game UI to configure settings for a game type.
@ -93,11 +93,11 @@ class GameActivity(Activity[PlayerType, TeamType]):
'config' should be an existing config dict (specifies 'edit' ui mode)
or None (specifies 'add' ui mode).
'completion_call' will be called with a filled-out config dict on
'completion_call' will be called with a filled-out settings dict on
success or None on cancel.
Generally subclasses don't need to override this; if they override
ba.GameActivity.get_game_settings() and
ba.GameActivity.get_available_settings() and
ba.GameActivity.get_supported_maps() they can just rely on
the default implementation here which calls those methods.
"""
@ -107,9 +107,10 @@ class GameActivity(Activity[PlayerType, TeamType]):
completion_call)
@classmethod
def get_score_info(cls) -> ba.ScoreInfo:
def getscoreconfig(cls) -> ba.ScoreConfig:
"""Return info about game scoring setup; can be overridden by games."""
return cls.score_info if cls.score_info is not None else ScoreInfo()
return cls.scoreconfig if cls.scoreconfig is not None else ScoreConfig(
)
@classmethod
def getname(cls) -> str:
@ -129,7 +130,7 @@ class GameActivity(Activity[PlayerType, TeamType]):
# A few substitutions for 'Epic', 'Solo' etc. modes.
# FIXME: Should provide a way for game types to define filters of
# their own.
# their own and should not rely on hard-coded settings names.
if settings is not None:
if 'Solo Mode' in settings and settings['Solo Mode']:
name = Lstr(resource='soloNameFilterText',
@ -167,9 +168,8 @@ class GameActivity(Activity[PlayerType, TeamType]):
return Lstr(translate=('gameDescriptions', description))
@classmethod
def get_game_settings(
cls,
sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]:
def get_available_settings(
cls, sessiontype: Type[ba.Session]) -> List[ba.Setting]:
"""
Called by the default ba.GameActivity.create_settings_ui()
implementation; should return a dict of config options to be presented
@ -191,9 +191,9 @@ class GameActivity(Activity[PlayerType, TeamType]):
'increment': Value increment for int/float settings.
# example get_game_settings() for a capture-the-flag game:
# example get_available_settings() for a capture-the-flag game:
@classmethod
def get_game_settings(cls, sessiontype):
def get_available_settings(cls, sessiontype):
return [("Score to Win", {
'default': 3,
'min_value': 1
@ -228,7 +228,7 @@ class GameActivity(Activity[PlayerType, TeamType]):
})]
"""
del sessiontype # Unused arg.
return [] if cls.game_settings is None else cls.game_settings
return [] if cls.available_settings is None else cls.available_settings
@classmethod
def get_supported_maps(cls, sessiontype: Type[ba.Session]) -> List[str]:

View File

@ -68,12 +68,12 @@ class TeamGameResults:
raise RuntimeError('Game set twice for TeamGameResults.')
self._game_set = True
self._sessionteams = [weakref.ref(team) for team in game.teams]
score_info = game.get_score_info()
scoreconfig = game.getscoreconfig()
self._playerinfos = copy.deepcopy(game.initialplayerinfos)
self._lower_is_better = score_info.lower_is_better
self._score_label = score_info.label
self._none_is_winner = score_info.none_is_winner
self._scoretype = score_info.scoretype
self._lower_is_better = scoreconfig.lower_is_better
self._score_label = scoreconfig.label
self._none_is_winner = scoreconfig.none_is_winner
self._scoretype = scoreconfig.scoretype
def set_team_score(self, team: ba.Team, score: Optional[int]) -> None:
"""Set the score for a given ba.Team.

View File

@ -0,0 +1,102 @@
# Copyright (c) 2011-2020 Eric Froemling
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# -----------------------------------------------------------------------------
"""Functionality for user-controllable settings."""
from __future__ import annotations
from typing import TYPE_CHECKING
from dataclasses import dataclass
if TYPE_CHECKING:
from typing import Any, List, Tuple
@dataclass
class Setting:
"""Defines a user-controllable setting for a game or other entity.
Category: Gameplay Classes
"""
name: str
default: Any
@dataclass
class BoolSetting(Setting):
"""A boolean game setting.
Category: Settings Classes
"""
default: bool
@dataclass
class IntSetting(Setting):
"""An integer game setting.
Category: Settings Classes
"""
default: int
min_value: int = 0
max_value: int = 9999
increment: int = 1
@dataclass
class FloatSetting(Setting):
"""A floating point game setting.
Category: Settings Classes
"""
default: float
min_value: float = 0.0
max_value: float = 9999.0
increment: float = 1.0
@dataclass
class ChoiceSetting(Setting):
"""A setting with multiple choices.
Category: Settings Classes
"""
choices: List[Tuple[str, Any]]
@dataclass
class IntChoiceSetting(ChoiceSetting):
"""An int setting with multiple choices.
Category: Settings Classes
"""
default: int
choices: List[Tuple[str, int]]
@dataclass
class FloatChoiceSetting(ChoiceSetting):
"""A float setting with multiple choices.
Category: Settings Classes
"""
default: float
choices: List[Tuple[str, float]]

View File

@ -144,7 +144,7 @@ class Level:
can be changed to separate its new high score lists/etc. from the old.
"""
if self._score_version_string is None:
scorever = self._gametype.get_score_info().version
scorever = self._gametype.getscoreconfig().version
if scorever != '':
scorever = ' ' + scorever
self._score_version_string = scorever

View File

@ -151,11 +151,10 @@ def filter_playlist(playlist: PlaylistType,
entry['is_unowned_game'] = True
# Make sure all settings the game defines are present.
neededsettings = gameclass.get_game_settings(sessiontype)
for setting_name, setting in neededsettings:
if (setting_name not in entry['settings']
and 'default' in setting):
entry['settings'][setting_name] = setting['default']
neededsettings = gameclass.get_available_settings(sessiontype)
for setting in neededsettings:
if setting.name not in entry['settings']:
entry['settings'][setting.name] = setting.default
goodlist.append(entry)
except ImportError as exc:
print(f'Import failed while scanning playlist: {exc}')

View File

@ -42,8 +42,8 @@ class ScoreType(Enum):
@dataclass
class ScoreInfo:
"""Info about a game's scoring setup.
class ScoreConfig:
"""Settings for how a game handles scores.
Category: Gameplay Classes

View File

@ -34,9 +34,8 @@ class AppDelegate(ba.AppDelegate):
def create_default_game_settings_ui(
self, gameclass: Type[ba.GameActivity],
sessionclass: Type[ba.Session], config: Optional[Dict[str, Any]],
completion_call: Callable[[Optional[Dict[str, Any]]],
Any]) -> None:
sessionclass: Type[ba.Session], config: Optional[dict],
completion_call: Callable[[Optional[dict]], Any]) -> None:
"""(internal)"""
# Replace the main window once we come up successfully.

View File

@ -57,25 +57,36 @@ class AssaultGame(ba.TeamGameActivity[Player, Team]):
name = 'Assault'
description = 'Reach the enemy flag to score.'
game_settings = [
('Score to Win', {
'min_value': 1,
'default': 3
}),
('Time Limit', {
'choices': [('None', 0), ('1 Minute', 60), ('2 Minutes', 120),
('5 Minutes', 300), ('10 Minutes', 600),
('20 Minutes', 1200)],
'default': 0
}),
('Respawn Times', {
'choices': [('Shorter', 0.25), ('Short', 0.5), ('Normal', 1.0),
('Long', 2.0), ('Longer', 4.0)],
'default': 1.0
}),
('Epic Mode', {
'default': False
}),
available_settings = [
ba.IntSetting(
'Score to Win',
min_value=1,
default=3,
),
ba.IntChoiceSetting(
'Time Limit',
choices=[
('None', 0),
('1 Minute', 60),
('2 Minutes', 120),
('5 Minutes', 300),
('10 Minutes', 600),
('20 Minutes', 1200),
],
default=0,
),
ba.FloatChoiceSetting(
'Respawn Times',
choices=[
('Shorter', 0.25),
('Short', 0.5),
('Normal', 1.0),
('Long', 2.0),
('Longer', 4.0),
],
default=1.0,
),
ba.BoolSetting('Epic Mode', default=False),
]
@classmethod

View File

@ -114,35 +114,44 @@ class CaptureTheFlagGame(ba.TeamGameActivity[Player, Team]):
name = 'Capture the Flag'
description = 'Return the enemy flag to score.'
game_settings = [
('Score to Win', {
'min_value': 1,
'default': 3
}),
('Flag Touch Return Time', {
'min_value': 0,
'default': 0,
'increment': 1
}),
('Flag Idle Return Time', {
'min_value': 5,
'default': 30,
'increment': 5
}),
('Time Limit', {
'choices': [('None', 0), ('1 Minute', 60), ('2 Minutes', 120),
('5 Minutes', 300), ('10 Minutes', 600),
('20 Minutes', 1200)],
'default': 0
}),
('Respawn Times', {
'choices': [('Shorter', 0.25), ('Short', 0.5), ('Normal', 1.0),
('Long', 2.0), ('Longer', 4.0)],
'default': 1.0
}),
('Epic Mode', {
'default': False
}),
available_settings = [
ba.IntSetting('Score to Win', min_value=1, default=3),
ba.IntSetting(
'Flag Touch Return Time',
min_value=0,
default=0,
increment=1,
),
ba.IntSetting(
'Flag Idle Return Time',
min_value=5,
default=30,
increment=5,
),
ba.IntChoiceSetting(
'Time Limit',
choices=[
('None', 0),
('1 Minute', 60),
('2 Minutes', 120),
('5 Minutes', 300),
('10 Minutes', 600),
('20 Minutes', 1200),
],
default=0,
),
ba.FloatChoiceSetting(
'Respawn Times',
choices=[
('Shorter', 0.25),
('Short', 0.5),
('Normal', 1.0),
('Long', 2.0),
('Longer', 4.0),
],
default=1.0,
),
ba.BoolSetting('Epic Mode', default=False),
]
@classmethod

View File

@ -62,34 +62,41 @@ class ChosenOneGame(ba.TeamGameActivity[Player, Team]):
name = 'Chosen One'
description = ('Be the chosen one for a length of time to win.\n'
'Kill the chosen one to become it.')
game_settings = [
('Chosen One Time', {
'min_value': 10,
'default': 30,
'increment': 10
}),
('Chosen One Gets Gloves', {
'default': True
}),
('Chosen One Gets Shield', {
'default': False
}),
('Time Limit', {
'choices': [('None', 0), ('1 Minute', 60), ('2 Minutes', 120),
('5 Minutes', 300), ('10 Minutes', 600),
('20 Minutes', 1200)],
'default': 0
}),
('Respawn Times', {
'choices': [('Shorter', 0.25), ('Short', 0.5), ('Normal', 1.0),
('Long', 2.0), ('Longer', 4.0)],
'default': 1.0
}),
('Epic Mode', {
'default': False
}),
available_settings = [
ba.IntSetting(
'Chosen One Time',
min_value=10,
default=30,
increment=10,
),
ba.BoolSetting('Chosen One Gets Gloves', default=True),
ba.BoolSetting('Chosen One Gets Shield', default=False),
ba.IntChoiceSetting(
'Time Limit',
choices=[
('None', 0),
('1 Minute', 60),
('2 Minutes', 120),
('5 Minutes', 300),
('10 Minutes', 600),
('20 Minutes', 1200),
],
default=0,
),
ba.FloatChoiceSetting(
'Respawn Times',
choices=[
('Shorter', 0.25),
('Short', 0.5),
('Normal', 1.0),
('Long', 2.0),
('Longer', 4.0),
],
default=1.0,
),
ba.BoolSetting('Epic Mode', default=False),
]
score_info = ba.ScoreInfo(label='Time Held')
scoreconfig = ba.ScoreConfig(label='Time Held')
@classmethod
def get_supported_maps(cls, sessiontype: Type[ba.Session]) -> List[str]:

View File

@ -95,21 +95,31 @@ class ConquestGame(ba.TeamGameActivity[Player, Team]):
name = 'Conquest'
description = 'Secure all flags on the map to win.'
game_settings = [
('Time Limit', {
'choices': [('None', 0), ('1 Minute', 60), ('2 Minutes', 120),
('5 Minutes', 300), ('10 Minutes', 600),
('20 Minutes', 1200)],
'default': 0
}),
('Respawn Times', {
'choices': [('Shorter', 0.25), ('Short', 0.5), ('Normal', 1.0),
('Long', 2.0), ('Longer', 4.0)],
'default': 1.0
}),
('Epic Mode', {
'default': False
}),
available_settings = [
ba.IntChoiceSetting(
'Time Limit',
choices=[
('None', 0),
('1 Minute', 60),
('2 Minutes', 120),
('5 Minutes', 300),
('10 Minutes', 600),
('20 Minutes', 1200),
],
default=0,
),
ba.FloatChoiceSetting(
'Respawn Times',
choices=[
('Shorter', 0.25),
('Short', 0.5),
('Normal', 1.0),
('Long', 2.0),
('Longer', 4.0),
],
default=1.0,
),
ba.BoolSetting('Epic Mode', default=False),
]
@classmethod

View File

@ -57,29 +57,39 @@ class DeathMatchGame(ba.TeamGameActivity[Player, Team]):
announce_player_deaths = True
@classmethod
def get_game_settings(
cls,
sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]:
settings: List[Tuple[str, Dict[str, Any]]] = [
('Kills to Win Per Player', {
'min_value': 1,
'default': 5,
'increment': 1
}),
('Time Limit', {
'choices': [('None', 0), ('1 Minute', 60), ('2 Minutes', 120),
('5 Minutes', 300), ('10 Minutes', 600),
('20 Minutes', 1200)],
'default': 0
}),
('Respawn Times', {
'choices': [('Shorter', 0.25), ('Short', 0.5), ('Normal', 1.0),
('Long', 2.0), ('Longer', 4.0)],
'default': 1.0
}),
('Epic Mode', {
'default': False
}),
def get_available_settings(
cls, sessiontype: Type[ba.Session]) -> List[ba.Setting]:
settings = [
ba.IntSetting(
'Kills to Win Per Player',
min_value=1,
default=5,
increment=1,
),
ba.IntChoiceSetting(
'Time Limit',
choices=[
('None', 0),
('1 Minute', 60),
('2 Minutes', 120),
('5 Minutes', 300),
('10 Minutes', 600),
('20 Minutes', 1200),
],
default=0,
),
ba.FloatChoiceSetting(
'Respawn Times',
choices=[
('Shorter', 0.25),
('Short', 0.5),
('Normal', 1.0),
('Long', 2.0),
('Longer', 4.0),
],
default=1.0,
),
ba.BoolSetting('Epic Mode', default=False),
]
# In teams mode, a suicide gives a point to the other team, but in
@ -88,7 +98,8 @@ class DeathMatchGame(ba.TeamGameActivity[Player, Team]):
# be able to go negative. (to avoid a strategy of just
# suiciding until you get a good drop)
if issubclass(sessiontype, ba.FreeForAllSession):
settings.append(('Allow Negative Scores', {'default': False}))
settings.append(
ba.BoolSetting('Allow Negative Scores', default=False))
return settings
@ -150,7 +161,7 @@ class DeathMatchGame(ba.TeamGameActivity[Player, Team]):
killer = msg.getkillerplayer(Player)
if killer is None:
return
return None
# Handle team-kills.
if killer.team is player.team:
@ -191,7 +202,8 @@ class DeathMatchGame(ba.TeamGameActivity[Player, Team]):
ba.timer(0.5, self.end_game)
else:
super().handlemessage(msg)
return super().handlemessage(msg)
return None
def _update_scoreboard(self) -> None:
for team in self.teams:

View File

@ -62,8 +62,8 @@ class EasterEggHuntGame(ba.TeamGameActivity[Player, Team]):
name = 'Easter Egg Hunt'
description = 'Gather eggs!'
game_settings = [('Pro Mode', {'default': False})]
score_info = ba.ScoreInfo(label='Score', scoretype=ba.ScoreType.POINTS)
available_settings = [ba.BoolSetting('Pro Mode', default=False)]
scoreconfig = ba.ScoreConfig(label='Score', scoretype=ba.ScoreType.POINTS)
# We're currently hard-coded for one map.
@classmethod

View File

@ -191,41 +191,52 @@ class EliminationGame(ba.TeamGameActivity[Player, Team]):
name = 'Elimination'
description = 'Last remaining alive wins.'
score_info = ba.ScoreInfo(label='Survived',
scoretype=ba.ScoreType.SECONDS,
none_is_winner=True)
scoreconfig = ba.ScoreConfig(label='Survived',
scoretype=ba.ScoreType.SECONDS,
none_is_winner=True)
# Show messages when players die since it's meaningful here.
announce_player_deaths = True
@classmethod
def get_game_settings(
cls,
sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]:
settings: List[Tuple[str, Dict[str, Any]]] = [
('Lives Per Player', {
'default': 1,
'min_value': 1,
'max_value': 10,
'increment': 1
}),
('Time Limit', {
'choices': [('None', 0), ('1 Minute', 60), ('2 Minutes', 120),
('5 Minutes', 300), ('10 Minutes', 600),
('20 Minutes', 1200)],
'default': 0
}),
('Respawn Times', {
'choices': [('Shorter', 0.25), ('Short', 0.5), ('Normal', 1.0),
('Long', 2.0), ('Longer', 4.0)],
'default': 1.0
}),
('Epic Mode', {
'default': False
}),
def get_available_settings(
cls, sessiontype: Type[ba.Session]) -> List[ba.Setting]:
settings = [
ba.IntSetting(
'Lives Per Player',
default=1,
min_value=1,
max_value=10,
increment=1,
),
ba.IntChoiceSetting(
'Time Limit',
choices=[
('None', 0),
('1 Minute', 60),
('2 Minutes', 120),
('5 Minutes', 300),
('10 Minutes', 600),
('20 Minutes', 1200),
],
default=0,
),
ba.FloatChoiceSetting(
'Respawn Times',
choices=[
('Shorter', 0.25),
('Short', 0.5),
('Normal', 1.0),
('Long', 2.0),
('Longer', 4.0),
],
default=1.0,
),
ba.BoolSetting('Epic Mode', default=False),
]
if issubclass(sessiontype, ba.DualTeamSession):
settings.append(('Solo Mode', {'default': False}))
settings.append(('Balance Total Lives', {'default': False}))
settings.append(ba.BoolSetting('Solo Mode', default=False))
settings.append(
ba.BoolSetting('Balance Total Lives', default=False))
return settings
@classmethod

View File

@ -94,23 +94,36 @@ class FootballTeamGame(ba.TeamGameActivity[Player, Team]):
name = 'Football'
description = 'Get the flag to the enemy end zone.'
game_settings = [
('Score to Win', {
'min_value': 7,
'default': 21,
'increment': 7
}),
('Time Limit', {
'choices': [('None', 0), ('1 Minute', 60), ('2 Minutes', 120),
('5 Minutes', 300), ('10 Minutes', 600),
('20 Minutes', 1200)],
'default': 0
}),
('Respawn Times', {
'choices': [('Shorter', 0.25), ('Short', 0.5), ('Normal', 1.0),
('Long', 2.0), ('Longer', 4.0)],
'default': 1.0
}),
available_settings = [
ba.IntSetting(
'Score to Win',
min_value=7,
default=21,
increment=7,
),
ba.IntChoiceSetting(
'Time Limit',
choices=[
('None', 0),
('1 Minute', 60),
('2 Minutes', 120),
('5 Minutes', 300),
('10 Minutes', 600),
('20 Minutes', 1200),
],
default=0,
),
ba.FloatChoiceSetting(
'Respawn Times',
choices=[
('Shorter', 0.25),
('Short', 0.5),
('Normal', 1.0),
('Long', 2.0),
('Longer', 4.0),
],
default=1.0,
),
]
default_music = ba.MusicType.FOOTBALL
@ -333,10 +346,11 @@ class FootballCoopGame(ba.CoopGameActivity[Player, Team]):
name = 'Football'
tips = ['Use the pick-up button to grab the flag < ${PICKUP} >']
score_info = ba.ScoreInfo(scoretype=ba.ScoreType.MILLISECONDS, version='B')
scoreconfig = ba.ScoreConfig(scoretype=ba.ScoreType.MILLISECONDS,
version='B')
default_music = ba.MusicType.FOOTBALL
# FIXME: Need to update co-op games to use get_score_info.
# FIXME: Need to update co-op games to use getscoreconfig.
def get_score_type(self) -> str:
return 'time'

View File

@ -125,23 +125,36 @@ class HockeyGame(ba.TeamGameActivity[Player, Team]):
name = 'Hockey'
description = 'Score some goals.'
game_settings = [
('Score to Win', {
'min_value': 1,
'default': 1,
'increment': 1
}),
('Time Limit', {
'choices': [('None', 0), ('1 Minute', 60), ('2 Minutes', 120),
('5 Minutes', 300), ('10 Minutes', 600),
('20 Minutes', 1200)],
'default': 0
}),
('Respawn Times', {
'choices': [('Shorter', 0.25), ('Short', 0.5), ('Normal', 1.0),
('Long', 2.0), ('Longer', 4.0)],
'default': 1.0
}),
available_settings = [
ba.IntSetting(
'Score to Win',
min_value=1,
default=1,
increment=1,
),
ba.IntChoiceSetting(
'Time Limit',
choices=[
('None', 0),
('1 Minute', 60),
('2 Minutes', 120),
('5 Minutes', 300),
('10 Minutes', 600),
('20 Minutes', 1200),
],
default=0,
),
ba.FloatChoiceSetting(
'Respawn Times',
choices=[
('Shorter', 0.25),
('Short', 0.5),
('Normal', 1.0),
('Long', 2.0),
('Longer', 4.0),
],
default=1.0,
),
]
default_music = ba.MusicType.HOCKEY

View File

@ -64,25 +64,38 @@ class KeepAwayGame(ba.TeamGameActivity[Player, Team]):
name = 'Keep Away'
description = 'Carry the flag for a set length of time.'
game_settings = [
('Hold Time', {
'min_value': 10,
'default': 30,
'increment': 10
}),
('Time Limit', {
'choices': [('None', 0), ('1 Minute', 60), ('2 Minutes', 120),
('5 Minutes', 300), ('10 Minutes', 600),
('20 Minutes', 1200)],
'default': 0
}),
('Respawn Times', {
'choices': [('Shorter', 0.25), ('Short', 0.5), ('Normal', 1.0),
('Long', 2.0), ('Longer', 4.0)],
'default': 1.0
}),
available_settings = [
ba.IntSetting(
'Hold Time',
min_value=10,
default=30,
increment=10,
),
ba.IntChoiceSetting(
'Time Limit',
choices=[
('None', 0),
('1 Minute', 60),
('2 Minutes', 120),
('5 Minutes', 300),
('10 Minutes', 600),
('20 Minutes', 1200),
],
default=0,
),
ba.FloatChoiceSetting(
'Respawn Times',
choices=[
('Shorter', 0.25),
('Short', 0.5),
('Normal', 1.0),
('Long', 2.0),
('Longer', 4.0),
],
default=1.0,
),
]
score_info = ba.ScoreInfo(label='Time Held')
scoreconfig = ba.ScoreConfig(label='Time Held')
default_music = ba.MusicType.KEEP_AWAY
@classmethod

View File

@ -68,25 +68,38 @@ class KingOfTheHillGame(ba.TeamGameActivity[Player, Team]):
name = 'King of the Hill'
description = 'Secure the flag for a set length of time.'
game_settings = [
('Hold Time', {
'min_value': 10,
'default': 30,
'increment': 10
}),
('Time Limit', {
'choices': [('None', 0), ('1 Minute', 60), ('2 Minutes', 120),
('5 Minutes', 300), ('10 Minutes', 600),
('20 Minutes', 1200)],
'default': 0
}),
('Respawn Times', {
'choices': [('Shorter', 0.25), ('Short', 0.5), ('Normal', 1.0),
('Long', 2.0), ('Longer', 4.0)],
'default': 1.0
}),
available_settings = [
ba.IntSetting(
'Hold Time',
min_value=10,
default=30,
increment=10,
),
ba.IntChoiceSetting(
'Time Limit',
choices=[
('None', 0),
('1 Minute', 60),
('2 Minutes', 120),
('5 Minutes', 300),
('10 Minutes', 600),
('20 Minutes', 1200),
],
default=0,
),
ba.FloatChoiceSetting(
'Respawn Times',
choices=[
('Shorter', 0.25),
('Short', 0.5),
('Normal', 1.0),
('Long', 2.0),
('Longer', 4.0),
],
default=1.0,
),
]
score_info = ba.ScoreInfo(label='Time Held')
scoreconfig = ba.ScoreConfig(label='Time Held')
@classmethod
def supports_session_type(cls, sessiontype: Type[ba.Session]) -> bool:

View File

@ -54,10 +54,10 @@ class MeteorShowerGame(ba.TeamGameActivity[Player, Team]):
name = 'Meteor Shower'
description = 'Dodge the falling bombs.'
game_settings = [('Epic Mode', {'default': False})]
score_info = ba.ScoreInfo(label='Survived',
scoretype=ba.ScoreType.MILLISECONDS,
version='B')
available_settings = [ba.BoolSetting('Epic Mode', default=False)]
scoreconfig = ba.ScoreConfig(label='Survived',
scoretype=ba.ScoreType.MILLISECONDS,
version='B')
# Print messages when players die (since its meaningful in this game).
announce_player_deaths = True

View File

@ -53,9 +53,9 @@ class NinjaFightGame(ba.TeamGameActivity[Player, Team]):
name = 'Ninja Fight'
description = 'How fast can you defeat the ninjas?'
score_info = ba.ScoreInfo(label='Time',
scoretype=ba.ScoreType.MILLISECONDS,
lower_is_better=True)
scoreconfig = ba.ScoreConfig(label='Time',
scoretype=ba.ScoreType.MILLISECONDS,
lower_is_better=True)
@classmethod
def get_supported_maps(cls, sessiontype: Type[ba.Session]) -> List[str]:

View File

@ -95,45 +95,55 @@ class RaceGame(ba.TeamGameActivity[Player, Team]):
name = 'Race'
description = 'Run real fast!'
score_info = ba.ScoreInfo(label='Time',
lower_is_better=True,
scoretype=ba.ScoreType.MILLISECONDS)
scoreconfig = ba.ScoreConfig(label='Time',
lower_is_better=True,
scoretype=ba.ScoreType.MILLISECONDS)
@classmethod
def get_game_settings(
cls,
sessiontype: Type[ba.Session]) -> List[Tuple[str, Dict[str, Any]]]:
settings: List[Tuple[str, Dict[str, Any]]] = [
('Laps', {
'min_value': 1,
'default': 3,
'increment': 1
}),
('Time Limit', {
'choices': [('None', 0), ('1 Minute', 60), ('2 Minutes', 120),
('5 Minutes', 300), ('10 Minutes', 600),
('20 Minutes', 1200)],
'default': 0
}),
('Mine Spawning', {
'choices': [('No Mines', 0), ('8 Seconds', 8000),
('4 Seconds', 4000), ('2 Seconds', 2000)],
'default': 4000
}),
('Bomb Spawning', {
'choices': [('None', 0), ('8 Seconds', 8000),
('4 Seconds', 4000), ('2 Seconds', 2000),
('1 Second', 1000)],
'default': 2000
}),
('Epic Mode', {
'default': False
}),
def get_available_settings(
cls, sessiontype: Type[ba.Session]) -> List[ba.Setting]:
settings = [
ba.IntSetting('Laps', min_value=1, default=3, increment=1),
ba.IntChoiceSetting(
'Time Limit',
default=0,
choices=[
('None', 0),
('1 Minute', 60),
('2 Minutes', 120),
('5 Minutes', 300),
('10 Minutes', 600),
('20 Minutes', 1200),
],
),
ba.IntChoiceSetting(
'Mine Spawning',
default=4000,
choices=[
('No Mines', 0),
('8 Seconds', 8000),
('4 Seconds', 4000),
('2 Seconds', 2000),
],
),
ba.IntChoiceSetting(
'Bomb Spawning',
choices=[
('None', 0),
('8 Seconds', 8000),
('4 Seconds', 4000),
('2 Seconds', 2000),
('1 Second', 1000),
],
default=2000,
),
ba.BoolSetting('Epic Mode', default=False),
]
# We have some specific settings in teams mode.
if issubclass(sessiontype, ba.DualTeamSession):
settings.append(('Entire Team Must Finish', {'default': False}))
settings.append(
ba.BoolSetting('Entire Team Must Finish', default=False))
return settings
@classmethod

View File

@ -59,17 +59,10 @@ class TargetPracticeGame(ba.TeamGameActivity[Player, Team]):
name = 'Target Practice'
description = 'Bomb as many targets as you can.'
game_settings = [
('Target Count', {
'min_value': 1,
'default': 3
}),
('Enable Impact Bombs', {
'default': True
}),
('Enable Triple Bombs', {
'default': True
}),
available_settings = [
ba.IntSetting('Target Count', min_value=1, default=3),
ba.BoolSetting('Enable Impact Bombs', default=True),
ba.BoolSetting('Enable Triple Bombs', default=True)
]
default_music = ba.MusicType.FORWARD_MARCH

View File

@ -72,7 +72,7 @@ class PlaylistEditGameWindow(ba.Window):
ba.screenmessage(ba.Lstr(resource='noValidMapsErrorText'))
raise Exception('No valid maps')
self._settings_defs = gameclass.get_game_settings(sessiontype)
self._settings_defs = gameclass.get_available_settings(sessiontype)
self._completion_call = completion_call
# To start with, pick a random map out of the ones we own.
@ -239,30 +239,31 @@ class PlaylistEditGameWindow(ba.Window):
v_align='center')
v -= map_height
for setting_name, setting in self._settings_defs:
value = setting['default']
for setting in self._settings_defs:
value = setting.default
value_type = type(value)
# Now, if there's an existing value for it in the config,
# override with that.
try:
if (config is not None and 'settings' in config
and setting_name in config['settings']):
value = value_type(config['settings'][setting_name])
and setting.name in config['settings']):
value = value_type(config['settings'][setting.name])
except Exception:
ba.print_exception()
# Shove the starting value in there to start.
self._settings[setting_name] = value
self._settings[setting.name] = value
name_translated = self._get_localized_setting_name(setting_name)
name_translated = self._get_localized_setting_name(setting.name)
mw1 = 280
mw2 = 70
# Handle types with choices specially:
if 'choices' in setting:
for choice in setting['choices']:
if isinstance(setting, ba.ChoiceSetting):
# if 'choices' in setting:
for choice in setting.choices:
if len(choice) != 2:
raise ValueError(
"Expected 2-member tuples for 'choices'; got: " +
@ -281,10 +282,10 @@ class PlaylistEditGameWindow(ba.Window):
'got: ' + repr(setting))
# Start at the choice corresponding to the default if possible.
self._choice_selections[setting_name] = 0
for index, choice in enumerate(setting['choices']):
self._choice_selections[setting.name] = 0
for index, choice in enumerate(setting.choices):
if choice[1] == value:
self._choice_selections[setting_name] = index
self._choice_selections[setting.name] = index
break
v -= spacing
@ -300,8 +301,8 @@ class PlaylistEditGameWindow(ba.Window):
parent=self._subcontainer,
position=(h + 509 - 95, v),
size=(0, 28),
text=self._get_localized_setting_name(setting['choices'][
self._choice_selections[setting_name]][0]),
text=self._get_localized_setting_name(setting.choices[
self._choice_selections[setting.name]][0]),
editable=False,
color=(0.6, 1.0, 0.6, 1.0),
maxwidth=mw2,
@ -314,7 +315,7 @@ class PlaylistEditGameWindow(ba.Window):
label='<',
autoselect=True,
on_activate_call=ba.Call(
self._choice_inc, setting_name, txt,
self._choice_inc, setting.name, txt,
setting, -1),
repeat=True)
btn2 = ba.buttonwidget(parent=self._subcontainer,
@ -323,25 +324,16 @@ class PlaylistEditGameWindow(ba.Window):
label='>',
autoselect=True,
on_activate_call=ba.Call(
self._choice_inc, setting_name, txt,
self._choice_inc, setting.name, txt,
setting, 1),
repeat=True)
widget_column.append([btn1, btn2])
elif value_type in [int, float]:
elif isinstance(setting, (ba.IntSetting, ba.FloatSetting)):
v -= spacing
try:
min_value = setting['min_value']
except Exception:
min_value = 0
try:
max_value = setting['max_value']
except Exception:
max_value = 9999
try:
increment = setting['increment']
except Exception:
increment = 1
min_value = setting.min_value
max_value = setting.max_value
increment = setting.increment
ba.textwidget(parent=self._subcontainer,
position=(h + 50, v),
size=(100, 30),
@ -368,7 +360,7 @@ class PlaylistEditGameWindow(ba.Window):
on_activate_call=ba.Call(
self._inc, txt, min_value,
max_value, -increment, value_type,
setting_name),
setting.name),
repeat=True)
btn2 = ba.buttonwidget(parent=self._subcontainer,
position=(h + 509 + 5, v),
@ -378,7 +370,7 @@ class PlaylistEditGameWindow(ba.Window):
on_activate_call=ba.Call(
self._inc, txt, min_value,
max_value, increment, value_type,
setting_name),
setting.name),
repeat=True)
widget_column.append([btn1, btn2])
@ -413,7 +405,7 @@ class PlaylistEditGameWindow(ba.Window):
value=value,
on_value_change_call=ba.Call(
self._check_value_change,
setting_name, txt))
setting.name, txt))
widget_column.append([cbw])
else:
@ -463,8 +455,8 @@ class PlaylistEditGameWindow(ba.Window):
self._completion_call).get_root_widget()
def _choice_inc(self, setting_name: str, widget: ba.Widget,
setting: Dict[str, Any], increment: int) -> None:
choices = setting['choices']
setting: ba.ChoiceSetting, increment: int) -> None:
choices = setting.choices
if increment > 0:
self._choice_selections[setting_name] = min(
len(choices) - 1, self._choice_selections[setting_name] + 1)

View File

@ -1,5 +1,5 @@
<!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND -->
<h4><em>last updated on 2020-06-02 for Ballistica version 1.5.0 build 20041</em></h4>
<h4><em>last updated on 2020-06-02 for Ballistica version 1.5.0 build 20042</em></h4>
<p>This page documents the Python classes and functions in the 'ba' module,
which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please <a href="mailto:support@froemling.net">let me know</a>. Happy modding!</p>
<hr>
@ -31,7 +31,7 @@
</ul>
<li><a href="#class_ba_PlayerInfo">ba.PlayerInfo</a></li>
<li><a href="#class_ba_PlayerRecord">ba.PlayerRecord</a></li>
<li><a href="#class_ba_ScoreInfo">ba.ScoreInfo</a></li>
<li><a href="#class_ba_ScoreConfig">ba.ScoreConfig</a></li>
<li><a href="#class_ba_Session">ba.Session</a></li>
<ul>
<li><a href="#class_ba_CoopSession">ba.CoopSession</a></li>
@ -43,6 +43,7 @@
</ul>
<li><a href="#class_ba_SessionPlayer">ba.SessionPlayer</a></li>
<li><a href="#class_ba_SessionTeam">ba.SessionTeam</a></li>
<li><a href="#class_ba_Setting">ba.Setting</a></li>
<li><a href="#class_ba_StandLocation">ba.StandLocation</a></li>
<li><a href="#class_ba_Stats">ba.Stats</a></li>
<li><a href="#class_ba_Team">ba.Team</a></li>
@ -220,6 +221,17 @@
<ul>
<li><a href="#class_ba_Existable">ba.Existable</a></li>
</ul>
<h4><a name="class_category_Settings_Classes">Settings Classes</a></h4>
<ul>
<li><a href="#class_ba_BoolSetting">ba.BoolSetting</a></li>
<li><a href="#class_ba_ChoiceSetting">ba.ChoiceSetting</a></li>
<ul>
<li><a href="#class_ba_FloatChoiceSetting">ba.FloatChoiceSetting</a></li>
<li><a href="#class_ba_IntChoiceSetting">ba.IntChoiceSetting</a></li>
</ul>
<li><a href="#class_ba_FloatSetting">ba.FloatSetting</a></li>
<li><a href="#class_ba_IntSetting">ba.IntSetting</a></li>
</ul>
<hr>
<h2><strong><a name="class_ba_Achievement">ba.Achievement</a></strong></h3>
<p><em>&lt;top level class&gt;</em>
@ -1087,7 +1099,7 @@ manually.</p>
<h3>Methods:</h3>
<dl>
<dt><h4><a name="method_ba_AppDelegate__create_default_game_settings_ui">create_default_game_settings_ui()</a></dt></h4><dd>
<p><span>create_default_game_settings_ui(self, gameclass: Type[<a href="#class_ba_GameActivity">ba.GameActivity</a>], sessionclass: Type[<a href="#class_ba_Session">ba.Session</a>], config: Optional[Dict[str, Any]], completion_call: Callable[[Optional[Dict[str, Any]]], None]) -&gt; None</span></p>
<p><span>create_default_game_settings_ui(self, gameclass: Type[<a href="#class_ba_GameActivity">ba.GameActivity</a>], sessionclass: Type[<a href="#class_ba_Session">ba.Session</a>], config: Optional[dict], completion_call: Callable[[Optional[dict]], None]) -&gt; None</span></p>
<p>Launch a UI to configure the given game config.</p>
@ -1161,6 +1173,21 @@ when done.</p>
<p>Behavior is similar to <a href="#function_ba_gettexture">ba.gettexture</a>()</p>
</dd>
</dl>
<hr>
<h2><strong><a name="class_ba_BoolSetting">ba.BoolSetting</a></strong></h3>
<p>Inherits from: <a href="#class_ba_Setting">ba.Setting</a></p>
<p>A boolean game setting.</p>
<p>Category: <a href="#class_category_Settings_Classes">Settings Classes</a>
</p>
<h3>Methods:</h3>
<dl>
<dt><h4><a name="method_ba_BoolSetting____init__">&lt;constructor&gt;</a></dt></h4><dd>
<p><span>ba.BoolSetting(name: str, default: bool)</span></p>
</dd>
</dl>
<hr>
@ -1291,6 +1318,21 @@ mycall()</pre>
<dt><h4><a name="method_ba_CelebrateMessage____init__">&lt;constructor&gt;</a></dt></h4><dd>
<p><span>ba.CelebrateMessage(duration: float = 10.0)</span></p>
</dd>
</dl>
<hr>
<h2><strong><a name="class_ba_ChoiceSetting">ba.ChoiceSetting</a></strong></h3>
<p>Inherits from: <a href="#class_ba_Setting">ba.Setting</a></p>
<p>A setting with multiple choices.</p>
<p>Category: <a href="#class_category_Settings_Classes">Settings Classes</a>
</p>
<h3>Methods:</h3>
<dl>
<dt><h4><a name="method_ba_ChoiceSetting____init__">&lt;constructor&gt;</a></dt></h4><dd>
<p><span>ba.ChoiceSetting(name: str, default: Any, choices: List[Tuple[str, Any]])</span></p>
</dd>
</dl>
<hr>
@ -1617,7 +1659,7 @@ start_long_action(callback_when_done=<a href="#class_ba_ContextCall">ba.ContextC
</dd>
</dl>
<h3>Methods Inherited:</h3>
<h5><a href="#method_ba_GameActivity__add_actor_weak_ref">add_actor_weak_ref()</a>, <a href="#method_ba_GameActivity__add_player">add_player()</a>, <a href="#method_ba_GameActivity__add_team">add_team()</a>, <a href="#method_ba_GameActivity__begin">begin()</a>, <a href="#method_ba_GameActivity__continue_or_end_game">continue_or_end_game()</a>, <a href="#method_ba_GameActivity__create_player">create_player()</a>, <a href="#method_ba_GameActivity__create_settings_ui">create_settings_ui()</a>, <a href="#method_ba_GameActivity__create_team">create_team()</a>, <a href="#method_ba_GameActivity__dep_is_present">dep_is_present()</a>, <a href="#method_ba_GameActivity__end">end()</a>, <a href="#method_ba_GameActivity__end_game">end_game()</a>, <a href="#method_ba_GameActivity__expire">expire()</a>, <a href="#method_ba_GameActivity__get_description">get_description()</a>, <a href="#method_ba_GameActivity__get_description_display_string">get_description_display_string()</a>, <a href="#method_ba_GameActivity__get_display_string">get_display_string()</a>, <a href="#method_ba_GameActivity__get_dynamic_deps">get_dynamic_deps()</a>, <a href="#method_ba_GameActivity__get_game_settings">get_game_settings()</a>, <a href="#method_ba_GameActivity__get_instance_description">get_instance_description()</a>, <a href="#method_ba_GameActivity__get_instance_description_short">get_instance_description_short()</a>, <a href="#method_ba_GameActivity__get_instance_display_string">get_instance_display_string()</a>, <a href="#method_ba_GameActivity__get_instance_scoreboard_display_string">get_instance_scoreboard_display_string()</a>, <a href="#method_ba_GameActivity__get_score_info">get_score_info()</a>, <a href="#method_ba_GameActivity__get_settings_display_string">get_settings_display_string()</a>, <a href="#method_ba_GameActivity__get_supported_maps">get_supported_maps()</a>, <a href="#method_ba_GameActivity__get_team_display_string">get_team_display_string()</a>, <a href="#method_ba_GameActivity__getname">getname()</a>, <a href="#method_ba_GameActivity__handlemessage">handlemessage()</a>, <a href="#method_ba_GameActivity__has_begun">has_begun()</a>, <a href="#method_ba_GameActivity__has_ended">has_ended()</a>, <a href="#method_ba_GameActivity__has_transitioned_in">has_transitioned_in()</a>, <a href="#method_ba_GameActivity__is_transitioning_out">is_transitioning_out()</a>, <a href="#method_ba_GameActivity__is_waiting_for_continue">is_waiting_for_continue()</a>, <a href="#method_ba_GameActivity__on_continue">on_continue()</a>, <a href="#method_ba_GameActivity__on_expire">on_expire()</a>, <a href="#method_ba_GameActivity__on_player_join">on_player_join()</a>, <a href="#method_ba_GameActivity__on_player_leave">on_player_leave()</a>, <a href="#method_ba_GameActivity__on_team_join">on_team_join()</a>, <a href="#method_ba_GameActivity__on_team_leave">on_team_leave()</a>, <a href="#method_ba_GameActivity__on_transition_in">on_transition_in()</a>, <a href="#method_ba_GameActivity__on_transition_out">on_transition_out()</a>, <a href="#method_ba_GameActivity__remove_player">remove_player()</a>, <a href="#method_ba_GameActivity__remove_team">remove_team()</a>, <a href="#method_ba_GameActivity__respawn_player">respawn_player()</a>, <a href="#method_ba_GameActivity__retain_actor">retain_actor()</a>, <a href="#method_ba_GameActivity__set_has_ended">set_has_ended()</a>, <a href="#method_ba_GameActivity__setup_standard_powerup_drops">setup_standard_powerup_drops()</a>, <a href="#method_ba_GameActivity__setup_standard_time_limit">setup_standard_time_limit()</a>, <a href="#method_ba_GameActivity__show_zoom_message">show_zoom_message()</a>, <a href="#method_ba_GameActivity__spawn_player">spawn_player()</a>, <a href="#method_ba_GameActivity__spawn_player_if_exists">spawn_player_if_exists()</a>, <a href="#method_ba_GameActivity__transition_in">transition_in()</a>, <a href="#method_ba_GameActivity__transition_out">transition_out()</a></h5>
<h5><a href="#method_ba_GameActivity__add_actor_weak_ref">add_actor_weak_ref()</a>, <a href="#method_ba_GameActivity__add_player">add_player()</a>, <a href="#method_ba_GameActivity__add_team">add_team()</a>, <a href="#method_ba_GameActivity__begin">begin()</a>, <a href="#method_ba_GameActivity__continue_or_end_game">continue_or_end_game()</a>, <a href="#method_ba_GameActivity__create_player">create_player()</a>, <a href="#method_ba_GameActivity__create_settings_ui">create_settings_ui()</a>, <a href="#method_ba_GameActivity__create_team">create_team()</a>, <a href="#method_ba_GameActivity__dep_is_present">dep_is_present()</a>, <a href="#method_ba_GameActivity__end">end()</a>, <a href="#method_ba_GameActivity__end_game">end_game()</a>, <a href="#method_ba_GameActivity__expire">expire()</a>, <a href="#method_ba_GameActivity__get_available_settings">get_available_settings()</a>, <a href="#method_ba_GameActivity__get_description">get_description()</a>, <a href="#method_ba_GameActivity__get_description_display_string">get_description_display_string()</a>, <a href="#method_ba_GameActivity__get_display_string">get_display_string()</a>, <a href="#method_ba_GameActivity__get_dynamic_deps">get_dynamic_deps()</a>, <a href="#method_ba_GameActivity__get_instance_description">get_instance_description()</a>, <a href="#method_ba_GameActivity__get_instance_description_short">get_instance_description_short()</a>, <a href="#method_ba_GameActivity__get_instance_display_string">get_instance_display_string()</a>, <a href="#method_ba_GameActivity__get_instance_scoreboard_display_string">get_instance_scoreboard_display_string()</a>, <a href="#method_ba_GameActivity__get_settings_display_string">get_settings_display_string()</a>, <a href="#method_ba_GameActivity__get_supported_maps">get_supported_maps()</a>, <a href="#method_ba_GameActivity__get_team_display_string">get_team_display_string()</a>, <a href="#method_ba_GameActivity__getname">getname()</a>, <a href="#method_ba_GameActivity__getscoreconfig">getscoreconfig()</a>, <a href="#method_ba_GameActivity__handlemessage">handlemessage()</a>, <a href="#method_ba_GameActivity__has_begun">has_begun()</a>, <a href="#method_ba_GameActivity__has_ended">has_ended()</a>, <a href="#method_ba_GameActivity__has_transitioned_in">has_transitioned_in()</a>, <a href="#method_ba_GameActivity__is_transitioning_out">is_transitioning_out()</a>, <a href="#method_ba_GameActivity__is_waiting_for_continue">is_waiting_for_continue()</a>, <a href="#method_ba_GameActivity__on_continue">on_continue()</a>, <a href="#method_ba_GameActivity__on_expire">on_expire()</a>, <a href="#method_ba_GameActivity__on_player_join">on_player_join()</a>, <a href="#method_ba_GameActivity__on_player_leave">on_player_leave()</a>, <a href="#method_ba_GameActivity__on_team_join">on_team_join()</a>, <a href="#method_ba_GameActivity__on_team_leave">on_team_leave()</a>, <a href="#method_ba_GameActivity__on_transition_in">on_transition_in()</a>, <a href="#method_ba_GameActivity__on_transition_out">on_transition_out()</a>, <a href="#method_ba_GameActivity__remove_player">remove_player()</a>, <a href="#method_ba_GameActivity__remove_team">remove_team()</a>, <a href="#method_ba_GameActivity__respawn_player">respawn_player()</a>, <a href="#method_ba_GameActivity__retain_actor">retain_actor()</a>, <a href="#method_ba_GameActivity__set_has_ended">set_has_ended()</a>, <a href="#method_ba_GameActivity__setup_standard_powerup_drops">setup_standard_powerup_drops()</a>, <a href="#method_ba_GameActivity__setup_standard_time_limit">setup_standard_time_limit()</a>, <a href="#method_ba_GameActivity__show_zoom_message">show_zoom_message()</a>, <a href="#method_ba_GameActivity__spawn_player">spawn_player()</a>, <a href="#method_ba_GameActivity__spawn_player_if_exists">spawn_player_if_exists()</a>, <a href="#method_ba_GameActivity__transition_in">transition_in()</a>, <a href="#method_ba_GameActivity__transition_out">transition_out()</a></h5>
<h3>Methods Defined or Overridden:</h3>
<h5><a href="#method_ba_CoopGameActivity____init__">&lt;constructor&gt;</a>, <a href="#method_ba_CoopGameActivity__celebrate">celebrate()</a>, <a href="#method_ba_CoopGameActivity__fade_to_red">fade_to_red()</a>, <a href="#method_ba_CoopGameActivity__get_score_type">get_score_type()</a>, <a href="#method_ba_CoopGameActivity__on_begin">on_begin()</a>, <a href="#method_ba_CoopGameActivity__setup_low_life_warning_sound">setup_low_life_warning_sound()</a>, <a href="#method_ba_CoopGameActivity__spawn_player_spaz">spawn_player_spaz()</a>, <a href="#method_ba_CoopGameActivity__supports_session_type">supports_session_type()</a></h5>
<dl>
@ -2188,6 +2230,36 @@ its time with lingering corpses, sound effects, etc.</p>
<p>Whether this object exists.</p>
</dd>
</dl>
<hr>
<h2><strong><a name="class_ba_FloatChoiceSetting">ba.FloatChoiceSetting</a></strong></h3>
<p>Inherits from: <a href="#class_ba_ChoiceSetting">ba.ChoiceSetting</a>, <a href="#class_ba_Setting">ba.Setting</a></p>
<p>A float setting with multiple choices.</p>
<p>Category: <a href="#class_category_Settings_Classes">Settings Classes</a>
</p>
<h3>Methods:</h3>
<dl>
<dt><h4><a name="method_ba_FloatChoiceSetting____init__">&lt;constructor&gt;</a></dt></h4><dd>
<p><span>ba.FloatChoiceSetting(name: str, default: float, choices: List[Tuple[str, float]])</span></p>
</dd>
</dl>
<hr>
<h2><strong><a name="class_ba_FloatSetting">ba.FloatSetting</a></strong></h3>
<p>Inherits from: <a href="#class_ba_Setting">ba.Setting</a></p>
<p>A floating point game setting.</p>
<p>Category: <a href="#class_category_Settings_Classes">Settings Classes</a>
</p>
<h3>Methods:</h3>
<dl>
<dt><h4><a name="method_ba_FloatSetting____init__">&lt;constructor&gt;</a></dt></h4><dd>
<p><span>ba.FloatSetting(name: str, default: float, min_value: float = 0.0, max_value: float = 9999.0, increment: float = 1.0)</span></p>
</dd>
</dl>
<hr>
@ -2317,7 +2389,7 @@ its time with lingering corpses, sound effects, etc.</p>
<h3>Methods Inherited:</h3>
<h5><a href="#method_ba_Activity__add_actor_weak_ref">add_actor_weak_ref()</a>, <a href="#method_ba_Activity__add_player">add_player()</a>, <a href="#method_ba_Activity__add_team">add_team()</a>, <a href="#method_ba_Activity__begin">begin()</a>, <a href="#method_ba_Activity__create_player">create_player()</a>, <a href="#method_ba_Activity__create_team">create_team()</a>, <a href="#method_ba_Activity__dep_is_present">dep_is_present()</a>, <a href="#method_ba_Activity__expire">expire()</a>, <a href="#method_ba_Activity__get_dynamic_deps">get_dynamic_deps()</a>, <a href="#method_ba_Activity__has_begun">has_begun()</a>, <a href="#method_ba_Activity__has_ended">has_ended()</a>, <a href="#method_ba_Activity__has_transitioned_in">has_transitioned_in()</a>, <a href="#method_ba_Activity__is_transitioning_out">is_transitioning_out()</a>, <a href="#method_ba_Activity__on_expire">on_expire()</a>, <a href="#method_ba_Activity__on_player_leave">on_player_leave()</a>, <a href="#method_ba_Activity__on_team_join">on_team_join()</a>, <a href="#method_ba_Activity__on_team_leave">on_team_leave()</a>, <a href="#method_ba_Activity__on_transition_out">on_transition_out()</a>, <a href="#method_ba_Activity__remove_player">remove_player()</a>, <a href="#method_ba_Activity__remove_team">remove_team()</a>, <a href="#method_ba_Activity__retain_actor">retain_actor()</a>, <a href="#method_ba_Activity__set_has_ended">set_has_ended()</a>, <a href="#method_ba_Activity__transition_in">transition_in()</a>, <a href="#method_ba_Activity__transition_out">transition_out()</a></h5>
<h3>Methods Defined or Overridden:</h3>
<h5><a href="#method_ba_GameActivity____init__">&lt;constructor&gt;</a>, <a href="#method_ba_GameActivity__continue_or_end_game">continue_or_end_game()</a>, <a href="#method_ba_GameActivity__create_settings_ui">create_settings_ui()</a>, <a href="#method_ba_GameActivity__end">end()</a>, <a href="#method_ba_GameActivity__end_game">end_game()</a>, <a href="#method_ba_GameActivity__get_description">get_description()</a>, <a href="#method_ba_GameActivity__get_description_display_string">get_description_display_string()</a>, <a href="#method_ba_GameActivity__get_display_string">get_display_string()</a>, <a href="#method_ba_GameActivity__get_game_settings">get_game_settings()</a>, <a href="#method_ba_GameActivity__get_instance_description">get_instance_description()</a>, <a href="#method_ba_GameActivity__get_instance_description_short">get_instance_description_short()</a>, <a href="#method_ba_GameActivity__get_instance_display_string">get_instance_display_string()</a>, <a href="#method_ba_GameActivity__get_instance_scoreboard_display_string">get_instance_scoreboard_display_string()</a>, <a href="#method_ba_GameActivity__get_score_info">get_score_info()</a>, <a href="#method_ba_GameActivity__get_settings_display_string">get_settings_display_string()</a>, <a href="#method_ba_GameActivity__get_supported_maps">get_supported_maps()</a>, <a href="#method_ba_GameActivity__get_team_display_string">get_team_display_string()</a>, <a href="#method_ba_GameActivity__getname">getname()</a>, <a href="#method_ba_GameActivity__handlemessage">handlemessage()</a>, <a href="#method_ba_GameActivity__is_waiting_for_continue">is_waiting_for_continue()</a>, <a href="#method_ba_GameActivity__on_begin">on_begin()</a>, <a href="#method_ba_GameActivity__on_continue">on_continue()</a>, <a href="#method_ba_GameActivity__on_player_join">on_player_join()</a>, <a href="#method_ba_GameActivity__on_transition_in">on_transition_in()</a>, <a href="#method_ba_GameActivity__respawn_player">respawn_player()</a>, <a href="#method_ba_GameActivity__setup_standard_powerup_drops">setup_standard_powerup_drops()</a>, <a href="#method_ba_GameActivity__setup_standard_time_limit">setup_standard_time_limit()</a>, <a href="#method_ba_GameActivity__show_zoom_message">show_zoom_message()</a>, <a href="#method_ba_GameActivity__spawn_player">spawn_player()</a>, <a href="#method_ba_GameActivity__spawn_player_if_exists">spawn_player_if_exists()</a>, <a href="#method_ba_GameActivity__spawn_player_spaz">spawn_player_spaz()</a>, <a href="#method_ba_GameActivity__supports_session_type">supports_session_type()</a></h5>
<h5><a href="#method_ba_GameActivity____init__">&lt;constructor&gt;</a>, <a href="#method_ba_GameActivity__continue_or_end_game">continue_or_end_game()</a>, <a href="#method_ba_GameActivity__create_settings_ui">create_settings_ui()</a>, <a href="#method_ba_GameActivity__end">end()</a>, <a href="#method_ba_GameActivity__end_game">end_game()</a>, <a href="#method_ba_GameActivity__get_available_settings">get_available_settings()</a>, <a href="#method_ba_GameActivity__get_description">get_description()</a>, <a href="#method_ba_GameActivity__get_description_display_string">get_description_display_string()</a>, <a href="#method_ba_GameActivity__get_display_string">get_display_string()</a>, <a href="#method_ba_GameActivity__get_instance_description">get_instance_description()</a>, <a href="#method_ba_GameActivity__get_instance_description_short">get_instance_description_short()</a>, <a href="#method_ba_GameActivity__get_instance_display_string">get_instance_display_string()</a>, <a href="#method_ba_GameActivity__get_instance_scoreboard_display_string">get_instance_scoreboard_display_string()</a>, <a href="#method_ba_GameActivity__get_settings_display_string">get_settings_display_string()</a>, <a href="#method_ba_GameActivity__get_supported_maps">get_supported_maps()</a>, <a href="#method_ba_GameActivity__get_team_display_string">get_team_display_string()</a>, <a href="#method_ba_GameActivity__getname">getname()</a>, <a href="#method_ba_GameActivity__getscoreconfig">getscoreconfig()</a>, <a href="#method_ba_GameActivity__handlemessage">handlemessage()</a>, <a href="#method_ba_GameActivity__is_waiting_for_continue">is_waiting_for_continue()</a>, <a href="#method_ba_GameActivity__on_begin">on_begin()</a>, <a href="#method_ba_GameActivity__on_continue">on_continue()</a>, <a href="#method_ba_GameActivity__on_player_join">on_player_join()</a>, <a href="#method_ba_GameActivity__on_transition_in">on_transition_in()</a>, <a href="#method_ba_GameActivity__respawn_player">respawn_player()</a>, <a href="#method_ba_GameActivity__setup_standard_powerup_drops">setup_standard_powerup_drops()</a>, <a href="#method_ba_GameActivity__setup_standard_time_limit">setup_standard_time_limit()</a>, <a href="#method_ba_GameActivity__show_zoom_message">show_zoom_message()</a>, <a href="#method_ba_GameActivity__spawn_player">spawn_player()</a>, <a href="#method_ba_GameActivity__spawn_player_if_exists">spawn_player_if_exists()</a>, <a href="#method_ba_GameActivity__spawn_player_spaz">spawn_player_spaz()</a>, <a href="#method_ba_GameActivity__supports_session_type">supports_session_type()</a></h5>
<dl>
<dt><h4><a name="method_ba_GameActivity____init__">&lt;constructor&gt;</a></dt></h4><dd>
<p><span>ba.GameActivity(settings: dict)</span></p>
@ -2334,7 +2406,7 @@ and calls either end_game or continue_game depending on the result</p>
</dd>
<dt><h4><a name="method_ba_GameActivity__create_settings_ui">create_settings_ui()</a></dt></h4><dd>
<h5><span><em>&lt;class method&gt;</span></em></h5>
<p><span>create_settings_ui(sessionclass: Type[<a href="#class_ba_Session">ba.Session</a>], settings: Optional[Dict[str, Any]], completion_call: Callable[[Optional[Dict[str, Any]]], None]) -&gt; None </span></p>
<p><span>create_settings_ui(sessionclass: Type[<a href="#class_ba_Session">ba.Session</a>], settings: Optional[dict], completion_call: Callable[[Optional[dict]], None]) -&gt; None </span></p>
<p>Launch an in-game UI to configure settings for a game type.</p>
@ -2343,11 +2415,11 @@ and calls either end_game or continue_game depending on the result</p>
<p>'config' should be an existing config dict (specifies 'edit' ui mode)
or None (specifies 'add' ui mode).</p>
<p>'completion_call' will be called with a filled-out config dict on
<p>'completion_call' will be called with a filled-out settings dict on
success or None on cancel.</p>
<p>Generally subclasses don't need to override this; if they override
<a href="#method_ba_GameActivity__get_game_settings">ba.GameActivity.get_game_settings</a>() and
<a href="#method_ba_GameActivity__get_available_settings">ba.GameActivity.get_available_settings</a>() and
<a href="#method_ba_GameActivity__get_supported_maps">ba.GameActivity.get_supported_maps</a>() they can just rely on
the default implementation here which calls those methods.</p>
@ -2374,38 +2446,9 @@ there is no 'winner' yet; this way things like the standard time-limit
(<a href="#method_ba_GameActivity__setup_standard_time_limit">ba.GameActivity.setup_standard_time_limit</a>()) will work with the game.</p>
</dd>
<dt><h4><a name="method_ba_GameActivity__get_description">get_description()</a></dt></h4><dd>
<dt><h4><a name="method_ba_GameActivity__get_available_settings">get_available_settings()</a></dt></h4><dd>
<h5><span><em>&lt;class method&gt;</span></em></h5>
<p><span>get_description(sessiontype: Type[<a href="#class_ba_Session">ba.Session</a>]) -&gt; str </span></p>
<p>Get a str description of this game type.</p>
<p>The default implementation simply returns the 'description' class var.
Classes which want to change their description depending on the session
can override this method.</p>
</dd>
<dt><h4><a name="method_ba_GameActivity__get_description_display_string">get_description_display_string()</a></dt></h4><dd>
<h5><span><em>&lt;class method&gt;</span></em></h5>
<p><span>get_description_display_string(sessiontype: Type[<a href="#class_ba_Session">ba.Session</a>]) -&gt; <a href="#class_ba_Lstr">ba.Lstr</a> </span></p>
<p>Return a translated version of get_description().</p>
<p>Sub-classes should override get_description(); not this.</p>
</dd>
<dt><h4><a name="method_ba_GameActivity__get_display_string">get_display_string()</a></dt></h4><dd>
<h5><span><em>&lt;class method&gt;</span></em></h5>
<p><span>get_display_string(settings: Optional[Dict] = None) -&gt; <a href="#class_ba_Lstr">ba.Lstr</a> </span></p>
<p>Return a descriptive name for this game/settings combo.</p>
<p>Subclasses should override getname(); not this.</p>
</dd>
<dt><h4><a name="method_ba_GameActivity__get_game_settings">get_game_settings()</a></dt></h4><dd>
<h5><span><em>&lt;class method&gt;</span></em></h5>
<p><span>get_game_settings(sessiontype: Type[<a href="#class_ba_Session">ba.Session</a>]) -&gt; List[Tuple[str, Dict[str, Any]]] </span></p>
<p><span>get_available_settings(sessiontype: Type[<a href="#class_ba_Session">ba.Session</a>]) -&gt; List[<a href="#class_ba_Setting">ba.Setting</a>] </span></p>
<p>Called by the default <a href="#method_ba_GameActivity__create_settings_ui">ba.GameActivity.create_settings_ui</a>()
implementation; should return a dict of config options to be presented
@ -2427,9 +2470,9 @@ of a name and a dict of options.</p>
<p>'increment': Value increment for int/float settings.</p>
<pre><span><em><small># example get_game_settings() for a capture-the-flag game:</small></em></span>
<pre><span><em><small># example get_available_settings() for a capture-the-flag game:</small></em></span>
@classmethod
def get_game_settings(cls, sessiontype):
def get_available_settings(cls, sessiontype):
return [("Score to Win", {
'default': 3,
'min_value': 1
@ -2463,6 +2506,35 @@ def get_game_settings(cls, sessiontype):
'default': False
})]</pre>
</dd>
<dt><h4><a name="method_ba_GameActivity__get_description">get_description()</a></dt></h4><dd>
<h5><span><em>&lt;class method&gt;</span></em></h5>
<p><span>get_description(sessiontype: Type[<a href="#class_ba_Session">ba.Session</a>]) -&gt; str </span></p>
<p>Get a str description of this game type.</p>
<p>The default implementation simply returns the 'description' class var.
Classes which want to change their description depending on the session
can override this method.</p>
</dd>
<dt><h4><a name="method_ba_GameActivity__get_description_display_string">get_description_display_string()</a></dt></h4><dd>
<h5><span><em>&lt;class method&gt;</span></em></h5>
<p><span>get_description_display_string(sessiontype: Type[<a href="#class_ba_Session">ba.Session</a>]) -&gt; <a href="#class_ba_Lstr">ba.Lstr</a> </span></p>
<p>Return a translated version of get_description().</p>
<p>Sub-classes should override get_description(); not this.</p>
</dd>
<dt><h4><a name="method_ba_GameActivity__get_display_string">get_display_string()</a></dt></h4><dd>
<h5><span><em>&lt;class method&gt;</span></em></h5>
<p><span>get_display_string(settings: Optional[Dict] = None) -&gt; <a href="#class_ba_Lstr">ba.Lstr</a> </span></p>
<p>Return a descriptive name for this game/settings combo.</p>
<p>Subclasses should override getname(); not this.</p>
</dd>
<dt><h4><a name="method_ba_GameActivity__get_instance_description">get_instance_description()</a></dt></h4><dd>
<p><span>get_instance_description(self) -&gt; Union[str, Sequence]</span></p>
@ -2532,13 +2604,6 @@ with the first value, ${ARG2} with the second, etc.</p>
<p>This name is used above the game scoreboard in the corner
of the screen, so it should be as concise as possible.</p>
</dd>
<dt><h4><a name="method_ba_GameActivity__get_score_info">get_score_info()</a></dt></h4><dd>
<h5><span><em>&lt;class method&gt;</span></em></h5>
<p><span>get_score_info() -&gt; <a href="#class_ba_ScoreInfo">ba.ScoreInfo</a> </span></p>
<p>Return info about game scoring setup; can be overridden by games.</p>
</dd>
<dt><h4><a name="method_ba_GameActivity__get_settings_display_string">get_settings_display_string()</a></dt></h4><dd>
<h5><span><em>&lt;class method&gt;</span></em></h5>
@ -2574,6 +2639,13 @@ for this game-type for the given <a href="#class_ba_Session">ba.Session</a> type
<p>This default implementation simply returns the 'name' class attr.</p>
</dd>
<dt><h4><a name="method_ba_GameActivity__getscoreconfig">getscoreconfig()</a></dt></h4><dd>
<h5><span><em>&lt;class method&gt;</span></em></h5>
<p><span>getscoreconfig() -&gt; <a href="#class_ba_ScoreConfig">ba.ScoreConfig</a> </span></p>
<p>Return info about game scoring setup; can be overridden by games.</p>
</dd>
<dt><h4><a name="method_ba_GameActivity__handlemessage">handlemessage()</a></dt></h4><dd>
<p><span>handlemessage(self, msg: Any) -&gt; Any</span></p>
@ -2842,6 +2914,36 @@ prefs, etc.</p>
<h3>Methods:</h3>
<p>&lt;all methods inherited from <a href="#class_ba_NotFoundError">ba.NotFoundError</a>&gt;</p>
<hr>
<h2><strong><a name="class_ba_IntChoiceSetting">ba.IntChoiceSetting</a></strong></h3>
<p>Inherits from: <a href="#class_ba_ChoiceSetting">ba.ChoiceSetting</a>, <a href="#class_ba_Setting">ba.Setting</a></p>
<p>An int setting with multiple choices.</p>
<p>Category: <a href="#class_category_Settings_Classes">Settings Classes</a>
</p>
<h3>Methods:</h3>
<dl>
<dt><h4><a name="method_ba_IntChoiceSetting____init__">&lt;constructor&gt;</a></dt></h4><dd>
<p><span>ba.IntChoiceSetting(name: str, default: int, choices: List[Tuple[str, int]])</span></p>
</dd>
</dl>
<hr>
<h2><strong><a name="class_ba_IntSetting">ba.IntSetting</a></strong></h3>
<p>Inherits from: <a href="#class_ba_Setting">ba.Setting</a></p>
<p>An integer game setting.</p>
<p>Category: <a href="#class_category_Settings_Classes">Settings Classes</a>
</p>
<h3>Methods:</h3>
<dl>
<dt><h4><a name="method_ba_IntSetting____init__">&lt;constructor&gt;</a></dt></h4><dd>
<p><span>ba.IntSetting(name: str, default: int, min_value: int = 0, max_value: int = 9999, increment: int = 1)</span></p>
</dd>
</dl>
<hr>
<h2><strong><a name="class_ba_Level">ba.Level</a></strong></h3>
<p><em>&lt;top level class&gt;</em>
</p>
@ -4345,38 +4447,38 @@ cause the powerup box to make a sound and disappear or whatnot.</p>
</dd>
</dl>
<hr>
<h2><strong><a name="class_ba_ScoreInfo">ba.ScoreInfo</a></strong></h3>
<h2><strong><a name="class_ba_ScoreConfig">ba.ScoreConfig</a></strong></h3>
<p><em>&lt;top level class&gt;</em>
</p>
<p>Info about a game's scoring setup.</p>
<p>Settings for how a game handles scores.</p>
<p>Category: <a href="#class_category_Gameplay_Classes">Gameplay Classes</a></p>
<h3>Attributes:</h3>
<h5><a href="#attr_ba_ScoreInfo__label">label</a>, <a href="#attr_ba_ScoreInfo__lower_is_better">lower_is_better</a>, <a href="#attr_ba_ScoreInfo__none_is_winner">none_is_winner</a>, <a href="#attr_ba_ScoreInfo__scoretype">scoretype</a>, <a href="#attr_ba_ScoreInfo__version">version</a></h5>
<h5><a href="#attr_ba_ScoreConfig__label">label</a>, <a href="#attr_ba_ScoreConfig__lower_is_better">lower_is_better</a>, <a href="#attr_ba_ScoreConfig__none_is_winner">none_is_winner</a>, <a href="#attr_ba_ScoreConfig__scoretype">scoretype</a>, <a href="#attr_ba_ScoreConfig__version">version</a></h5>
<dl>
<dt><h4><a name="attr_ba_ScoreInfo__label">label</a></h4></dt><dd>
<dt><h4><a name="attr_ba_ScoreConfig__label">label</a></h4></dt><dd>
<p><span>str</span></p>
<p>A label show to the user for scores; 'Score', 'Time Survived', etc.</p>
</dd>
<dt><h4><a name="attr_ba_ScoreInfo__lower_is_better">lower_is_better</a></h4></dt><dd>
<dt><h4><a name="attr_ba_ScoreConfig__lower_is_better">lower_is_better</a></h4></dt><dd>
<p><span>bool</span></p>
<p>Whether lower scores are preferable. Higher scores are by default.</p>
</dd>
<dt><h4><a name="attr_ba_ScoreInfo__none_is_winner">none_is_winner</a></h4></dt><dd>
<dt><h4><a name="attr_ba_ScoreConfig__none_is_winner">none_is_winner</a></h4></dt><dd>
<p><span>bool</span></p>
<p>Whether a value of None is considered better than other scores.
By default it is not.</p>
</dd>
<dt><h4><a name="attr_ba_ScoreInfo__scoretype">scoretype</a></h4></dt><dd>
<dt><h4><a name="attr_ba_ScoreConfig__scoretype">scoretype</a></h4></dt><dd>
<p><span><a href="#class_ba_ScoreType">ba.ScoreType</a></span></p>
<p>How the score value should be displayed.</p>
</dd>
<dt><h4><a name="attr_ba_ScoreInfo__version">version</a></h4></dt><dd>
<dt><h4><a name="attr_ba_ScoreConfig__version">version</a></h4></dt><dd>
<p><span>str</span></p>
<p>To change high-score lists used by a game without renaming the game,
change this. Defaults to an empty string.</p>
@ -4385,8 +4487,8 @@ change this. Defaults to an empty string.</p>
</dl>
<h3>Methods:</h3>
<dl>
<dt><h4><a name="method_ba_ScoreInfo____init__">&lt;constructor&gt;</a></dt></h4><dd>
<p><span>ba.ScoreInfo(label: 'str' = 'Score', scoretype: '<a href="#class_ba_ScoreType">ba.ScoreType</a>' = &lt;ScoreType.POINTS: 'p'&gt;, lower_is_better: 'bool' = False, none_is_winner: 'bool' = False, version: 'str' = '')</span></p>
<dt><h4><a name="method_ba_ScoreConfig____init__">&lt;constructor&gt;</a></dt></h4><dd>
<p><span>ba.ScoreConfig(label: 'str' = 'Score', scoretype: '<a href="#class_ba_ScoreType">ba.ScoreType</a>' = &lt;ScoreType.POINTS: 'p'&gt;, lower_is_better: 'bool' = False, none_is_winner: 'bool' = False, version: 'str' = '')</span></p>
</dd>
</dl>
@ -4867,6 +4969,22 @@ of the session.</p>
<h3>Methods:</h3>
<p>&lt;all methods inherited from <a href="#class_ba_NotFoundError">ba.NotFoundError</a>&gt;</p>
<hr>
<h2><strong><a name="class_ba_Setting">ba.Setting</a></strong></h3>
<p><em>&lt;top level class&gt;</em>
</p>
<p>Defines a user-controllable setting for a game or other entity.</p>
<p>Category: <a href="#class_category_Gameplay_Classes">Gameplay Classes</a>
</p>
<h3>Methods:</h3>
<dl>
<dt><h4><a name="method_ba_Setting____init__">&lt;constructor&gt;</a></dt></h4><dd>
<p><span>ba.Setting(name: str, default: Any)</span></p>
</dd>
</dl>
<hr>
<h2><strong><a name="class_ba_ShouldShatterMessage">ba.ShouldShatterMessage</a></strong></h3>
<p><em>&lt;top level class&gt;</em>
</p>
@ -5230,7 +5348,7 @@ of the session.</p>
</dd>
</dl>
<h3>Methods Inherited:</h3>
<h5><a href="#method_ba_GameActivity__add_actor_weak_ref">add_actor_weak_ref()</a>, <a href="#method_ba_GameActivity__add_player">add_player()</a>, <a href="#method_ba_GameActivity__add_team">add_team()</a>, <a href="#method_ba_GameActivity__begin">begin()</a>, <a href="#method_ba_GameActivity__continue_or_end_game">continue_or_end_game()</a>, <a href="#method_ba_GameActivity__create_player">create_player()</a>, <a href="#method_ba_GameActivity__create_settings_ui">create_settings_ui()</a>, <a href="#method_ba_GameActivity__create_team">create_team()</a>, <a href="#method_ba_GameActivity__dep_is_present">dep_is_present()</a>, <a href="#method_ba_GameActivity__end_game">end_game()</a>, <a href="#method_ba_GameActivity__expire">expire()</a>, <a href="#method_ba_GameActivity__get_description">get_description()</a>, <a href="#method_ba_GameActivity__get_description_display_string">get_description_display_string()</a>, <a href="#method_ba_GameActivity__get_display_string">get_display_string()</a>, <a href="#method_ba_GameActivity__get_dynamic_deps">get_dynamic_deps()</a>, <a href="#method_ba_GameActivity__get_game_settings">get_game_settings()</a>, <a href="#method_ba_GameActivity__get_instance_description">get_instance_description()</a>, <a href="#method_ba_GameActivity__get_instance_description_short">get_instance_description_short()</a>, <a href="#method_ba_GameActivity__get_instance_display_string">get_instance_display_string()</a>, <a href="#method_ba_GameActivity__get_instance_scoreboard_display_string">get_instance_scoreboard_display_string()</a>, <a href="#method_ba_GameActivity__get_score_info">get_score_info()</a>, <a href="#method_ba_GameActivity__get_settings_display_string">get_settings_display_string()</a>, <a href="#method_ba_GameActivity__get_supported_maps">get_supported_maps()</a>, <a href="#method_ba_GameActivity__get_team_display_string">get_team_display_string()</a>, <a href="#method_ba_GameActivity__getname">getname()</a>, <a href="#method_ba_GameActivity__handlemessage">handlemessage()</a>, <a href="#method_ba_GameActivity__has_begun">has_begun()</a>, <a href="#method_ba_GameActivity__has_ended">has_ended()</a>, <a href="#method_ba_GameActivity__has_transitioned_in">has_transitioned_in()</a>, <a href="#method_ba_GameActivity__is_transitioning_out">is_transitioning_out()</a>, <a href="#method_ba_GameActivity__is_waiting_for_continue">is_waiting_for_continue()</a>, <a href="#method_ba_GameActivity__on_continue">on_continue()</a>, <a href="#method_ba_GameActivity__on_expire">on_expire()</a>, <a href="#method_ba_GameActivity__on_player_join">on_player_join()</a>, <a href="#method_ba_GameActivity__on_player_leave">on_player_leave()</a>, <a href="#method_ba_GameActivity__on_team_join">on_team_join()</a>, <a href="#method_ba_GameActivity__on_team_leave">on_team_leave()</a>, <a href="#method_ba_GameActivity__on_transition_out">on_transition_out()</a>, <a href="#method_ba_GameActivity__remove_player">remove_player()</a>, <a href="#method_ba_GameActivity__remove_team">remove_team()</a>, <a href="#method_ba_GameActivity__respawn_player">respawn_player()</a>, <a href="#method_ba_GameActivity__retain_actor">retain_actor()</a>, <a href="#method_ba_GameActivity__set_has_ended">set_has_ended()</a>, <a href="#method_ba_GameActivity__setup_standard_powerup_drops">setup_standard_powerup_drops()</a>, <a href="#method_ba_GameActivity__setup_standard_time_limit">setup_standard_time_limit()</a>, <a href="#method_ba_GameActivity__show_zoom_message">show_zoom_message()</a>, <a href="#method_ba_GameActivity__spawn_player">spawn_player()</a>, <a href="#method_ba_GameActivity__spawn_player_if_exists">spawn_player_if_exists()</a>, <a href="#method_ba_GameActivity__transition_in">transition_in()</a>, <a href="#method_ba_GameActivity__transition_out">transition_out()</a></h5>
<h5><a href="#method_ba_GameActivity__add_actor_weak_ref">add_actor_weak_ref()</a>, <a href="#method_ba_GameActivity__add_player">add_player()</a>, <a href="#method_ba_GameActivity__add_team">add_team()</a>, <a href="#method_ba_GameActivity__begin">begin()</a>, <a href="#method_ba_GameActivity__continue_or_end_game">continue_or_end_game()</a>, <a href="#method_ba_GameActivity__create_player">create_player()</a>, <a href="#method_ba_GameActivity__create_settings_ui">create_settings_ui()</a>, <a href="#method_ba_GameActivity__create_team">create_team()</a>, <a href="#method_ba_GameActivity__dep_is_present">dep_is_present()</a>, <a href="#method_ba_GameActivity__end_game">end_game()</a>, <a href="#method_ba_GameActivity__expire">expire()</a>, <a href="#method_ba_GameActivity__get_available_settings">get_available_settings()</a>, <a href="#method_ba_GameActivity__get_description">get_description()</a>, <a href="#method_ba_GameActivity__get_description_display_string">get_description_display_string()</a>, <a href="#method_ba_GameActivity__get_display_string">get_display_string()</a>, <a href="#method_ba_GameActivity__get_dynamic_deps">get_dynamic_deps()</a>, <a href="#method_ba_GameActivity__get_instance_description">get_instance_description()</a>, <a href="#method_ba_GameActivity__get_instance_description_short">get_instance_description_short()</a>, <a href="#method_ba_GameActivity__get_instance_display_string">get_instance_display_string()</a>, <a href="#method_ba_GameActivity__get_instance_scoreboard_display_string">get_instance_scoreboard_display_string()</a>, <a href="#method_ba_GameActivity__get_settings_display_string">get_settings_display_string()</a>, <a href="#method_ba_GameActivity__get_supported_maps">get_supported_maps()</a>, <a href="#method_ba_GameActivity__get_team_display_string">get_team_display_string()</a>, <a href="#method_ba_GameActivity__getname">getname()</a>, <a href="#method_ba_GameActivity__getscoreconfig">getscoreconfig()</a>, <a href="#method_ba_GameActivity__handlemessage">handlemessage()</a>, <a href="#method_ba_GameActivity__has_begun">has_begun()</a>, <a href="#method_ba_GameActivity__has_ended">has_ended()</a>, <a href="#method_ba_GameActivity__has_transitioned_in">has_transitioned_in()</a>, <a href="#method_ba_GameActivity__is_transitioning_out">is_transitioning_out()</a>, <a href="#method_ba_GameActivity__is_waiting_for_continue">is_waiting_for_continue()</a>, <a href="#method_ba_GameActivity__on_continue">on_continue()</a>, <a href="#method_ba_GameActivity__on_expire">on_expire()</a>, <a href="#method_ba_GameActivity__on_player_join">on_player_join()</a>, <a href="#method_ba_GameActivity__on_player_leave">on_player_leave()</a>, <a href="#method_ba_GameActivity__on_team_join">on_team_join()</a>, <a href="#method_ba_GameActivity__on_team_leave">on_team_leave()</a>, <a href="#method_ba_GameActivity__on_transition_out">on_transition_out()</a>, <a href="#method_ba_GameActivity__remove_player">remove_player()</a>, <a href="#method_ba_GameActivity__remove_team">remove_team()</a>, <a href="#method_ba_GameActivity__respawn_player">respawn_player()</a>, <a href="#method_ba_GameActivity__retain_actor">retain_actor()</a>, <a href="#method_ba_GameActivity__set_has_ended">set_has_ended()</a>, <a href="#method_ba_GameActivity__setup_standard_powerup_drops">setup_standard_powerup_drops()</a>, <a href="#method_ba_GameActivity__setup_standard_time_limit">setup_standard_time_limit()</a>, <a href="#method_ba_GameActivity__show_zoom_message">show_zoom_message()</a>, <a href="#method_ba_GameActivity__spawn_player">spawn_player()</a>, <a href="#method_ba_GameActivity__spawn_player_if_exists">spawn_player_if_exists()</a>, <a href="#method_ba_GameActivity__transition_in">transition_in()</a>, <a href="#method_ba_GameActivity__transition_out">transition_out()</a></h5>
<h3>Methods Defined or Overridden:</h3>
<h5><a href="#method_ba_TeamGameActivity____init__">&lt;constructor&gt;</a>, <a href="#method_ba_TeamGameActivity__end">end()</a>, <a href="#method_ba_TeamGameActivity__on_begin">on_begin()</a>, <a href="#method_ba_TeamGameActivity__on_transition_in">on_transition_in()</a>, <a href="#method_ba_TeamGameActivity__spawn_player_spaz">spawn_player_spaz()</a>, <a href="#method_ba_TeamGameActivity__supports_session_type">supports_session_type()</a></h5>
<dl>