> For the complete documentation index, see [llms.txt](https://tanishisherewith.gitbook.io/dynamic-hud/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tanishisherewith.gitbook.io/dynamic-hud/widget/how-to-create-a-custom-widget.md).

# How to create a custom widget

## Creating a Custom Widget

Extend the `Widget` class to create custom widgets in **DynamicHUD**, defining unique rendering and behavior. Use `DynamicValueWidget` for widgets with dynamic data (e.g., `TextWidget`, `GraphWidget`), which links to `DynamicValueRegistry` for real-time values. Widgets use `WidgetBuilder` for fluent construction and support saving/loading via NBT.

#### Example: Custom Widget

```java
public class MyWidget extends DynamicValueWidget {
    public static WidgetData<MyWidget> DATA = new WidgetData<>("MyWidget", "Custom widget", MyWidget::new);

    public MyWidget(String modId, String registryID, String registryKey) {
        super(DATA, modId, registryID, registryKey);
    }

    @Override
    public void renderWidget(DrawContext context, int mouseX, int mouseY) {
        String text = (String) getValue();
        DrawHelper.drawText(context, text, x, y, 0xFFFFFF);
    }

    @Override
    public Object getValue() {
        return valueSupplier != null ? valueSupplier.get() : "";
    }

    public static class Builder extends DynamicValueWidgetBuilder<Builder, MyWidget> {
        @Override
        public MyWidget build() {
            return new MyWidget(modID, registryID, registryKey)
                .setPosition(x, y)
                .setDisplay(display)
                .setLocked(isLocked)
                .setShouldScale(shouldScale);
        }
    }
}
```

* **Purpose**: Displays dynamic text from `DynamicValueRegistry`.
* **Builder**: Configures position, visibility, and registry keys.
* **Rendering**: Uses `DrawHelper` for text rendering (supports shapes, gradients, textures via `DrawHelper`, `ColorHelper`, `TextureHelper`).

#### Saving and Loading

Override `writeToTag` and `readFromTag` to save/load custom fields. Always call `super` to preserve base properties (e.g., position, `modId`).

```java
@Override
public void writeToTag(NbtCompound tag) {
    super.writeToTag(tag);
    // Add custom fields
}

@Override
public void readFromTag(NbtCompound tag) {
    super.readFromTag(tag);
    // Read custom fields
}
```

{% hint style="warning" %}
Call `super` in `writeToTag` and `readFromTag` to avoid losing base widget properties.
{% endhint %}
