2.3.0latestClickSorted 2.3.0Sep 3, 2026 ClickSorted 2.3.0 adds an in-game self-test and compatibility-diagnostics tool, lowers the minimum supported server back down to Paper 1.20.6, and extracts the plugin's internal utility code into a shared library.Highlights
- New `/clicksorted admin selftest` — an in-game correctness and version-compatibility self-test, for admins validating an update against their exact Paper build before trusting it on a live server. - Broadened compatibility — minimum supported server lowered back to Paper/Folia 1.20.6 (from the 1.21.6 floor introduced in 2.2.0). The/clicksorted menudialog automatically disables itself on servers older than 1.21.6 (no Dialog API); every other feature works down to 1.20.6. - Internal plugin-agnostic utility code (config/migration engine, logging, localisation, rate limiting, permission helpers, update checking, Adventure Component helpers) was extracted into a new shared library, KcMcLib, consumed as a git submodule. No behavior change for players or admins.Breaking Changes
- `/clicksorted admin benchmark` now also requires `enable_benchmark: true` in `config.yml` (new key, defaultfalse), matching the existingenable_selftest-style gate — previously theclicksorted.admin.commands.benchmarkpermission alone was enough. Admins who use the benchmark command need to add this key. - Internal Java API reshuffle, for third-party plugin developers only. Several non-event internal classes (the migration engine, config lifecycle, logging, theMessageSource/Localizedmessage facade, rate limiting, permission helpers, the Modrinth update checker, and Adventure Component helpers) moved out ofnet.kccricket.clicksorted.*into the newnet.kccricket.kcmclib.*namespace, andMessageSource/Localized'sgetColoredMessage/getMessagewere renamed torender/raw. The public event API —InventorySortEvent,PlayerPreferenceChangeEvent,Preference, and thePlayerSortingPrefssetters — is unchanged; only code that directly imported the moved internal classes needs updating.New Features
In-game self-test & compatibility diagnostics
/clicksorted admin selftest(permissionclicksorted.admin.commands.selftest, defaultop; also requires the newenable_selftestconfig key, defaultfalse, since a run stages and restores the tester's real inventory and preferences) runs the plugin's algorithm and integration checks against the server it's actually installed on: -selftest algo— pure algorithm checks, no Paper API surface involved. -selftest probe— runs the capability-probe suite alone, a quick compatibility fingerprint of the running server. -selftest sim— synthetic events dispatched through the real listeners. -selftest start [quick|full]— an interactive LIVE session that walks the tester through real click-method gestures (quick) or the full set of region/lock/blacklist/bundle scenarios (full), restoring their inventory and preferences from a crash-safe backup afterward;selftest next/status/stopcontrol an in-progress session. Failures are grouped into SANITY/INTEGRATION/ENDTOEND categories so a weak-signal algorithm hiccup can't masquerade as a real version-compatibility break — only ENDTOEND failures (real client gestures) carry full compatibility signal. Intended for admins/testers checking a plugin update, not routine play.Bug Fixes
- Self-test LIVE session restore could lose the crash-safety backup if any single restore step failed — exactly the kind of version-incompatibility failure this subsystem exists to catch — stranding the tester's real inventory and preferences with no recovery path. Each restore step now runs independently, and the backup is only cleared once every step has actually run. -/clicksorted menucould show stale "hover" wording on its click-method status line when a single Save changed both the click method and the allow-on-hover preference together. - Fixed a permission leak where the/clicksorted admincommand node was visible in tab-complete to every player, even though none of its subcommands were actually usable without their own permission. -/clicksorted bundle blacklist add|remove materialtab-completion now suggests namespaced material IDs (e.g.minecraft:dirt), matching what the command actually accepts, instead of a drifted, un-namespaced local implementation. - A bundle that contained another bundle was treated as completely full, so ClickSorted would never pack anything into it — a nested bundle was charged an entire bundle's capacity instead of vanilla's one-sixteenth plus whatever it holds. Bundle weight now matches vanilla exactly, including beehives/bee nests holding bees (a whole bundle, previously undercounted — the undercount could let a bundle be packed past its real capacity and rejected on reload) and items with a custom stack size. - TREEMAP sorting crashed on every pre-1.21.2 server — a call to the newerhasCustomModelDataComponent()API had no fallback for the plugin's own stated 1.20.6 floor. It now falls back to the olderhasCustomModelData()check on servers where the newer API doesn't exist.Other Improvements
- Trigger instructions (chat messages and self-test prompts) now reflect the player's actual allow-on-hover setting instead of always describing the plain, non-hover gesture. -config.ymlnow warns on reload/load about any key it doesn't recognize (a leftover from an old config version, or a typo) instead of silently ignoring it. - New maintainer-only./gradlew generateItemNamestool regenerates the item display-name/sort-key table from the current Paper API; not bundled into the plugin jar.Compatibility
Paper/Folia 1.20.6 – 26.2.x
Java 21+
Upgrading
1. Stop your server. 2. Replace the old jar inplugins/with this release. 3. If you use/clicksorted admin benchmark, addenable_benchmark: truetoconfig.yml. 4. Start your server.2.2.0ClickSorted 2.2.0Jul 7, 2026 ClickSorted 2.2.0 adds a dialog-based preferences UI, per-player localisation with self-updating default strings, and raises the minimum supported server to Paper 1.21.6.Highlights
- New `/clicksorted menu` — a single Paper Dialog listing every sorting preference (enabled, click/sort method, start corner, fill axis, allow-on-hover, bundle in-inventory/in-containers, bundle stack-limit) with current values pre-filled, plus buttons to launch the slot-lock and bundle-blacklist GUIs without leaving the flow. The existing/clicksorted sort/click/bundle/statuscommands are unchanged and remain the console/scripting interface. - Per-player localisation — every message now resolves against the viewing/target player's Minecraft client locale, with a sparse-override model so default text updates automatically without shadowing admin customizations. See below.Breaking Changes
- Minimum supported server raised to Paper 1.21.6 (from 1.21.5), the version that introduced the Dialog API this release's preferences menu is built on. A 1.21.5 server can no longer run this build — upgrade Paper first. - `lang.yml` is replaced by `lang/<locale>.yml` override files (e.g.lang/en_us.yml). An existinglang.ymlis migrated automatically on first load: any key you had customized is extracted intolang/en_us.yml, the old file is archived tolang.yml.bak, and any key left at its default is dropped (so you pick up any improved default text in this release). No action is required. See [docs/admin/lang.md](https://kccricket.github.io/ClickSorted/admin/lang.md).New Features
Dialog-based preferences menu
/clicksorted menu(permissionclicksorted.commands.menu, defaulttrue) opens a single form covering every scalar sorting preference, each shown only if the player holds the matching command's permission node, so the dialog can never change something the player couldn't already change by command. Saving applies every changed value through the samePlayerSortingPrefssetters the commands use, so listener vetoes and PDC persistence behave identically. The "Locked Slots…" and "Bundle Blacklist…" buttons preserve any unsaved edits made in the dialog, open the corresponding GUI, and restore the dialog with those edits intact once the GUI is closed. Bedrock/Geyser clients cannot render server-side dialogs; the existing commands remain their path to the same preferences.Per-player localisation & self-updating lang defaults
Default message strings are now bundled inside the jar (lang/en_us.yml) rather than copied onto disk, so a changed default in a future release takes effect for everyone automatically — no more permanently-shadowedlang.yml. Admins customize strings via sparse override files atplugins/ClickSorted/lang/<locale>.yml; only the keys you edit are overridden, everything else keeps resolving to the built-in default. Messages are now resolved per-player against their Minecraft client locale, so future translation files (de_de.yml,pt_br.yml, …) are a pure drop-in with no code changes. A newdefault_localeconfig key (defaulten_us) controls console output and the fallback for any locale with no matching file. See [docs/admin/lang.md](https://kccricket.github.io/ClickSorted/admin/lang.md) for the full resolution order.Compatibility
Paper/Folia 1.21.6 – 26.1.x
Java 21+
Upgrading
1. Stop your server. 2. Replace the old jar inplugins/with this release. 3. Start your server.Other Improvements
- README and documentation updated for the new command and the 1.21.6 floor.2.1.0ClickSorted 2.1.0Jul 3, 2026 ClickSorted 2.1.0 makes sorting and preference changes fully listener-actionable for third-party plugins, adds a configurable update-check cadence, and closes a Folia edge case around shared virtual inventories.Highlights
- `InventorySortEvent` is now listener-actionable — narrow a sort withexcludeSlot/excludeItem, inspect precise slot classification (OUT_OF_RANGE/ADMIN_LOCKED/USER_LOCKED/SORTABLE), and explain a cancellation withsetCancelReason, shown to the player rate-limited. - New `PlayerPreferenceChangeEvent` — every per-player preference change (click/sort method, start corner, fill axis,enabled, sort-over-items, bundle-packing settings, locked-slot toggles, bundle blacklist add/remove/clear) now fires a cancellable, typed event before it's applied or persisted. - New `PreferenceResult` — every event-firingPlayerSortingPrefssetter now returnsAPPLIED/UNCHANGED/CANCELLEDinstead of a bareboolean/void, so callers can tell a real no-op apart from a listener veto. - Configurable update-check cadence —check_for_updates_interval_hours(default 24) controls how often the recurring Modrinth check repeats while the server runs. - Folia safety — on Folia, ClickSorted now refuses to sort a plugin-created inventory that is open to more than one viewer at once (e.g. a shared virtual GUI), since such an inventory has no single owning region thread and could otherwise race between viewers' region threads. Vanilla inventories and single-viewer plugin GUIs are unaffected.Breaking Changes
These changes are scoped to third-party plugin developers integrating with ClickSorted's Java API — there is no impact on server admins or players. - `PlayerSortingPrefs` setter return types changed. Methods likesetEnabled,setClickMethod,setSortingMethod,setStartCorner,setFillAxis,setSortOverItems,setBundlePackInInventory,setBundlePackInContainers,setBundleStackLimit,addToBundleBlacklist/removeFromBundleBlacklist(and the name variants),clearBundleBlacklist, andtoggleSlotLockednow returnPreferenceResultinstead ofboolean/void. Third-party plugins calling these directly and using the return value must update to checkPreferenceResult.applied()/cancelled().setLockedSlotsis unchanged (stillvoid, fires no event). - `InventorySortEvent(InventoryView, Inventory, int min, int max)` is deprecated (not removed) in favor of the new set-based constructor, which carries lock and admin-blacklist metadata the old one can't express. Existing code using the old constructor keeps compiling and working.New Features
The event now carries the click's full region, per-player and admin lock sets, and the admin item-blacklist snapshot, and exposes: -InventorySortEvent: listener-actionablegetSortableSlots()/excludeSlot(int)— read and narrow the live sortable set. -getRegionSlots(),getUserLockedSlots(),getAdminLockedSlots()— the raw inputs behind the sortable set. -statusOf(int)/getSlots()— classify any or every slot asOUT_OF_RANGE,ADMIN_LOCKED,USER_LOCKED, orSORTABLE. -excludeItem(Material)/excludeItem(String)/getExcludedMaterials()/getExcludedItemNames()/matchesExcludedItem(ItemStack)— listener-contributed item exclusions, unioned with the admin blacklist. -setCancelReason(Component)/getCancelReason()— an optional explanation shown to the player (rate-limited, since this event fires on every matching click) when a listener cancels the sort. See the new [Development → Events](development/events/inventory-sort-event.md) docs page for full details and an example listener.
A new cancellable event fired byPlayerPreferenceChangeEventPlayerSortingPrefsbefore any per-player preference changes.getChange()returns a sealedChange<T>(ValueChange<T>orLockedSlotChange, which adds aslot()) with typedoldValue()/newValue();getChange(Preference<T>)gives a type-narrowed accessor for one specific preference (Preference.CLICK_MODE,.SORT_MODE,.ENABLED, etc. — see the newPreference<T>class). A cancelling listener may callsetCancelReason(Component); ClickSorted's own commands show that reason, falling back to a genericpreferenceChangeBlockedlang key when none is set. Only fires when the new value actually differs from the old one. See the new [Development → Events](development/events/player-preference-change-event.md) docs page for full details and an example listener.PreferenceResultPlayerSortingPrefsmutators now return aPreferenceResultrecord (APPLIED,UNCHANGED, orCANCELLEDwith an optionalcancelReason()), letting ClickSorted's commands (and any third-party caller) distinguish a value that was already set from one a listener blocked, and report each correctly to the player.Configurable update-check cadence
check_for_updates_interval_hours(default24, minimum1, lower values clamped up) controls how oftenUpdateCheckerrepeats its Modrinth check while the server keeps running, in addition to the existing startup/reload check./clicksorted admin reloadnow restarts the full update-check schedule (previously it only fired a one-off check).Development documentation
Newdocs/development/section covering building & testing from source and the events ClickSorted publishes (InventorySortEvent,PlayerPreferenceChangeEvent), for plugin authors integrating with ClickSorted.Bug Fixes
- Bundle-blacklist add/remove/clear couldn't distinguish "already in that state" from "a listener blocked it" — these now report a listener veto as blocked rather than silently falling through to the "already present"/"not present" message.Other Improvements
-ClickSortedCommandsdeduplicated:blockedAndReported/reportBlacklistResulthelpers own the cancel-report half of every preference-setting command once, instead of per call site. -PlayerSortingPrefsdeduplicated: enum/boolean setters delegate to sharedsetEnumPref/setBoolPrefhelpers, and the set-valued blacklist mutators tomutateBlacklist, which own the fire→write→return sequence once; set-valued stores re-read PDC after the event fires so re-entrant listener mutations aren't clobbered. - A no-op preference setter call that matches the config default still pins the value in PDC (without firing the event), so an explicit choice survives a later default change. -ProtectedItems.blocks(ItemStack, String)overload added so callers that already resolved an item's display name (e.g.InventorySortEvent.matchesExcludedItem) avoid a second lookup.Compatibility
Paper/Folia 1.21.5 – 26.1.x
Java 21+
Upgrading
1. Stop your server. 2. Replace the old jar inplugins/with this release. 3. Start your server.check_for_updates_interval_hoursis added toconfig.ymlautomatically (default24); no other config or stored-preference migration is required.Note for plugin developers: if you call
PlayerSortingPrefssetters directly and use their return value, update to the newPreferenceResultreturn type (see Breaking Changes above).What's Changed
- AddInventorySortEventslot classification, item exclusions, and cancel reasons by @kccricket - Add configurable update-check cadence and cancellable preference events by @kccricket - IntroducePreferenceResultto distinguish no-op, applied, and cancelled preference changes by @kccricket - Fix: distinguish cancelled bundle-blacklist changes from no-ops; dedupe/cache event helpers by @kccricket - Refactor: pin explicit preference no-ops to PDC and dedupe command/event helpers by @kccricket - Refuse to sort cross-region-unsafe shared plugin inventories on Folia by @kccricket2.0.0ClickSorted 2.0.0Jul 2, 2026 ClickSorted 2.0.0 introduces a per-player bundle blacklist, server-wide admin item and slot locks, a dedicated enabled toggle, and a reorganised command tree.Highlights
- Per-player bundle blacklist — exclude specific item types or display names from bundle packing via a GUI or commands; blacklisted bundle colors are also skipped as packing bins. - Admin item blacklist — server admins can declare materials and display names that ClickSorted will never sort, move, or pack, viaconfig.ymland per-player permission nodes. - Admin slot locks — server admins can lock specific player inventory slots server-wide viaconfig.yml(locked_slots.player) orclicksorted.lock.player.slot.<n>permission nodes. Admin-locked slots appear as non-toggleable iron-bars panes in the lock GUI. - Dedicated `enabled` preference — click-sorting can now be toggled on/off independently of the click method (/clicksorted sort enabled).ClickMethod.NONEis removed. - Command tree reorganised by domain — per-player preferences grouped undersort,click,bundle, andlock-slots; admin diagnostics underadmin.Breaking Changes
- Command tree restructured. Thesetsubcommand group is removed. Old paths → new paths: -/clicksorted set sort-method→/clicksorted sort method-/clicksorted set click-method→/clicksorted click method-/clicksorted set hover→/clicksorted click allow-on-hover-/clicksorted set lock→/clicksorted lock-slots-/clicksorted set bundle inventory|others→/clicksorted bundle enabled in-inventory|in-containers-/clicksorted set bundle stacklimit→/clicksorted bundle stack-limit-/clicksorted set start-corner→/clicksorted sort start-corner-/clicksorted set fill-axis→/clicksorted sort fill-axis-/clicksorted set enabled→/clicksorted sort enabled- Admin commands moved underadmin:reload→admin reload,getcfg→admin config,debug→admin debug,benchmark→admin benchmark. Update macros, command blocks, and aliases. - `ClickMethod.NONE` removed. Players who hadNONEstored are automatically migrated: their click method is set toSWAPandenabledis set tofalse. Use/clicksorted sort enabled no(or the bare/clicksortedtoggle) to disable click-sorting going forward. - Config keys renamed (auto-migrated on first startup): -defaults.bundle_inventory→defaults.bundle_in_inventory-defaults.bundle_others→defaults.bundle_in_containers- Permission nodes restructured. Key renames: -clicksorted.commands.reload→clicksorted.admin.commands.reload-clicksorted.commands.getcfg→clicksorted.admin.commands.config-clicksorted.commands.debug→clicksorted.admin.commands.debug-clicksorted.commands.benchmark→clicksorted.admin.commands.benchmarkNew sort-time bundle gates added:clicksorted.bundle,clicksorted.bundle.inventory,clicksorted.bundle.container. Update any permission-plugin configurations that reference the old nodes.New Features
Per-player bundle blacklist
/clicksorted bundle blacklistopens a 54-slot GUI: click an item in your real inventory to add it to the blacklist by material (for vanilla items) or by display name (for custom-named items); click a listed entry to remove it; pagination arrows navigate large lists. Text-command alternatives: -bundle blacklist add material|remove material <material>,bundle blacklist list,bundle blacklist clear— material entries. -bundle blacklist add item-name|remove item-name <text>— display-name entries.listandclearabove cover both materials and names together. Material entries block any item of that type; name entries match case-insensitively against the item's resolved display name (custom name →item_namedata component → vanilla /items.ymlname). Blacklisted items are never packed into or unpacked from bundles; blacklisted bundle colors are also skipped as packing bins.Admin item blacklist
Admins can prevent ClickSorted from ever touching specific items — never sorted, moved, or packed/unpacked regardless of player preferences. Two enforcement channels (unioned): -blacklist.materials: []/blacklist.names: []inconfig.yml— server-wide; reloads with/clicksorted admin reload. -clicksorted.blacklist.material.<material>/clicksorted.blacklist.name.<slug>permission nodes — per-player or group-based via a permissions plugin. Name slug rule: strip legacy color codes → lowercase → collapse non-[a-z0-9]runs to_→ strip edge underscores. E.g."Creative Menu"→creative_menu.Admin slot locks
Admins can lock specific player inventory slots (0–35) server-wide so they are always excluded from sorting and cannot be toggled by the player in the lock GUI. Two enforcement channels (unioned): -locked_slots.player: []inconfig.yml— server-wide; reloads with/clicksorted admin reload. -clicksorted.lock.player.slot.<n>permission nodes — per-player or group-based. Admin-locked slots render as non-toggleable iron-bars panes in the lock GUI.Dedicated
Click-sorting can now be enabled or disabled independently of which click method is configured. Toggle with the bareenabledpreference/clicksorted, with/clicksorted sort enabled, or with/clicksorted sort enabled yes|no. The enabled state appears in/clicksorted status. Server default:defaults.enabled: trueinconfig.yml.
Name-based matching (admin name blacklist, bundle name blacklist) now resolves theitem_namedata component resolutionitem_namedata component — the base name set by data packs or plugins before any custom rename — in addition to custom display names. Lookup priority: custom name →item_name→ vanilla /items.ymlname.Graceful reload failure
Config reload failures are now caught and reported to the admin via theconfigReloadFailedlang key (lang.yml), with the previous configuration remaining active. The server console receives the full stack trace.Bug Fixes
- Bundle-displaced items dropped instead of placed — items displaced from bundles during a sort now fill free slots in the region rather than being dropped on the ground. - NPE when bundle contains items with no loose counterpart —BundlePackernow handles the case where a bundle's contents have no corresponding loose stack instead of throwing aNullPointerException.Other Improvements
-MaterialNameSetextracted as a shared record for material + display-name matching, used by bothBundleBlacklistandProtectedItems. - Shared GUI helpers consolidated intoClickSortedHolderbase class (BlacklistGuiHolder,LockGuiHolder). - Integration test coverage expanded: crafting exclusion, item conservation, fuzz testing, held-cursor state, and more.Compatibility
Paper/Folia 1.21.5 – 26.1.x
Java 21+
Upgrading
1. Stop your server. 2. Replace the old jar inplugins/with this release. 3. Recommended: deletelang.ymlto regenerate language strings. 4. Start your server — config keys and stored preferences migrate automatically on first load.Migration notes:
-
defaults.bundle_inventoryanddefaults.bundle_othersinconfig.ymlare rewritten todefaults.bundle_in_inventory/defaults.bundle_in_containersautomatically.- Players who had
ClickMethod.NONEstored will have their preference migrated toSWAP+enabled: falseautomatically.- Permission-plugin configurations referencing
clicksorted.commands.reload|getcfg|debug|benchmarkshould be updated toclicksorted.admin.commands.reload|config|debug|benchmark.What's Changed
- Add per-player bundle blacklist (GUI + commands) by @kccricket - Add admin item blacklist via config and permission nodes by @kccricket - Add admin slot locks via config and permission nodes by @kccricket - Replace ClickMethod.NONE with dedicated enabl1.2.1ClickSorted 1.2.1Jun 24, 2026 ClickSorted 1.2.1 fixes bundle packing silently ignoring dyed bundles as pack targets.Bug Fixes
- Colored bundles not recognized as pack bins —BundlePackernow matches all bundle color variants (e.g.RED_BUNDLE,BLUE_BUNDLE) when scanning for pack targets, not justMaterial.BUNDLE. Dyed bundles in an inventory were passed over as bins and left empty during a bundle-packing sort.Compatibility
Paper/Folia 1.21.5 – 26.1.x
Java 21+
Upgrading
1. Stop your server. 2. Replace the old jar inplugins/with this release. 3. Start your server.What's Changed
- Fix bundle packing to match all bundle color variants by @kccricket1.2.0ClickSorted 1.2.0Jun 23, 2026 ClickSorted 1.2.0 adds a treemap sort method, configurable sort direction, an automatic update check, and fixes several sorting correctness bugs including an item-loss edge case.Highlights
- Treemap sort — a newTREEMAPsort method groups each item type into its own contiguous near-square block, sized to that type's stack count. The most numerous types claim the largest rectangles; smaller types fill in beside or below them; and when the inventory is nearly full, remaining types degrade to a gap-free linear fill so no slots are wasted. - Sort direction — each player can now choose which corner items are placed from (TOP_LEFT,TOP_RIGHT,BOTTOM_LEFT,BOTTOM_RIGHT) and whether rows or columns fill first (HORIZONTAL/VERTICAL), via/clicksorted set start-cornerand/clicksorted set fill-axis. Both settings affect treemap placement as well as the linear sorts. - Automatic update check — on startup and after/clicksorted reload, the plugin queries the Modrinth API and logs a console notice if a newer release exists. Can be disabled withcheck_for_updates: false. - Item-loss fix — enchantments and otherItemMetafields are now included in the sort-key merge-equality check, so identically typed but differently enchanted items are never merged. - Hover coupled to click method —single_clicknow forces sort-over-items off (it only ever triggers on an empty slot);control_dropforces it on. Switching click method adjusts the hover preference automatically, and trying to override it manually shows a clear message.Breaking Changes
- Minimum server version is now Paper/Folia 1.21.5New Features
Treemap sort method
/clicksorted set sort-method treemapselects the newTREEMAPmode. UnlikeNAME(linear alphabetical) andGROUP(linear by creative-tab bucket),TREEMAPassigns each item type a shelf-packed, contiguous near-square rectangle in the inventory grid. Types are ranked largest-first so the biggest stacks dominate the most visible area. The rectangle's shape is chosen to minimise wasted cells while staying close to square; types that can no longer fit cleanly fall back to filling free cells in reading order, so a nearly-full inventory degrades gracefully to a gap-free fill.TREEMAPis always available — nogroups.ymlrequired. Thestart_cornerandfill_axispreferences (see below) control which corner the largest block anchors to and whether shelves of blocks grow horizontally or vertically.Sort direction
Two new per-player preferences control how sorted items are written back into the inventory grid (for linear sorts) and how treemap shelves are oriented: -/clicksorted set start-corner <TOP_LEFT|TOP_RIGHT|BOTTOM_LEFT|BOTTOM_RIGHT>— which corner items are placed from (defaultTOP_LEFT). -/clicksorted set fill-axis <HORIZONTAL|VERTICAL>— whether rows (HORIZONTAL) or columns (VERTICAL) fill first (defaultHORIZONTAL). Server admins set defaults withdefaults.start_corneranddefaults.fill_axisinconfig.yml. The newGridGeometry/SlotOrder/TreemapPackerclasses implement the layout internally.Automatic update check
On startup and after/clicksorted reload,UpdateCheckerfires an async Modrinth API query. If a newer release version is available, two INFO-level lines are logged to the console with the version number and download links. Failures degrade silently to a debug log. Disable entirely withcheck_for_updates: falseinconfig.yml.Preference repair
A "preference repair" procedure runs on player join and resets any per-player PDC value that can no longer be parsed as its expected type (e.g. a stale enum name from an old version). Each reset preference sends the player a chat notice (prefResetInvalidinlang.yml) naming the preference, the bad value, and the new default.Bug Fixes
- Item loss from same-material stacks with differing meta — Merge equality now includesItemMeta, so enchanted and plain tools are never collapsed together. Previously, merging a stack of stackable items with different enchantments could silently discard the extras. [PR #46] - Lifted stack not re-deposited on `DOUBLE_CLICK` — a double-click sort left the item on the cursor unreturned to the inventory if the click initiated the sort. The stack is now placed back before writing sorted results. - `SINGLE_CLICK` sort could fire over an occupied slot — the sort-over-items gate now enforces thatsingle_clickonly triggers on an empty slot unconditionally (hover is forced off for this method). - Sort grid origin not row-aligned — now aligns the sort origin to the first full row of the inventory, preventing partial-row layouts at the top of large containers. - Real chest grids and fill-axis not honoured — the slot-order implementation now correctly reflects actual chest grid dimensions and respects the fill-axis setting end-to-end. [PR #46] - `Log` not null-safe before `onEnable` — the logger handle is now checked for null before early log calls during plugin load.Other Improvements
- Deduplicated enum/boolean PDC accessors inPlayerSortingPrefsusing a shared accessor pattern;sortable_inventoriesis now backed by anEnumSet. -GridGeometryis now the single authoritative source for the mount-slot offset used in player inventory layout. - Newlang.ymlkeys:setStartCornerTo,setFillAxisTo,hoverForcedByClickMethod,hoverGovernedByClickMethod,prefResetInvalid,invalidValue,statusStartCorner,statusFillAxis. - Newlang.ymlkey:prefix— a configurable MiniMessage string prepended to every status, error, and alert message sent to players. Defaults to<gray>[<aqua>ClickSorted<gray>]. Set to""to disable. Lock-GUI item names are not affected. - Unified command-feedback messaging: all player-facingset …/status/reload messages were reworded for a consistent voice and now default to white text./clicksorted set …subcommands also send a clearinvalidValueerror when an argument can't be parsed, naming the bad value and listing valid options (previously invalid input was silently ignored). [PR #47] - Treemap grouping refined: durable items get their own block per meta variant while non-durable items (including bundles) group by material, with a stable within-block stack order (enchanted books ordered by primary enchantment), and rectangle selection now prefers squareness over minimal waste. [PR #48] - README and CLAUDE.md updated for sort direction, the update check, hover coupling, preference repair, and the new config/lang keys.Compatibility
Paper/Folia 1.21.5 – 26.1.x
Java 21
Upgrading
1. Stop your server. 2. Replace the old jar inplugins/with this release. 3. Start your server.Note: The two new per-player preferences (
start_corner,fill_axis) are read fromconfig.ymldefaults if a player has never set them. No manual migration is needed.What's Changed
- Add Modrinth-based update check by @kccricket in #45 - Add TREEMAP sort method, sort direction (start corner + fill axis), and treemap layout engine by @kccricket in #46 - Unify command feedback messages and add configurableprefixby @kccricket in #47 - Refine treemap grouping/ordering so bundles and meta variants pack correctly by @kccricket in #48 - Couple hover preference to click method, repair invalid prefs by @kccricket - Fix item loss from same-material stacks with differing ItemMeta by @kccricket - Fix re-deposit of lifted stack on DOUBLE_CLICK sort by @kccricket - Fix SINGLE_CLICK sort over occupied slots by @kccricket - Fix sort grid alignment and chest grid layout by @kccricket - Dedupe enum/boolean accessors and EnumSet sortables by @kccricket1.1.1ClickSorted 1.1.1Jun 14, 2026 ClickSorted 1.1.1 adds explicit Folia support, hardens shared state for Folia's per-region worker threads, and fixes sorting from inside ClickSorted's own GUIs.Highlights
- Explicit Folia support — the plugin now declaresfolia-supportedand makes all shared mutable state safe for Folia's per-region worker threads. - Lock GUI no longer sortable — sort triggers inside ClickSorted's own GUIs are now ignored unconditionally, so a click in the lock GUI can no longer rearrange its panes or the inventory beneath it. - Atomic action throttle — the per-player throttle window is now updated atomically, closing a race under concurrent clicks.Bug Fixes
- ClickSorted's own GUIs are never sorted — the lock GUI is a CHEST-type inventory that matched the sortable set, so a sort-trigger click inside it could rearrange its panes before the GUI listener cancelled the interaction. AClickSortedHoldermarker interface now makes the sort listener bail on any ClickSorted GUI, independent ofignore_plugin_inventory. - The action throttle window is now atomic, preventing a race when a player's clicks arrive concurrently.Other Improvements
- Hardened shared mutable state for Folia:CooldownMessenger's cooldown map is now aConcurrentHashMap(keyed by player UUID),GroupsConfigmappings are built locally and swapped atomically on reload, andItemsConfig/MainConfigreload swaps are published viavolatile. - Dropped the obsoleteSWAP_OFFHANDoffhand-reset workaround — modern Paper's inventory ack/sequence system reconciles the client prediction, so cancelling the event suffices. This removes the plugin's onlygetScheduler()call; an integration test pins the contract that a SWAP-triggered sort leaves the offhand untouched across a tick. - Replacedplugin.ymlwithpaper-plugin.yml. - AvoidedInventoryViewmethod calls from plugin bytecode inLockGuiListener(usingInventoryEvent.getInventory()), preventingIncompatibleClassChangeErroracross 1.20.6/1.21. -MessageUtilnow takes an AdventureAudienceinstead ofCommandSender, making the Adventure routing explicit and allowing any audience to be passed. - Made item-name lookup a pure read and removed test-only public methods with no production callers. - Added a GitHub Actions CI workflow that runs the test suite on PRs (Java 25, matching the Paper API requirement).Compatibility
Paper/Folia 1.20.6 – 26.1.x
Java 21
Upgrading
1. Stop your server. 2. Replace the old jar inplugins/with this release. 3. Start your server.What's Changed
- Support Folia explicitly and harden cross-thread/version safety by @kccricket in #43 - Never sort ClickSorted's own GUIs by @kccricket - Make the action throttle window atomic by @kccricket - Convertplugin.ymltopaper-plugin.ymlby @kccricket - Optimize Adventure usage inMessageUtilby @kccricket in #41 - Add GitHub Actions CI workflow to run tests on PRs by @kccricket in #421.1.0ClickSorted 1.1.0Jun 13, 2026 ClickSorted 1.1.0 adds slot locking and bundle packing, restructures all player preferences under a singlesetcommand, and introduces a settings-migration framework so stored values survive future renames.Highlights
- Slot locking — mark individual inventory slots to keep them untouched by sorting, managed through a visual/clicksorted set lockGUI. - Bundle packing — sorting can now fold each item type's leftover remainder into the bundles you keep in an inventory, reclaiming slots in the same click. Opt in per region for your own inventory and for containers. - Commands restructured under `set` — per-player preferences now live under/clicksorted set …(sort-method,click-method,hover,lock,bundle), with a new/clicksorted statusto print your current settings. - Settings migration framework — a single catalog migrates renamed values and drops removed settings across both config and per-player data, so legacy values (e.g.DOUBLE→DOUBLE_CLICK) convert automatically on load/join. - Per-player action throttle — caps how fast a scripted client can drive plugin work, with a/clicksorted benchmarkdiagnostic for measuring the sort and repack paths.Breaking Changes
- Preference commands moved under `set`./clicksorted sortis now/clicksorted set sort-methodand/clicksorted clickis now/clicksorted set click-method; the old top-level forms no longer exist. Update any macros, command blocks, or aliases. (Theclicksorted.commands.sort/.clickpermission nodes are unchanged.) - Shift-click preference cycling removed. Shift-left/right-clicking in your inventory no longer cycles your sort and click preferences. The/clicksorted shiftclickcommand, theclicksorted.commands.shiftclickpermission, and thedefaults.shift_clickconfig key are gone. Shift-left-click and shift-right-click are now available as explicit sort triggers instead (/clicksorted set click-method shift_left_click|shift_right_click). - `ClickMethod` values renamed.DOUBLE→DOUBLE_CLICKandSINGLE→SINGLE_CLICK. Stored player preferences andconfig.ymlvalues are rewritten automatically on load/join, so no manual action is needed unless you script against the raw values.New Features
Slot locking
/clicksorted set lockopens a chest GUI that mirrors your inventory — three rows for main storage and one for the hotbar, separated by a divider. Lime panes are unlocked, barrier icons are locked, and black panes mark slots outside the sortable range. Click a pane to toggle it; changes save immediately, and locked slots are neither read nor overwritten when you sort. Locks apply only to your own inventory (main region and hotbar) — containers always sort in full.Bundle packing
When enabled, a sort first consolidates bundle-eligible items by type: full stacks stay loose in the inventory and only the leftover remainder is packed into a bundle — and only when it's an efficient trade (the remainder is at or below half a bundle's weight). The result is a pure function of the item multiset, so re-running on an unchanged inventory is a no-op. Toggle it per region with/clicksorted set bundle inventory on|offand/clicksorted set bundle others on|off, and cap distinct entries per bundle with/clicksorted set bundle stacklimit <n|off>(server defaults:defaults.bundle_inventory,defaults.bundle_others,defaults.bundle_stack_limit).Command restructure & status
All preference commands moved under/clicksorted set(sort→set sort-method,click→set click-method, plusset hover,set lock,set bundle). A new/clicksorted statusreports your click method, sort method, and sort-over-items state.Settings migration framework
A newMigrationscatalog owns "what is stored where," migrating bothconfig.ymland per-player persistent data through one entry point each. Renamed values are declared as lineages that converge in a single pass; removed settings are dropped from the store. LegacyClickMethodspellings migrate automatically and the deprecatedshift_clicksetting is removed on upgrade.Action throttle & benchmark
A global per-player rate limiter (action_cooldown_ms, default 150 ms) gates every plugin-driven action; players withclicksorted.throttle.bypass(default op) are exempt./clicksorted benchmark [iterations]runs an in-situ micro-benchmark of the sort and bundle-repack paths.Bug Fixes
- Empty-slot sorting, over-cancellation, and non-fungible item merge — sorting on empty slots, event over-cancellation, and merging of non-fungible items (bundles and non-stackables) are now handled correctly. -player_sort_maxis now treated as an exclusive bound (matching its default of 36) and is clamped to the armor boundary, so a misconfigured value can no longer scramble armor or off-hand slots.Other Improvements
- Consolidated the throttle gate intoActionThrottle.throttled()and routed all command handlers through sharedrequirePlayer/parseStatehelpers, removing duplicated guard logic. - Regeneratedgroups.ymlfor Minecraft 26.1.2, correcting some mis-grouped items (e.g. chains). - README and CLAUDE.md updated for thesetcommand tree, bundle packing, the action throttle, and the new config/lang keys.Compatibility
Paper/Folia 1.20.6 – 26.1.x
Java 21
Upgrading
1. Stop your server. 2. Replace the old jar inplugins/with this release. 3. Start your server.Note: Existing preferences migrate automatically — legacy click-mode values (
DOUBLE,SINGLE) are rewritten to their current spellings and the deprecatedshift_clicksetting is dropped on first load/join. No manual config edits are required.What's Changed
- Add slot-lock GUI (/clicksorted set lock) by @kccricket - Restructure commands underset, rename click/sort, add status by @kccricket - Settings migration framework, hover command, and expanded ClickMethod by @kccricket - Pool-and-repack bundle packing folded into a unified sort pipeline by @kccricket - Per-player action throttle and in-situ benchmark by @kccricket - Fix empty-slot sorting, over-cancellation, and non-fungible item merge by @kccricket - Fixplayer_sort_maxexclusivity and clamping by @kccricket - Fix Minecraft 26.1.2 item grouping (chains) by @kccricket1.0.0ClickSorted 1.0.0Jun 8, 2026 ClickSorted 1.0.0 is a ground-up modernization of the original ClickSort plugin, rewritten for Paper 1.21.x with a clean architecture and no legacy dependencies.Highlights
- New package & name — rebranded fromClickSort(me.desht.clicksort) toClickSorted(net.kccricket.clicksorted) with a fully reorganized, concern-based package layout. - No more SQLite — player sorting preferences are now stored in Bukkit's Persistent Data Container; no database file, no async JDBC, no migration needed. - Paper-native commands — the old dhutilsAbstractCommand/CommandManagerframework is gone; commands are a Brigadier tree registered viaLifecycleEvents.COMMANDS. - Adventure / MiniMessage messages — all user-facing text is now an AdventureComponent; legacy § color codes are fully replaced andlang.ymluses MiniMessage format throughout. - Full integration test suite — 10 test classes covering sort behavior, commands, config reload, cooldown messaging, player prefs, and resource updating via MockBukkit.New Features
Add-only config merging
ResourceUpdaterperforms an add-only merge of bundled defaults into the plugin data folder on startup. New keys added in a future release appear in your live config automatically; existing customizations are never overwritten.Expanded sortable inventory types
config.ymlnow includes additional inventory types (barrel, blast furnace, dispenser, dropper, furnace, hopper, smoker) in the defaultsortable_inventorieslist so more containers sort out of the box.Updated item groups
groups.ymlhas been updated to reflect the full 1.21.5 creative-mode tab groupings, giving GROUP sort a more intuitive ordering for current-version items.Bug Fixes
-SortEnginenull/empty-inventory edge cases hardened — operations on inventories with no sortable slots no longer throw. -InventorySortEventdefensive guard — the post-sort event is only fired when a sort actually occurs, preventing spurious third-party handler calls. -LangConfigmissing-key fallback — referencing an undefined message key now returns a safe placeholder instead of throwing aNullPointerException.Other Improvements
- Build system — migrated from Maven (pom.xml) to Gradle (build.gradle.kts) with the Shadow plugin for fat-JAR assembly. - Java 21 bytecode target — the build now emits Java 21 class files, matching the minimum JVM required by modern Paper builds. - Removed dhutils — the entire embeddedme.desht.dhutilslibrary (≈3 000 lines) is gone; only the handful of utilities actually used by the plugin were rewritten as focused classes (Log,ItemNames,CooldownMessenger,Permissions). - Removed Essentials integration — the VALUE sort method (which relied on Essentials item worth data) has been removed; NAME and GROUP remain. - Removed `coloured_console` setting — console output is always plain text; the config key had no effect on modern Paper and is no longer present. - Removed legacy version compatibility shims — version-parsing workarounds for Minecraft 1.12 and earlier are gone. - Unified config lifecycle — all four config files (config.yml,lang.yml,groups.yml,items.yml) are managed through a singleConfigManager; reload via/clicksorted reloadrefreshes all of them atomically. - Typed debug levels —DebugLevelis now an enum (OFF,LOW,MEDIUM,HIGH) replacing the old integer-based debug flag, with log calls gated by level comparison. - Documented YAML configs — all four bundled resource files now have inline comments explaining every key. - Expanded README — covers installation, permissions, commands, configuration reference, and the GROUP sort method.Compatibility
Paper/Folia 1.20.6+
Java 21
Upgrading from ClickSort (original fork)
1. Stop your server. 2. Remove the old ClickSort jar fromplugins/. 3. Placeclicksorted-1.0.0.jarinplugins/. 4. Start your server. Freshconfig.yml,lang.yml,groups.yml, anditems.ymlfiles will be generated inplugins/ClickSorted/. 5. (Optional) Review your oldplugins/ClickSort/settings and migrate any customizations to the new config files. Note that player sorting preferences were stored in SQLite and cannot be migrated; players will start with defaults.Upgrading from ClickSort (original fork)
1. Stop your server. 2. Remove the old ClickSort jar fromplugins/. 3. Deleteplugins/ClickSort/— player preferences were stored in SQLite and cannot be migrated; players will start with default preferences. 4. Placeclicksorted-1.0.0.jarinplugins/. 5. Start your server. Freshconfig.yml,lang.yml,groups.yml, anditems.ymlfiles will be generated inplugins/ClickSorted/.
Similar projects
Plugin →VeinMiner
Mine the whole vein on mining a single ore/block. Make the tedious mining experience to something satisfying and fun! FTB Ultimine alternative
99.3MSueta
Simple Voice Chat
A working voice chat in Minecraft!
76.8MSueta
Let Me Despawn
Improves performance by tweaking mob despawn rules. Say bye to pesky unintentional persistent mobs.
25MSueta
Chunky
Pre-generates chunks, quickly and efficiently
18.4MSueta
VeinMiner Enchantment
Veinminer Addon - Adds vineminer enchantment to enchanting tables. Only tools with the enchantment can veinmine
18MSueta
JourneyMap
Real-time map used for mapping in-game or your browser as you explore.
14.7MSueta