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.