DataUI Developer Guide
v1.0.0 Β· Forge 1.12.2
Developer Documentation

DataUI Developer Guide & Wiki

Official documentation for the declarative, reactive, and modern user interface framework for Minecraft.

DataUI 1.0.0Forge 1.12.2Responsive

πŸ“˜ DataUI Developer Guide & Wiki

Welcome to the official documentation for DataUI, the declarative, reactive, and modern user interface framework for Minecraft (Forge 1.12.2).

Mod version: 1.0.0

πŸ“‘ Table of Contents

  1. Philosophy & Principles
  2. Quick Start (Creating a Screen)
  3. Declarative Layout System
  4. Size Management & Responsive
  5. Overflow Policy (Overflow & Overlap)
  6. Reactivity & State Binding (Signals)
  7. Widget Catalog
  8. Animations & Transitions
  9. Themes & Design Tokens
  10. Debug Mode & Profiler
  11. Concrete Examples

1. Philosophy & Principles

DataUI is built on four pillars:


2. Quick Start (Creating a Screen)

To create a screen in your mod, extend DataUIScreen and build the node tree in buildUI():

package com.monmod.client.gui;

import com.dataui.api.UI;
import com.dataui.core.Node;
import com.dataui.forge.DataUIScreen;

public class MyMachineScreen extends DataUIScreen {

    @Override
    protected Node buildUI() {
        return UI.stack()
            .fillScreen()
            .add(
                UI.panel()
                    .width(400)
                    .height(280)
                    .centerInParent()
                    .padding(16)
                    .add(
                        UI.column()
                            .gap(10)
                            .add(UI.text("Energy Generator").fontSize(14).color(0xFFFFFF))
                            .add(UI.button("Activate").onClick(() -> System.out.println("Click!")))
                    )
            );
    }
}

To open your screen on the client side:

Minecraft.getMinecraft().displayGuiScreen(new MyMachineScreen());

3. Declarative Layout System

DataUI provides several specialized containers accessible via the static UI API:

UI.column()

Stacks children vertically from top to bottom.

UI.column()
    .gap(8)                // Pixel spacing between each child
    .padding(12)           // Inner margin
    .add(UI.text("Line 1"))
    .add(UI.text("Line 2"));

UI.row()

Aligns children horizontally from left to right.

UI.row()
    .gap(6)
    .add(UI.button("Cancel"))
    .add(UI.button("Confirm"));

UI.grid()

Responsive grid with fixed columns or automatic calculation (autoFit).

// Responsive grid: automatically adapts to available width (columns of at least 120px)
UI.grid()
    .autoFit(120)
    .gap(8)
    .add(card1)
    .add(card2)
    .add(card3);

UI.stack()

Layers children on the same space (layers / z-order).
*Note: Overlap between children is normal and allowed in a Stack.*

UI.stack()
    .add(backgroundLayer)
    .add(contentLayer)
    .add(tooltipLayer);

4. Size Management & Responsive

You can set width (width) and height (height) using the Size utility or numeric values:

ModeExampleDescription
Fixed (pixels).width(200) or .size(200, 100)Fixed size in pixels.
Fill container.width(Size.fill())Occupies 100% of the available space in the parent.
Percentage.width(Size.percent(50))Occupies 50% of the parent's width.
Content.width(Size.content())Adjusts exactly to the internal content size.

Min / Max Constraints

To ensure readability and prevent an element from becoming too small or too large when resizing:

UI.button("Start")
    .width(Size.fill())
    .minWidth(100)       // Will never go below 100px
    .maxWidth(250);      // Will never exceed 250px

5. Overflow Policy (Overflow & Overlap)

DataUI handles interface overflow cleanly:

UI.panel()
    .overflow(OverflowPolicy.AUTO) // Default behavior

Policies (OverflowPolicy)

PolicyGeometric EffectRender Effect (Scissor)Debug Profiler
AUTO (Default)No changeProtected by Scissor on overflowWarning
VISIBLENo changeNo scissor (e.g. dropdowns, tooltips)No warning
CLIPNo changePermanent scissor on boundsNo warning
SCROLLNo changeUsed with the Scroll widgetNo warning
SHRINKProportionally shrinks flexible children (with minWidth/minHeight floor)Scissor if still too largeNo warning
WARNNo changeNo scissorWarning

