Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 75 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ Optionally install [Mod Menu](https://modrinth.com/mod/modmenu) to see loaded GU
| `/guiapi open <id> <targets>` | Open a GUI for target players |
| `/guiapi list` | List all loaded GUI definitions |
| `/guiapi reload` | Reload all datapack resources (including GUIs) |
| `/guiapi var get <player> <key>` | Get a player's runtime variable |
| `/guiapi var set <player> <key> <value>` | Set a player's runtime variable |
| `/guiapi var clear <player>` | Clear all runtime variables for a player |
| `/guiapi help` | Show command and JSON field reference in-game |

**Permission level 2** (OP) required.
Expand Down Expand Up @@ -90,6 +93,7 @@ Supported in `title`, button `name`, `lore`, `message` values, and `run_command`
| `{page1}` | Current page index (1-based) |
| `{pages}` | Total page count |
| `{score:objective}` | Player's score in the given scoreboard objective |
| `{var:key}` | Player's runtime variable `key` (empty string if unset) |

### `click_type` values

Expand All @@ -108,6 +112,12 @@ Supported in `title`, button `name`, `lore`, `message` values, and `run_command`
| `close` | — | — | Close the GUI. |
| `open_gui` | `namespace:name` | — | Close and open another GUI. |
| `message` | Text string | — | Send a chat message to the player. Supports placeholders. |
| `sound` | `namespace:sound.id` or `namespace:sound.id:volume:pitch` | — | Play a sound to the player. Volume and pitch default to `1.0`. |
| `set_var` | New value (supports placeholders) | — | Set a runtime variable. Requires `"var": "key"` field. |
| `add_var` | Integer to add | — | Add an integer to a runtime variable (creates it at 0 if unset). Requires `"var": "key"`. |
| `sub_var` | Integer to subtract | — | Subtract an integer from a runtime variable. Requires `"var": "key"`. |
| `reset_var` | — | — | Delete a single runtime variable. Requires `"var": "key"`. |
| `clear_vars` | — | — | Delete all runtime variables for this player. |
| `next_page` | — | — | Go to the next page. |
| `prev_page` | — | — | Go to the previous page. |
| `goto_page` | Page index (string) | — | Jump to a specific page. |
Expand All @@ -125,6 +135,10 @@ Conditions control button **visibility**. Hidden buttons cannot be clicked.
| `score_gt` | `"objective:threshold"` | Player's score > threshold |
| `score_lt` | `"objective:threshold"` | Player's score < threshold |
| `score_eq` | `"objective:value"` | Player's score == value |
| `var_eq` | `"key:value"` | Runtime variable `key` equals `value` (string compare) |
| `var_gt` | `"key:value"` | Runtime variable `key` (int) > `value` |
| `var_lt` | `"key:value"` | Runtime variable `key` (int) < `value` |
| `var_set` | `key` | Runtime variable `key` is set (any value) |

### Toggle buttons

Expand All @@ -137,10 +151,10 @@ A toggle button shows different item/name/lore/actions depending on a scoreboard
| `name_on` / `name_off` | string | `§aEnabled` / `§7Disabled` | Display name in each state. |
| `lore_on` / `lore_off` | string[] | `[]` | Lore in each state. |
| `glint_on` / `glint_off` | boolean | `false` | Glint in each state. |
| `actions_on` | action[] | `[tag @s remove <tag>]` | Actions when clicking while ON. Default removes the tag. |
| `actions_off` | action[] | `[tag @s add <tag>]` | Actions when clicking while OFF. Default adds the tag. |
| `actions_on` | action[] | `[tag @s remove <tag>]` | Actions executed when clicking while ON (turning OFF). Default removes the tag. |
| `actions_off` | action[] | `[tag @s add <tag>]` | Actions executed when clicking while OFF (turning ON). Default adds the tag. |

The default `actions_on`/`actions_off` use `run_with: console` and handle the tag automatically — you only need to specify them if you want additional side effects.
The tag is flipped via Java API before `actions_on`/`actions_off` run, so there is no race condition. Custom actions are executed in order after the flip — use them for sounds, messages, or side-effect commands. The GUI always reopens automatically to show the new state unless an action in the chain closes or navigates away.

---

Expand Down Expand Up @@ -181,6 +195,54 @@ The default `actions_on`/`actions_off` use `run_with: console` and handle the ta
}
```

### Runtime variables

Variables are per-player, in-memory, and cleared when the GUI closes.

```json
{
"title": "§6Counter: {var:count}",
"rows": 1,
"on_open": [
{ "type": "set_var", "var": "count", "value": "0" }
],
"buttons": [
{
"slot": 3,
"item": "minecraft:lime_dye",
"name": "§a+1",
"lore": ["§7Count: §f{var:count}"],
"actions": [
{ "type": "add_var", "var": "count", "value": "1" },
{ "type": "open_gui", "value": "example:counter" }
]
},
{
"slot": 4,
"item": "minecraft:red_dye",
"name": "§c-1",
"lore": ["§7Count: §f{var:count}"],
"condition": { "type": "var_gt", "value": "count:0" },
"actions": [
{ "type": "sub_var", "var": "count", "value": "1" },
{ "type": "open_gui", "value": "example:counter" }
]
},
{
"slot": 5,
"item": "minecraft:barrier",
"name": "§7Reset",
"actions": [
{ "type": "reset_var", "var": "count" },
{ "type": "open_gui", "value": "example:counter" }
]
}
]
}
```

> Variables survive page navigation within the same GUI but are cleared on close. Use `on_open` to initialize them to a known value.

### on_open and on_close hooks

```json
Expand All @@ -204,8 +266,16 @@ The default `actions_on`/`actions_off` use `run_with: console` and handle the ta
"item_off": "minecraft:barrier",
"name_on": "§aNotifications: ON",
"name_off": "§cNotifications: OFF",
"lore_on": ["§7Click to disable."],
"lore_off": ["§7Click to enable."]
"lore_on": ["§7Click to disable.", "§8Player: {player}"],
"lore_off": ["§7Click to enable.", "§8Player: {player}"],
"actions_on": [
{ "type": "sound", "value": "minecraft:block.lever.click:1.0:0.8" },
{ "type": "message", "value": "§7Notifications disabled, {player}." }
],
"actions_off": [
{ "type": "sound", "value": "minecraft:block.lever.click:1.0:1.2" },
{ "type": "message", "value": "§aNotifications enabled, {player}!" }
]
}
}
```
Expand Down
27 changes: 21 additions & 6 deletions example-datapack/data/example/gui/admin_panel.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"title": "§6Admin Panel §8— {player}",
"rows": 3,
"on_open": [
{ "type": "run_command", "value": "tag @s add in_admin_panel", "run_with": "console" }
{ "type": "run_command", "value": "tag @s add in_admin_panel", "run_with": "console" },
{ "type": "sound", "value": "minecraft:block.note_block.pling:1.0:1.2" }
],
"on_close": [
{ "type": "run_command", "value": "tag @s remove in_admin_panel", "run_with": "console" }
Expand All @@ -14,6 +15,7 @@
"name": "§aRules",
"lore": ["§7Click to see the server rules."],
"actions": [
{ "type": "sound", "value": "minecraft:entity.experience_orb.pickup" },
{ "type": "message", "value": "§6Rules: §fBe respectful. No griefing. No cheating." }
]
},
Expand All @@ -25,6 +27,7 @@
"click_type": "left",
"actions": [
{ "type": "run_command", "value": "tp @s 0 64 0" },
{ "type": "sound", "value": "minecraft:entity.enderman.teleport" },
{ "type": "close" }
]
},
Expand All @@ -46,9 +49,17 @@
"item_off": "minecraft:shield",
"name_on": "§cPvP: ON",
"name_off": "§aPvP: OFF",
"lore_on": ["§7Click to disable PvP."],
"lore_off": ["§7Click to enable PvP."],
"glint_on": true
"lore_on": ["§7Click to disable PvP.", "§8Player: {player}"],
"lore_off": ["§7Click to enable PvP.", "§8Player: {player}"],
"glint_on": true,
"actions_on": [
{ "type": "sound", "value": "minecraft:block.anvil.land:0.5:1.0" },
{ "type": "message", "value": "§cPvP disabled, {player}." }
],
"actions_off": [
{ "type": "sound", "value": "minecraft:entity.player.attack.sweep" },
{ "type": "message", "value": "§aPvP enabled, {player}!" }
]
}
},
{
Expand All @@ -73,15 +84,19 @@
"condition": { "type": "has_tag", "value": "admin" },
"actions": [
{ "type": "run_command", "value": "gamemode creative @s", "run_with": "console" },
{ "type": "message", "value": "§aCreative mode enabled." },
{ "type": "sound", "value": "minecraft:ui.toast.challenge_complete:1.0:0.8" },
{ "type": "message", "value": "§aCreative mode enabled, {player}." },
{ "type": "close" }
]
},
{
"slot": 16,
"item": "minecraft:barrier",
"name": "§cClose",
"actions": [{ "type": "close" }]
"actions": [
{ "type": "sound", "value": "minecraft:block.wooden_button.click_off" },
{ "type": "close" }
]
}
]
}
63 changes: 63 additions & 0 deletions example-datapack/data/example/gui/counter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"title": "§6Counter: §f{var:count} §8— {player}",
"rows": 1,
"on_open": [
{ "type": "set_var", "var": "count", "value": "0" },
{ "type": "sound", "value": "minecraft:block.note_block.pling:0.8:1.0" }
],
"buttons": [
{
"slot": 2,
"item": "minecraft:lime_dye",
"name": "§a+1",
"lore": ["§7Current: §f{var:count}"],
"actions": [
{ "type": "add_var", "var": "count", "value": "1" },
{ "type": "sound", "value": "minecraft:block.note_block.pling:1.0:1.5" },
{ "type": "open_gui", "value": "example:counter" }
]
},
{
"slot": 3,
"item": "minecraft:red_dye",
"name": "§c-1",
"lore": ["§7Current: §f{var:count}", "§8Disabled at 0."],
"condition": { "type": "var_gt", "value": "count:0" },
"actions": [
{ "type": "sub_var", "var": "count", "value": "1" },
{ "type": "sound", "value": "minecraft:block.note_block.bass:1.0:1.0" },
{ "type": "open_gui", "value": "example:counter" }
]
},
{
"slot": 4,
"item": "minecraft:paper",
"name": "§fValue: §e{var:count}",
"lore": [
"§7Player: §f{player}",
"§7GUI: §8{gui}"
]
},
{
"slot": 5,
"item": "minecraft:comparator",
"name": "§7Reset",
"lore": ["§8Only visible when count > 0."],
"condition": { "type": "var_set", "value": "count" },
"actions": [
{ "type": "reset_var", "var": "count" },
{ "type": "sound", "value": "minecraft:block.lever.click:1.0:0.8" },
{ "type": "open_gui", "value": "example:counter" }
]
},
{
"slot": 7,
"item": "minecraft:barrier",
"name": "§cClose",
"actions": [
{ "type": "sound", "value": "minecraft:block.wooden_button.click_off" },
{ "type": "close" }
]
}
]
}
Loading