Accessors
IConfiguratorAccessor<T> is the bridge between a Java type and a configurator UI. When ConfiguratorParser finds a normal @Configurable field, it asks:
IConfiguratorAccessor accessor = ConfiguratorAccessors.findByType(field.getGenericType());
Configurator configurator = accessor.create(name, getter, setter, forceUpdate, field, owner);
The accessor decides whether it supports the field type, supplies a default value, and creates the concrete Configurator.
Built-in Type Families
LDLib2 registers many client accessors in ldlib2:configurator_accessor.
Built-in support:
| Type family | Java types | Notes |
|---|---|---|
| Boolean | boolean, Boolean |
Uses a toggle. |
| Numbers | int, long, float, double, short, byte and boxed types |
Supports @ConfigNumber, @DefaultValue, and @ConfigColor. |
| String | String, String[] |
String[] is edited as multiple string rows. |
| Enum | any enum type | Supports @ConfigSelector; StringRepresentable names are used when available. |
| Text | Component |
Component text configurator. |
| Minecraft registry values | Block, Item, Fluid, EntityType<?> |
Usually backed by registry search/selector UI. |
| Resource IDs | ResourceLocation |
Supports @ConfigRL for font and tag-key modes. |
| Item and fluid stacks | ItemStack, FluidStack |
Uses item/fluid oriented configurators. |
| NBT | Tag |
Edits raw NBT/tag data. |
| Position and shape | BlockPos, AABB, Range |
Uses numeric field groups. |
| LDLib UI data | Position, Size, Pivot, LengthPercent, Translate2D |
Common UI layout/style data types. |
| JOML math | Vector2f, Vector2i, Vector3f, Vector3i, Vector4f, Vector4i, Quaternionf |
Uses grouped numeric configurators. |
| Scene references | TransformRef |
Used by scene-editor related data. |
| Render/UI resources | IGuiTexture, IRenderer |
Lets users choose registered implementations and edit their configurable data. |
| Arrays | T[] |
Dynamic wrapper around the child type's accessor. |
| Collections | Collection<T>, usually List<T> or Set<T> |
Dynamic wrapper around the child type's accessor; supports @ConfigList. |
Arrays and collections are handled dynamically. LDLib2 finds the child accessor first, then wraps it in ArrayConfiguratorAccessor or CollectionConfiguratorAccessor.
If a type is not listed here, it can still work when:
- it is inside a field marked
@Configurable(subConfigurable = true); - it has a custom
IConfiguratorAccessor; - you build its UI manually in
buildConfigurator(...); - a list uses
@ConfigList(configuratorMethod = "...")to provide item UI.
Custom Accessor
Create an accessor when you have a domain type that should always use the same editor control.
@LDLRegisterClient(name = "shop_currency", registry = "ldlib2:configurator_accessor")
public class CurrencyAccessor implements IConfiguratorAccessor<Currency> {
@Override
public boolean test(Class<?> type) {
return type == Currency.class;
}
@Override
public Currency defaultValue(@Nullable Field field, @Nullable Class<?> type) {
return Currency.EMPTY;
}
@Override
public Configurator create(
String name,
Supplier<Currency> supplier,
Consumer<Currency> consumer,
boolean forceUpdate,
@Nullable Field field,
@Nullable Object owner
) {
return new SelectorConfigurator<>(
name,
supplier,
consumer,
Currency.EMPTY,
forceUpdate,
CurrencyRegistry.getAll(),
Currency::id
);
}
}
The registry annotation makes the accessor available to ConfiguratorAccessors.findByType(...) on the client.
Choosing An Extension Point
Use a custom accessor when the mapping is type-wide: every Currency should use the same selector.
Use @ConfigList(configuratorMethod = "..."), @ConfigSearch, or manual buildConfigurator(...) when the UI depends on one owner object or one specific field.
Use @ConfigSetter when the default UI is fine, but writing the value needs validation or side effects.