Optional packages, mode controllers, subscriptions, private services, and realm-specific integrations can exist without being active. Gate them narrowly and let the rest of the mod continue.

Gate the complete feature path

A failed import guard is not enough if later module-level code still resolves dependencies or defines classes using unavailable names.

FEATURE_AVAILABLE = False
FeatureController = None

try:
    from event_package.controller import FeatureController
    FEATURE_AVAILABLE = True
except ImportError:
    pass


def start_optional_feature():
    if not FEATURE_AVAILABLE:
        return False
    if not runtime_controller_is_active():
        return False
    return create_feature_controller(FeatureController)

Feature-gate, do not mod-gate

  • Disable only the component that truly depends on the optional service.
  • Keep independent local browsing, display, persistence, and layout behavior available.
  • Scope entitlement checks to the content or action the entitlement actually owns.
  • Treat package presence, enabled XML flags, and successful imports as clues—not proof of current runtime activation.

Native action boundaries

  • Prefer public processors, controllers, and request APIs over copied private implementations.
  • Re-check eligibility immediately before the request because cache and context can change during callbacks.
  • Use native result messages where helpful, but retain a readable fallback.
  • Do not hold a battle-exit flow open while waiting for an unrelated server response.
  • When several independent requests must be submitted before teardown, dispatch them before calling the original exit method rather than chaining through callbacks that may lose their owner.

Trust boundaries

Local browser tools

Bind to loopback, expose a narrow API, validate all payloads, and cross to the game thread safely.

Optional integration checklist

  • Every optional import is contained within the feature gate.
  • The runtime controller or active mode is checked before use.
  • Missing services disable only dependent behavior.
  • Requests are idempotent and guarded against duplicates.
  • Server response and synchronized state are distinguished.
  • Teardown cancels retries and clears short-lived deduplication state.

Gate the whole optional feature

A module-level abort flag is not sufficient if later descriptors, class definitions, or initialization still reference unavailable names. Keep imports, service access, handlers, and startup for the optional component behind the same gate.

Optional feature readiness

Optional systems should be documented as availability patterns, not as one feature's workflow. Module import success, service registration, current mode, account state, and synchronized cache contents are separate checks.

  • Guard optional imports narrowly. Treat an expected missing package as a capability check, not as a reportable exception; use silent or low-noise diagnostics unless an API fails after the feature was considered available.
  • Confirm the current mode or feature controller before using mode-specific state.
  • Keep cache absence distinct from synchronized empty results.
  • Clear feature-owned state when the optional system unloads or the mode changes.
  • Do not present a temporary mode API as a permanent client contract.