This custom GUI system allows datapack creators to build interactive interfaces using JSON definitions and Lua scripting. GUIs can range from simple chest-like containers to complex custom interfaces with buttons, sliders, text boxes, and more.
Key Features:
Traditional chest-like inventory interfaces (9-54 slots). Best for item selection menus, shop interfaces, and simple button grids.
Pixel-perfect custom interfaces with unlimited flexibility. Best for complex dashboards, settings panels, interactive displays, and mini-games.
data/
└── your_namespace/
└── triggerapi/
└── gui/
├── my_gui.json # GUI definition
└── scripts/
└── my_script.lua # Lua scripts
Opening a GUI from Lua:
mc.player.openGui("your_namespace:my_gui")
Container GUIs use a traditional chest inventory layout.
{
"type": "container",
"title": "My Container",
"size": 27,
"background": {
"item": "minecraft:gray_stained_glass_pane",
"fill_empty": true
},
"container_buttons": [
{
"slot": 13,
"item": "minecraft:diamond",
"name": "§bClick Me!",
"lore": [
"§7This is a button",
"§7Click to execute script"
],
"glow": true,
"script": "mc.player.sendMessage('Button clicked!')",
"close_on_click": false
}
]
}
| Property | Type | Default | Description |
|---|---|---|---|
type | String | "custom" | Set to "container" for chest GUIs |
title | String | "GUI" | Title displayed at top of container |
size | Integer | 27 | Number of slots (multiple of 9, max 54) |
background | Object | null | Background item configuration |
container_buttons | Array | [] | List of button definitions |
| Property | Type | Default | Description |
|---|---|---|---|
item | String | null | Item ID to use as background |
fill_empty | Boolean | false | Fill all empty slots with background item |
| Property | Type | Default | Description |
|---|---|---|---|
slot | Integer | Required | Slot index (0-53) |
item | String | Required | Item ID to display |
name | String | null | Display name (supports § codes) |
lore | Array | [] | Lore lines (supports § codes) |
glow | Boolean | false | Add enchantment glint |
script | String | null | Lua script or file reference |
close_on_click | Boolean | false | Close GUI when clicked |
Scripts can be inline or file references:
Inline:
"script": "mc.player.sendMessage('Hello!')"
File reference (ends with .lua):
"script": "your_namespace:button_handler.lua"
File location: data/your_namespace/triggerapi/gui/scripts/button_handler.lua
Custom GUIs provide pixel-perfect control over layout and appearance.
{
"type": "custom",
"title": "My Custom GUI",
"width": 176,
"height": 166,
"background_texture": "your_namespace:textures/gui/my_background.png",
"elements": [
{
"type": "button",
"id": "my_button",
"x": 10,
"y": 20,
"width": 100,
"height": 20,
"texture": "minecraft:textures/gui/widgets.png",
"texture_x": 0,
"texture_y": 66,
"hover_texture_y": 86,
"script": "mc.player.sendMessage('Custom button clicked!')"
}
]
}
| Property | Type | Default | Description |
|---|---|---|---|
type | String | "custom" | Must be "custom" |
title | String | "GUI" | Window title |
width | Integer | 176 | GUI width in pixels |
height | Integer | 166 | GUI height in pixels |
background_texture | String | null | Background texture path |
elements | Array | [] | List of GUI elements |
All custom elements share base properties like id, x, y, width, and height.
| Property | Type | Default | Description |
|---|---|---|---|
type | String | Required | Element type |
id | String | Required | Unique identifier |
x | Integer | Required | X position (pixels from left) |
y | Integer | Required | Y position (pixels from top) |
width | Integer | Required | Element width in pixels |
height | Integer | Required | Element height in pixels |
tooltip | Array | [] | Tooltip lines on hover |
Interactive clickable button.
| Property | Type | Default | Description |
|---|---|---|---|
texture | String | null | Texture resource location |
texture_x | Integer | 0 | X offset in texture |
texture_y | Integer | 0 | Y offset (normal state) |
hover_texture_y | Integer | 0 | Y offset (hover state) |
image_width | Integer | 256 | Total texture width |
image_height | Integer | 256 | Total texture height |
script | String | null | Script on click |
Script Context Variables: guiId, button (0=left, 1=right, 2=middle)
Static or dynamic text display.
| Property | Type | Default | Description |
|---|---|---|---|
text | String | Required | Text to display (supports § colors) |
color | Integer (Hex) | 0x404040 | Text color (ARGB) |
shadow | Boolean | false | Enable text shadow |
scale | Float | 1.0 | Text scale multiplier |
Static image display.
| Property | Type | Default | Description |
|---|---|---|---|
texture | String | Required | Texture resource location |
texture_x | Integer | 0 | X offset in texture |
texture_y | Integer | 0 | Y offset in texture |
image_width | Integer | 256 | Total texture width |
image_height | Integer | 256 | Total texture height |
Display a Minecraft item.
| Property | Type | Description |
|---|---|---|
item | String | Item resource location (Required) |
Displays progress as a fillable bar (updated via Lua every 50ms).
| Property | Type | Default | Description |
|---|---|---|---|
bar_color | Integer (Hex) | 0xFF00FF00 | Fill color (ARGB) |
background_color | Integer (Hex) | 0xFF808080 | Background color |
border_color | Integer (Hex) | 0xFF000000 | Border color |
show_percentage | Boolean | false | Display percentage text |
vertical | Boolean | false | Vertical orientation |
progress_script | String | null | Script returning 0.0-1.0 |
Progress Script Example:
-- Must return a value between 0.0 and 1.0
return mc.player.health / mc.player.maxHealth
Interactive slider for numeric input.
| Property | Type | Default | Description |
|---|---|---|---|
min_value | Float | 0.0 | Minimum value |
max_value | Float | 100.0 | Maximum value |
default_value | Float | 50.0 | Starting value |
step | Float | 1.0 | Value increment (0=continuous) |
slider_color | Integer (Hex) | 0xFFFFFFFF | Track color |
handle_color | Integer (Hex) | 0xFF8B8B8B | Handle color |
text_color | Integer (Hex) | 0xFFFFFFFF | Value text color |
show_value | Boolean | true | Display current value |
on_change_script | String | null | Script on value change |
Script Context: ctx.value (current slider value as string)
Display a 3D rendered entity.
| Property | Type | Default | Description |
|---|---|---|---|
entity_type | String | Required | Entity resource location |
entity_scale | Float | 30.0 | Render scale |
rotate_entity | Boolean | true | Auto-rotate (360° every 3.6s) |
entity_nbt | String | null | NBT data (JSON format) |
Editable text input field.
| Property | Type | Default | Description |
|---|---|---|---|
max_length | Integer | 32 | Maximum character count |
hint_text | String | null | Placeholder text |
text_color | Integer (Hex) | 0xFFFFFFFF | Text color |
hint_color | Integer (Hex) | 0xFF808080 | Hint text color |
multiline | Boolean | false | Allow multiple lines (4x max_length) |
on_text_change_script | String | null | Script on text change |
Reading value: local username = ctx.username_input_value
Dropdown selection menu.
| Property | Type | Default | Description |
|---|---|---|---|
options | Array | Required | List of selectable options |
default_option | Integer | 0 | Default selected index |
dropdown_color | Integer (Hex) | 0xFFFFFFFF | Dropdown background |
selected_color | Integer (Hex) | 0xFF00FF00 | Selected option highlight |
text_color | Integer (Hex) | 0xFF000000 | Text color |
on_select_script | String | null | Script on selection change |
Script Context: ctx.value (selected option index as string)
Toggle switch (on/off).
| Property | Type | Default | Description |
|---|---|---|---|
default_state | Boolean | false | Starting state (true=on) |
on_color | Integer (Hex) | 0xFF00FF00 | Color when enabled |
off_color | Integer (Hex) | 0xFFFF0000 | Color when disabled |
on_toggle_script | String | null | Script on toggle |
Script Context: ctx.value ("true" or "false")
Checkbox with optional label.
| Property | Type | Default | Description |
|---|---|---|---|
default_state | Boolean | false | Starting state (true=checked) |
check_color | Integer (Hex) | 0xFF00FF00 | Checkmark color |
label | String | null | Text label next to checkbox |
label_color | Integer (Hex) | 0xFF404040 | Label text color |
checked_texture | String | null | Custom checkmark texture |
unchecked_texture | String | null | Custom unchecked texture |
on_toggle_script | String | null | Script on toggle |
Script Context: ctx.value ("true" or "false")
When scripts execute, they have access to:
mc table: Minecraft game access (see Lua API documentation)ctx table: Persistent context storage (shared across script calls)util table: Utility functionsThe ctx table persists data across button clicks and element interactions within the same GUI session.
Setting context values:
ctx.player_choice = "option_a"
ctx.counter = 5
ctx.has_completed = true
Reading context values:
if ctx.counter then
ctx.counter = ctx.counter + 1
else
ctx.counter = 1
end
mc.player.sendMessage("Count: " .. ctx.counter)
Pre-populated context variables:
guiId: Current GUI resource location (string)on_change_script when value changesprogress_script every 50ms to get current valueon_text_change_script when text changeson_select_script when selection changeson_toggle_script when toggledOpening another GUI:
mc.player.openGui("your_namespace:next_gui")
Closing current GUI:
mc.player.closeGui()
Giving items:
mc.player.giveItem("minecraft:diamond", 64)
Teleporting:
mc.player.teleport(100, 64, 200)
Broadcasting messages:
mc.util.broadcast("§6Server Announcement!")
Executing commands:
mc.util.executeCommand("time set day")
Multi-step workflow:
-- First button
if not ctx.step then
ctx.step = 1
mc.player.sendMessage("Step 1: Complete task A")
end
-- Second button
if ctx.step == 1 then
ctx.step = 2
mc.player.sendMessage("Step 2: Complete task B")
mc.player.giveItem("minecraft:diamond", 1)
end
-- Third button
if ctx.step == 2 then
mc.player.sendMessage("All steps complete!")
mc.player.closeGui()
end
For container GUIs, context is managed entirely on the server and persists across button clicks automatically.
For custom GUIs, context is synchronized between client and server:
SyncContextPacket to client with current contextGuiStateUpdatePacket when elements changeFile: data/myshop/triggerapi/gui/weapon_shop.json
{
"type": "container",
"title": "§6Weapon Shop",
"size": 27,
"background": {
"item": "minecraft:black_stained_glass_pane",
"fill_empty": true
},
"container_buttons": [
{
"slot": 11,
"item": "minecraft:wooden_sword",
"name": "§fWooden Sword",
"lore": ["§7Price: §e10 Gold", "§aClick to purchase"],
"script": "myshop:buy_item.lua",
"close_on_click": false
},
{
"slot": 13,
"item": "minecraft:iron_sword",
"name": "§fIron Sword",
"lore": ["§7Price: §e50 Gold", "§aClick to purchase"],
"glow": true,
"script": "myshop:buy_item.lua",
"close_on_click": false
},
{
"slot": 15,
"item": "minecraft:diamond_sword",
"name": "§bDiamond Sword",
"lore": ["§7Price: §e200 Gold", "§aClick to purchase"],
"glow": true,
"script": "myshop:buy_item.lua",
"close_on_click": false
}
]
}
File: data/myshop/triggerapi/gui/scripts/buy_item.lua
-- Get item name from clicked slot
local items = {
[11] = {name = "wooden_sword", price = 10},
[13] = {name = "iron_sword", price = 50},
[15] = {name = "diamond_sword", price = 200}
}
local item_data = items[tonumber(ctx.slot)]
if item_data then
mc.player.giveItem("minecraft:" .. item_data.name, 1)
mc.player.sendMessage("§aPurchased " .. item_data.name .. " for " .. item_data.price .. " gold!")
mc.player.playSound("minecraft:entity.experience_orb.pickup", 1.0)
else
mc.player.sendMessage("§cInvalid item!")
end
File: data/mymod/triggerapi/gui/settings.json
{
"type": "custom",
"title": "§6Game Settings",
"width": 200,
"height": 180,
"background_texture": "minecraft:textures/gui/demo_background.png",
"elements": [
{
"type": "text",
"id": "title",
"x": 50,
"y": 10,
"width": 100,
"height": 10,
"text": "§l§6Settings",
"color": 0xFFFFFF,
"shadow": true,
"scale": 1.5
},
{
"type": "slider",
"id": "volume_slider",
"x": 70,
"y": 30,
"width": 100,
"height": 10,
"min_value": 0.0,
"max_value": 100.0,
"default_value": 50.0,
"step": 5.0,
"show_value": true,
"on_change_script": "ctx.volume = ctx.value"
},
{
"type": "checkbox",
"id": "particles",
"x": 10,
"y": 90,
"width": 16,
"height": 16,
"default_state": true,
"label": "Enable Particles",
"label_color": 0x404040,
"on_toggle_script": "ctx.particles_enabled = ctx.value"
},
{
"type": "button",
"id": "save_button",
"x": 50,
"y": 150,
"width": 100,
"height": 20,
"texture": "minecraft:textures/gui/widgets.png",
"texture_x": 0,
"texture_y": 66,
"hover_texture_y": 86,
"script": "mymod:save_settings.lua"
}
]
}
Complete dashboard with progress bars showing health, food, and XP with auto-updating values every 50ms.
{
"type": "custom",
"title": "§bPlayer Statistics",
"width": 220,
"height": 200,
"elements": [
{
"type": "progress_bar",
"id": "health_bar",
"x": 70,
"y": 15,
"width": 130,
"height": 15,
"bar_color": 0xFFFF0000,
"background_color": 0xFF404040,
"show_percentage": true,
"progress_script": "return mc.player.health / mc.player.maxHealth"
},
{
"type": "entity",
"id": "player_model",
"x": 80,
"y": 120,
"width": 60,
"height": 80,
"entity_type": "minecraft:player",
"entity_scale": 25.0,
"rotate_entity": true
}
]
}
ctx) for persistent datamc.util.print() to log to consoleCommon colors in 0xAARRGGBB format:
| Color | Hex Code | Description | Example |
|---|---|---|---|
| White | 0xFFFFFFFF | Fully opaque white | Sample Text |
| Black | 0xFF000000 | Fully opaque black | Sample Text |
| Red | 0xFFFF0000 | Fully opaque red | Sample Text |
| Green | 0xFF00FF00 | Fully opaque green | Sample Text |
| Blue | 0xFF0000FF | Fully opaque blue | Sample Text |
| Yellow | 0xFFFFFF00 | Fully opaque yellow | Sample Text |
| Purple | 0xFF9900FF | Fully opaque purple | Sample Text |
| Gold | 0xFFFFAA00 | Fully opaque orange/gold | Sample Text |
| Aqua | 0xFF55FFFF | Fully opaque aqua | Sample Text |
| Gray | 0xFF808080 | Fully opaque gray | Sample Text |
| Dark Gray | 0xFF404040 | Fully opaque dark gray | Sample Text |
| Light Gray | 0xFFCCCCCC | Fully opaque light gray | Sample Text |
| Transparent | 0x00000000 | Fully transparent | Invisible |
| Semi-Black | 0x80000000 | 50% transparent black | 50% Transparent |
AA = Alpha (transparency): 00 = invisible, FF = opaqueRR = Red component: 00 to FFGG = Green component: 00 to FFBB = Blue component: 00 to FF
data/namespace/triggerapi/gui/filename.jsondata/namespace/triggerapi/gui/scripts/filename.luaprogress_script returns a number between 0.0 and 1.0ctx tableguiId, slot, button, clickType, value)mc table referenceminecraft:textures/gui/ for vanilla textures§ followed by color code (0-9, a-f) for text formatting