Overflow vs Overlap

*(In debug mode F9, these two alerts are listed separately.)*


6. Reactivity & State Binding (Signals)

Create state signals to bind your game variables to the interface without manual polling:

// 1. Declare signals
Signal energy = new Signal<>(4500);
Signal status = new Signal<>("Waiting");

// 2. Bind to widgets
UI.text(status)                     // Text updates automatically
    .fontSize(12);

UI.progress(energy)                 // Gauge animates automatically
    .max(10000)
    .width(200);

// 3. Change the value anywhere in your code
energy.set(7800);
status.set("Running");

7. Widget Catalog

πŸ”² Containers & Cards

πŸ“ Text & Badges

πŸ”˜ Controls & Inputs

πŸ“Š Data & Bars


UI.scroll(): enable scrolling and choose the scrollbar

By default, mouse wheel scrolling and the scrollbar are active. These two options are independent:

// Scrollable content, but hidden scrollbar.
UI.scroll()
.scrollbarVisible(false)
.add(content);

// Fixed area: no mouse wheel scrolling, no scrollbar.
UI.scroll()
.scrollEnabled(false)
.scrollbarVisible(false)
.add(content);

When scrollEnabled(false) is used in a nested scroll, the mouse wheel is passed to the parent container.


8. Animations & Transitions

DataUI includes a smooth animation engine based on easing curves:

// Fade-in and translation appearance animation
UIAnimation.fadeIn(myPanel, 300); // 300 ms

// Custom transition
UIAnimation.tween(node)
    .property("alpha", 0.0f, 1.0f)
    .property("scale", 0.8f, 1.0f)
    .duration(250)
    .easing(Easing.EASE_OUT_CUBIC)
    .start();

9. Themes & Design Tokens

Customize colors, corner radius, and styles globally:

// Define a modern dark theme
Theme darkTheme = new Theme()
    .setBackgroundColor(0xEE1E1E2E)
    .setPrimaryColor(0xFF89B4FA)
    .setTextColor(0xFFCDD6F4)
    .setCornerRadius(6);

DataUI.setTheme(darkTheme);

10. Debug Mode & Profiler

During development, enable debug mode to visualize the component tree, FPS, UI frame time, and warnings in real time:

// In your mod initialization (ClientProxy)
DataUI.debug(true);

Developer Shortcut

In production mode (DataUI.debug(false)), all diagnostic calculations are automatically disabled to ensure optimal performance.


11. Concrete Examples

Full example: Industrial machine control screen

Goals achieved:

public class MachineScreen extends DataUIScreen {

    private final Signal energy = new Signal<>(7200);
    private final Signal temperature = new Signal<>(42.5f);
    private final Signal active = new Signal<>(true);
    private final Signal status = active.map(a -> a ? "Β§aRUNNING" : "Β§cSTOPPED");

