Releases: AbstractMenus/minecraft-plugin
v1.18.0 Optimization, fixes and up performance
AbstractMenus 1.18.0
First release after the performance overhaul. The typical menu refresh path is 3–5× cheaper on the main thread than in 1.17.8, and the MiniMessage pipeline no longer shows up in Spark profiles of normal workloads. Existing HOCON configs load unchanged.
🔥 Highlights
| Hot frame on the bench workload | 1.17.8 (baseline) | 1.18.0 | Δ |
|---|---|---|---|
MenuManager$UpdateTask.run |
1.04 % | 0.33 % | 3.2× |
SimpleItem.applyProperties |
0.99 % | 0.20 % | 5× |
MiniMessageUtil$ActiveReplacer.parseToLegacy |
0.40 % | not in top | gone |
MiniMessageImpl.deserialize |
0.36 % | not in top | gone |
PlaceholderAPI.setPlaceholders |
0.67 % | not in top | gone |
Inclusive sample percentages from Spark, same Paper 1.21.11 server, same bench-menu workload, same alt accounts. Linear extrapolation to 50 simultaneous players puts the menu path from ~52 % of main-thread CPU down to ~16 %.
✨ Added
- Pre-compute for static names & lore in
PropName/PropLore- fully-static text is converted through MiniMessage once at load and cached; refreshes skip PAPI + MiniMessage entirely for those items. - Copy-on-write item cloning —
SimpleItem.clone()now shares property-map references with the template; onlyaddProperty/removeProperty/setPropertiestrigger the real deep copy. - Skull caches —
Skulls.getPlayerSkull(name)now caches by lowercased name, invalidated onPlayerJoinEvent.PropHDBreuses a singleHeadDatabaseAPIinstance instead of allocating one per render. - Player reference cache in
MenuManager.UpdateTask— no moreBukkit.getPlayer(uuid)lookup per open menu per tick. - Bench harness —
src/main/resources/bench-menus/contains 10 reference menus and a README that stress each hot path for Spark / JMH measurements. JMH micro-benchmarks live undersrc/test/java/ru/abstractmenus/bench/. - GitHub Actions — build + release workflows under
.github/workflows/, with JUnit test report publishing, shaded-JAR artifacts, and automatic JAR attachment to GitHub releases. - Test suite — ~190 unit + integration tests covering util classes, datatype deserializers, compound HOCON serializers, the CoW item contract, the MiniMessage legacy path, and Mockito-based regression pinning.
🛠 Changed
- MiniMessage legacy color replacement rewritten from O(K×N) to O(N) - single-pass
appendReplacement, fast-path returns the same input reference when no§codes are present. Extracted intoLegacyColorTagReplacerso the logic is unit-testable without Adventure service-loader collisions. Frame.play()returns builtItemStacks directly — eliminates the seconditem.build(...)pass thatAnimatedMenu.update()used to run, cutting per-frame work roughly in half.- Dependency bumps: Paperweight
beta.21, Adventure MiniMessage4.26.1, Lombok1.18.44, item-nbt-api2.15.7, PlaceholderAPI2.12.2, LuckPerms5.5, shadow9.4.1, ProGuard7.9.1, JUnit Jupiter5.14.3, VaultAPI1.7.1, FoliaLib0.4.4. - Low-hanging perf fixes:
PropData.applydedups doublegetByte(),GeneratedMenu.opendrops a duplicate snapshot,OpenSignusesTag.SIGNS,StringUtil.replaceKeyPrefixno longer compiles a regex per call,Server/BungeePlaceholdersreplace split +Arrays.copyOfRange+String.joinwith a singlesubstring. - Lombok-ified trivial data holders (
Tuple,EntityData,PropBindings.BindGroup,LegacyValueComparator.Comparator,DataType) — −44 lines of hand-rolled getters/setters.
🐛 Fixed
OpenSignleft-click regression — inverted click-type guard disabled left clicks; both clicks work again. Also removes anIndexOutOfBoundsExceptionon sign configs with >4 lines and uses a safeinstanceof Signpattern instead of an unchecked cast.ActionCommandchat-event cycle — switched toplayer.performCommand(...)fromplayer.chat("/" + cmd); avoids re-triggeringOpenChatactivators and removes a double placeholder pass.PropSkullOwnerunconditionalLogger.severe— used to fire on every successful render. Now only on thenullbranch, downgraded towarning.MojangApiconnection / scanner leaks —HttpURLConnectionis disconnected on IOException andScanneris wrapped in try-with-resources.BungeeManager.pingTaskmain-thread violation -sendPluginMessageis now dispatched through the Bukkit scheduler (was called from a rawScheduledExecutorService).MenuManager.servewatcher thread — daemonised, joined on disable;loadFilefrom the watcher dispatches back to the main thread viaBukkitTasks.runTask.ProfileStorage.onPlayerJointhreading — Bukkit API calls moved to the main thread; only the Mojang HTTP fetch stays async.
📝 Docs
- README refreshed with the current feature list, requirements, architecture diagram, bench pack pointer, and contributor section.
PR_DESCRIPTION.mddocuments the performance wave in detail - per-commit breakdown, before/after numbers, caveats..github/RELEASE.mdspells out the release flow the new workflows enable.
⚠️ Caveats
- Sound IDs on Paper 1.21.x —
Registry.SOUNDS.get(NamespacedKey.fromString(...))rejects the old uppercase enum-style sound IDs (UI_BUTTON_CLICK,BLOCK_NOTE_BLOCK_CHIME). Configs need the lowercase dotted form (ui.button.click,block.note_block.chime). Update your menus or copy frombench-menus/_templates.conf. - MockBukkit integration tests are
@Disabled— MockBukkit 4.108 and Paper 1.21.11 collide during registry bootstrap. The skeleton is checked in and will re-enable once either side closes the ordering.
🙌 Contributors
Thanks to everyone who shipped this release:
- @Nan1t — original author, architectural guidance
- @BrainRTP — performance wave, test suite, bench harness, CI
- @WhyZerVellasskx — modern colorize path, keyed enchantment support, PAPI tag resolver, multi-placeholder fixes, 1.21.4 support, release automation groundwork
See the full contributor graph for everyone who has ever touched the code.
📦 Install
Drop AbstractMenus-1.18.0.jar into plugins/ on Paper 1.20.6 – 1.21.11 (Folia supported). Soft-deps: PlaceholderAPI, Vault + an economy plugin, LuckPerms — none required, all hooks degrade gracefully if missing.
v1.17.5-beta
What's Changed
- Fix some bugs and cleaning code by @WhyZerVellasskx in #6
- Add support 1.21.4 by @WhyZerVellasskx in #9
New Contributors
- @WhyZerVellasskx made their first contribution in #6
Full Changelog: https://github.com/AbstractMenus/minecraft-plugin/commits/v1.17.5-beta