Skip to content

Lifecycle Listeners

GMalvestiti edited this page Aug 31, 2026 · 3 revisions

Register listeners on the builder, or on the holder after creation, to react to completed config operations. Each listener chooses the logical side whose main thread receives it:

// Register on the builder (before creation)
ConfigHolder<MyModConfig> holder = LiteConfig.holder(MyModConfig.class)
    .modId("mymod")
    .onUpdate(ConfigSide.CLIENT, config -> hudRenderer.setScale(config.hudScale))
    .onLoad(ConfigSide.SERVER, config -> LOGGER.info("config loaded from disk"))
    .onSave(ConfigSide.SERVER, config -> LOGGER.debug("config saved"))
    .create();

// Register on the holder after creation — useful for addons and extensions
ConfigSubscription subscription =
    holder.onUpdate(ConfigSide.CLIENT, config -> myAddon.onConfigChanged(config));

// Removes this listener; closing the holder removes all listeners registered through it.
subscription.close();

Use ConfigSide.CLIENT, SERVER, or BOTH. BOTH creates one registration for each side. If the selected side has no active main-thread executor, the listener is skipped and the condition is logged.

Each listener fires only for its matching event:

Hook Fires after
onUpdate An accepted update or updateAndSave, or a changed server-sync transition
onLoad A successful load (not on a fallback-to-defaults load)
onSave A successful save or updateAndSave

When listeners do not fire: on a rejected update, on unchanged synchronized values, on a load that fell back to defaults, and on the build-time load that create() performs during construction (the holder does not yet exist to attach listeners to).

Listener contract:

  • The listener receives the published state — the same object data() returns at that moment. Read it without mutating or retaining it. Call copy() if values need to outlive the listener.
  • The listener is dispatched to the selected side's main-thread executor, in registration order.
  • A listener that throws is logged as ConfigError.CHANGE_LISTENER_FAILED. It does not fail the triggering operation or prevent later listeners from running.

Listeners observe completed holder operations. For normalization and validation within the config lifecycle itself, see Validation and Lifecycle Hooks.

Clone this wiki locally