Changelog

Track all changes, improvements, and fixes across every HyperPerms release.

30 releasesLatest: 2.9.0GitHub Releases
2.9.0Latest

HyperPerms v2.9.0

February 28, 20262 Changed
Major version changes may include breaking changes. Always read the release notes before upgrading, especially for major versions.
2.9.0LatestHyperPerms v2.9.0
February 28, 20262 changes
Changed(2)
Web editor returning 500 on /hp editor β€” The gzip compression introduced in 2.8.9 was applied to all session create requests, but the Cloudflare Worker API does not support Content-Encoding: gzip on incoming request bodies. This caused every /hp editor command to fail with "Server returned status 500". Compression is now only applied to payloads exceeding 500KB, keeping normal requests uncompressed while still protecting very large servers from HTTP 413 errors.
If you are on 2.8.9, update immediately.*
2.8.9HyperPerms v2.8.9
February 28, 202621 changes
Added(1)
New annotationsβ€”@CommandGroup, @Command, @Arg, @OptionalArg, @Permission, @Confirm
Changed(18)
200+ permission nodes registered across admin, command, skill, boost, and alternate prefix categories
All 23 skill nodes β€” mmoskilltree.skill.mining, .woodcutting, .excavation, .harvesting, .fishing, .swords, .daggers, .polearms, .staves, .axes, .blunt, .archery, .unarmed, .defense, .taming, .acrobatics, .crafting, .repair, .alchemy, .enchanting, .cooking, .smithing, .building
All 140 XP boost permission nodes covering personal and global boosts for all skills, skill categories, and all-skills targets with varying multipliers, durations, and cooldowns
*ziggfreed. alternate prefix support* β€” MMOSkillTree checks permissions through both mmoskilltree. and ziggfreed.mmoskilltree.* prefixes. HyperPerms now correctly resolves both via bidirectional aliases
Hytale command path aliases β€” com.ziggfreed.mmoskilltree.command. paths resolve to their mmoskilltree.command. equivalents
Wildcard expansion for all MMST permission categories
Tab completion & web editor now show all MMST permission nodes
Updated RPG & Survival templates with appropriate MMST permissions at each rank tier (XP boosts scale with rank progression)
11 ordered stages: Config β†’ Storage β†’ CoreManager β†’ Resolver β†’ Registry β†’ Chat β†’ Integration β†’ Web β†’ Scheduler β†’ Analytics β†’ DefaultGroups
PluginLifecycle orchestrator initializes stages in order and shuts them down in reverse β€” if any stage fails, previously initialized stages are safely torn down
ServiceContainer provides typed dependency injection across all stages
HyperPerms.java reduced from ~400 lines of monolithic init to ~25 lines β€” all setup logic now lives in dedicated Stage implementations
CommandScanner automatically discovers and registers annotated command methods at startup
CommandDispatcher handles argument parsing, permission checks, and confirmation flows
5 annotated command groups replace 42 individual command classes: GroupCommands, UserCommands, DebugCommands, RootCommands, PermsCommands, BackupCommands
Net reduction of ~1,500 lines with significantly better maintainability
Gzip compressed session requests β€” Session create payloads are now gzip compressed before sending to the API, preventing HTTP 413 errors on servers with many groups and permissions
Integrated 2.8.8's centralized sync and diff-based permission logic into the new lifecycle system
Fixed(2)
Fixed config being null during early stage initialization
Fixed default groups being created before storage was fully ready
2.8.8HyperPerms v2.8.8
February 24, 20267 changes
Changed(7)
Server Versionβ€”* 2026.02.19-1a311a592
Permission pollution in Hytale's permissions.json - syncPermissionsToHytale() previously pushed all resolved permissions on every change, causing hundreds of permissions to accumulate. Now uses diff-based sync that computes the delta between Hytale's current state and HyperPerms' resolved set, only adding missing and removing stale permissions
Race condition in concurrent permission syncs - Multiple threads (command thread, scheduler, CF pool, web editor) could call syncPermissionsToHytale() simultaneously for the same user, racing on Hytale's non-thread-safe HashSet view from getUserPermissions(). Added per-UUID synchronization locks and defensive copying of the live view
Scattered manual sync calls - Six user commands and HyperPermsPermissionProvider each had their own inline syncPermissionsToHytale() call via bootstrap reflection. Centralized all sync logic into a CacheInvalidator.setSyncListener() hook β€” every cache invalidation now automatically triggers Hytale sync for affected online users
Group commands invalidated entire cache - Group permission/property changes (setperm, unsetperm, setprefix, setsuffix, setweight, setexpiry, parent add/remove) called invalidateAll() instead of targeted invalidateGroup(), causing unnecessary cache churn for unrelated users
Expired permissions not synced to Hytale - ExpiryCleanupTask removed expired nodes but didn't invalidate the cache or trigger Hytale sync, so expired permissions remained active until the player reconnected
Inconsistent cache invalidation API - Some commands used getCache().invalidate() (bypassing sync) while others used getCacheInvalidator().invalidate() (with sync). Unified all commands to use getCacheInvalidator()
v2.8.7v2.8.7
February 22, 20263 changes
Fixed(3)
Permissions not applied after permissions.json wipe - syncPermissionsToHytale() only removed negated permissions from Hytale's internal storage but never added granted permissions. After an OOM crash wiped Hytale's permissions.json, third-party plugins (OrbisGuard, etc.) using PermissionsModule.hasPermission() saw an empty permission set. Now pushes all expanded granted permissions (with wildcard and alias resolution) to other providers, then removes denied permissions β€” ensuring negations still override grants
JSON storage data loss on JVM crash - saveUser(), saveGroup(), and saveTrack() used Files.writeString() with TRUNCATE_EXISTING, which could leave files empty or corrupt if the JVM crashed mid-write. Now writes to a .tmp file first, then atomically renames to the target path
Corrupt JSON file crashes entire load - loadAllUsers(), loadAllGroups(), and loadAllTracks() only caught IOException, not JsonParseException (a RuntimeException). A single corrupt file would crash the entire load and prevent all other files from loading. Now catches all exceptions, logs a warning with the filename and error, and continues loading remaining files
2.8.6v2.8.6 β€” MariaDB/MySQL Storage, Command Refactor & Bug Fixes
February 22, 202623 changes
Added(18)
Full MariaDBStorageProvider (~1,050 lines) with HikariCP connection pooling
Complete async CRUD for users, groups, tracks, and permission nodes
JSON dump backup/restore strategy for networked databases
5-table schema: users, groups, usernodes, groupnodes, tracks (InnoDB, utf8mb4)
Configure via storage.typeβ€”"mariadb" or "mysql" in config.json
Full connection optionsβ€”host, port, database, username, password, poolSize, useSSL
useSSL config option with automatic migration from older config versions
HikariCP 6.2.1 and MariaDB JDBC 3.5.1 bundled in shadow JAR
New Logger.DebugCategory enum with 10 categoriesβ€”RESOLUTION, CACHE, STORAGE, CONTEXT, INHERITANCE, INTEGRATION, CHAT, WEB, MIGRATION, EXPIRY
Each toggleable individually via /hp debug toggle <category>
Debug traces throughout the chat pipeline (ChatListener, ChatManager, ChatFormatter, PrefixSuffixResolver)
Debug traces for integration setup (Factions, WerChat, PlaceholderAPI, MysticNameTags, VaultUnlocked)
Registered missing hytale.mods.outdated.notify permission node matching Hytale's HytalePermissions class
Startup warning when vanilla OP/Default groups contain custom permissions that will be silently lost on restart
Added UPDATESALL, UPDATESTOGGLE, UPDATES_NOTIFY permission constants
JitPack publishing β€” depend on HyperPerms via com.github.HyperSystemsDev:HyperPerms:<version>
CONTRIBUTING.md β€” contributor guide with build setup, code style, and branch strategy
Standalone build support for JitPack/CI environments
Changed(2)
Build system overhaul β€” Hytale Server API now resolved automatically from maven.hytale.com instead of local JAR files. VaultUnlocked upgraded to 2.19.0 via Maven
Hytale permissions alignment β€” Aligned with hytale-permissions-docs v1.1.0: documented multi-provider aggregation, nondeterministic iteration avoidance, wildcard restrictions, and permissions.json initialization semantics
Fixed(3)
Web editor HTTP/2 connection failures β€” Forced HTTP/1.1 to prevent "header parser received no bytes" errors when ALPN negotiation fails
Noisy gamemode group warnings β€” Hytale calls addUserToGroup with virtual gamemode groups on every login; downgraded from warning to debug level
MariaDB resource leak β€” Fixed unclosed connection in backup/restore, missing backups directory initialization, and redundant setAutoCommit call
2.8.5HyperPerms v2.8.5
February 17, 202610 changes
Changed(10)
Server Versionβ€”* 2026.02.17-255364b8e
Server compatibilityβ€”Compile against latest Hytale server JAR to resolve NoSuchMethodError on PacketHandler.write() (TabListListener crash)
User load race conditionβ€”UserManagerImpl.loadUser() now uses first-writer-wins to prevent concurrent loads from replacing a user whose username was already set by onPlayerConnect
Server version warningβ€”Manifest now specifies target server version (prevents PluginManager "does not specify a target server version" warning)
Offline player resolutionβ€”resolveUser() now falls back to storage lookup and PlayerDB API when in-memory search fails, enabling commands like /hp user <name> info to work for offline players
PlayerDB integrationβ€”New PlayerDBService utility for looking up any Hytale player by username via the playerdb.co API (5-minute TTL cache)
Online player safety netβ€”New findOnlineUuidByName() on PlayerContextProvider resolves players who are connected but whose async user load hasn't completed yet
PlayerResolver extractionβ€”Moved inline resolveUser() logic from HyperPermsCommand to dedicated PlayerResolver utility with 5-step resolution chain (UUID parse β†’ loaded users β†’ online players β†’ storage β†’ PlayerDB)
Improved loggingβ€”Player connect/disconnect, user loading, and permission sync now use info level for better server diagnostics
Target-aware buildβ€”Compile against release or prerelease server JAR via -PhytaleTarget Gradle flag
2.8.4HyperPerms v2.8.4
February 15, 20264 changes
Changed(2)
HyperFactions permission registry overhaulβ€”Reorganized all HyperFactions permissions into a proper hierarchical structure with category wildcards (hyperfactions.faction., hyperfactions.member., hyperfactions.territory.*, etc.) and better descriptions
Runtime discovery namespace filteringβ€”Only keeps permissions whose namespace matches the plugin's JAR filename, manifest Name, or manifest Group β€” eliminates false positives from bundled/relocated dependencies
Fixed(2)
*Web editor showing com. command path permissions**: Hytale command path format permissions (e.g., com.hyperfactions.hyperfactions.command.faction) are now filtered from the web UI plugin permission scanner (still used internally for wildcard resolution)
Runtime discovery no longer skips HyperSystems pluginsβ€”Removed hardcoded exclusion of hyperhomes, hyperwarps, hyperfactions from discovery β€” these plugins register their own permissions via the built-in registry and discovery should not interfere
2.8.3HyperPerms v2.8.3
February 12, 202636 changes
Added(36)
MysticNameTags Integration - First-class soft dependency with reflection-based detection
Event-driven cache invalidation on permission/group changes via HyperPerms EventBus
Calls TagManager.clearCanUseCache() and MysticNameTagsAPI.refreshNameplate() on changes so tags update without relog
Group-level permission changes invalidate all online players who may inherit from the affected group
LuckPerms conflict detection with warning log
Local CachedTagData with 5-second TTL for API method results
Public APIβ€”getActiveTagDisplay, getActiveTagId, getAvailableTagCount, hasTagPermission, refreshPlayerTags, etc.
Configurable via config.json mysticnametags section (enabled, refresh toggles, tag permission prefix)
Auto-migration adds config section to existing configs
PlaceholderAPI Expansion - 5 new MysticNameTags placeholders
%hyperperms_tag% - Active tag ID
%hyperpermstagdisplay% - Active tag display text (colored)
%hyperpermstagcount% - Number of available tags
%hyperperms_tags% - All available tag IDs (comma-separated)
%hyperpermshastag_<name>% - Check tag permission (true/false)
Temporary Permissions Developer API - Full public API for managing timed permissions programmatically
New TemporaryPermissionInfo record DTO with getRemaining() and isExpired() methods
PermissionHolder interfaceβ€”12 new methods for setting, querying, and modifying temporary permissions
setPermission(perm, value, Duration/Instant) - Set permissions with expiry
isTemporaryPermission(perm) / getPermissionExpiry(perm) / getPermissionRemaining(perm) - Query expiry state
setPermissionExpiry(perm, Instant) / adjustPermissionExpiry(perm, Duration) - Modify or remove expiry
getTemporaryPermissions() - Enumerate all active temporary permissions
addGroup(name, Duration/Instant) - Temporary group membership via interface
HyperPermsAPI top-level convenience methodsβ€”setTemporaryPermission(), getTemporaryPermissions(), isTemporaryPermission(), getPermissionRemaining()
All methods are backward-compatible default methods β€” no breaking changes
Permission Enumeration API - getResolvedPermissions(UUID) on HyperPermsAPI
Returns all granted permission strings for a user including inherited permissions from group hierarchy
Enables plugins to scan permissions by prefix without depending on the native provider chain
EssentialsPlus Compatibility - Fixed provider ordering causing parameterized permission queries to fail silently
Hytale's native provider was first in the chain and couldn't resolve HyperPerms virtual groups
ensureFirstProvider() now reorders the provider chain so HyperPerms is always first
Fixes essentialsplus.sethome.limit.[n], essentialsplus.home.reduce.cooldown.*, and similar queries
Compilation Warnings - Resolved all 63 compiler warnings for a completely clean build
Fixed 56 dangling-doc-comments warnings in migration record types
Fixed 4 unchecked/rawtypes warnings in AsyncPermissionCheckBuilder
Fixed 3 text-blocks trailing whitespace warnings in SQLiteAnalyticsStorage
2.8.2HyperPerms v2.8.2
February 9, 202615 changes
Added(15)
Temporary Permissions - Duration/expiry support for permissions and group membership
/hp user setperm <player> <perm> [value] [duration] - Set permissions with optional expiry (e.g. 1d, 2h30m, 1w)
/hp group setperm <group> <perm> [value] [duration] - Same for groups
/hp user setexpiry <player> <perm> <duration|permanent> - Modify expiry on existing permissions
/hp group setexpiry <group> <perm> <duration|permanent> - Same for groups
/hp group parent add <group> <parent> [duration] - Temporary group inheritance
/hp user addgroup <player> <group> [duration] - Temporary group membership
All duration arguments are optional, defaulting to permanent (backwards compatible)
/hp user info and /hp group info now display expiry in amber for temporary permissions
Uses existing TimeUtil duration parsing (30s, 5m, 2h, 1d, 1w, combos, permanent)
Web Editor Expiry Pipeline - Fixed web editor silently dropping expiry data when applying changes
Change.java now carries expiry field through the DTO pipeline
WebEditorService reads expiry from JSON in all parsing paths
ChangeApplier.buildNode() applies expiry when building permission nodes
Web editor UI already supported expiry β€” only the Java-side pipeline was broken
2.8.1HyperPerms v2.8.1
February 8, 202613 changes
Changed(1)
Build System - Fixed Shadow JAR clobbering in multi-project Gradle builds
Fixed(12)
Permission Negation Bug - Fixed critical bug where negated permissions set via web editor were granted instead of denied
Web editor sent conflicting data (-permission prefix with value: false), causing double negation in the permission resolver
Backend ChangeApplier now normalizes - prefix permissions to always use value: true
Frontend toBackendNode now sends correct value for negated permissions
Permission Display - Fixed /hp group info and /hp user info showing raw internal format for negated permissions
Was showing + -hytale.command.spawn or - -hytale.command.spawn
Now correctly shows - hytale.command.spawn with red color
Also fixed in /hp user tree inheritance display
Command Feedback - Fixed setperm commands showing "Granted" for denied permissions
/hp group setperm group perm false now correctly says "Denied perm on group"
/hp group setperm group -perm now correctly says "Denied perm on group"
Permission List Sorting - Group and user info commands now display permissions in alphabetical order
v2.8.0HyperPerms v2.8.0 - API v2, PlaceholderAPI, Templates & Analytics
February 8, 202610 changes
Added(6)
9 new event types with cancellable support and priority ordering
Async permission methodsβ€”hasPermissionAsync(), getPermissionValueAsync()
Fluent query builderβ€”api.checkAsync(uuid).permission("node").inWorld("world").result()
Metrics tracking for permission operations
Faction placeholders for scoreboards, holograms, and chat
Group/rank and prefix/suffix placeholders
Fixed(4)
Fixed async threading issue in permission checks
Group weight now used as default prefix/suffix priority
Improved error messaging for empty web editor changes
Better Windows H2 file lock error handling
v2.7.8API v2 Foundation & PlaceholderAPI Integration
February 5, 202623 changes
Added(2)
New Event Classesβ€”*
Added comprehensive API documentation links
Changed(21)
GroupCreateEvent - Fired when a group is created (cancellable)
GroupDeleteEvent - Fired when a group is deleted (cancellable)
GroupModifyEvent - Fired when group properties change
UserGroupChangeEvent - Fired when user group membership changes
UserLoadEvent - Fired when user data is loaded
UserUnloadEvent - Fired when user is unloaded from cache
DataReloadEvent - Fired when data is reloaded
TrackPromotionEvent - Fired on track promotion (cancellable)
TrackDemotionEvent - Fired on track demotion (cancellable)
Event Enhancementsβ€”*
Cancellable interface for events that can be cancelled
EventPriority enum (LOWEST, LOW, NORMAL, HIGH, HIGHEST, MONITOR)
Async event subscription support
PermissionHolderListener pattern for User/Group models
Redesigned README with expanded features and documentation links
Improved getting started guide
Drop-in replacement for v2.7.7
No configuration changes required
All API v2 additions are backwards compatible
Existing event subscriptions continue to work
Discordβ€”* https://discord.gg/SNPjyfkYPc
v2.7.7Permission Templates, Analytics, Optional SQLite
February 5, 20269 changes
Added(9)
11 Built-in Templates:*
Custom Templatesβ€”* Create your own by placing JSON files in the templates/ folder.
Web editor URLs are clickable in iTerm2, Windows Terminal, GNOME Terminal, and more
Automatic detection of supported terminals
Fallback to plain URLs for unsupported terminals
Beforeβ€”~15MB (native libraries for 20+ platforms)
Afterβ€”~2.4MB (84% reduction)
To enable SQLite featuresβ€”*
Without SQLiteβ€”* Everything works - analytics disabled, JSON storage used.
v2.7.4Cloudflare Workers API Migration
February 4, 20261 change
Added(1)
No manual configuration required!* When you upgrade to v2.7.4, the plugin automatically:
v2.7.3Performance Fix & LuckPerms H2 Migration
February 3, 202623 changes
Added(2)
Added checkPermission() method to HyperPerms that returns TriState and properly uses the cache
Added clear error message for Windows file locking issues
Changed(18)
Technical Detailsβ€”*
Refactored HyperPermsPermissionSet.contains() to use the cached lookup instead of calling resolver directly
Performance Impactβ€”*
Beforeβ€”Every contains() call triggered full resolve() - O(n groups * m nodes)
Afterβ€”Cache hit = O(1) lookup; cache miss = resolve + cache store
Expected 90%+ reduction in CPU time for permission checks
Dynamically loads H2 driver from LuckPerms libs/ folder for version compatibility
Handles locked databases by creating temporary copies
Set thread context classloader for proper class isolation
H2 is now compileOnly to avoid version conflicts with bundled driver
Case-insensitive folder name detection (finds LuckPerms_LuckPerms, etc.)
Flexible pattern matching for database files
Support for various LuckPerms folder naming conventions
Users are directed to stop LuckPerms before migrating when database is locked
Drop-in replacement for v2.7.0
No configuration changes required
Fully backwards compatible
Discordβ€”* https://discord.gg/SNPjyfkYPc
Fixed(2)
Fixed connection URL to use absolute paths (required by H2 2.1.x+)
Fixed path resolution to correctly find LuckPerms in /mods/ folder
Removed(1)
Removed redundant getOrLoadUser() private method
v2.7.0Track Promote/Demote & Update Command Fix
February 2, 202611 changes
Added(8)
Promotes a user to the next rank on the specified track
If the user is not on the track, adds them to the first group
Shows informative message if user is already at the top
Handles all edge cases gracefully
Demotes a user to the previous rank on the specified track
Shows error if user is not currently on the track
Shows informative message if user is already at the bottom
Handles all edge cases gracefully
Fixed(3)
Issueβ€”Running /hp update confirm threw an "expected 0, given 1" argument error
Root Causeβ€”The command framework validated arguments before execution, rejecting "confirm" because no argument descriptor existed
Solutionβ€”Refactored to use the nested subcommand pattern, properly registering confirm as a subcommand of update
v2.6.0HyperFactions Integration
February 1, 20265 changes
Added(3)
Added built-in support for HyperFactions permission integration
Seamless permission checking between HyperPerms and HyperFactions
Automatic permission provider registration when HyperFactions is detected
Fixed(2)
Permission Set Checksβ€”Fixed an issue where user data wasn't properly loaded during permission set validation
Improved reliability of permission checks during early player connection
v2.5.1Hytale-Native Permission Resolution
January 31, 20267 changes
Changed(5)
Aligned permission resolution order with Hytale's native implementation
Global wildcard (*) is now checked first, matching Hytale's behavior
Prefix wildcards now resolve shortest-first (a. before a.b.)
"admin.*"
"-admin.dangerous" # This still works
Fixed(2)
Fixed user not being loaded during permission set checks, which could cause negation checks to fail
Fixed runtime permission discovery not finding the plugins directory
v2.5.0Runtime Permission Discovery, Update Notifications & LuckPerms Migration
January 30, 202615 changes
Fixed(15)
Added hex color parsing (Β§xΒ§RΒ§RΒ§GΒ§GΒ§BΒ§B format)
Added underline and strikethrough format codes
Werchat detectionβ€”HyperPerms defers chat handling when Werchat is installed
New ChatAPI.getRawPrefix() and getRawSuffix() methods
Resolved chat prefix conflict when both plugins are installed
Dynamic event priority based on HyFactions presence
Outputβ€”[FactionTag] [RankPrefix] PlayerName: message
Complete rewrite using Hytale's packet system
Proper async prefix/suffix resolution
Strip color codes and invisible Unicode characters
Add left padding to prevent UI clipping
Null-safe server root resolution in LuckPerms migrator
Removed verbose debug logging spam
HyperHomesβ€”Added share, admin, and bypass wildcard expansions
HyperWarpsβ€”Full wildcard expansion with bypass permissions
v2.4.5VaultUnlocked Integration & Dynamic Permission Support
January 26, 20264 changes
Fixed(4)
Fixed optional dependency format for Hytale's plugin loader
Added comprehensive debug logging for Vault operations (enable with /hp debug)
Improved transient permission handling (graceful fallback instead of errors)
Enhanced cache invalidation after Vault-based modifications
v2.4.3Hytale Permission Discovery & Major Bug Fixes
January 24, 202645 changes
Added(22)
~100+ new permission mappings between web UI and actual Hytale nodes
Legacy hytale.system.command.* format support for older configs
Wildcard expansion now includes all actual Hytale permissions
Case-insensitive permission checking for Hytale compatibility
Warp Commandsβ€”*
hytale.command.warp.go - Use warps
hytale.command.warp.set - Create warps
hytale.command.warp.remove - Delete warps
hytale.command.warp.list - List warps
hytale.command.warp.reload - Reload warp config
Inventory Commandsβ€”*
hytale.command.invsee - View other player inventories
hytale.command.invsee.modify - Edit other player inventories
hytale.command.spawnitem - Spawn items directly
Teleport Sub-commandsβ€”*
.teleport.all, .back, .forward, .top, .home, .world, .history
Preserved camelCase for hytale.editor.builderTools (case-sensitive!)
Full editor permission treeβ€”brush, prefab, selection, packs, history
Added HYTALE_PERMISSIONS.md - Complete reference of all actual Hytale permission nodes
Web UI to Hytale permission mapping tables
Wildcard expansion documentation
Verification/testing steps
Changed(8)
30 files modified with +3,095 / -689 lines*
HYTALE_PERMISSIONS.md - Permission reference documentation
PermissionAliases.java - Centralized alias management (988 lines)
CaseInsensitiveSet.java - Hytale compatibility utility
HyperPermsCommand.java - Complete refactor (+800 lines)
PermissionRegistry.java - ~100 new permissions registered
PermissionResolver.java - Alias-aware permission checking
HyperPermsPermissionProvider.java - Alias expansion in provider
Fixed(15)
Refactored command help system with centralized formatting
Flag syntax for optional argumentsβ€”--name, --filename instead of positional args
Visual indicatorsβ€”βœ“, βœ—, β€’ for better UX
Replaced legacy color codes with Message API composition
Confirmation steps for destructive commands (group deletion, user clearing, backup restoration)
Per-entity locking for concurrent user and group modifications
Cache invalidation now occurs after storage operations
Duplicate track prevention during concurrent creation
Exception logging in event handlers
Alias expansion in getUserDirectPermissions() to match getExpandedPermissions() logic
Debug logging for alias expansion tracing
CaseInsensitiveSet for Hytale compatibility
Fixed /hp check command to use two required arguments
Fixed clearNodes() in user clear command to avoid UnsupportedOperationException
Cleaned up default-groups.json to use proper Hytale permission nodes
v2.4.1User Data Persistence Fix
January 24, 202617 changes
Changed(17)
User data was never loaded during server startup - only groups and tracks were loaded
A race condition existed between loadUser() and getOrCreateUser() that could overwrite loaded user data
Fire-and-forget async saves could be lost during quick server shutdowns
1. Load All Users on Startup*
Added userManager.loadAll().join() during server initialization
Ensures all user data is loaded from storage when the server starts
2. Race Condition Prevention*
Modified loadUser() to use atomic compute() operations
Prevents newly-created default users from overwriting loaded user data
Only overwrites existing users if they still have the default group
3. Synchronous Critical Saves*
Changed all critical saveUser() calls to await completion with .join()
Prevents data loss during rapid server shutdowns
Affectsβ€”setPrimaryGroup, addGroup, removeGroup, setPermission, removePermission, setPrefix, setSuffix, and clear commands
HyperPerms.java - Added user loading on startup
UserManagerImpl.java - Fixed race condition in loadUser()
HyperPermsCommand.java - Awaited critical save operations
v2.3.5v2.3.5
January 23, 202611 changes
Changed(11)
Added permission aliasing for HyperHomes plugin
hyperhomes.gui now properly maps to com.hyperhomes.hyperhomes.command.homes.gui
hyperhomes.use grants access to main home commands
Wildcard hyperhomes.* expands to all HyperHomes permissions
Fixed user permissions not being recognized by Hytale's built-in system
Added virtual user group mechanism for direct user permissions
Proper wildcard expansion at all hierarchy levels
Full group inheritance chain resolution
Added TabList cache invalidation
Cleaned up debug logging
Performance improvements to permission resolution
v2.3.4ChatAPI Prefix Fix
January 21, 20266 changes
Fixed(6)
Fixed ChatAPI race condition - The getPrefix() and getSuffix() methods were firing two separate async operations that could race, causing incomplete cache entries. Now uses a single atomic preload operation.
Added ChatAPI preload on player connect - The ChatAPI cache is now preloaded when players connect, ensuring prefix/suffix data is available immediately for the first chat message.
Improved cache handling - Added defensive guards to prevent partial cache entries (e.g., prefix-only entries with null suffix) from being stored, which could persist for the 30-second TTL.
Added ChatAPI cleanup on disconnect - Player data is now properly invalidated from the ChatAPI cache when they disconnect.
ChatAPI.java - Fixed race condition in getPrefix/getSuffix, improved updateCache
HyperPermsPlugin.java - Added preload on connect and invalidate on disconnect
v2.3.3ChatAPI & Web Editor Fixes
January 21, 20267 changes
Changed(7)
Fixed ChatAPI.getPrefix() returning empty - External plugins using the ChatAPI (like WerChat, HyFactions integrations) were sometimes getting empty prefixes due to timeout issues. Increased cache TTL and sync timeout for more reliable prefix/suffix retrieval.
Fixed web editor null pointer exceptions - The /hp apply command would fail with "Cannot invoke getAsString() because return value is null" when the web editor API returned data with missing fields. Added comprehensive null-safety checks to all JSON parsing.
Improved JSON parsing robustness - Manual permission entries in the web editor now handle multiple field name variations (node, permission, name) and gracefully skip invalid entries instead of crashing.
ChatAPI cache TTL increased from 10s to 30s
Sync fallback timeout increased from 100ms to 500ms
Added automatic preload on cache miss for better subsequent calls
Added safe JSON getter methods for defensive parsing
v2.3.2Fix permissions, add resetgroups command
January 20, 20264 changes
Added(1)
Added /hp resetgroups --confirm command to reset all groups to plugin defaults
Fixed(3)
Fix faction placeholders (%faction%, %factionrank%, %factiontag%) not resolving in chat
Fix permission inheritance - inherited permissions from parent groups now work correctly
Fix default group permission nodes - changed hytale.command. to hytale.system.command.
v2.3.1Fix faction placeholders, Fix permission inheritance
January 20, 20260 changes

View full release notes on GitHub for details.

v2.3.0Tab List Support & Tebex Integration
January 20, 202611 changes
Added(10)
Native prefix/suffix display in the server tab list
New tabList config section with customizable format
Uses same placeholders as chat (%prefix%, %player%, %suffix%, etc.)
Automatic cache invalidation when permissions change
New TabListAPI for external plugin integration
Commands now support offline players via UUID
/hp user addgroup {uuid} <group> creates user if needed
/hp user setprimarygroup {uuid} <group> works for players who haven't joined
/hp user setperm {uuid} <permission> works for offline players
Perfect for Tebex commands using {id} placeholder
Fixed(1)
Fixed web editor "type field is null" crash when fetching changes
v2.2.5Fix default group permissions for non-OP players
January 18, 20260 changes

View full release notes on GitHub for details.

v2.2.4Windows Auto-Update Fix
January 18, 20260 changes

View full release notes on GitHub for details.

Version Numbering

HyperPerms follows semantic versioning (MAJOR.MINOR.PATCH):

MAJOR

Breaking changes that may require config updates

MINOR

New features that are backwards compatible

PATCH

Bug fixes and minor improvements

Get notified about new releases

Stay up to date with the latest HyperPerms updates, features, and security patches.

Subscribe to updates