GUI Customization
Overview
All GUIs in SCS2 are defined in YAML files located in /plugins/SimpleClaimSystem/guis/. Every aspect of the GUI — layout, materials, item names, lore, click actions, and sounds — is fully customizable without touching any code.
SCS2 includes GUIs for: claim management, permissions (5 pages), flags (3 pages), members, banned players, chunks, claims list, sale browser, admin panels, the optional claim menu opened by /claim (menu_claim.yml, see Claim menu), and more.
Your files are never overwritten
A GUI file is extracted from the jar only when it does not exist yet. Once it is on disk the plugin never rewrites it, so an item you removed on purpose never comes back on a reload or a restart.
The flip side is that an item introduced by an update would only reach fresh installs. Since 2.8.1 the plugin therefore adds such an item to your existing files a single time, on the first start after the update:
- the item goes to its usual slot when it is free, otherwise to the first free slot of the page, and the console tells which file received it;
- your layout and comments are left untouched, and a copy of the file as it was is kept next to it with a
.bakextension; - the addition is recorded in
plugins/SimpleClaimSystem/gui-migrations.ymland is never attempted again. Remove the item afterwards and it stays removed; - when no slot is free, nothing is written and the console prints the block to paste by hand.
The same applies to the Bedrock forms in bedrock-guis/. 2.8.1 adds this way the PASSIVE_ENTITY_GRIEF flag (Java and Bedrock flags menus), which servers updated to 2.8 did not see in their menus, and the hologram toggle of the Bedrock settings form.
GUI Structure
Each GUI YAML file has the following base properties:
# Example: banned players GUI
gui-title: "gui-banned-title" # language file key
rows: 3 # 1-6 rows (slots = rows x 9)
slots: [0,1,2,3,4,5,6,7,8] # positions for list items
slots-sound: "minecraft:ui.button.click"
| Property | Description |
|---|---|
gui-title | Either a key in your language file (e.g., en_US.yml) or raw MiniMessage when the value doesn't match any key. The raw mode lets you embed Nexo/Oraxen glyph sequences directly to position a custom GUI background from your resource pack without editing the lang file. With Nexo, use <shift:-16> / <shift:32> for pixel offsets (negative shifts left, positive shifts right) and <glyph:my_bg> to render a glyph defined in your pack. Example: <shift:-16><glyph:gui_town1>. Supports MiniMessage tags and placeholders. |
rows | Number of rows (1 to 6). Total slots = rows x 9. |
slots | Array of slot positions where dynamic list items will be displayed (e.g., player heads in a members list). |
slots-sound | Sound played when clicking a dynamic list slot. |
Item Properties
Each item in a GUI supports the following properties:
| Property | Description |
|---|---|
slot | Position(s) in the GUI grid. Supports a single value or an array (e.g., [1,2,3]) to place the same item in multiple slots. |
material | Minecraft material type (e.g., DIAMOND_SWORD, PLAYER_HEAD). |
custom_model_data_value | Custom model data number for resource pack integration (ItemsAdder, Oraxen, etc.). |
item_model_key | Resource pack item model identifier for 1.21+ custom item models. |
target-title | Display name — references a language file key. |
target-lore | Item description — references a language file key. Supports multi-line via \n. |
target-button-on | Button text when the toggle is active (for toggle items). |
target-button-off | Button text when the toggle is inactive. |
sound | Sound played when this item is clicked. |
permission | Permission node required to see and use this item. Players without it see a filler or nothing. |
Click Actions
GUI items can respond to four click kinds: left, right, shift_left (alias shiftleft), shift_right (alias shiftright). Each entry under the actions map is a list of action steps run in declaration order — so you can chain multiple effects per click (e.g. send a message and run a command and close the GUI).
Action types
Three action types ship out of the box, registered in GuiActionFactory.fromSection:
| Type | Required keys | Description |
|---|---|---|
close (alias close_inventory) | — | Closes the player's open inventory (player.closeInventory()). |
msg (alias message) | value (MiniMessage string) | Sends the parsed message to the player via the Adventure audience. |
cmd (alias command) | value, optional executor (player or console, default player) | Runs the command. %player% is replaced with the player's name, sanitised to [A-Za-z0-9_.] to prevent command injection through hostile usernames on offline-mode servers. |
Example: single action per click
my_button:
slot: 22
material: EMERALD
target-title: "custom-button-title"
target-lore: "custom-button-lore"
sound: "minecraft:entity.experience_orb.pickup"
permission: "scs.claim.menu" # optional
actions:
left:
- type: cmd
executor: player
value: "spawn"
right:
- type: msg
value: "<green>You right-clicked!</green>"
shift_left:
- type: close
Example: chained actions
Each click kind takes a list, so a single click can fire several actions in sequence:
warp_button:
slot: 13
material: NETHER_STAR
actions:
left:
- type: msg
value: "<gray>Teleporting...</gray>"
- type: cmd
executor: console
value: "tp %player% world 0 80 0"
- type: close
shift_right:
- type: msg
value: "<red>Action cancelled.</red>"
- type: close
Built-in vs. custom actions
On every click in an SCS GUI, the dispatcher runs the built-in handler for that item key first (e.g. clicking the permissions item opens MenuPermissionsGui), then walks the actions list for that click kind. Both fire — useful for, say, opening the permissions menu AND playing a custom message in chat.
Edge cases
- Click types not in the recognised set (
MIDDLE,DROP,NUMBER_KEY, etc.) resolve tonullinClickKind.fromBukkitand run no custom action. - Permissions: when an item declares
permission:and the player lacks it, both the built-in handler and the custom actions are skipped. - YAML reload via
/scs reloadrebuilds the action map; runtime mutation isn't supported.
Adding a new action type
Implement GuiAction.execute(Player) in Guis/Actions/ and add a new case in GuiActionFactory.fromSection (and optionally fromLegacy) returning your instance. The factory dispatches by the type string at YAML load.
Legacy single-action format
Older shipped GUIs used a single-string field, still recognised by GuiActionFactory.fromLegacy:
my_button:
slot: 10
material: PAPER
action: "click:cmd:player:spawn"
# or: "click:msg:Hello world"
# or: "click:close"
Format: <prefix>:<type>[:<executor>]:<value>. The first segment (commonly click) is ignored; only type and trailing fields are parsed. The action is bound to the left click only. Use the structured actions: map above for any new item — it's strictly more powerful (multi-click, multi-step, console executor, MiniMessage).
Reserved Items
Certain item names are reserved by the GUI loader and carry built-in click behaviour. The following names are present in the shipped guis/*.yml and bedrock-guis/*.yml files:
| Item Name | Function |
|---|---|
BackPage | Navigate to the previous page of a paginated list. |
NextPage | Navigate to the next page. |
Home | Return to the parent GUI (e.g. the home menu of the current claim). |
Pick | Confirmation slot used by selection menus (banned-players list, member-management list). |
Reserved items keep their built-in click behaviour but you can still customize their material, title, lore, and slot position. BackPage/NextPage are automatically hidden when there are no more pages in that direction.