Cấu trúc menu
Mỗi menu là một file YAML trong thư mục menus/. Tên file chính là ID menu.
Dưới đây là toàn bộ các node gốc mà serializer đọc (kèm alias regex — bạn có thể viết tên khác mà vẫn nhận).
Sơ đồ tổng thể#2>
Title: ... # Tiêu đề (một hoặc mảng animation)
Title-Update: 40 # Chu kỳ quay title animation (ticks)
Layout: ... # Bố cục menu (bắt buộc)
PlayerInventory: ... # Bố cục phần inventory người chơi (tùy chọn)
Type: CHEST # Loại container (tùy chọn)
Size: 3 # Số hàng nếu không dùng Layout (tùy chọn)
Render-Type: WINDOW # WINDOW / ENCHANT / MERCHANT / DISPLAY / BOOK (xem trang Render-Type)
Options: ... # Tùy chọn menu
Bindings: ... # Lệnh / item mở menu
Events: ... # Open / Close / Click
Icons: ... # Phần thân menu
Input: ... # (Fork) các slot kéo đồ vào GUI
Tasks: ... # Tác vụ định kỳ khi mở menu
Functions: ... # JS function dùng như biến ${name}
Lang: ... # Đa ngôn ngữ cho chính menu này
Serializer dò key bằng regex, không bắt buộc đúng chính tả: Title cũng khớp
Name, Layout khớp Shape, Options khớp
Settings, Icons khớp Buttons… Tuy vậy, hãy dùng tên chuẩn
ở trên cho dễ bảo trì.
Title — tiêu đề#2>
# Static
Title: 'My Shop'
# Animation — mảng title quay vòng, Title-Update là chu kỳ (ticks)
Title:
- 'Hello, ShinnUI!'
- 'Hello, %player_name%!'
- 'Support Animated Titles'
Title-Update: 80
- Title hỗ trợ màu, hex, biến và function variable.
- Dynamic title đổi bằng cách gửi lại cửa sổ container (packet
OpenWindow) rồi vẽ lại toàn bộ slot — không phải "đổi tên" inventory.
- Chu kỳ
Title-Update áp dụng toàn menu, không đặt riêng theo trang. Muốn title khác nhau theo trang: dùng function variable kiểm tra %shinnui_menu_page% hoặc dùng action set-title.
- I18n: có thể đặt các title theo locale trong node
Lang (xem phần Lang).
Layout — bố cục#2>
Serializer dò key bằng regex, không bắt buộc đúng chính tả: Title cũng khớp
Name, Layout khớp Shape, Options khớp
Settings, Icons khớp Buttons… Tuy vậy, hãy dùng tên chuẩn
ở trên cho dễ bảo trì.
# Static Title: 'My Shop' # Animation — mảng title quay vòng, Title-Update là chu kỳ (ticks) Title: - 'Hello, ShinnUI!' - 'Hello, %player_name%!' - 'Support Animated Titles' Title-Update: 80
- Title hỗ trợ màu, hex, biến và function variable.
- Dynamic title đổi bằng cách gửi lại cửa sổ container (packet
OpenWindow) rồi vẽ lại toàn bộ slot — không phải "đổi tên" inventory. - Chu kỳ
Title-Updateáp dụng toàn menu, không đặt riêng theo trang. Muốn title khác nhau theo trang: dùng function variable kiểm tra%shinnui_menu_page%hoặc dùng actionset-title. - I18n: có thể đặt các title theo locale trong node
Lang(xem phần Lang).
Layout — bố cục#2>
Layout là "bản vẽ" menu bằng ký tự. Mỗi ký tự là ID của một icon trong node Icons;
khoảng trắng = slot trống không clickable; ký tự được bọc trong backtick (`` ` ``) cho phép dùng
nhiều ký tự làm một ID.
Layout: - '########`Close`' - ' ' - ' PT ' - ' ' - '####*###`Next`' PlayerInventory: # Bố cục inventory người chơi (tối đa 4 dòng x 9) - ' ' - ' ' - ' ' - ' '
- Số dòng của Layout quyết định số hàng của chest (1–6).
- Nhiều trang: viết Layout dạng mảng lồng nhau, mỗi phần tử là một trang:
Layout:
- - '########`Close`'
- ' '
- ' P '
- ' '
- '####*###`Next`'
- - '########`Close`'
- ' '
- ' T '
- ' '
- '`Pre`########'
- Nếu một trang không có dòng tương ứng trong
PlayerInventorythì phần inventory người chơi của trang đó bị làm trống. - Ký tự icon hỗ trợ cả ký tự Unicode/hán tự.
- Icon vẫn có thể đặt slot thủ công qua
slots:trong icon — khi đó nó ghi đè vị trí layout.
Options — tùy chọn#2>
Options:
Arguments: true # Bật truyền tham số khi mở menu (mặc định true)
Default-Arguments: [ ] # Tham số mặc định, tự điền phần thiếu
Default-Layout: 0 # Trang mở mặc định (số hoặc biến)
Free-Slots: # Slot "tự do" — người chơi có thể lấy đồ ra/vào
- 71-73
Hide-Player-Inventory: false # Che toàn bộ inventory người chơi (trang trí bằng layout)
Min-Click-Delay: 200 # Chống click nhanh: ms giữa 2 click
Depend-Expansions: [ 'server', 'player' ] # PAPI expansion bắt buộc phải có khi mở menu
| Option | Chi tiết |
|---|---|
Arguments | Tắt nếu lệnh bind của bạn xung đột với lệnh có tham số. Xem Truyền tham số. |
Default-Arguments | Ví dụ ["a","b"] mà người chơi chỉ cung cấp ["a"] → tham số thứ 2 tự điền b. |
Free-Slots | Slot nào không nằm trong layout và không free sẽ bị chặn click của người chơi. Dạng '71-73' hoặc biến trả số. |
Hide-Player-Inventory | Khi bật, phần dưới GUI chỉ hiển thị theo PlayerInventory layout (đồ thật không click được). Menu Input phải đặt false. |
Min-Click-Delay | Áp cho từng người chơi trong từng menu (cooldown CLICK_DELAY). |
Depend-Expansions | Nếu thiếu expansion, sự kiện mở menu bị cancel và plugin gửi danh sách expansion cần tải (tự động yêu cầu download expansion qua PAPI cloud nếu có quyền). |
Bindings — lệnh & item#2>
Bindings:
Commands:
- '(?i)example(-)?(gui)?(s)?' # regex, khớp cả /example /examplegui /examples...
Items:
- 'material:compass' # Item matcher
- 'material:clock,lore:OPEN_MENU'
Lệnh bind là lệnh ảo (khớp khi người chơi gõ), còn Items tự động mở menu khi click phải item khớp khi GUI đang đóng. Xem chi tiết matcher tại Item Matcher.
Events — sự kiện menu#2>
Events:
Open: # Chạy trước khi mở (có thể cancel)
- condition: 'perm *shinnui.use'
actions:
- 'sound: BLOCK_CHEST_OPEN-1-0'
deny:
- 'sound: ENTITY_ITEM_BREAK-1-0'
- 'title: `&c&lPermission Required` `&7&lYou need permission &6&lshinnui.use` 15 20 15'
- 'return' # return => HỦY sự kiện mở menu
Close:
- 'sound: BLOCK_CHEST_CLOSE-1-0'
Click: [] # Bắt click toàn menu (hiếm dùng)
- Giá trị của event là một reaction (nhóm action có điều kiện).
return trong Open sẽ hủy mở menu; trong Close sẽ hủy đóng.
- Meta
open_event_reason được set trước khi chạy Open, nhận giá trị
PLAYER_COMMAND, CONSOLE, BINDING_COMMANDS, BINDING_ITEMS, BINDING_SHORTCUT… — có thể đọc bằng {meta:open_event_reason}.
Input — slot kéo đồ (tính năng fork)#2>
Input:
- slot: 10 # Slot tĩnh trong GUI
material: IRON_INGOT # Chỉ nhận material này (hoặc dùng matcher / nexo-id)
required: 4 # Phải đủ 4 mới cho commit (0 = tùy chọn)
max-amount: 8 # Buffer tối đa 8
return trong Open sẽ hủy mở menu; trong Close sẽ hủy đóng.open_event_reason được set trước khi chạy Open, nhận giá trị
PLAYER_COMMAND, CONSOLE, BINDING_COMMANDS, BINDING_ITEMS, BINDING_SHORTCUT… — có thể đọc bằng {meta:open_event_reason}.Input:
- slot: 10 # Slot tĩnh trong GUI
material: IRON_INGOT # Chỉ nhận material này (hoặc dùng matcher / nexo-id)
required: 4 # Phải đủ 4 mới cho commit (0 = tùy chọn)
max-amount: 8 # Buffer tối đa 8
Đây là node riêng của fork này — menu cho phép người chơi shift-click kéo đồ vào GUI,
buffer-pure (không trừ đồ thật cho đến khi chạy action input).
Toàn bộ chi tiết ở trang Input Menu.
Tasks — tác vụ định kỳ#2>
Tasks:
tikTok:
period: 80 # Chu kỳ (ticks)
task:
- condition: '$ sender.isOp()' # Kether mặc định
actions:
- 'sound: BLOCK_NOTE_BLOCK_BIT-1-2'
- Bắt đầu chạy khi menu mở, hủy khi đóng menu.
- Đổi trang không hủy task.
- Cấu trúc:
ID → period → task (reaction).
Functions — script nội bộ#2>
Functions:
flash: |-
function flash() {
var display = new Date().getSeconds() % 2 == 0
return display ? args[0] : " "
}
flash()
ID → period → task (reaction).Functions:
flash: |-
function flash() {
var display = new Date().getSeconds() % 2 == 0
return display ? args[0] : " "
}
flash()
Định nghĩa JS function dùng được ở mọi giá trị text trong menu bằng cú pháp
${flash_➥} (dấu _ phân tách tham số). Chi tiết ở
Functions nội bộ.
Lang — đa ngôn ngữ theo menu#2>
Lang:
vi_VN:
Title: 'Cửa hàng'
Icons:
'close': { display: { name: '&cĐóng' } }
en_US:
Title: 'Shop'
Icons:
'close': { display: { name: '&cClose' } }
Node Lang cho phép định nghĩa lại Title/Icon theo locale; khi mở menu, plugin chọn
theo locale người chơi. Icon ẩn danh trong Lang được map theo ID thường.
Truyền tham số (Arguments)#2>
Khi mở menu bằng lệnh có tham số (hoặc action open: Shop apple 10), các tham số
trở thành biến có thể dùng ở gần như mọi chỗ:
| Biến | Giá trị với args apple, juice, orange |
|---|---|
{0} | apple |
{1} | juice |
{2} | orange |
- Đóng menu không xóa tham số — lần mở sau vẫn giữ, trừ khi dùng action
clear-args. - Đổi tham số bằng action
set-arguments: a b c. - Lệnh bind dạng
'is upgrade'sẽ khớp cả/is upgrade 233— phần thừa thành tham số.
Templates — menu mẫu kèm sẵn#2>
Trong menus/ của plugin có các file ví dụ rất đáng đọc:
| File | Demo về |
|---|---|
Example.yml | Menu tổng hợp: title animation, sub-icon, page, tasks, functions, bindings. |
Input-Demo.yml | Input Menu: công thức 4 sắt + 4 vàng + 2 kim cương, confirm/deny. |
Input-Matcher-Demo.yml | Input slot dùng matcher (enchant/pdc/nbt/nexo-id). |
Random-Demo.yml | Action random: — bảng trọng số, else, lồng condition. |
Catcher-Validation-Demo.yml | Catcher nhiều stage + validation: regex + fail:/retype. |
Effect-Demo.yml | Effect Packs — gói sound/particle đặt tên. |
Book-Demo.yml, Merchant-Demo.yml, Enchant-Demo.yml, Display-Demo.yml | Bốn Render-Type đặc biệt — xem trang Render-Type. |
Demo-Buttons.yml, Profile.yml | Các pattern icon thường gặp. |