Loader behavior and import safety
- The built-in loader discovers lower-cased filenames beginning with
mod_. Development builds look for.py; normal builds look for.pyc. - Keep deployable mods self-contained unless a shared dependency is a deliberate part of the design. Reuse only the small helper techniques the mod actually needs, and keep them inside the mod where practical so installation remains simple and package-name conflicts are avoided.
- Discovery uses a set of lower-cased VFS keys, so import order is not a safe dependency mechanism.
- The loader calls
init()andfini()when present and can broadcast other methods throughsendEvent. _callModMethodcatchesAttributeErroraround both lookup and execution. AnAttributeErrorraised inside a lifecycle method may disappear without a useful error; catch and log fragile attribute access within the mod.- An unhandled
ImportErrorprevents the whole mod from loading. Wrap optional client-feature imports locally so only that feature is disabled. - Import-time side effects precede
init(). Prefer idempotentinit()installation where practical because it is easier to tear down and diagnose.
Callback, loop, and closure safety
- Bind delayed loop values with default arguments
(
lambda value=value: ...) orfunctools.partial; otherwise closures may all use the final loop value. - Set a callback ID to
Nonebefore running its callback logic so it can safely schedule a successor. - Cancellation can race with execution. Callback bodies need an active/context
guard even when
BigWorld.cancelCallbackis used. - Recurring loops need one owner and one scheduling guard. Event and timer paths must not independently start duplicate loops.
- If a worker waits for a main-thread result using
threading.Event, use a timeout and return an explicit error. - Daemon threads avoid blocking shutdown but do not replace stop events, server
shutdown, or bounded
join()when resources need cleanup.
Read by topic
Choose a focused chapter. Complete examples and reference details are preserved on their topic pages.