GUI Architecture
Last updated Nov 2, 2026
GUI Architecture
This page explains how SoapsCommon menus fit together. Use it when you want the big picture. For YAML keys, see GUI System.
Who owns what
| Piece | Where it lives | Who edits it |
|---|---|---|
| Shared GUI engine | SoapsCommon JAR | Nobody on the server (library code) |
| Menu YAML files | Each plugin's data folder | You |
| Global filler, border, click sound | gui/_settings.yml in that plugin |
You |
| Built-in staff panels | Java in the suite plugin (Event Engine panels in Common) | Cosmetic overrides only (when supported); engine GUIs paint black border then gray filler |
| Click actions | action: fields in menu YAML |
You (plus extra actions the plugin registers) |
SoapsCommon does not store menus under plugins/SoapsCommon/. Edit the plugin that opens the menu (for example plugins/SoapsAdmin/gui/).
How a menu opens
- A player runs a command, clicks an item, or another menu uses
[open_menu]. - The suite plugin asks its SoapsCommon
GuiManagerfor that menu id. - SoapsCommon builds the inventory from YAML (title, size, items, sounds).
- Clicks are routed through one shared listener in SoapsCommon.
- The
action:string on the clicked item runs (close, open another menu, command, and so on).
You never register a separate GUI listener for SoapsCommon menus. The library handles click, drag, and close events for every suite plugin that uses it.
Menu types
Suite plugins load menus in a few ways. The names below match how SoapsCommon classifies them:
| Type | What you can change | Typical use |
|---|---|---|
| Custom | Full layout, items, and actions in a YAML file under gui/ |
Player hubs, shops, daily rewards, custom screens |
| Skin override | Cosmetics only (materials, names, lore) via system-gui.yml |
Soften the look of a built-in panel without rewriting its logic |
| Merged | Effective result after defaults + skin override | Java-backed admin/staff panels that still honor YAML cosmetics |
Custom menus are fully defined in YAML. Built-in panels may ignore slot or action edits; see that plugin's wiki.
Settings cascade
Values resolve from general to specific:
- SoapsCommon built-in defaults (see Config Reference)
- Plugin
gui/_settings.yml(filler, border, click sound) - The individual menu YAML (
title,size, per-menu filler/border, items) - Runtime context from the owning plugin (
{player}, balances, target names, and so on)
A per-menu filler or border overrides _settings.yml for that menu only.
Folder models
Multi-file gui/ folder (SoapsAdmin is the main example):
plugins/SoapsAdmin/gui/
_settings.yml
system-gui.yml Optional cosmetic overrides for built-in panels
player-hub.yml
shop-hub.yml
...
Single file (some smaller plugins):
plugins/SomePlugin/gui.yml
The YAML schema is the same either way. SoapsCommon loads it; the plugin decides which model to use.
Master switch
Each consumer plugin can turn menus off without removing SoapsCommon:
gui:
enabled: false
That key lives in the consumer config.yml. See Configuration.
Auto-refresh
Set refresh: <seconds> on a menu YAML to rebuild the screen on a timer. Use 0 (default) to disable. Prefer [refresh] click actions for one-shot rebuilds.
Cursor preservation (suite standard)
Re-opening an inventory with player.openInventory(...) resets the mouse cursor to the center of the screen. SoapsCommon treats that as a last resort.
| Situation | What to do |
|---|---|
| Update items after a click on the same menu | screen.refresh() or YAML [refresh] |
Re-show the same menu id/size (e.g. new FooGui(...).open(player)) |
open() soft-rebuilds in-place; cursor stays put |
Change page on a PaginatedGui |
Default: in-place refresh() (no close/reopen) |
| Open a different menu id or a different size | Full open (cursor reset is expected) |
Do not call player.closeInventory() before reopening the same menu. That forces a cursor reset. Let GuiScreen.open soft-replace, or call refresh() on the live screen.
Practical checklist
When a menu misbehaves:
- Confirm SoapsCommon and the suite plugin are matching 2.0.x builds
- Confirm
gui.enabled: truein the consumer plugin - Check YAML syntax in the menu file and
_settings.yml - Decide whether the screen is custom (edit YAML) or built-in (check that plugin's wiki)
- Turn on
settings.debug: truein the consumer plugin while testing
Related pages
- GUI System: YAML fields, items, and click actions
- Config Reference: default values when keys are omitted
- FAQ: common install and config questions
Still stuck? Ask about this page