Skip to content

API Container GUIs

Piggo41 edited this page Oct 16, 2026 · 15 revisions

Container GUIs

Lua API / Container GUIs

On this page

betamoon.containerGuis:add(definition)

Registers a declarative screen for a container. Returns a handle with qualified name. Required name and container handle; the container must belong to the same script. Changes require restart.

local gui = betamoon.containerGuis:add {
    name = "mymod:block/storage", container = container,
    layout = { title = "Storage" },
    elements = { { type = "text", text = "Input", x = 40, y = 24 } }
}

Field definitions

layout

Field Type Default / meaning
preset string minecraft:container; selects built-in background defaults.
rows integer 1–6 3; chest row count.
width integer 1–256 Texture width when supplied, otherwise 176.
height integer 1–256 Texture height or default 166; chest uses 114 + rows × 18.
title label Inventory name at x=8,y=6.
playerInventoryLabel label Inventory at x=8,y=height−94.
pauseGame boolean Default false.

Labels

A label can be a string, false to hide it, or a table: text, x, y, width, color, align, shadow. Omitted coordinates/text use the defaults above; width defaults to GUI width−16; color defaults 0x404040; align defaults left and shadow false.

background

Optional table.

Field Type Default / meaning
style string Optional minecraft generated panel or chest style.
image texture reference/key or PNG path Optional custom background.
builtin string Optional named built-in background.
drawSlotFrames boolean Default false; draws frames at container slot positions.

Without an explicit image/builtin/style, layout preset selects the background. Built-ins: minecraft:container, minecraft:chest, minecraft:dispenser, minecraft:furnace, minecraft:crafting, minecraft:inventory. Custom image takes precedence over builtin.

Common element fields

elements is a list of declarations. Non-group elements accept:

Field Default / meaning
type Required element type below.
x, y 0; local pixel offsets, including parent group offsets.
anchor top_left; other values listed below.
layer content; background/content/foreground drawing order.
visibleWhen Optional condition.
tooltip Optional text or list of lines.

Fixed-size elements must fit the canvas. Item previews occupy 16×16 pixels. Anchors: top_left, top_center, top_right, center, bottom_left, bottom_center, bottom_right.

Image sources

Image/progress elements choose image (texture reference/key or relative PNG path) or builtin, not both. Progress backgrounds choose background (texture reference/key or PNG path) or backgroundBuiltin, not both. Absolute engine texture paths are rejected for element images.

Built-in sprite Dimensions
minecraft:furnace_flame 14×14
minecraft:furnace_flame_background 14×14; unlit flame, placed behind flame progress
minecraft:furnace_arrow 24×16
minecraft:furnace_arrow_background 24×16; empty arrow, placed behind arrow progress
minecraft:crafting_arrow 24×17
minecraft:slot 18×18
minecraft:output_slot 26×26

type = "image"

Draws an image. Required image/builtin source. Optional positive width, height default to source dimensions.

{ type = "image", builtin = "minecraft:slot", x = 20, y = 20 }

type = "text"

Draws text or a synchronized field value. Requires text or value. value is a synchronized tile field name; format formats that one value: for example, "Progress: %d" for an integer or "Active: %s" for a boolean. An invalid format falls back to the plain value. Optional align (left/center/right), width (default 0), color (default 0x404040), shadow (false).

{ type = "text", value = "progress", x = 8, y = 60 }

type = "progress"

Draws a clipped progress image. Required value (synced field), maximum (positive integer or synced field name), and image/builtin source.

Optional direction: left_to_right (default), right_to_left, top_to_bottom, bottom_to_top. minimumPixels defaults 0 and is clamped nonnegative. hideWhenEmpty defaults false. Optional background/backgroundBuiltin draws behind the fill.

{ type = "progress", value = "progress", maximum = 100,
  builtin = "minecraft:furnace_arrow", x = 76, y = 35 }

type = "state_image"

Selects an image by synchronized value field. Supply states mapping stringified field values to texture references/keys or PNG paths, or whenTrue / whenFalse texture references/keys or PNG paths. Those boolean shortcuts override corresponding state entries. Optional default texture reference/key or PNG is used when no state matches; otherwise nothing is drawn.

{ type = "state_image", value = "active",
  whenTrue = "on.png", whenFalse = "off.png", x = 8, y = 20 }

type = "rectangle"

Draws a solid rectangle. Requires positive width, height, and color.

{ type = "rectangle", width = 40, height = 2, color = "gray", x = 8, y = 20 }

type = "tooltip"

Adds a hover region. Requires positive width and height; provide tooltip or fallback text as text/list.

{ type = "tooltip", width = 24, height = 16, text = "Progress", x = 76, y = 35 }

type = "item"

Draws a non-interactive item preview. Exactly one of slot (declared inventory slot name) and item (fixed stack) is required. showCount defaults true.

{ type = "item", slot = "input", showCount = true, x = 8, y = 30 }

Interactive slots belong to the container declaration, not this preview element.

type = "group"

Groups child elements with inherited x, y offsets and visibleWhen. Child conditions are ANDed with the group condition.

{ type = "group", x = 8, y = 20,
  elements = { { type = "text", text = "Status" } } }

Interactive controls

Interactive elements reference behavior declared in the container's controls table. The seven built-in elements are:

