GUI and Display
This page covers what the player sees: the gui and display sections of config.yml, the structure of the gui/storage_gui.yml template, and the click semantics.
For capacity and slot counts see Capacity; for the remaining config.yml keys see Configuration.
gui
gui:
storage_rows: 5
deposit_feedback: actionbar
require_empty_cursor_for_withdraw: false| Field | Type | Default | Description |
|---|---|---|---|
storage_rows | int | 5 | Display row count, valid 1–5. The function row always owns the last row, so the real window height is storage_rows + 1. |
deposit_feedback | enum | actionbar | Feedback channel after a successful deposit: actionbar / message / none. |
require_empty_cursor_for_withdraw | boolean | false | Whether withdrawal requires an empty cursor. See the note below. |
Setting deposit_feedback to none is not recommended. Under mixed deposit an item lands where the entry order puts it and may end up on another page; with feedback disabled the player will believe the item vanished.
require_empty_cursor_for_withdraw is a misclick guard. When set to true, clicking a display slot while holding an item on the cursor no longer deposits: the click becomes a no-op and reports gui.deposit.cursor_guard. This closes the "meant to withdraw but still had a leftover cursor" mis-click window, at the cost of losing the "click an entry while holding an item to deposit" shortcut. When set to false (the default) that shortcut deposit is kept. Either way the fixed deposit port and deposit_all remain available for depositing.
storage_rows Conversion Table
The slots values in the template file are only placeholders. Real slot numbers are derived from gui.storage_rows at load time:
storageRows = clamp(gui.storage_rows, 1, 5)
totalRows = storageRows + 1
functionBase = storageRows * 9
display area = 0 .. functionBase - 1
function row = functionBase + offsetstorage_rows | totalRows | Slots per page | Display slots | Function slots (offset 0–8) |
|---|---|---|---|---|
| 1 | 2 | 9 | 0–8 | 9–17 |
| 2 | 3 | 18 | 0–17 | 18–26 |
| 3 | 4 | 27 | 0–26 | 27–35 |
| 4 | 5 | 36 | 0–35 | 36–44 |
| 5 | 6 | 45 | 0–44 | 45–53 |
Clamping rules: a value >= 6 is clamped to 5 with a warning; a value <= 0 is clamped to 1 with a warning. totalRows peaks at 6, which already sits inside CoreLib's 1–6 range.
storage_gui.yml Template Structure
id: storage_gui
gui_type: CHEST
title: "<gradient:#4DA6FF:#FFD166>绘卷仓库</gradient>"
slots:
storage_slot:
type: storage_slot
slots: [0]
item:
source: "gray_stained_glass_pane"
page_prev:
type: page_prev
offset: 0
slots: [0]
item:
source: "arrow"| Top-level key | Description |
|---|---|
id | Template id. Must be storage_gui; the implementation looks the template up by this id. |
gui_type | Container type, CHEST. The row count is not declared here, it is derived from gui.storage_rows. |
title | Window title, MiniMessage supported. |
slots | The slot entry table, where each key names one entry. |
The 9 slot types available under slots:
| Slot type | Purpose |
|---|---|
storage_slot | The display-area prototype. Required: without it the display area cannot be built and the whole template fails to resolve. |
deposit_slot | The fixed deposit port. Clicking it with a loaded cursor deposits. |
page_prev | Previous page. |
page_info | Current page information, display only. |
page_next | Next page. |
search | Opens the search prompt; right-click while searching clears the filter. |
sort | Cycles the sort; shift-click cycles it in reverse. |
deposit_all | Bulk deposit across the 36 main inventory slots. |
unlock | Entry point for paid expansion. |
An entry may declare type explicitly; when omitted it is derived from the lower-cased entry key, so naming an entry after its type is enough.
How offset Relates to slots
Function-row entries only declare offset (valid 0–8). The slots key in the template exists only to satisfy the shared template parser and is overwritten by the conversion at load time, so it must never be read as a real position.
- When
offsetis missing, not a number, or outside 0–8, the entry is rejected with a warning. - When two entries claim the same
offset, the later one is rejected with a warning. - When every function entry is rejected, a warning is logged and the paging and deposit buttons become unavailable.
The display area's storage_slot is a prototype: at load time it expands across the whole display area, 0 .. functionBase - 1. The item configured on it only supplies the placeholder appearance of a locked slot and does not affect how unlocked slots render.
Changing gui.storage_rows moves the function row automatically; no slot number needs to be edited by hand.
GUI Click Semantics
| Location | Action | Effect |
|---|---|---|
| Display slot | Loaded cursor + left-click | Deposits the whole cursor |
| Display slot | Loaded cursor + right-click | Deposits 1 unit |
| Display slot | Empty cursor + left / right / shift-left / shift-right | Withdraws per withdraw_amounts |
| Display slot | Empty cursor + middle-click | Opens the chat prompt for a custom amount (subject to withdraw_prompt_enabled) |
deposit_slot | Loaded cursor | Deposits the whole cursor |
deposit_slot | Empty cursor | Reports that the port is empty |
deposit_all | Click | Bulk-deposits across the 36 main inventory slots |
sort | Click / shift-click | Cycles the sort / cycles it in reverse |
search | Click | Opens the search prompt; right-click while searching clears the filter |
page_prev / page_next | Click | Pages; an empty page cannot be paged into |
| Player inventory item | Shift-click | Redirected into the deposit port logic |
Rejected click kinds: double-click, number keys, offhand swap, the drop key and Ctrl + drop. They respectively aggregate across slots, bypass cursor semantics or discard the item outright, so none of them can be given a safe meaning; such clicks report gui.click.unsupported.
While a search filter is active, deposits into the display area are refused (paging follows the filtered result set, so a display slot no longer identifies a real slot number), but the fixed deposit port keeps working.
Withdrawal amounts, the default sort and the deposit filter live in the behavior section, documented in Configuration.
display
display:
amount_mode: percent
percent_scale: 99
compact_units: ["K", "M", "B", "T", "P", "E"]
compact_decimals: 2
show_exact_amount: true
lore_position: bottom| Field | Type | Default | Description |
|---|---|---|---|
amount_mode | enum | percent | How the slot item's amount is expressed: percent shows occupancy as 1–99, one is always 1. |
percent_scale | int | 99 | Scale ceiling for percent mode; the implementation clamps it into 1–99. |
compact_units | list | [K, M, B, T, P, E] | Compact amount units. Leave empty to use exact numbers. |
compact_decimals | int | 2 | Decimal places kept in compact format; trailing zeroes are trimmed. |
show_exact_amount | boolean | true | Whether to also show the grouped exact amount in lore. |
lore_position | enum | bottom | Where generated lines go relative to the template lore: top / bottom. |
1–99 Scale Rules
The valid range of the max_stack_size component is exactly 1–99, so the implementation never uses 100 or above and no packet trickery is involved. The scale boundaries are deliberate:
| Case | Displayed amount |
|---|---|
amount_mode: one | Always 1 |
stackLimit unlimited (Long.MAX_VALUE) or <= 0 | Degrades to 1; a percentage is meaningless for an unlimited ceiling |
Stored amount <= 0 | 1 |
Stored amount >= stackLimit (genuinely full) | percent_scale (default 99) |
| Partially filled | clamp(round(amount / stackLimit * scale), 1, scale - 1), so at most 98 by default |
Without these clamps a nearly-empty slot would render as 0 (invisible) and a nearly-full one would be indistinguishable from full.
The percentage text in lore is computed independently on the real 0–100 range and does not inherit the 1–99 clamping.
Compact Units
compact_units maps in order onto the six thresholds 10³, 10⁶, 10⁹, 10¹², 10¹⁵ and 10¹⁸. Long.MAX_VALUE is roughly 9.22E, so the E unit covers the entire long range. Values below 1000, or an empty unit list, produce the plain number.
Related Pages
- Configuration: the remaining
config.ymlsections, includingbehaviorandsearch. - Capacity: slots per page, total pages and the three-level
stackLimit. - Unlock Costs: the tiers and batch options behind the
unlockbutton. - Commands and Permissions:
/estorage reloadalso reloads the GUI template.