Battle mode information appears in several related but separate namespaces. A reliable mod first decides which question it is asking, then reads the field owned by that layer instead of comparing every mode-like value against one shared list.
Why namespaces matter
Mode identifiers are not one universal enum. The lobby can describe what the player is queued for, the arena can describe the active battle rules, the GUI can describe which battle interface family to load, and vehicle or feature systems can use string tags for eligibility or filtering.
Identifier map
| Namespace | Typical owner | Use it for | Do not use it for |
|---|---|---|---|
arenaGuiType |
Battle GUI and arena presentation layer | Selecting the battle view family or interface branch. | Distinguishing every ruleset, difficulty, queue, or reward variant. |
arenaBonusType |
Battle rules and arena result semantics | Filtering active battle rules when the battle is already known. | Prequeue lobby decisions before the arena exists. |
| Queue type | Lobby matchmaking and prebattle controllers | Understanding which queue or prebattle flow the player is entering. | Making conclusions about an already-loaded arena without checking arena state. |
| Mode tags | Vehicle, feature, or configuration data | Eligibility, availability, feature flags, and configuration filtering. | Comparing directly to numeric arena or queue constants. |
Choose the owner that answers the question
Use the value owned by the system whose state you are actually trying to interpret. This is the same rule used across the guide: the lowest-level value is not automatically the most meaningful value, and the highest-level value is not automatically safer. The correct layer is the one that owns the fact.
- For battle UI behavior, start from the active battle GUI or arena presentation owner.
- For battle rules, result grouping, and mode-specific combat behavior, start from arena-owned rule state.
- For lobby selection and queue availability, start from the queue or prebattle controller.
- For vehicle eligibility, configuration filtering, or feature availability, start from the tag or configuration owner.
Safe access pattern
Keep the namespace decision close to the lifecycle point that makes the value valid. Avoid resolving a battle-only value during import or while the player is still in the hangar.
def _get_current_battle_mode_snapshot():
player = BigWorld.player()
if player is None or not hasattr(player, 'arena'):
return None
arena = getattr(player, 'arena', None)
if arena is None:
return None
return {
'gui_type': getattr(player, 'arenaGuiType', None),
'bonus_type': getattr(player, 'arenaBonusType', None),
'period': getattr(arena, 'period', None),
}
def _is_supported_battle(snapshot):
if not snapshot:
return False
# Illustrative only: verify the active constants in the current client build.
return snapshot['bonus_type'] in SUPPORTED_ARENA_BONUS_TYPES
The important part is not the placeholder constant. The important part is that the snapshot is read from the battle owner only when the battle owner exists, and the later filter compares the value against the matching namespace.
Verification workflow
- Find the field you want to read, not just a similarly named constant.
- Trace where that field is assigned or synchronized.
- Find which constants or maps are compared against that field in current client source.
- Check whether optional feature packages inject additional values at runtime.
- Confirm whether the value is valid in lobby, battle, replay, and reconnect contexts.
- Log the namespace and raw value together when diagnosing a mismatch.
Common mistakes
- Comparing a queue type against an arena bonus type constant.
- Assuming one GUI type means one exact ruleset.
- Using vehicle mode tags as if they were numeric arena identifiers.
- Reading arena state before the avatar and arena are ready.
- Keeping a cached mode value across battle exit, reconnect, replay rewind, or account changes.
- Hard-coding a temporary extension value without verifying that the extension package is present in the current build.
Version sensitivity
Core constants can move slowly, while feature packages and event modes can add or remap values through extension initialization. Treat unfamiliar identifiers as source-verification work, not as a reason to add broad fallback behavior that silently accepts every mode.
Contextual capability checks
Capability sets are keyed by bonus type, not GUI-family or queue ID. An empty base set can mean unknown/uninitialized registry rather than deliberately disabled features. Context owners can supply their own overrides; explicit None or an empty mapping bypasses the global override instead of inheriting it. Prefer the actual arena/result context when matching native gating.
ClientArena.hasBonusCap uses ANY semantics: a set matches if at least one member is present. An all-capabilities requirement needs an AND check with the same contextual overrides. Tuple/list values are not interchangeable with set/frozenset groups. The checked Python 2 scalar path accepts str rather than all Unicode text types.
An empty AND requirement can succeed even for an unknown mode; that does not prove the registry is populated. Use the actual membership contract and context overrides, and distinguish a decompilation error from an API requiring a compatibility fallback. A registered capability does not itself establish live feature availability.