    @Override
    protected Node buildUI() {
        return UI.stack()
            .fillScreen()

            // ── Background ───────────────────────────────────────────────
            .add(
                UI.panel()
                    .fillScreen()
                    .color(0xFF10131A)
            )

            // ── Main Content (90% responsive + Auto-protected) ───────────
            .add(
                UI.panel()
                    .width(Size.percent(90))
                    .height(Size.percent(90))
                    .centerInParent()
                    .padding(16)
                    .overflow(OverflowPolicy.AUTO)
                    .add(
                        UI.column()
                            .gap(12)

                            // ── Header ──────────────────────────────────
                            .add(
                                UI.row()
                                    .gap(10)
                                    .add(
                                        UI.column()
                                            .gap(2)
                                            .add(UI.text("INDUCTION FURNACE").fontSize(16).color(0xFFFFFFFF))
                                            .add(UI.text("Main factory β€’ Level 2").fontSize(10).color(0xFF8A93A6))
                                    )
                                    .add(UI.panel().width(Size.fill()))
                                    .add(UI.badge("● CONNECTED", 0xFF45D483))
                            )

                            // ── Status + Energy ─────────────────────────
                            .add(
                                UI.card("Machine status", "Real-time information")
                                    .add(
                                        UI.column()
                                            .gap(8)
                                            .add(
                                                UI.row()
                                                    .gap(8)
                                                    .add(UI.text("Status").fontSize(11))
                                                    .add(UI.text(status).fontSize(11))
                                            )
                                            .add(UI.text("Energy").fontSize(11))
                                            .add(
                                                UI.progress(energy)
                                                    .max(10000)
                                                    .width(Size.fill())
                                            )
                                            .add(
                                                UI.row()
                                                    .gap(6)
                                                    .add(UI.text("7 200 / 10 000 FE").fontSize(10).color(0xFF8A93A6))
                                            )
                                    )
                            )

                            // ── Responsive Statistics (Auto-reflow Grid) ─
                            .add(
                                UI.grid()
                                    .autoFit(130)
                                    .gap(8)
                                    .add(
                                        UI.card("Temperature", "")
                                            .add(UI.text(temperature.map(t -> String.format("%.1f Β°C", t))).fontSize(18))
                                    )
                                    .add(
                                        UI.card("Production", "")
                                            .add(UI.text("1 240 RF/t").fontSize(18))
                                    )
                                    .add(
                                        UI.card("Efficiency", "")
                                            .add(UI.text("94.7 %").fontSize(18))
                                    )
                                    .add(
                                        UI.card("Uptime", "")
                                            .add(UI.text("04:32:18").fontSize(18))
                                    )
                            )

                            // ── Controls + Activity Logs ────────────────
                            .add(
                                UI.row()
                                    .gap(12)

                                    // Controls
                                    .add(
                                        UI.card("Control", "Machine management")
                                            .width(Size.percent(40))
                                            .add(
                                                UI.column()
                                                    .gap(8)
                                                    .add(
                                                        UI.button("Start")
                                                            .width(Size.fill())
                                                            .onClick(() -> active.set(true))
                                                    )
                                                    .add(
                                                        UI.button("Stop")
                                                            .width(Size.fill())
                                                            .onClick(() -> active.set(false))
                                                    )
                                                    .add(
                                                        UI.slider(0, 100, 1, 75)
                                                            .width(Size.fill())
                                                    )
                                            )
                                    )

                                    // Scrollable log
                                    .add(
                                        UI.card("Log", "Recent events")
                                            .width(Size.fill())
                                            .add(
                                                UI.scroll()
                                                    .height(130)
                                                    .add(
                                                        UI.column()
                                                            .gap(5)
                                                            .add(UI.text("12:42  Β§aProduction started"))
                                                            .add(UI.text("12:43  Β§7Temperature stabilized"))
                                                            .add(UI.text("12:45  Β§eHigh energy"))
                                                            .add(UI.text("12:47  Β§aNominal production"))
                                                            .add(UI.text("12:49  Β§7Automatic maintenance"))
                                                    )
                                            )
                                    )
                            )
                    )
            );
    }
}

Rendering and Automatic Responsive Adaptation

With a wide interface:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ INDUCTION FURNACE                          ● CONNECTED      β”‚
β”‚ Main factory                                               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Machine status                                             β”‚
β”‚ RUNNING                                                    β”‚
β”‚ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 7200 / 10000             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Temperatureβ”‚ Production β”‚ Efficiency β”‚ Uptime              β”‚
β”‚ 42.5 Β°C    β”‚ 1240 RF/t  β”‚ 94.7 %     β”‚ 04:32:18            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Control                 β”‚ Log                              β”‚
β”‚                         β”‚                                   β”‚
β”‚ [ Start ]               β”‚ 12:42 Production started         β”‚
β”‚ [ Stop  ]               β”‚ 12:43 Temperature stabilized     β”‚
β”‚                         β”‚ 12:45 High energy                β”‚
β”‚ ──────────────          β”‚ ...                               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

When the window is narrowed, UI.grid().autoFit(130) dynamically reorganizes the cards from 4 columns to 3, then 2, then 1 column, without any additional code.