Polymart is now Voxel Shop! We're upgrading many features of the site, and during this open beta you will experience occasional bugs. Learn more
Lightweight, open-source alternative to Deluxemenus for Paper and Folia 1.21.1+
v1.0.6
Features:
- Flicker-free menu transitions: page changes and same-size cross-menu opens swap title and contents in a single bundle packet, no intermediate empty frame. Toggle with `smooth_transitions` in config.yml.
Performance:
- Material lookup cache: `Material.matchMaterial` now resolved once per unique string.
- Static ItemStack cache: items with no placeholders and no player-dependent material are built once and cloned on subsequent renders. Cleared on reload.
- Cross-menu smooth swap nulls only orphan slots instead of calling `inventory.clear()` on the whole inventory.
Fixes:
- Crash on disable: `onDisable` was closing every online player's open inventory, NPEing on Folia for real Ender Chests during world teardown. Now only closes our own menus, try/catch around each.
- ConcurrentModificationException on Folia from tab-complete and broadcast actions iterating `Bukkit.getOnlinePlayers()` mid-mutation. All iterations now go through `Util.snapshotOnlinePlayers()` which retries on CME and falls back to empty.
- `update_interval` below 1 second was ignored (global task capped at 1 second). Task now ticks at 50ms.
- Animated items flickering back to base (update task was overwriting frames the animation task had just written).
- Static items with `{page}` / `{max_page}` in lore showed stale numbers after paging. Added a `refreshStaticItems` pass.
- Meta add/subtract on DOUBLE accumulated floating-point error. Now uses BigDecimal and preserves input scale.
- Bare action names in requirement deny lists (e.g. `- close`) were sent to chat instead of executed.
- `player:` action no longer double-slashes commands starting with `/`.
- `click_cooldown` was cached at enable and not refreshed on `/am reload`. Now read live from config.
Editor fixes:
- Freshly dropped items were deleted on save (orphan-cleanup loop iterated a live view that included items it had just added).
- Player head textures were lost. Dropped heads now save as `basehead-<texture>` or `head-<owner>` instead of plain `PLAYER_HEAD`.
- Only material/slot/amount/name/lore were captured. Now also captures custom_model_data, item_model, tooltip_style, enchantments, item_flags, unbreakable, rarity, hide_tooltip, damage, and leather/potion RGB.
- Names and lore now serialize with MiniMessage so colors, gradients, fonts, and decorations survive (was plain text).
- Falls back to `item_name` when an item has no `custom_name` so resource-pack items with only the canonical name save correctly.
- Nexo, ItemsAdder, Oraxen, and HeadDatabase items now save as `nexo-<id>` / `itemsadder-<id>` / `oraxen-<id>` / `hdb-<id>` via each plugin's reverse-lookup API instead of as their vanilla base material.
- Items dragged in with stale editor PDC tags from a prior editor session (e.g. shift-clicked out, dropped into a new menu) were saved as bare `slot:` stubs. Tags are now ignored unless they target a name that already exists in the current menu's config.
- Per-property metadata captures are wrapped so a single failing API call (e.g. on a future-version-only method) skips that section instead of aborting the whole item.
Diagnostics:
- Defensive `%player_name%` fallback at the end of action/placeholder resolution, with debug log when the fallback fires.
- `MetaStore.set` logs `[Meta] <player> set <key> (<type>) = <value>` to console when `debug: true`.
- Editor logs `[Editor] <type> saved as material '<resolved>'` when `debug: true`.