The runtime functions most often used by mods are callback scheduling, cancellation, time access and current-player lookup.

Scheduled callbacks

BigWorld.callback(delay, callable) schedules a callable on the client thread after a delay and returns a handle. The callback is delayed work, not a worker thread.

The delay is in seconds. Pass a callable, such as partial(fn, value), rather than the result of calling fn(value). A zero delay defers execution; it does not prove that an entity, view or synchronized cache will be ready when the callback runs. Prefer the owner's readiness event over repeated zero-delay polling.

Illustrative: this authored single-file fragment uses one module-global callback slot shared by every caller, rather than one slot per account, arena or view. apply_payload is undefined: supply its behavior and payload contract, and connect cancel_scheduled() to the real owner's stop, context-change and unload paths. Importing BigWorld requires the client runtime.

import BigWorld
from functools import partial

_callback_id = None
_generation = 0

def _run(expected_generation, payload):
    global _callback_id
    if expected_generation != _generation:
        return
    _callback_id = None
    apply_payload(payload)

def schedule(payload, delay=0.0):
    global _callback_id
    cancel_scheduled()
    _callback_id = BigWorld.callback(
        delay,
        partial(_run, _generation, payload)
    )

def cancel_scheduled():
    global _callback_id, _generation
    _generation += 1
    if _callback_id is not None:
        BigWorld.cancelCallback(_callback_id)
        _callback_id = None

schedule cancels before registering a replacement. Cancellation increments _generation even without a pending handle. When a handle exists, the native cancel call happens before clearing the slot: an escaping cancellation failure leaves the old handle stored with the new generation already published, and prevents replacement registration. If registration then fails after successful cancellation, invalidation and cancellation are not rolled back and no new handle is assigned. A normal schedule return is None, not its stored handle or an action result.

The partial retains the generation value and supplied payload object. It does not copy, validate or serialize the payload or snapshot gameplay context; a shared mutable payload can change before use. A stale _run returns before clearing the current handle or looking up the helper. An admitted invocation clears the slot first, then calls the current apply_payload and discards its result. A missing helper or escaping helper failure therefore occurs after clearing, with no retry, restoration or completion signal.

Clearing before the helper lets it schedule a successor without a later unconditional clear erasing that successor's handle. The generation check admits work at one point; it cannot abort a helper already running or undo its side effects. No active flag prevents scheduling after teardown. One caller's schedule or cancellation also invalidates another caller's work using these same globals.

The current CallbackDelayer source shows cancellation before replacement and removal before invoking a body, supporting those ownership shapes rather than this fragment's generation policy. Its callable-keyed helper can repeat using a nonnegative body return; this fragment ignores the application result and implements no such repeat protocol. The delayed-action recipe also uses a different order: it clears its slot before checking its token.

Source inspection establishes the authored control flow; engine timing, engine behavior after failed cancellation and replay/context transitions were not runtime-tested for this fragment. A shipped adaptation also needs the diagnostics contract: module version attribution and traceback-bearing records for caught unexpected failures, with any optional reporter kept optional. These lines supply no diagnostics or version constant.

Context invalidation

Cancel pending work when its account, arena, entity or view context ends. In the example, cancellation also advances the generation, so an obsolete invocation returns before touching the current handle or applying its payload. Scheduling a replacement invalidates the previous operation through the same path.

Cancellation cannot undo work that already ran. A generation check also does not establish readiness: reacquire and validate the current owner before applying a result. If applying it starts another asynchronous operation, that completion needs its own context check.

Use the same ownership rules for repeating tasks and asynchronous wrappers: keep cancellation with the owner, and reject completions from an old context. See Callback Lifecycle Patterns for repeating tasks and asynchronous owners.

Time functions

BigWorld.time()

Historically exposes client simulation time. It is useful for measuring engine-relative intervals, not calendar timestamps.

BigWorld.serverTime()

Historically exposes synchronized server time. Availability and semantics must be checked in the current client.

BigWorld.stime()

Appears in older references. Treat it as legacy until verified; do not build new logic around its name alone.

Current player

BigWorld.player() returns the current player-controlled client entity when one exists. The result can be None, and its concrete type changes with context.

Illustrative, function-body fragment: the early return requires an enclosing function; these six lines are not a standalone module. Supply the BigWorld import in client code. A missing name, missing player attribute or failing player call escapes before the guard. Only None returns early; any other object, even a false-valued one, reaches the attribute reads.

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

arena = getattr(player, 'arena', None)
space_id = getattr(player, 'spaceID', None)

Each getattr returns the existing attribute unchanged, or the default None when lookup reports absence through AttributeError. A present None is indistinguishable from absence here; zero and other false-valued results are preserved. These are ordinary sequential lookups, so getters can execute code and other lookup exceptions escape. If the arena read fails, the space assignment is not reached; if the space read fails, the earlier arena assignment is not rolled back.

The player is looked up once and both reads use that retained object. An arena value can itself be a borrowed mutable reference. The fragment provides no type, value, connection, arena, space or GUI readiness check, atomic snapshot or guarantee that the player remains current. The current player helper predicates test attribute presence, while Avatar construction initializes arena to None and builds it later: presence alone does not prove readiness.

Connect actual work to its owner and readiness lifecycle, invalidate delayed work when that owner changes, and reacquire or revalidate before use. These lines add no subscription, cleanup, cancellation, generation check, retry, notification or surrounding-function completion contract. No client/native lookup, getter or transition was executed for this authored fragment. Shipped adaptations need version attribution and traceback-bearing diagnostics for caught unexpected failures, with any reporter optional; an expected missing context should not become an error report or an excuse for a broad catch.

Runtime checklist

  • Store every callback handle you own.
  • Cancel callbacks during context teardown and fini().
  • Guard delayed work with a generation or context token.
  • Never assume the player entity exists during import or lobby transitions.
  • Use a background worker for blocking work and return results through a callback.

Stateful speed and clock reads

A provider's live value, Vehicle.getSpeed and Avatar's HUD-oriented speed getter are different sources. The Avatar path selects default/instantaneous components, applies per-read caps and can expand those caps by 0.25 per call. Extra polling can advance presentation state without elapsed time or new movement data. Do not differentiate that output as if each read were an independent physics sample.

The speedometer handler publishes signed integer km/h only when that integer changes. Slow movement can remain displayed as zero, and the updater interval is not the spacing of every event. Missing or unstarted vehicles can also yield zero. Choose a physics provider when you need movement samples rather than HUD text changes.

Choose the clock and provider from the question: server deadline, engine-time lifetime, replay position and corrected UTC are not interchangeable. Preserve timing anchors and owner generation, especially when a replay seek invalidates transient observations. See state interpretation.