Skip to main content
The Open GUI Action creates and displays an inventory-based GUI with layout pools, advanced interactions, animations, and persistent storage.

Core Parameters

guiType
GuiType
default:"CUSTOM"
Type of GUI to display. Choose from 23 supported types.
title
Var<String>
Title displayed at the top of the GUI. Supports MiniMessage, PlaceholderAPI, and CraftEngine tags.
size
InventorySize
Size of the inventory (only for CUSTOM type). Values: 9, 18, 27, 36, 45, 54.

Layout System

The layout pool defines reusable layout components referenced by ID.
layoutPool
List<LayoutData>
Available layout definitions. Each layout has an id field. Types: simple, flex, paginated, scrollable, frame, composite, book, merchant.
mainLayoutId
String
ID of the layout to display from the pool. If omitted, an EmptyLayout is used.

Layout Types

SimpleLayout — items placed at explicit (x, y) coordinates on a virtual grid. Each item uses x, y, count, direction, gap, and repeatY for positioning. FlexLayout — auto-positioning with justifyContent (START, CENTER, END, SPACE_BETWEEN), alignItems (START, CENTER, END), and wrap. PaginatedLayout — discrete pages with configurable itemsPerPage, nextPage/previousPage buttons. ScrollableLayout — wraps an innerId layout with scroll support. Configurable virtualWidth, virtualHeight, custom scroll buttons, and showDefaultButtons. Scroll navigation buttons (UP/DOWN/LEFT/RIGHT) are separate from content and can be positioned independently. FrameLayout — divides the screen into named frames. Each frame: id, x, y, width, height, layoutId. Frames can overlap with fixed-position scroll buttons. CompositeLayout — layers multiple children layouts (by their IDs) on top of each other. BookLayout — renders pages as a written book with MiniMessage formatting. MerchantLayout — defines trades with result, costOne, optional costTwo, maxUses, experienceReward, villagerExperience, priceMultiplier, and criteria (conditions per trade — hidden if not met).

Item Configuration (GuiItemData)

All items use XY grid positioning — no legacy index-based slots field.
x
Int
X coordinate (0-8) in the virtual slot grid. Required for all slots.
y
Int
Y coordinate (0-5) for 6-row inventories. Required for all slots.
count
Int
default:"1"
Number of slots to generate starting from (x, y), repeating in the configured direction.
direction
Direction
default:"RIGHT"
Direction of repetition for multiple slots. Options: RIGHT, DOWN, LEFT, UP.
gap
Int
default:"1"
Gap in slots between repetitions when count > 1.
repeatY
Int
default:"1"
Number of rows to repeat in 2D grid. When set, slots repeat horizontally first (via direction/count), then repeat vertically by this many rows.
item
Var<Item>
The item to display. Use Item.Empty for the player’s held item.
displayName
Var<String>?
default:"null"
Custom display name. Supports placeholders and MiniMessage.
lore
List<Var<String>>
default:"[]"
Custom lore lines.
criteria
List<Criteria>
default:"[]"
Conditions for this item to appear. Evaluated at menu build time.
interactionList
List<InteractionData>
default:"[]"
Click actions per interaction type (LEFT_CLICK, RIGHT_CLICK, SWAP_OFFHAND, etc.). Each entry: type, commands, triggers, closeMenu, executeReturn.
allowPickup
Boolean
default:"false"
Allow the player to take the item from the GUI.
isGhost
Boolean
default:"false"
Click copies the item to the cursor without removing it from the slot.
fill
Boolean
default:"false"
Fill all empty slots with this item configuration.
cooldownTicks
Long
default:"0"
Cooldown in ticks (50ms each) before the slot can be clicked again. 0 = disabled.
animation
SlotAnimationData?
Smooth movement animation: targetX, targetY, duration (ms), easing (linear, ease_in, ease_out).
input
InputData?
Dialog input configuration: title, placeholder, targetVar, onInputCommands, onInputTriggers.
triggers
List<Ref<TriggerableEntry>>
default:"[]"
Triggers executed when the slot is clicked.
modifiers
List<Modifier>
default:"[]"
Fact modifiers applied on click.

Storage Slots

Slots can persist items across sessions by referencing a GUI Storage artifact.
storage
StorageSlotData?
Persistent storage configuration for this slot. When set, click interactions are handled by the storage system instead of interactionList.

Storage Placeholders

In storage slot displayName and lore, use these placeholders that resolve at render time:
PlaceholderDescriptionExample
{stored_name}Display name of the stored itemDiamond
{stored_amount}Current item count42
{stored_max}Maximum slot capacity64

