Performance optimization, organization patterns, and common pitfalls
📁 File Organization
Naming Conventions
Use consistent, descriptive names for your GUI files and IDs:
Pattern
Example
Use Case
Feature name
shop.yml, bank.yml
Simple, single-purpose GUIs
Category prefix
admin-ban.yml, admin-kick.yml
Related GUIs grouped by category
Lowercase with dashes
server-selector.yml
Multi-word names
Avoid spaces, special characters, and uppercase in file names and GUI IDs. The ID is case-sensitive when used in commands.
Folder Structure
Keep your CustomGuis/ folder organized. While GUIPlus reads all .yml files from this folder, a clean structure helps you manage large GUI collections:
plugins/GUIPlus/CustomGuis/
├── shop.yml # Main shop
├── bank.yml # Banking system
├── warps.yml # Warp menu
├── profile.yml # Player profile
├── adminpanel.yml # Admin tools
├── rules.yml # Server rules
└── daily.yml # Daily rewards
Tip: GUIPlus does not support subfolders inside CustomGuis/. All GUI files must be in the root of the folder.
⚡ Performance
Minimize Placeholder Usage in Lore
PlaceholderAPI placeholders in item lore are re-evaluated every second (20 ticks). Having many placeholders across many items can increase server load:
Avoid:
Better: Consolidate data into fewer items or use static text where values don't change frequently:
Keep GUIs Focused
Rather than building one massive GUI with many scenes, create separate GUIs for different purposes and link them with commands:
This keeps each GUI file manageable and reduces the number of items loaded at once.
Use Conditions Efficiently
Conditions are evaluated when the GUI opens and when items refresh. Simpler conditions are faster:
has-permission — Very fast (permission lookup)
has-money — Fast (single Vault call)
conditional-placeholder — Speed depends on the placeholder being evaluated
cooldown — Fast (timestamp comparison)
📝 YAML Tips
Quoting Strings
Always quote strings that start with special YAML characters (%, &, *, !, {, [, etc.):
Single quotes (') are safest for Minecraft formatting codes since § and & don't need escaping.
Empty Lore Lines
Use '' (empty single-quoted string) for blank lines in lore:
Number vs String
Some fields accept both numbers and placeholder strings. When using a placeholder, quote it:
Indentation
YAML uses spaces, not tabs. Use 2-space indentation consistently:
Tip: Use a YAML validator (search "YAML lint" online) to catch indentation and syntax errors before reloading.
🔁 Common Patterns
Glass Pane Borders
Fill empty slots with glass panes to create clean borders:
Tip: Use the in-game editor to place border items quickly rather than writing YAML by hand.
Back Button Pattern
Add a consistent "back" button that returns to the previous GUI:
Close Button Pattern
Sound Feedback
Always add sound feedback to click events. It gives players clear confirmation that their action worked:
Combining Left/Right Click Actions
Use clickType to give items dual functionality:
Add instructions in the lore so players know:
⚠ Common Pitfalls
Duplicate YAML Keys
YAML maps cannot have duplicate keys. If you need two click events of the same type, use unique keys:
Wrong:
Correct:
Forgetting to Quote Placeholders in Conditions
Placeholder values in conditions must be quoted:
Wrong:
Correct:
Using = for Numeric Comparison
The = operator in conditional-placeholder does string comparison, not numeric. 10 does not string-equal 10.0:
Wrong (for numeric equality):
Correct:
Cooldown Values in Milliseconds
Cooldown durations are in milliseconds, not seconds:
Duration
Milliseconds
1 second
1000
30 seconds
30000
5 minutes
300000
1 hour
3600000
24 hours
86400000
Material Names
Use the Bukkit material name, not the Minecraft display name:
The command click event has a setOp: true option that temporarily gives the player OP to execute a command. Avoid using this. Instead, use console_command to run privileged commands from the console:
Avoid:
Prefer:
Input Validation
When using chat fetcher for player input, always validate:
Type check — Use is-integer or is-double to ensure the input is a number
Range check — Use conditional-placeholder to check bounds (e.g., %input%>0)
Economy check — Use has-money to verify funds before deducting
# In your main menu, link to sub-menus
click-events:
command:
commands:
- gui open shop
# These need quotes because % is a special character indicator in some parsers
conditionFailMessage: '§cYou need at least $500!'
conditional_condition: '%player_level%>=10'
item-lore:
- ''
- §7This has spacing above and below
- ''
# Static number — no quotes needed
money-remove:
amount: 500
# Dynamic placeholder — quotes needed
money-remove:
amount: '%input%'