GUI element Container control Purpose and default size
button action Text action button, 100 x 20.
icon_button action Compact icon action button, 20 x 20.
checkbox toggle 12 x 12 checkbox, optionally followed by text.
toggle_button toggle Text button with selected and unselected states, 100 x 20.
slider number Horizontal or vertical numeric control, 100 x 20.
text_box text Editable text field, 100 x 16.
choice choice Previous/value/next selector, 100 x 20.

toggle is also accepted as an alias for toggle_button. The advanced interactive element binds to a custom control and provides a blank surface for custom pointer logic.

All require control, accept positive width and height, and accept text, focusable, style, and visuals. The default style is betamoon:classic. Slider supports orientation = "horizontal"|"vertical". Slider and custom interactive elements accept captureDrag; it defaults to true. Set it to false when the control should receive the normal press and release without receiving captured drag updates while the primary button is held. Interactive elements consume their mouse action before Minecraft slot handling, so a slot underneath is not clicked.

  • Buttons, icon buttons, checkboxes, and toggle buttons activate after a primary press and release inside the element.
  • Choice selectors move backward or forward through their left and right arrow regions. Keyboard arrows also change the value; secondary click remains a backward shortcut.
  • Sliders clamp and snap while dragging; arrows change one step and Page Up/Down use pageStep.
  • Text boxes accept mouse caret placement, horizontally scroll long values, and support keyboard selection, copy/cut/paste, editing, navigation, Enter commit, Escape revert, and commit on focus loss. Holding a character, Backspace, Delete, or navigation key uses the platform's normal delayed key repeat. If tile text changed while focused, the external value wins and ctx.input.conflicted is true.
  • Tab and Shift+Tab move focus through visible, enabled, focusable controls.
  • Custom controls receive press, drag, release, scroll, focus, and blur phases through onInput. Pointer input provides element-local x/y; captured drag and release input also provides deltaX/deltaY. The complete callback input table is documented under container controls.
elements = {
    { type = "button", control = "reset", x = 8, y = 18, text = "Reset" },
    { type = "icon_button", control = "reset", x = 112, y = 18, iconBuiltin = "confirm" },
    { type = "checkbox", control = "enabled", x = 8, y = 44, text = "Enabled" },
    { type = "toggle_button", control = "enabled", x = 8, y = 62, text = "Power" },
    { type = "slider", control = "speed", x = 8, y = 88, width = 120 },
    { type = "text_box", control = "label", x = 8, y = 114, width = 120 }
}

An icon button requires either icon, using a texture asset/key/path, or iconBuiltin. Built-in icon names are close, confirm, plus, and minus.

Interactive elements in the same layer may not overlap. Hidden or disabled controls release pending interaction ownership.

Control visuals

Every control uses bundled Minecraft-style sprites from style = "betamoon:classic". The sprites support normal, hovered, pressed, focused, disabled, and invalid interaction states; checkboxes and toggle buttons also show their selected state. Rejected value changes briefly use the invalid state.

Override individual states with visuals: normal, hovered, pressed, focused, disabled, selected, invalid, or a selected interaction state such as selected_hovered. A state accepts a texture asset/key/path, or { texture = asset, border = pixels } for nine-slice scaling. Omitted states keep the built-in style. Asset overrides follow the normal bm_assets/ texture-pack rules.

visuals = {
    normal = { texture = "mymod:gui/button", border = 3 },
    hovered = { texture = "mymod:gui/button_hovered", border = 3 }
}

Texture packs can restyle the built-in controls under bm_assets/betamoon/textures/gui/controls/. For example, the normal button frame is bm_assets/betamoon/textures/gui/controls/button/normal.png. Keep each replacement image's dimensions and nine-slice border layout compatible with the original.

visibleWhen

Single comparison: exactly one of field (synced tile field) or session (container-session field), plus exactly one of equals, notEquals, greaterThan, greaterOrEqual, lessThan, lessOrEqual. Ordered comparisons require numeric data and a numeric operand.

Compound conditions use either all = { ... } or any = { ... }, never both. Groups must be nonempty.

visibleWhen = { field = "progress", greaterThan = 0 }

Colors

Accept an integer color or named Minecraft color: black, dark_blue, dark_green, dark_aqua, dark_red, dark_purple, gold, gray, dark_gray, blue, green, aqua, red, light_purple, yellow, white.

Synchronized presentation

Field-based elements and conditions require declared data with sync = true; only integer/boolean tile data can synchronize. Tooltip text substitutes {fieldName} with the synchronized value, for example "Heat: {heat}"; see the showcase for presentation combinations.

Example assets: GUI showcase assets and installation.

The showcase PNG assets are available under the MIT License.

GUI lookup

Method Result
betamoon.containerGuis:get(name) GUI handle, or nil when absent.
betamoon.containerGuis:getRequired(name) GUI handle; raises an error when absent.
betamoon.containerGuis:find(query) Result list filtered by optional name, owner, and container.
betamoon.containerGuis:first(query) First match, or nil.
betamoon.containerGuis:one(query) Sole match, nil for none, or an error for multiple matches.

GUI handle

A live handle exposes name, owner, exists, container, effective width and height, pauseGame, and elementCount.

gui:override(definition)

Replaces the complete validated presentation while retaining the original container and its slots/control schema. New screens use the effective definition. Removing the returned override handle restores the previous presentation.

Clone this wiki locally