Heads up!
Added in Fzzy Config 0.5.0
Fzzy Config has an event system
- Methods in
Config
for managing events in your config ⤵ - An
EventApi
for registering to generic config events ⤵ - A way to attach listeners to Validation ⤵
Config Implementations
There are methods in Config
that correspond to event stages. These are called alongside the events described below; if you only need to take action in your own config it's better to implement these than to register to the events, which are called for every config.
Method | Environment | Description |
---|---|---|
onSyncClient | Client | Called when a player logs in or data packs are reloaded |
onSyncServer | Server | Called when a player logs in or data packs are reloaded |
onUpdateClient | Client | Called after a config is updated in-game; when "apply changes" is used or the config GUI is closed, or when an update is received |
onUpdateServer | Server | Called when a update is synced to the server and it passes permission checks |
Heads up!
These methods are called on their respective main threads (Render/Server thread), so it is safe to interact with game state.
public class MyConfig extends Config {/* constructor *///perform actions on update in a variety of contexts.// Here you might be invalidating some cache because settings have changed, and then alerting the player.@Overridepublic void onUpdateServer(ServerPlayerEntity playerEntity) {MyUtil.invalidateCacheFor(playerEntity);playerEntity.sendMessage("Settings updated, cache reset");}}
Config Events
The EventApi
manages registration to events in Fzzy Config. Call the Event API with ConfigApi.event()
. The events in the API mirror the methods in Config
, but are fired for every config relevant to the event. They also pass generic information (Config
vs. the exact config subclass).
Method | Environment | Params | Description |
---|---|---|---|
onSyncClient | Client | config ID: Identifier, config: Config | Fired when a player logs in or data packs are reloaded |
onSyncServer | Server | config ID: Identifier, config: Config | Fired when a player logs in or data packs are reloaded |
onUpdateClient | Client | config ID: Identifier, config: Config | Fired after a config is updated in-game; when "apply changes" is used or the config GUI is closed, or when an update is received |
onUpdateServer | Server | config ID: Identifier, config: Config, player: ServerPlayer | Fired when a update is synced to the server and it passes permission checks |
onRegisteredClient | Client | config ID: Identifier, config: Config | Fired when a config is registered on the client |
onRegisteredServer | Client and Server | config ID: Identifier, config: Config | Fired when a config is registered on the client and server |
Heads up!
Events are called on their respective main threads (Render/Server thread), so it is safe to interact with game state.
public void init() {//register to events using the specified listenerConfigApi.event().onSyncClient((Identifier id, Config config) -> {//in this sync event we might wait until some config is synced to the client//and then run some init. This doesn't have to be your config! Use to time loading of integration too.if (id.equals(configICareAbout)) {MyUtils.initialize();}});ConfigApi.event().onRegisteredServer(configINeedToLoadAfter, (Config config) -> {//respect a load order, only load a config if another is present, do mod integration tasks once needed data from the other mod is ready, etc.MyIntegration.doStuff(config);});}
Listeners
The above events are called when an update is "officially" completed for the entire config. If you need to inspect changes to a setting under any circumstance, either a player change or an in-code change, you can attach a listener to a ValidatedField
.
These listeners are Consumer
of the field itself. There are two methods available for attachment:
addListener
, directly inValidatedField
itself. This has no return; you will have to attach in an init block.withListener
, an extension function withValidatedField
as a receiver. This method passes the field through, allowing you to attach inline, it also preserves the typing of the field.
Heads up!
These changes may be made on any thread, depending on the particulars of how the field is interacted with. Take precautions when interacting with game state.
// add listener is the direct approach to attaching a listener. It doesn't have a return nor does it preserve typing, so use of `withListener` is recommendedprivate static ValidatedBoolean helper() {ValidatedBoolean myBool = new ValidatedBoolean(false);myBool.addListener(myField -> do.stuff());return myBool;}ValidatedBoolean myListenedField = helper();//with listener inlines the attachment more easily, and maintains the typing inside the consumer.ValidatedBoolean myListenedBool = ValidatedField.withListener(new ValidatedBoolean(false), valBool -> do.stuff());