Click Configuration

Storage click behaviors are globally configurable via GUI Settings. Default mappings:
ActionDefault Click
Place one itemLEFT
Place all from cursorSHIFT_LEFT
Take one itemRIGHT
Take all from slotSHIFT_RIGHT
Take one stack (64)SWAP_OFFHAND
Fill from inventoryDOUBLE_CLICK
Drop all on groundDROP

Interaction Configuration

globalInteractions
List<InteractionData>
default:"[]"
Menu-wide keybind handlers. Each entry: type (InteractionType), commands, triggers, closeMenu, executeReturn.

Interaction Types

LEFT_CLICK, RIGHT_CLICK, SHIFT_LEFT_CLICK, SHIFT_RIGHT_CLICK, MIDDLE_CLICK, DOUBLE_CLICK, NUMBER_KEY_1..9, DROP, DROP_ALL, SWAP_OFFHAND, SCROLL_UP, SCROLL_DOWN

Internal Commands

CommandEffect
gui:closeClose current menu
gui:backReturn to previous menu
gui:scroll <dx> <dy> [targetId]Scroll viewport
gui:scroll_upScroll up 1 row (shorthand)
gui:scroll_downScroll down 1 row (shorthand)
gui:scroll_leftScroll left 1 column (shorthand)
gui:scroll_rightScroll right 1 column (shorthand)
gui:page <delta> [layoutId]Change paginated page
gui:slider_set <index>Update slider position
gui:inputOpen input dialog
gui:open <entryId>Open another menu
gui:action <entryId>Trigger another entry

Audio

audio
GuiAudioData
Lifecycle sounds: onOpen, onClose, onScroll, onClick — each accepts Typewriter Sound objects.

Example: Shop Menu

action:
  type: open_gui
  id: "shop_main"
  guiType: CUSTOM
  size: "54"
  title: "<bold><gold>Server Shop</gold></bold>"
  mainLayoutId: "shop_flex"
  layoutPool:
    - type: "flex"
      id: "shop_flex"
      justifyContent: "CENTER"
      alignItems: "CENTER"
      wrap: true
      items:
        - x: 2
          y: 2
          item: { material: DIAMOND_SWORD }
          displayName: "<aqua>Weapons"
          interactionList:
            - type: LEFT_CLICK
              commands: ["shop open weapons"]
        - x: 6
          y: 2
          item: { material: IRON_CHESTPLATE }
          displayName: "<aqua>Armor"
          interactionList:
            - type: LEFT_CLICK
              commands: ["shop open armor"]
  globalInteractions:
    - type: DROP
      closeMenu: true
  audio:
    onOpen: { sound: "block.chest.open", volume: 1.0 }
    onClose: { sound: "block.chest.close", volume: 1.0 }

Example: Scrollable Crate Menu

action:
  type: open_gui
  id: "crate_rewards"
  guiType: CUSTOM
  size: "54"
  title: "<gold>Crate Rewards"
  mainLayoutId: "reward_scroll"
  layoutPool:
    - type: "scrollable"
      id: "reward_scroll"
      virtualWidth: 9
      virtualHeight: 12
      showDefaultButtons: true
      innerId: "reward_items"
    - type: "simple"
      id: "reward_items"
      items:
        - x: 0
          y: 0
          count: 9
          direction: RIGHT
          item: { material: DIAMOND }
          displayName: "<aqua>Reward {index}"
          interactionList:
            - type: LEFT_CLICK
              commands: ["give %player% diamond 1"]

Example: FrameLayout with Sidebar

action:
  type: open_gui
  id: "panel"
  guiType: CUSTOM
  size: "54"
  title: "<dark_gray>Control Panel"
  mainLayoutId: "panel_root"
  layoutPool:
    - type: "frame"
      id: "panel_root"
      frames:
        - id: sidebar
          x: 0; y: 0; width: 4; height: 6
          layoutId: sidebar_items
        - id: content
          x: 5; y: 0; width: 4; height: 6
          layoutId: content_items
    - type: "simple"
      id: "sidebar_items"
      items:
        - x: 0
          y: 0
          count: 4
          direction: DOWN
          item: { material: COMPASS }
          displayName: "<green>Tab {index}"
          interactionList:
            - type: LEFT_CLICK
              commands: ["menu switch tab_{index}"]
    - type: "paginated"
      id: "content_items"
      itemsPerPage: 20
      items:
        - item: { material: PAPER }
          displayName: "<yellow>Item {index}"