BigWorld.callback is useful for waiting until the client reaches a later state, but delayed execution crosses lifecycle boundaries. A callback belongs to the future; any object it captured belongs to the past.

OwnerThe system that schedules the callback also owns cancellation and cleanup.
RiskCallbacks can run after battle exit, disconnect, view destruction, or replay rewind.
PatternStore the callback handle, cancel it during teardown, and revalidate context when it fires.

Single pending callback

For periodic or readiness work, keep one pending callback per task. Scheduling duplicates is a common source of repeated initialization and UI duplication.

import BigWorld
import logging

LOG = logging.getLogger('mod.example.runtime')
_pendingRefresh = None
_isStarted = False


def _schedule_refresh(delay=0.1):
    global _pendingRefresh
    _cancel_refresh()
    _pendingRefresh = BigWorld.callback(delay, _on_refresh)


def _cancel_refresh():
    global _pendingRefresh
    if _pendingRefresh is None:
        return
    try:
        BigWorld.cancelCallback(_pendingRefresh)
    except Exception:
        LOG.exception('Failed to cancel refresh callback')
    _pendingRefresh = None


def _on_refresh():
    global _pendingRefresh
    _pendingRefresh = None

    if not _isStarted:
        return

    player = BigWorld.player()
    if player is None:
        return

    # Re-resolve the current owner here. Do not trust captured objects.
    _refresh_from_current_context(player)

Bounded readiness retry

Use bounded retries when waiting for UI, account, arena, or resource readiness. Infinite timers hide bugs and can keep running after the owner disappears.

_pendingOwnerRetry = None
_ownerGeneration = 0
_isStarted = False


def _schedule_owner_retry(delay=0.1, attempt=0):
    global _pendingOwnerRetry
    _cancel_owner_retry()
    token = _ownerGeneration
    _pendingOwnerRetry = BigWorld.callback(
        delay,
        lambda token=token, attempt=attempt: _wait_for_owner(token, attempt)
    )


def _cancel_owner_retry():
    global _pendingOwnerRetry
    if _pendingOwnerRetry is None:
        return
    try:
        BigWorld.cancelCallback(_pendingOwnerRetry)
    except Exception:
        LOG.exception('Failed to cancel owner readiness retry')
    _pendingOwnerRetry = None


def _wait_for_owner(token, attempt=0):
    global _pendingOwnerRetry
    _pendingOwnerRetry = None

    if not _isStarted or token != _ownerGeneration:
        return
    if attempt >= 20:
        LOG.warning('Owner did not become ready')
        return

    owner = _resolve_owner_if_ready()
    if owner is not None:
        _attach_to_owner(owner)
        return

    _schedule_owner_retry(0.1, attempt + 1)

Read by topic

Choose a focused chapter. Complete examples and reference details are preserved on their topic pages.