promotional bannermobile promotional banner

MMO Skill Tree & Abilities

(Multiple Languages) MMO Skill Tree adds an RPG-style progression system where every action you take helps you grow stronger.

File Details

MMOSkillTree-0.6.2.jar

  • R
  • Jan 28, 2026
  • 473.61 KB
  • 1.0K
  • Early Access

File Name

MMOSkillTree-0.6.2.jar

Supported Versions

  • Early Access

Changelog

v0.6.2

Inventory Space Check for Item Rewards

  • Inventory space validation - Item rewards (commands using /give) now check that the player has enough inventory space before claiming
  • UI claim gating - The Rewards page returns an "inventory full" notification (red) when a player tries to claim rewards without space, preserving the unclaimed state
  • Auto-claim gating - Level-up auto-claim paths (checkAndExecuteRewards, checkGlobalSkillRewards, checkTotalLevelRewards, checkAllRewards) all skip rewards when inventory is full, leaving them unclaimed for later
  • Non-give commands unaffected - Rewards that don't use /give (e.g., /mmoboost give) are not blocked by inventory checks
  • Localized notification in all 8 languages (EN, ES, FR, PT, HU, TR, DE, IT)

v0.6.1

Boost Stacking Limits

  • Hard cap on total XP multiplier - New maxBoostMultiplier setting (default: 5.0x) prevents runaway XP gains regardless of how many boosts are active
  • Active boost count limits - Configurable caps on simultaneous personal boosts (maxPersonalBoosts, default: 3) and global boosts (maxGlobalBoosts, default: 3)
  • Stack mode selection - Choose between "additive" (all boosts sum together) or "highest" (best global + best personal only) via boostStackMode setting
  • Token preservation on limit - When a player tries to activate a boost token at the limit, the token is NOT consumed and an error message is shown
  • Admin boost gating - /mmoboost global returns an error when the global limit is reached instead of silently creating a boost
  • Boost Page UI awareness:
    • Limits info line shows current state: "Limits: 5.0x cap | additive | Personal 2/3 | Global 1/3"
    • Token and permission activate buttons are disabled (red "LIMIT REACHED") when the relevant limit is hit
  • Admin UI section - New "Boost Stacking Limits" section in /mmoadmin with:
    • Text fields for max multiplier, max personal, and max global boosts
    • Toggle buttons for additive/highest stack mode
    • Save button applies all changes at once
  • Config version bump - skill-config.json version 8 → 9 (auto-regenerated on first load)
  • Localized in all 8 languages (EN, ES, FR, PT, HU, TR, DE, IT)

Admin Button on XP Page

  • Quick admin access - Admins now see an "Admin" tab in the /xp sidebar, just above Settings
  • Opens the /mmoadmin configuration page directly from the skill overview
  • Only visible to players with mmoskilltree.admin permission (or OP when permissions disabled)
  • Server-side permission check on click prevents unauthorized access

Bug Fixes

  • Fixed global boost permissions not working - AwardBoostPage generated "global" as the scope value in permission strings, but BoostScope only recognizes "all" for global boosts. Permissions like mmoskilltree.xpboosts.all.global.2.30.60 silently failed to parse, causing global boosts created via the Admin Award Boost UI to never appear. Now correctly generates "all" scope (e.g., mmoskilltree.xpboosts.all.all.2.30.60).
    • Action required: Any previously awarded global boost permissions contain the wrong scope and must be re-issued. Replace .global. with .all. in existing permission entries, or re-award through the UI.

v0.6.0

Command Rewards v2.0 - Schema Redesign

Major overhaul of the command rewards system with a unified schema and override-based config.

New Schema

  • Unified rewards list - All rewards are now commands (items given via /give commands)
  • Override-based config - Config stores only customizations, defaults preserved across updates
  • Per-command customization:
    • localizationKey - Preferred way to set display name (supports all languages)
    • displayName - Fallback literal display name
    • color - Hex color for UI display (e.g., #ffaa00)
    • runAs - CONSOLE (default) or PLAYER
  • Display logic - Rewards without display info are executed but hidden from UI

New Config Format

{
  "schemaVersion": 1,
  "enabled": true,
  "overrides": {
    "MINING": {
      "10": [
        {
          "command": "/give {player} Ingredient_Bar_Iron --quantity=25",
          "localizationKey": "reward.item.iron_bars",
          "color": "#ffaa00"
        }
      ]
    }
  }
}

Override Semantics

  • Missing levels use defaults automatically
  • Set level to empty array [] to disable rewards at that level
  • New defaults propagate without losing your customizations
  • Schema version only changes for structural changes

Migration

  • Automatic V4 migration - Existing configs are converted and backed up
  • Claimed rewards preserved - Level-based tracking maintained across upgrade

Global Skill Rewards

  • New reward category: GLOBAL_SKILL - Bonus rewards given to ALL skills at milestone levels
    • Tracked per-skill: Mining 50 and Swords 50 each independently trigger level 50 global rewards
    • Configurable via GLOBAL_SKILL key in command-rewards.json overrides
    • Visible in the player Rewards UI as "Lv X Bonus" rows alongside per-skill rewards
    • Default: 1.25x Global XP Boost (15 min) at Level 100 for every skill mastered

XP Boost Token Rewards

  • Boost tokens as milestone rewards - Level-up milestones now include XP boost tokens
    • Personal skill boosts at Lv 50 (1.5x 15min) and Lv 100 (2x 30min) for each skill
    • Personal all-skills boosts at Total Lv 100 (1.5x 30min) and Total Lv 350 (2x 45min)
    • Global server boosts at Total Lv 500 (1.5x 30min), 750 (2x 30min), 1000 (2x 60min)
    • Global boosts broadcast to all online players via /say when activated

Admin Command Rewards UI

  • New CommandRewardsPage - Visual editor for command rewards, accessible from /mmoadmin
    • Category tabs: Gathering, Combat, Crafting, Misc, Total Level, All Skills (Global)
    • Skill selector for per-skill categories, hidden for Total Level and All Skills
    • Level selector showing all configured milestone levels
    • Reward table with columns: Command, Display Name, Loc Key, Color, Status
    • Add/Edit section with fields for Command, Display Name, Loc Key, Color
    • Inline Disable button on each default reward to create override without that reward
    • Remove button on overridden rewards to delete individual entries
    • Disable Level to set empty override (no rewards at that level)
    • Reset to Default to remove override and restore defaults

Auto-Derived Display Info

  • Item rewards auto-derive display names from item IDs (e.g., Ingredient_Bar_Iron → "Iron Bars")
  • Item rewards auto-derive tier colors from item ID patterns:
    • Common materials (Iron, Copper): #c8c8c8
    • Uncommon (Cobalt, Thorium): #4aff7f
    • Rare (Adamantite, Mithril): #4a9eff
    • Epic (Onyxium): #c84aff
    • Legendary (Prisma, Voidstone): #ffaa4a
    • Gems, essences, and tools each have appropriate colors
  • Rewards without explicit display info now visible in admin UI with auto-derived names

Bug Fixes

  • Fixed incorrect ore XP rates - Removed explicit low-XP entries for special terrain ores (Ore_Cobalt_Slate, Ore_Adamantite_Magma, Ore_Iron_Basalt) that overrode wildcard patterns with incorrect values (4-6 XP instead of proper ore rates)
  • Fixed tier label missing in player Rewards UI - localization fallback returned empty string for undefined keys, causing blank tier headers
  • Fixed Visible boolean type error - Hytale CustomUI requires boolean values for Visible property, not string representations
  • Fixed display name override in tier headers - Auto-derived item names no longer replace "Level X" tier labels

Technical Changes

  • CommandRewardEntry.java - New unified format with command, localizationKey, displayName, color, runAs
  • LevelRewards.java - New container for level -> List<CommandRewardEntry> mapping
  • CommandRewardsConfig.java - Converted to override-based pattern (like XpMapsConfig)
    • Stores userOverrides separately from effective config
    • Generates _reference/defaults-command-rewards.json for server owner transparency
    • Changed configVersion to schemaVersion
    • Added globalSkillRewards / globalSkillOverrides with full getter/mutator/save/load support
  • CommandRewardsDefaults.java - All ItemReward definitions converted to /give commands
    • Added formatItemName() and getItemColor() for auto-derivation
    • Added getGlobalSkillDefaults() with milestone rewards for all skills
    • Added boost token reward factories: boostSkill(), boostAll(), boostGlobal()
  • CommandRewardService.java - Simplified to only execute commands
    • Added checkGlobalSkillRewards() for per-skill global reward tracking
    • Updated checkAllRewards() to process global skill rewards
    • Updated claimLevelRewards() to handle GLOBAL_SKILL_* keys
  • CommandRewardsPage.java (NEW) - Admin UI page for viewing/editing command rewards
  • CommandRewardsPage.ui (NEW) - Admin UI template with category tabs, skill/level selectors, reward table
  • CommandRewardRow.ui (NEW) - Row template with Disable/Remove inline buttons
  • ItemRewardsPage.java - Shows global skill bonus rewards alongside per-skill rewards
    • Added claimGlobal action handler for claiming global skill rewards
    • Fixed getDisplayName() to not use auto-derived displayName for tier headers
  • Messages.java - Updated getCommandRewardDisplayName() to take level parameter
  • AdminConfigPage.java - Added "Edit Rewards" button navigating to CommandRewardsPage

v0.5.11

Admin Item Rewards Toggle

  • New toggle in /mmoadmin - Enable/disable item rewards from command-rewards.json
    • Toggle found in the "General Settings" section
    • When disabled, the Rewards tab is hidden from ViewXpPage
    • Config saved immediately on toggle

UI Improvements

  • Active Boosts Display - ViewXpPage now shows active XP boosts above the buffs bar

    • Displays up to 3 active boosts with time remaining
    • Shows scope indicator: [G] for global boosts, [P] for personal
    • Global boosts shown in blue, personal in green
    • Format: [G] 2.0x Mining - 14:32 (scope, multiplier, target, time)
  • Skill Tree Buff Indicator - Skill tree buffs now prefixed with [Tree]

    • Example: [Tree] +15 HP +5% DMG
    • Helps distinguish skill tree rewards from other sources
  • Improved Time Display - Boost durations and cooldowns now show human-readable formats

    • Under 1 hour: mm:ss (e.g., "45:30")
    • 1-24 hours: Xh Ym (e.g., "2h 30m")
    • Over 24 hours: Xd Yh (e.g., "3d 5h")
    • Fully localized time units for all 8 languages

Leaderboard Fix

  • Total Level Calculation - Fixed leaderboard to use summed skill levels
    • Previously used formula-based level from total XP (confusing)
    • Now sums individual skill levels for intuitive display
    • Example: Mining 50 + Woodcutting 50 = Total Level 100 (not formula result)

Technical

  • AdminConfigPage.java

    • Added #ToggleItemRewards button with event binding
    • Calls CommandRewardsConfig.getInstance().setEnabled() on toggle
  • ViewXpPage.java

    • Added populateActiveBoosts() method
    • Modified getSkillBuffsText() to add [Tree] prefix
    • Imports: ActiveBoost, BoostScope
  • ViewXpPage.ui

    • Added #ActiveBoostsBar section with 3 boost labels
    • Added #ActiveBoostsSpacer for spacing control
  • LeaderboardDataStore.java

    • Changed data.totalLevel = skills.getTotalLevel() to data.totalLevel = skills.getSummedTotalLevel()
  • LocalizationConfig.java

    • Added ui.admin.item_rewards_label in all 8 languages
    • Added time.days_short, time.hours_short, time.minutes_short for localized time units
    • Added notify.command_reward_received in all 8 languages
  • XpBoostService.java

    • Updated formatTimeRemaining() to show Xh Ym for hours, Xd Yh for days
    • Added localized overload formatTimeRemaining(ms, skills) using language-specific time units
  • CommandExecutor.java

    • Added overload executeAsConsole(command, username) for better logging context
  • CommandRewardService.java

    • Now passes username to console command execution for logging

v0.5.10

New Command: /bulksetxp

  • Bulk XP command - Set XP for one, many, or all players at once
    • Usage: /bulksetxp <skill|all> <value> [targets]
    • Targets: Single player name, comma-separated names, or * for all online players
    • Examples:
      • /bulksetxp mining 1000 - Set all players to 1000 mining XP
      • /bulksetxp all 0 Player1 - Reset all skills to 0 for Player1
      • /bulksetxp swords 5000 A,B,C - Set swords to 5000 for specific players
    • Aliases: setxpall, masssetxp
    • Admin permission required

Command Architecture Update

  • Async command pattern - /mmoboost and /bulksetxp now use AbstractAsyncWorldCommand

    • Better console support - commands work reliably from console
    • Uses withDefaultArg for optional parameters (cleaner syntax)
    • Store operations properly dispatched to world thread via world.execute()
  • Simplified /mmoboost syntax - Removed --args= prefix

    • Old: /mmoboost give --args=Steve|mining|2|30
    • New: /mmoboost give Steve|mining|2|30
    • Still uses | (pipe) to separate values

Technical

  • BulkSetXpCommand.java - New command extending AbstractAsyncWorldCommand

    • Uses withDefaultArg("targets", ...) with default * for all players
    • Store access via entityRef.getStore() inside world.execute() callback
    • Validates rewards after XP change (revokes if level dropped)
    • Reports success count and any failures
  • BoostCommand.java - Refactored to AbstractAsyncWorldCommand

    • Changed from AbstractPlayerCommand to AbstractAsyncWorldCommand
    • Uses withDefaultArg instead of withOptionalArg
    • Subcommands needing Store access (give, clear, status) wrapped in world.execute()
    • Subcommands without Store access (global, list) run directly
    • Simplified message handling (direct strings instead of localization for admin commands)
  • CLAUDE.md - Documented async command pattern

    • Added "Command Patterns" section explaining AbstractAsyncWorldCommand vs AbstractPlayerCommand
    • Critical pattern: world.execute() required for Store operations in async context
    • Store thread affinity causes IllegalStateException if accessed from wrong thread
  • hytale-api.md - Added "Async Commands & World Thread" section

    • Documents the thread safety requirement for Store access
    • Code examples showing wrong vs right approach
    • world.execute(Runnable) dispatches work to world thread

v0.5.9

Skill Permission Filtering

  • Permission-based skill visibility - When skill permissions are enabled, skills are now filtered throughout the UI

    • Skills without permission are hidden from the XP overview page
    • Skills without permission are excluded from total/category level calculations
    • Navigation in Skill Tree and Item Rewards pages skips unpermitted skills
    • Leaderboard skill filters only show skills the viewer has access to
    • Category tabs hidden - Category tabs (Gathering, Combat, etc.) are hidden if player has no permission for any skill in that category
    • Leaderboard category filters also hidden when no skills available in that category
  • Admin permission help text - /mmoadmin now shows permission nodes when permissions are enabled

    • Explains mmoskilltree.skill.* for all skills
    • Explains mmoskilltree.skill.mining, .swords, etc. for individual skills
    • Explains mmoskilltree.command.xp for the /mmoxp command

Award Boost Admin Page

  • Award Boost Page - New admin UI for granting boost permissions and tokens to players
    • Access via "Award Boost" button in /mmoadmin
    • Dual input fields:
      • UUID field for recurring permissions (uses /perm user add)
      • Username field for one-time tokens (uses XpBoostService directly)
    • Dynamic skill list - Shows all skills with XP values configured
      • Skill buttons wrap after 8 per row using SkillButtonRow.ui template
    • Target categories: All, Gathering, Combat, Production
    • Target individual skills: Mining, Woodcutting, Swords, etc. (all configured skills)
    • Preset + Custom inputs - Use quick buttons or type custom values
      • Multiplier: 1.5x, 2x, 3x, 5x, 10x presets + custom field
      • Duration: 15m, 30m, 1h, 2h, 24h presets + custom field (minutes)
      • Cooldown: None, 1h, 24h, 7d presets + custom field (minutes)
    • Choose scope (Personal or Global)
    • Live permission preview updates as you configure
    • Rate limiting - 500ms cooldown prevents button spam
    • Improved readability with lighter text colors
    • Full localization in all 8 languages

Technical

  • ViewXpPage.java - getFilteredSkills() now filters by PermissionUtil.canGainSkillXp()

    • Total/category calculations use filtered skill list
    • hasUnclaimedItemRewards() filters by permission
    • Added hasPermissionForCategory() to check if player has any permitted skills in a category
    • Category tabs hidden when hasPermissionForCategory() returns false
  • SkillTreePage.java - Permission check before displaying skill tree

    • Shows "No permission" message if player lacks skill permission
    • Navigation methods filter by permission
  • LeaderboardPage.java - getSkillsForCategoryFiltered() filters skill buttons by permission

    • Category filter buttons hidden when no skills available in that category
  • ItemRewardsPage.java - Permission check for skill rewards (total rewards always available)

    • Navigation methods filter by permission
  • AdminConfigPage.ui - Added #PermissionsHelp label and #AwardBoostBtn button

  • AwardBoostPage.java - New admin page for awarding boost permissions and tokens

    • Dual input: UUID for recurring permissions, Username for one-time tokens
    • Dynamic skill buttons from getConfiguredSkills() using SkillButton.ui + SkillButtonRow.ui templates
    • Skill buttons wrap after 8 per row (SKILLS_PER_ROW constant)
    • Custom text fields for multiplier, duration, cooldown (override presets)
    • Recurring permissions use CommandExecutor.executeAsConsole() with /perm user add UUID permission
    • Token awards call XpBoostService.awardToken() directly (finds online player for immediate delivery)
    • Rate limiting with ACTION_COOLDOWN_MS (500ms) prevents spam
    • Permission string format: mmoskilltree.xpboosts.<target>.<scope>.<mult>.<dur>.<cooldown>
  • AwardBoostPage.ui - Improved layout and readability

    • Scrollable content area (TopScrolling)
    • Dynamic skill buttons container with SkillButtonRow.ui template
    • Dual text fields for UUID and Username inputs
    • Custom text fields for multiplier, duration, cooldown
    • Lighter text colors for better readability (#b0c4d8, #8090a0)
  • SkillButtonRow.ui - New template for skill button rows (LayoutMode: Left, Height: 28)

  • BoostCommand.java - Added console execution support

    • Checks for ConsoleSender instance to allow /mmoboost from console
    • Console commands bypass admin permission check
    • All subcommands (give, global, list, clear, status) support console execution
  • LocalizationConfig.java - Added keys for all 8 languages:

    • ui.skilltree.no_permission - "No permission"
    • ui.admin.permissions_help - Permission explanation text
    • ui.admin.award_boost - "Award Boost" button label

Bug Fixes

  • Luck loot empty values - Empty string values in luck loot tables now correctly give no bonus item

    • Allows disabling luck drops for specific blocks by setting empty value
    • Disabled cracked ore variants in special terrain to prevent exploits:
      • Ore_Thorium_Mud_Cracked, Ore_Cobalt_Slate_Cracked, Ore_Adamantite_Magma_Cracked, Ore_Iron_Basalt_Cracked
    • XP maps also updated to disable XP for these cracked ore variants
  • Disabled XP patterns - Patterns with 0 or negative XP (-1) are now properly skipped for combat skill detection

    • Disabled weapons don't receive skill bonuses (damage, crit, lifesteal)
    • Consistent behavior: disabled pattern = no XP and no combat bonuses
    • Added comment clarifying bestXp > 0 check semantics

Config Compatibility

  • No config version bump required - uses existing skillPermissionsEnabled setting
  • Existing permission nodes unchanged (mmoskilltree.skill.*, mmoskilltree.command.*)

v0.5.8

Skill Overview UX Redesign

  • Compact buff bar - All active buffs shown in a single horizontal bar at the top

    • Shows: XP Boost, Damage, Block, Crit, Lifesteal
    • Bright color-coded values for easy reading
    • Displays best values across all combat skills
  • Inline skill buffs - Each skill row now shows claimed rewards inline

    • Buffs appear below the progress bar: +15 HP +5% DMG +3% LUCK
    • Values of same type are combined (e.g., +5 HP + +10 HP = +15 HP)
    • See exactly what bonuses each skill provides at a glance
  • Improved readability - Better contrast and sizing

    • Lighter text colors for better visibility on dark background
    • Larger font sizes for buff displays
    • XP values show whole numbers for millions (1M instead of 1.2M)
    • Wider skill name and XP columns
  • Streamlined header - Stats moved to right side of title

    • Total Level, Total XP, Skills count in compact layout
    • More space for skill progress list

Permissions System

  • Reload permissions command - /mmoconfig reloadperms

    • Reloads boost permissions from permissions.json without restart
    • Shows count of loaded boost permission templates
  • Dynamic boost permissions - XpBoostService reads from permissions.json

    • Boost permissions extracted from users and groups sections
    • Refresh button in Boost page reloads permissions in real-time
    • Supports wildcard permissions (mmoskilltree.xpboosts.*)

Bug Fixes

  • Total level calculation - Now excludes skills without XP map data

    • Skills not configured in xp-maps.json don't count toward total
    • More accurate representation of actual progress
  • Block label - Defense renamed to "Block" in all 8 languages

    • More consistent with in-game terminology

Combat Reward Targeting

  • Targeted combat rewards - Combat bonuses can now apply to specific weapons/skills

    • New CombatTarget enum: ALL, MELEE, RANGED, MAGIC, and individual skills
    • MELEE includes: Swords, Daggers, Polearms, Staves, Axes, Blunt, Unarmed
    • RANGED includes: Archery
    • Rewards default to ALL (backward compatible with existing configs)
  • "All Combat" rewards at high tiers - New reward options for combat skills

    • Tier 8: +3% Damage (All), +3% Critical (All)
    • Tier 9: +4% Damage (All), +4% Critical (All), +2% Lifesteal (All)
    • Global bonuses as alternative to skill-specific bonuses

Technical

  • ViewXpPage.ui - Redesigned layout with horizontal buffs bar
  • SkillRow.ui - Added inline buffs display section
  • ViewXpPage.java - New populateBuffsBar() and getSkillBuffsText() methods
  • XpBoostService - File-based permissions loading with reload support
  • MMOConfigCommand - Added reloadperms subcommand
  • SkillComponent - getSummedTotalLevel() now filters by XP map data

Config Compatibility

  • No config version bump required - combatTarget is optional with ALL default
  • Existing skill-tree.json files work unchanged
  • Defense bonus remains global (applies when taking damage, not dealing)

v0.5.7

XP Boost System

  • Global and personal XP boosts - Players can activate boosts that multiply XP gains

    • Global boosts affect all players on the server
    • Personal boosts affect only the activator
    • Boosts can target all skills, specific skills, or skill categories
    • Multiple boosts stack additively (1.5x + 2x = 2.5x total)
  • Boost Tokens - One-time boost awards via commands

    • Admins award tokens with /mmoboost give --args=<player>|<target>|<multiplier>|<duration>|[scope]
    • Tokens can be personal (default) or global scope - global tokens activate server-wide when used!
    • Tokens are stored until the player chooses to activate them
    • Works for offline players - tokens delivered on next login
    • No permission required to activate awarded tokens
    • Players activate tokens from the Boost UI when ready
  • Permission-based boost activation - Server owners control who can activate repeatable boosts

    • Permission format: mmoskilltree.xpboosts.<target>.<scope>.<multiplier>.<duration>.<cooldown>
    • Target: all, skill name, or category name
    • Scope: self (personal) or all (global)
    • Multiplier uses underscore for decimal: 1_5 = 1.5x
    • Duration and cooldown in minutes
    • Example: mmoskilltree.xpboosts.mining.self.2_0.30.60 - 2x Mining, self, 30min, 1hr cooldown
  • Boost UI Page - New "Boosts" tab in ViewXpPage with three sections:

    • Active Boosts - Currently running boosts (global + personal) with time remaining
    • Boost Tokens - One-time tokens awarded via commands, ready to activate
    • Reusable Boosts - Repeatable boosts available from permissions (with cooldowns)
    • Refresh button to update display
  • Admin /mmoboost command - OPs can manage boosts directly (uses --args= with | separator)

    • /mmoboost give --args=<player|*>|<target>|<mult>|<mins>|[scope] - Award boost token
    • /mmoboost global --args=<target>|<multiplier>|<minutes> - Activate global boost immediately
    • /mmoboost list - Show active global boosts
    • /mmoboost clear --args=<player> - Clear boosts and tokens
    • /mmoboost status --args=<player> - Show boost status including tokens
  • Persistence - Boosts and tokens persist across server restarts

    • Global boosts saved to mods/mmoskilltree/active-boosts.json
    • Pending tokens for offline players saved in the same file
    • Personal boosts and tokens stored in player's SkillComponent
    • Cooldowns track last activation timestamp

Other Changes

  • Defense skill renamed to Block - Display name updated to "Block" across all code and UI
    • Updated in all 8 languages (EN: Block, ES: Bloqueo, FR: Blocage, PT: Bloqueio, HU: Blokkolás, TR: Blok, DE: Blocken, IT: Blocco)
  • Command UX improvement - /mmoboost uses --args= with pipe-separated values
    • Example: /mmoboost give --args=Steve|mining|2|30

Technical

  • New data classes: BoostScope, BoostTarget, ActiveBoost, BoostPermission, BoostToken
  • XpBoostService - Singleton service for boost management with token support
  • SkillComponent additions: personalBoosts, boostCooldowns, boostTokens maps with codec serialization
  • SkillService integration - Boost multiplier applied additively with reward bonuses, token delivery on first action
  • BoostPage.java - Interactive UI page for boost management (3 sections)
  • BoostCommand.java - Admin command with pipe-separated args and token scope support
  • Localization - Full boost UI translations for all 8 languages (EN, ES, FR, PT, HU, TR, DE, IT)

v0.5.6

Override-Based Config System (XpMapsConfig & LuckConfig)

  • Configs now store ONLY overrides - Customizations are preserved across mod updates

    • File stores only values that differ from defaults
    • Missing keys automatically use built-in defaults
    • New defaults propagate without losing your changes
    • XpMapsConfig: Use value -1 to explicitly disable a default XP pattern
    • LuckConfig: Use value "__DISABLED__" to explicitly disable a default luck pattern
  • Reference file generation - mods/mmoskilltree/_reference/

    • defaults-xp-maps.json - All default XP values per skill
    • defaults-luck-loot.json - All default luck loot table entries
    • Auto-generated read-only files for server owner reference
    • Updated on every config load
  • New commands:

    • /mmoconfig diff --args=<skill|all|luck> - Show only overrides (XP and luck)
    • /mmoconfig trim - Remove redundant overrides from both XP and luck configs
    • /mmoconfig disable --args=<skill|pattern> - Explicitly disable a default pattern
  • Improved /mmoconfig list - Now shows override status for each pattern

    • Cyan text indicates overridden values (shows default in brackets)
    • Green text indicates default values
    • Header shows override count per skill
  • Schema versioning - schemaVersion replaces configVersion for override-based configs

    • Schema version only bumps for structural changes (new fields)
    • Default value changes no longer require version bump
    • Old configs with configVersion are read for backwards compatibility

Admin UI

  • New /mmoadmin command - Opens interactive admin configuration UI

    • TextField inputs for direct value entry (base XP, scale multiplier)
    • Toggle settings: creative mode XP, skill permissions, leveling formula
    • Real-time milestone preview updates as you type
    • Formula description shows actual calculation being used
    • Config override statistics and trim functionality
    • Quick actions: reload configs, reload language, trim overrides, reset to defaults
    • Aliases: /mmoconfig-ui, /mmosettings
  • XP Overrides Page - Visual editor for skill XP values

    • Access via "Edit XP Values" button in Admin Config page
    • Category tabs: Gathering, Combat, Crafting, Misc
    • Dynamic skill selector buttons per category
    • Pattern list showing: name, default value, current value, status
    • Status indicators: Default (green), Override (orange), Disabled (red)
    • Add/Update patterns with text fields for pattern name and XP value
    • Disable button to set patterns to -1 (disabled)
    • Reset button per row to revert overrides to defaults
    • Click pattern name to copy to text field for easy editing
  • Permissions toggle - Single toggle controls both skill and command permissions

    • UI label simplified to "Enable Permissions"
    • When enabled: skill XP gains and commands require permissions
    • When disabled: all players can gain XP and use commands
  • Admin permission paradigm - Flexible OP/permission-based access

    • OP players always have admin access regardless of permission settings
    • When permissions enabled: non-OP players can get admin via mmoskilltree.admin
    • Applied to both /mmoconfig command and /mmoadmin UI

Localization

  • Config command messages fully localized - All 8 supported languages updated
    • Override system messages (diff, trim, disable, reset, reload)
    • Admin page labels and buttons (20 keys per language)
    • Support for: English, Spanish, French, Portuguese, Hungarian, Turkish, German, Italian
    • Falls back to English for players without skill data

Technical

  • XpMapsConfig.java - Complete rewrite for override-based system

    • userOverrides map tracks only customizations
    • load() now merges file overrides on top of defaults
    • save() writes only overrides (smaller config files)
    • DISABLED_VALUE = -1 sentinel for explicit pattern removal
    • New methods: getOverrides(), getAllOverrides(), isDefault(), getDefaultValue(), resetToDefault(), disablePattern(), trimRedundantOverrides()
  • LuckConfig.java - Complete rewrite for override-based system

    • Same override-based architecture as XpMapsConfig
    • DISABLED_VALUE = "__DISABLED__" sentinel for explicit luck pattern removal
    • Reference file: _reference/defaults-luck-loot.json
  • ConfigVersionUtil.java - Added extractSchemaVersion() method

    • Checks for schemaVersion first, falls back to configVersion
  • MMOConfigCommand.java - Added handlers for diff, trim, disable commands

    • Updated list command to show override indicators
    • Updated remove command to show revert-to-default behavior
    • All config messages now use localization via Messages helper
    • Added getPlayerSkills() and msg() helper methods
  • LocalizationConfig.java - Added 40+ new localization keys per language

    • cmd.config.* keys for all override system messages
    • ui.admin.* keys for admin config page (20 keys per language)
  • New files:

    • CommandExecutor.java - Shared utility for executing commands as console or player
    • AdminConfigPage.java - Interactive admin configuration UI page
    • AdminConfigUICommand.java - Command to open the admin UI
    • AdminConfigPage.ui - UI layout for admin configuration page
    • XpOverridesPage.java - XP pattern editor page with category/skill navigation
    • XpOverridesPage.ui - UI layout for XP overrides page
    • XpPatternRow.ui - Template for pattern list rows
    • SkillButton.ui - Template for dynamic skill selector buttons
  • PermissionUtil.java - Added admin permission support

    • ADMIN_PERMISSION = "mmoskilltree.admin" constant
    • hasAdminPermission(Player) - OP always has access; checks permission when enabled
    • isOp(Player) - Helper for OP status checks
  • CommandRewardService.java - Refactored to use CommandExecutor utility

    • Removed duplicate command execution methods (DRY)
    • Uses shared CommandExecutor.executeAsConsole() and CommandExecutor.executeAsPlayer()
  • MMOConfigCommand.java - Updated permission paradigm

    • Removed hardcoded setPermissionGroups("OP")
    • Uses PermissionUtil.hasAdminPermission() for flexible access control

Bug Fixes

  • Fixed combat XP exploit - Players can no longer gain XP from hitting projectiles (arrows, etc.)
    • CombatDamageEventSystem now detects Projectile component in entity archetype
    • Projectiles are always blocked from giving XP (hardcoded, not config-dependent)

v0.5.5

UI Improvements

  • Item Rewards Fully Disabled When Config Disabled - Complete protection when item rewards are turned off
    • Rewards tab hidden in ViewXpPage
    • ItemRewardsPage shows "Item Rewards Disabled" if somehow accessed directly
    • All navigation (tabs, arrows) hidden on disabled page
    • Event handlers check isEnabled() before opening rewards page

Upgrade Safety

  • Stat Rewards Reapplied on Config Update - Existing players get correct stat values after mod updates

    • When SkillTreeConfig version changes, all stat modifiers (Health, Stamina, Mana) are reapplied
    • Online players: stats recalculated immediately on reload/reloaddefaults
    • Offline players: stats recalculated on first XP action after login
    • Prevents stale stat values from old config versions
  • Orphaned Reward Cleanup - Removes stat modifiers from rewards that no longer exist

    • When skill tree config changes remove tiers or reward IDs, old stat modifiers are cleaned up
    • cleanupOrphanedRewards() now calls removeOrphanedStatModifiers() for each removed reward
    • Tries removing all stat types (Health, Stamina, Mana) since original reward type is unknown

Balance Changes

  • Block (STAT_DEFENSE) Nerfed by 50% - Block reduction values were too powerful

    • All STAT_DEFENSE skill tree rewards reduced by half
    • Before: 4% → 20% range across tiers
    • After: 2% → 10% range across tiers
    • Maximum stacked Block from all skills now ~45% (was ~90%)
  • Item Reward Tiers Expanded - Added intermediate tiers for smoother progression with hybrid OSRS formula

    • New Level 65 tier for all 16 skills (Expert-level materials)
    • New Level 80 tier for all 16 skills (Advanced materials)
    • Rewards include mid-to-late game materials like Mithril, Adamantite, Onyxium
    • Legendary materials (Prisma, Voidheart, Elemental Essences) at Level 80+
    • Total: 6 milestone tiers per skill (10, 25, 50, 65, 80, 100)

Technical

  • SkillTreeService.java - Added reapplyStatRewards() and removeOrphanedStatModifiers() methods
  • SkillService.java - Added setSkillTreeConfigChanged() flag for tracking skill tree config updates
  • SkillTreeConfig.java - Triggers stat reapplication when config version changes on load
  • MMOConfigCommand.java - validateAllOnlinePlayers() now also reapplies stat rewards
  • ViewXpPage.java - Added CommandRewardsConfig.isEnabled() checks for tab visibility and event handling
  • ItemRewardsPage.java - Added disabled state check in build() method
  • CommandRewardsDefaults.java - Added Level 65 and 80 reward entries for all skills
  • SkillTreeDefaults.java - Reduced all STAT_DEFENSE values by 50%
  • SkillTreeConfig.java - CONFIG_VERSION bumped to 3
  • CommandRewardsConfig.java - CONFIG_VERSION bumped to 4

v0.5.4

Improvements

  • Milestone XP display - When changing formula, basexp, or scale, shows XP required for milestone levels
    • Format: XP required: Lv10=14.3k | Lv25=95.6k | Lv50=446.2k | Lv80=2.3M | Lv100=10.0M
    • Helps server owners understand impact of config changes instantly

Technical

  • MMOConfigCommand.java - Added showMilestoneXp() helper method with formatted output

v0.5.3

⚠️ BREAKING CHANGE: Leveling formula completely changed. XP requirements are higher at all levels, so existing players will have lower levels with the same XP. Use /mmoconfig formula --args=legacy to restore the old formula.

Hybrid OSRS Leveling Formula

  • Complete formula overhaul - Combines OSRS exponential curve with quadratic floor

    • Early/mid levels ~10% harder than previous quadratic formula
    • Endgame scales exponentially (OSRS-style)
    • Level 100 = ~10M XP (true endgame grind)
  • New XP requirements (with default settings):

    • Level 10: ~14,270 XP
    • Level 25: ~95,573 XP
    • Level 50: ~446,222 XP
    • Level 80: ~2,274,045 XP
    • Level 100: ~10,000,000 XP
  • Config parameters:

    • baseXpPerLevel (default: 300) - Quadratic floor component
    • levelScaleMultiplier (default: 200) - OSRS exponential factor
    • OSRS component uses 2^(level/7) - each level requires ~10% more XP than the last
    • Quadratic floor ensures early/mid levels aren't too easy

Improvements

  • /mmoconfig formula - Switch between hybrid (OSRS) and legacy (quadratic) leveling formulas
    • hybrid: OSRS exponential + quadratic floor (default, ~10M XP at level 100)
    • legacy: Simple quadratic (~1.5M XP at level 100 with base=150, scale=2)
  • /mmoconfig reload - Now reloads ALL config files (was missing XpMaps, Luck, CommandRewards)
  • /mmoconfig reloaddefaults - Now resets ALL configs to built-in defaults

Bug Fixes

  • Item Rewards UI - Fixed crash when viewing Total Level rewards with more than 15 items per tier
    • Now supports up to 30 items per tier (6 rows)

Technical

  • SkillConfig.java - CONFIG_VERSION bumped to 8, defaults changed to hybrid values (base=300, scale=200)
  • SkillComponent.java - getXpForLevel() and calculateLevel() use hybrid OSRS formula
  • ItemRewardsPage.java - Supports up to 30 items per tier (was 15)
  • RewardTierRow.ui - Added ItemsRow4-6 for larger reward tiers
  • CommandRewardsConfig.java - Added reloadDefaults() method
  • MMOConfigCommand.java - Updated reload handlers to include all configs

v0.5.2

Bug Fixes

  • Harvest Exploit Prevention - Players can no longer gain XP by placing and harvesting items

    • Previously, placing a fruit/crop and then harvesting it would award XP via PickupItemEvent
    • Now tracks placed item IDs in addition to block positions
    • When you pick up an item you recently placed, XP is skipped
    • Separate expiration timer for items: placedItemExpireMinutes (default: 5 minutes)
    • Other players CAN still get XP from items you placed (fair multiplayer)
  • Life Essence Crafting Exploit Prevention - Currency conversion recipes no longer give Crafting XP

    • Ingredient_Life_Essence_100_Recipe_ → 0 XP
    • Ingredient_Life_Essence_Concentrated_Recipe_ → 0 XP
  • No +0 XP Notifications - Actions that give 0 XP no longer show notifications

Configuration

  • placedItemExpireMinutes - New config option in skill-config.json
    • Minutes until placed items expire for harvest tracking (default: 5)
    • Shorter than block expiration since items are typically harvested quickly
    • Separate from placedBlockExpireMinutes (which defaults to 0/never for blocks)

Technical

  • SkillConfig.java - CONFIG_VERSION bumped to 5
    • Added placedItemExpireMinutes field (default: 5)
    • Added getter/setter methods
  • PlacedBlockTracker.java - Extended to track placed item IDs
    • New TrackedItem class with atomic count and timestamp
    • trackPlacedItem(playerHash, itemId) - Track when player places an item
    • consumePlacedItem(playerHash, itemId) - Check and decrement on pickup (returns true if should skip XP)
    • Cleanup in cleanupExpired() now uses separate expiration for blocks and items
    • getTotalTrackedItems() - Stats method for debugging
  • PlaceBlockEventSystem.java - Now calls trackPlacedItem() in addition to position tracking
  • PickupItemEventSystem.java - Checks consumePlacedItem() before awarding XP
  • CraftingDefaults.java - Added 0 XP entries for Life Essence conversion recipes
  • CraftRecipeEventSystem.java - Removed debug log statement
  • SkillService.java - Skip XP processing when bestXp <= 0 (no notifications for 0 XP)
  • MMOConfigCommand.java - /mmoconfig reload now reloads ALL configs (was missing XpMaps, Luck, CommandRewards)
  • MMOConfigCommand.java - /mmoconfig reloaddefaults now resets ALL configs to defaults
  • CommandRewardsConfig.java - Added reloadDefaults() method

v0.5.1

New Features

  • Target Player XP Command - OPs can now set other players' XP directly

    • /setmmoxp <skill> <value> --target=<player> - Set XP for another player
    • Requires mmoskilltree.command.setxp.others permission (default: OP)
    • Target must be online and in the same world
    • Works with all skills or "all" for bulk changes
    • Example: /setmmoxp mining 1000 --target=PlayerName
  • Custom Reward Display Names - Configure display names for item rewards

    • Add displayName field to reward entries in command-rewards.json
    • Value must be a localization key (e.g., "reward.mining.starter_kit")
    • Add the key to your localization/messages-*.json files
    • Falls back to "Level X" if key not found or not configured
  • Localized SetXP Command Messages - All command messages now support localization

    • Error messages (permission denied, player not found, invalid XP, unknown skill)
    • Success messages (skill set, all skills set, with/without target)
    • Localized in all 8 supported languages

Technical

  • SetXpCommand.java - Added --target optional argument for targeting other players

    • Uses world.getPlayers() to iterate players in the same world (deprecated but functional)
    • findPlayerRefByUsername() method finds target player's entity ref
    • Uses PermissionUtil.hasCommandPermission(player, "setxp.others") for permission check
    • Works with existing MMOSkillTreeAPI.setXp() for data modification
    • All messages now localized via Messages.get() helper
  • manifest.json - Added new permission node

    • mmoskilltree.command.setxp.others - Set other players' XP with --target (default: OP)
  • LocalizationConfig.java - Added setxp command message keys for all 8 languages

    • cmd.setxp.no_permission_others, cmd.setxp.player_not_found, cmd.setxp.no_skill_data
    • cmd.setxp.xp_negative, cmd.setxp.unknown_skill, cmd.setxp.available_skills
    • cmd.setxp.success_all, cmd.setxp.success_all_target, cmd.setxp.success_skill, cmd.setxp.success_skill_target
    • cmd.setxp.rewards_revoked - Notification when rewards are revoked
  • SkillTreeService.java - Added reward validation methods

    • validateAndRevokeRewards() - Revokes rewards for a skill when level drops below tier requirements
    • validateAllRewards() - Validates all skills (used when setting all XP)
    • Uses RewardEffectRegistry to properly remove stat modifiers
  • SkillComponent.java - Added helper methods for reward management

    • clearClaimedRewardsForTier() - Clears all rewards for a specific tier
    • getAllClaimedRewards() - Returns map of tier -> list of reward IDs for a skill
  • SetXpCommand.java - Integrated reward validation after XP changes

    • Calls SkillTreeService.validateAndRevokeRewards() for single skill changes
    • Calls SkillTreeService.validateAllRewards() for "all" skill changes
    • Shows revoked count to admin if any rewards were revoked
  • CommandRewardEntry.java - Added displayName field for custom reward names

  • CommandRewardsConfig.java - Parses and saves displayName from JSON config

  • Messages.java - Added getCommandRewardDisplayName() helper for resolving display names

  • ItemRewardsPage.java - Uses custom displayName if configured

  • CommandRewardService.java - Fixed ConsoleSender integration for console commands

Admin Commands

  • Reset Item Rewards Command - /mmoconfig resetrewards --args=<player>
    • Resets all claimed item rewards for an online player
    • Player can re-claim rewards at their current level milestones
    • Example: /mmoconfig resetrewards --args=PlayerName

Balance Changes

  • Leveling Curve Rebalanced - Adjusted default leveling parameters for longer progression

    • baseXpPerLevel changed from 100 to 150
    • levelScaleMultiplier changed from 1.1 to 1.35
    • Creates a steeper curve where high levels require significantly more XP
    • Level 50 now requires ~127k XP (was ~69k), Level 100 requires ~1M XP (was ~297k)
    • Existing servers can adjust via /mmoconfig basexp and /mmoconfig scale
  • Item Rewards Scaling Improved - Default item rewards scaled up to match harder leveling curve

    • All skill rewards increased 3-5x at higher tiers
    • Life Essence added to all skills at every tier
    • Level 100 rewards now include ~100 Life Essence, ~80 rare bars, ~10-15 Voidheart
    • Total Level rewards scaled up significantly (e.g., Total 1000 now gives 1000 Life Essence)
    • Elemental essences (Fire, Ice, Lightning) quantities increased proportionally

Reward Validation

  • Automatic Reward Revocation - Rewards are validated and revoked when player no longer qualifies
    • Triggers when XP is reduced via /setmmoxp
    • Triggers when leveling config changes: /mmoconfig basexp, /mmoconfig scale, /mmoconfig reload, /mmoconfig reloaddefaults
    • Offline players are validated on their first skill action after logging in
    • Revokes all rewards from tiers where player level is now below requirement
    • Removes stat modifiers (health, stamina, mana) via RewardEffectRegistry
    • Displays count of revoked rewards to admin

Config Refactoring

  • Config File Split - Separated large SkillConfig into focused configs for easier management

    • skill-config.json - General settings only (leveling formula, permissions, placed blocks, entity blacklist)
    • xp-maps.json (NEW) - XP values per skill (block patterns, weapon tiers, etc.)
    • luck-loot.json (NEW) - Luck bonus loot tables (block pattern -> item ID)
    • Each config has its own version number for independent updates
  • XpMapsConfig.java - New singleton config for XP values per skill

  • LuckConfig.java - New singleton config for luck loot tables

  • SkillConfig.java - Slimmed down, delegates XP/luck methods to new configs (marked deprecated)

  • MMOSkillTreePlugin.java - Initializes all new configs on startup


v0.5.0

New Features

  • Item Rewards at Skill Milestones - Receive item rewards when reaching specific skill levels

    • New config file: mods/mmoskilltree/command-rewards.json
    • Supports individual skill milestones (e.g., Mining level 10, 25, 50, 100)
    • Supports total level milestones (50, 100, 200, 350, 500, 750, 1000)
    • Comprehensive defaults included - All 16 skills have pre-configured item rewards
    • Items scale with progression:
      • Level 10 (Starter): 2-3 basic items (copper tools, common ingredients)
      • Level 25 (Progressing): 3-4 items (iron/cobalt gear, uncommon materials)
      • Level 50 (Skilled): 5-6 items (rare materials, gems, better gear)
      • Level 100 (Master): 6-10 items including legendary weapons (Flame, Void, Spectral)
    • Example: Mining 100 rewards include Flame Pickaxe, Mithril bars, Voidstones
    • Manual claiming required - Rewards are NOT auto-claimed; use the Rewards UI
    • Commands can also be executed (see Command Rewards below)
  • Item Rewards UI Page - New page to view and claim your item rewards

    • Access via "Rewards" tab on the Skill Overview page
    • Shows all tiers with status: LOCKED (gray), READY (orange), CLAIMED (green)
    • View reward contents before unlocking
    • CLAIM button to receive items into your inventory
    • Items wrap to new lines after 5 per row (supports up to 15 items per tier)
    • Toggle between Skill Rewards and Total Level Rewards tabs
    • Navigate between skills with arrow buttons
    • Rewards tab highlights with orange color and * when unclaimed rewards available
  • Item Reward Notifications - Get notified when new rewards become available

    • On level-up: "Mining Lv.10 item rewards available! Open /xp > Rewards"
    • On total level milestone: "Total Lv.100 item rewards available! Open /xp > Rewards"
    • Localized in all 8 supported languages
  • Command Rewards - Server owners can also configure commands to run at milestones

    • Placeholders: {player}, {level}, {skill}, {total_level}
    • RunAs modes: CONSOLE (full permissions) or PLAYER (player's permissions)
    • One-time rewards - commands only execute once per milestone
    • Example: Broadcast message at total level 100

Configuration

  • command-rewards.json - New config file for item and command rewards

    {
      "configVersion": 3,
      "enabled": true,
      "rewards": {
        "MINING": [
          {"level": 10, "displayName": "reward.mining.starter", "giveItems": ["Item_Pickaxe_Copper:1", "Ingredient_Bar_Copper:5"], "runAs": "CONSOLE"},
          {"level": 100, "displayName": "reward.mining.master", "giveItems": ["Weapon_Pickaxe_Flame:1", "Rock_Gem_Voidstone:3"], "runAs": "CONSOLE"}
        ],
        "TOTAL": [
          {"level": 100, "giveItems": ["Ingredient_Bar_Mithril:10", "Rock_Gem_Diamond:5"], "commands": ["say {player} reached total level 100!"], "runAs": "CONSOLE"}
        ]
      }
    }
    
  • Per-Config Versioning - Each config file now has its own version number

    • Previously: All configs shared a single CURRENT_CONFIG_VERSION = 10
    • Now: SkillConfig.CONFIG_VERSION = 3, SkillTreeConfig.CONFIG_VERSION = 2, CommandRewardsConfig.CONFIG_VERSION = 3
    • Only the changed config gets backed up when updating, not all configs

Technical

  • CommandRewardEntry.java - Data class for level/commands/giveItems/runAs
    • ItemReward inner class for item ID and quantity
    • ItemReward.parse() static method to parse "ItemId:Quantity" format
  • CommandRewardsConfig.java - Singleton config loader following SkillConfig pattern
  • CommandRewardsDefaults.java - Comprehensive item reward defaults for all 16 skills
    • All item IDs verified against Hytale's item database
    • Rewards use actual game items (weapons, tools, ingredients, gems)
  • CommandRewardService.java - Checks milestones, gives items, executes commands
    • checkAndExecuteRewards(playerRef, skills, skillType, newLevel) - For skill level-ups
    • checkTotalLevelRewards(playerRef, skills) - For total level milestones
    • giveItemToPlayer() - Adds items directly to player inventory
    • Placeholder processing: {player}, {level}, {skill}, {total_level}
  • ItemRewardsPage.java - New UI page for viewing and claiming item rewards
    • populateSkillRewards() / populateTotalRewards() - Render reward tiers
    • populateItems() - Distribute items across rows (5 per row, up to 3 rows)
    • handleClaimSkillReward() / handleClaimTotalReward() - Manual claim handlers
  • ItemRewardsPage.ui - UI layout with skill/total tabs, tier list, navigation
  • RewardTierRow.ui - Template for tier rows with claim button and 3 item rows
  • RewardItem.ui - Template for individual item display (icon + quantity)
  • SkillComponent.java - Added claimedCommandRewards field for tracking claimed rewards
    • New codec entry for persistence
    • New methods: hasClaimedCommandReward(), claimCommandReward(), getClaimedCommandRewardIds(), resetCommandRewards()
    • New method: getSummedTotalLevel() - Sum of individual skill levels (more intuitive than formula-based total)
  • ViewXpPage.java - Added "Rewards" tab navigation to ItemRewardsPage
  • ViewXpPage.ui - Added #TabRewards button
  • ConfigVersionUtil.java - Removed shared CURRENT_CONFIG_VERSION constant
    • Updated checkAndBackupIfNeeded(configPath, storedVersion, expectedVersion) to take expected version parameter
  • SkillService.java - Integrated CommandRewardService after level-up detection
  • MMOSkillTreePlugin.java - Loads CommandRewardsConfig in setup()
  • LocalizationConfig.java - Added ItemRewardsPage localization keys in all 8 languages
    • ui.rewards.title, ui.rewards.total_title, ui.rewards.level, ui.rewards.claimed, ui.rewards.available, ui.rewards.locked, ui.rewards.claim, etc.

v0.4.9

New Features

  • Deployable XP Exploit Fix - Totems and turrets no longer give combat XP
    • Prevents XP farming by repeatedly hitting player-deployed entities
    • Lays groundwork for future entity blacklist customization
    • New command: /mmoconfig blacklist - view current blacklist (expansion planned)
    • Config: combatXpEntityBlacklist array in skill-config.json

UX Improvements

  • Fractional XP Accumulator - Small XP bonuses (like +5%) now properly accumulate instead of being lost to rounding
    • Previously: 10 XP with 5% bonus → 10 * 1.05 = 10.5 → truncated to 10 (bonus lost!)
    • Now: Fractional remainder (0.5) is saved and added to next XP gain
    • Example: Gain 1: 10.5 → award 10, store 0.5 | Gain 2: 10.5 + 0.5 = 11.0 → award 11
    • Players see the bonus manifest every few actions (deterministic, no RNG)
    • Mathematically accurate over time - no XP is ever lost

Technical

  • SkillComponent.java - Added fractionalXpMap (ConcurrentHashMap<SkillType, Double>)
    • New codec entry {SKILL}FracXp for persistence
    • New methods: getFractionalXp(skill), setFractionalXp(skill, amount)
  • SkillService.java - Updated addXp() to use fractional accumulator pattern
    • Calculates exact XP with bonus multiplier
    • Adds accumulated fractional remainder from previous gains
    • Awards integer portion, saves decimal remainder for next time
  • SkillConfig.java - Added combatXpEntityBlacklist field with pattern matching
    • isEntityBlacklisted(entityType) - check if entity matches any blacklist pattern
    • addEntityBlacklist(pattern) / removeEntityBlacklist(pattern) - manage entries
  • CombatDamageEventSystem.java - Added entity blacklist check before awarding combat XP
    • getEntityType() - extracts entity archetype name from chunk
    • Blacklisted entities still take damage/trigger effects, just no XP awarded
  • MMOConfigCommand.java - Added /mmoconfig blacklist subcommand
  • ConfigVersionUtil.java - Bumped to version 10

v0.4.8

New Features

  • Placed Block XP Exploit Prevention - Players can no longer gain XP by breaking blocks they placed
    • Tracks block positions when players place blocks
    • Breaking a self-placed block awards no XP and removes tracking
    • Other players CAN still get XP from blocks you placed (fair multiplayer)
    • Applies to Mining, Woodcutting, Excavation block breaks (not item pickups)
    • Configurable via trackPlacedBlocks (default: true)
    • Optional expiration via placedBlockExpireMinutes (0 = never expire)

Balance Changes

  • Building XP Simplified - Changed from dynamic 50% of gathering values to flat 4 XP per block

    • All placed blocks now give 4 XP regardless of block type
    • Previously calculated as 50% of the mining/woodcutting/excavation value
    • Simpler and more predictable progression
  • Mushroom XP Reduced - Reduced mushroom harvesting XP from higher values to 1 XP

    • Plant_Crop_Mushroom_ and Plant_Mushroom_ now give 1 XP
    • Prevents easy XP farming from abundant mushrooms

Localization

  • Italian Language Support - Full translation of all UI, notifications, skills, and rewards
    • New language file: messages-it.json
    • 8 languages now supported: English, Spanish, French, Portuguese, Hungarian, Turkish, German, Italian

Configuration

  • trackPlacedBlocks - Enable/disable placed block tracking (default: true)

    • When enabled, players cannot gain XP from breaking blocks they placed
    • Set to false to allow the old behavior
  • placedBlockExpireMinutes - Minutes until placed blocks "become natural" (default: 0)

    • Set to 0 for blocks to never expire (only removed when broken)
    • Set to a positive value (e.g., 30) to allow XP after that many minutes

Technical

  • PlacedBlockTracker.java - New singleton service for tracking player-placed blocks
    • Uses ConcurrentHashMap with player hash -> Set of tracked blocks
    • BlockPosition record stores x, y, z coordinates
    • TrackedBlock record stores position and timestamp for expiration
    • Methods: trackPlacement(), wasPlacedByPlayer(), removeTracking(), cleanupExpired()
  • PlaceBlockEventSystem.java - Now calls PlacedBlockTracker.trackPlacement() on block place
  • BreakBlockEventSystem.java - Checks PlacedBlockTracker.wasPlacedByPlayer() before awarding XP
  • PickupItemEventSystem.java - Same check for interactive pickups (harvesting)
  • SkillConfig.java - Added trackPlacedBlocks and placedBlockExpireMinutes fields

v0.4.7

Bug Fixes

  • Fixed leaderboard crash on multi-world servers - Leaderboard no longer crashes when players are in different world instances (e.g., dungeons, temples)
    • Error was: IllegalStateException: Assert not in thread! when accessing player data across world threads
    • Now uses cached leaderboard data instead of accessing live data from other world threads
    • Online/offline indicator still works correctly (based on player connection status)
    • Viewer's own data is still live (same thread)

Technical

  • LeaderboardPage.java - Refactored gatherPlayerData() to avoid cross-thread Store access
    • Only calls playerRef.getUsername() on other players (thread-safe)
    • Uses LeaderboardDataStore cache for all player XP/level data
    • Gets live data only for the viewer (who is on the current thread)

v0.4.6

Bug Fixes

  • Fixed command permissions blocking all players - Commands like /mmoxp, /skilltree, and /xpdisplay were requiring permission nodes even when permission system was disabled
    • Added enableCommandPermissions config option (default: false)
    • When disabled, all players can use all commands without needing mmoskilltree.command.* permissions
    • Enable via config file or future admin command to require permission nodes for commands
    • Matches the existing behavior of skill permissions (enableSkillPermissions)

Technical

  • SkillConfig.java - Added enableCommandPermissions field with getter/setter and JSON serialization
  • PermissionUtil.java - Updated hasCommandPermission() to check isCommandPermissionsEnabled() before requiring permissions
    • Added wildcard permission support (mmoskilltree.command.*) for command permissions

v0.4.5

New Features

  • Keb's Katanas Mod Support - Added default XP values for katanas from the Keb's Katanas mod

    • Legendary: Keb_Katana_Prisma (55 XP)
    • Epic: Keb_Katana_Mithril (48 XP), Keb_Katana_Onyxium (52 XP)
    • Rare: Keb_Katana_Cobalt (23 XP), Keb_Katana_Adamantite (28 XP), Keb_Katana_Thorium (28 XP)
    • Uncommon: Keb_Katana_Copper (8 XP), Keb_Katana_Steel (8 XP)
  • Configurable Permission System - Opt-in permission nodes for skill XP gain and commands

    • Permission checking is disabled by default for backwards compatibility
    • Enable via /mmoconfig permissions --args=true
    • When enabled, players need mmoskilltree.skill.<skillname> or mmoskilltree.skill.* to gain XP
  • Skill Permissions - Control which players can gain XP in specific skills

    • mmoskilltree.skill.* - Wildcard for all skills (default: granted)
    • mmoskilltree.skill.mining - Individual skill permissions
    • All 16 skills have their own permission node
    • Silent deny - players without permission simply don't gain XP (no error message)
  • Command Permissions - Control access to plugin commands

    • mmoskilltree.command.xp - /mmoxp command (default: granted)
    • mmoskilltree.command.skilltree - /skilltree command (default: granted)
    • mmoskilltree.command.xpdisplay - /xpdisplay command (default: granted)
    • mmoskilltree.command.setxp - /setmmoxp command (default: op)
    • mmoskilltree.command.config - /mmoconfig command (default: op)
  • New Admin Command - /mmoconfig permissions --args=<true|false>

    • Toggle skill permission checking on/off
    • Displays current state and usage help

Upgrade Notes

  • Config version bumped to 8 - Existing configs will be backed up automatically
  • Your old config is saved as skill-config_backup.json in mods/mmoskilltree/
  • Restore any custom XP values from the backup file after upgrading

Technical

  • ConfigVersionUtil.java - Bumped CURRENT_CONFIG_VERSION to 8
  • LongswordDefaults.java - Added 8 Keb's Katanas with tiered XP values
  • manifest.json - Added Permissions array with all skill and command permission nodes
  • SkillConfig.java - Added enableSkillPermissions field with getter/setter
  • PermissionUtil.java - New utility class for permission checking
    • canGainSkillXp(player, skill) - Checks skill permission (respects config toggle)
    • hasCommandPermission(player, command) - Checks command permission
  • SkillService.java - Added permission check in processTrigger() before awarding XP
  • Command classes - All 5 commands now check mmoskilltree.command.<name> permission
    • GetXpCommand, SkillTreeCommand, XpDisplayCommand, SetXpCommand, MMOConfigCommand
  • LocalizationConfig.java - Added cmd.no_permission key to all 7 languages

v0.4.4

New Features

  • Offline Player Leaderboard - Leaderboard now displays both online and offline players
    • Player data is cached when XP is gained and on server shutdown
    • Online players show live data; offline players show cached data
    • Visual indicator distinguishes online (green dot) from offline (gray dot) players
    • Player count now shows "X online / Y total" format

Technical

  • LeaderboardDataStore.java - New singleton service for persistent leaderboard caching
    • Stores player skill data in mods/mmoskilltree/leaderboard-cache.json
    • Thread-safe with ConcurrentHashMap
    • Automatically saves on JVM shutdown via shutdown hook
  • SkillService.java - Added leaderboard cache update on XP gain
  • LeaderboardPage.java - Merged online player data with cached offline data
    • Added isOnline field to PlayerLeaderboardEntry
    • Added createEntryFromCache() method for offline player entries
    • Online/offline visual styling in leaderboard rows
  • LeaderboardRow.ui - Added #OnlineStatus indicator element
  • MMOSkillTreePlugin.java - Added leaderboard cache initialization and shutdown hook
  • LocalizationConfig.java - Added ui.leaderboard.player_count_online key for all 7 languages

v0.4.3

New Features

  • Turkish Localization - Added Turkish (Türkçe) as a supported language

    • Full translation of all UI text, notifications, skill names, and reward types
  • German Localization - Added German (Deutsch) as a supported language

    • Full translation of all UI text, notifications, skill names, and reward types
  • Expanded Language Selector - Settings page now supports up to 15 languages

    • Increased from 2 rows of 3 buttons to 3 rows of 5 buttons
    • Ready for community-contributed translations

Bug Fixes

  • Fixed Wan's Wonder Weapons Battleaxe - Corrected typo in item ID
    • WanMine_God_Slayer_BatlleaxeWanMine_God_Slayer_Battleaxe

Technical

  • LocalizationConfig.java - Added getTurkishDefaults() and getGermanDefaults() with full translations
  • LocalizationConfig.java - Added ensureTurkishDefaults() and ensureGermanDefaults() methods
  • SettingsPage.java - Increased maxLangButtons from 6 to 15
  • SettingsPage.ui - Added #LangBtn3 through #LangBtn14 buttons in 3 rows of 5
  • SettingsPage.ui - Increased #LanguageSetting height from 160 to 204
  • SettingsPage.ui - Increased #LanguageButtons height from 80 to 124

v0.4.2

Bug Fixes

  • Disabled Luck for Crafting - Removed luck bonus from crafting due to critical item duplication bug
    • Luck bonuses were incorrectly duplicating crafted items
    • Will be re-enabled in a future update once the underlying issue is resolved

Technical

  • CraftRecipeEventSystem.java - Removed LuckUtil.tryLuckBonus() call

v0.4.1

New Features

  • Mighty Staffs Mod Support - Added default XP values for staffs from the Mighty Staffs mod

    • Weapon_Staff_Bo_Wood (6 XP)
  • Wan's Wonder Weapons Mod Support - Added default XP values for weapons from the Wan's Wonder Weapons mod

    • Swords: WanMine_Lethal_Leftovers_Sword, WanMine_Gaia's_Wrath_Sword, WanMine_Quasar_Cosmic_Sword (65-70 XP)
    • Longswords: WanMine_Soulblight_Longsword, WanMine_Soulblight_Longsword_v1 (65 XP)
    • Daggers: WanMine_Chromatic_Cleaver_Dagger, WanMine_Daybreak_Dagger, WanMine_Heartroot_Dagger, WanMine_Ashthorn_Dagger, WanMine_Nightshade_Dagger, WanMine_Frostburn_Dagger, WanMine_Nightfall_Dagger (58-68 XP)
    • Battleaxe: WanMine_God_Slayer_Battleaxe (70 XP)
    • Maces: WanMine_Helioram_Mace, WanMine_Maelstrom_Mace, WanMine_Mjollnir_Mace (65-70 XP)

Technical

  • StaffDefaults.java - Added Weapon_Staff_Bo_Wood
  • SwordDefaults.java - Added Legendary tier with 3 WanMine swords
  • LongswordDefaults.java - Added 2 WanMine longswords to Legendary tier
  • DaggerDefaults.java - Added Legendary tier with 7 WanMine daggers
  • BattleaxeDefaults.java - Added Legendary tier with WanMine_God_Slayer_Battleaxe
  • MaceDefaults.java - Added Legendary tier with 3 WanMine maces

v0.4.0

New Features

  • Skill Tree Scrolling - Skill tree UI now scrolls when there are many tiers
  • XP Progress Bar - Skill tree header shows progress bar to next level with "current / needed" XP format
  • STAT_MANA Reward - New reward type for increasing maximum mana
  • Complete 10-Tier Reward Redesign - All 16 skills now have 10 tiers of rewards (Lv 5, 10, 15, 20, 30, 40, 50, 65, 75, 100)

Mana System Design

Players start with 0 mana - it must be earned through skill tree choices. Each skill class has a distinct mana identity:

  • Staves - THE mana class (360+ max mana potential). Bo staff masters channel mystical energy
  • Archery - High mana (290+) for wand and spellbook users
  • Crafting - Moderate mana (305) for enchanting and magical item creation
  • Block/Harvesting - Low mana (65-180) for survivability or nature attunement
  • Physical Combat (Swords, Daggers, Axes, Blunt, Polearms) - Minimal mana (15-38). Warriors rely on steel, not sorcery
  • Gathering (Mining, Woodcutting, Excavation) - Minimal mana (23-38). Laborers focus on physical prowess
  • Acrobatics/Building - Zero mana. Pure physical disciplines focused on stamina

Tier Structure

Tier Level Choices Required
0-1 5-10 2 1
2-3 15-20 3 1
4-5 30-40 4 2
6-7 50-65 5 2
8 80 5 3
9 100 6 3

Technical

  • SkillTreePage.ui: #TiersList LayoutMode changed to TopScrolling
  • SkillTreePage.ui: Added #SkillProgress ProgressBar in header
  • SkillTreePage.java: Added progress calculation using getLevelProgress()
  • SkillTreePage.java: Fixed ProgressBar.Value to use double instead of String
  • SkillTreePage.java: MAX_CHOICES increased from 5 to 6 for tier 9
  • RewardType.java: Added STAT_MANA enum
  • StatModifierUtil.java: Added applyManaBonus/removeManaBonus methods
  • StatManaEffect.java: New effect handler
  • RewardEffectRegistry.java: Registered StatManaEffect
  • LocalizationConfig.java: Added reward.stat_mana to all 5 languages
  • SkillTreeDefaults.java: Complete rewrite with 10 tiers for all 16 skills

v0.3.5

Bug Fixes

  • Leaderboard Combat Skill Filters - Fixed combat category only showing 6 of 10 skills in the filter bar

    • Added SkillFilter6-9 buttons to support all combat skills
    • All 10 combat skills now visible: Swords, Daggers, Polearms, Staves, Axes, Blunt, Archery, Unarmed, Block, Acrobatics
  • Archery XP Defaults - Removed magic staves from Archery skill

    • Staves (magic/ranged) were incorrectly included in Archery defaults
    • Staves now correctly belong only to the STAVES skill (melee staves)

Technical

  • LeaderboardPage.ui - Added #SkillFilter6 through #SkillFilter9 buttons
  • LeaderboardPage.java:217 - Changed skill filter loop from i < 6 to i < 10
  • ArcheryDefaults.java - Removed StaffDefaults.getDefaults() call

v0.3.4

New Features

  • Leaderboard Page - View player rankings accessible from ViewXpPage
    • Shows all players ranked by total level and XP
    • Sort by category: Total Level, Gathering, Combat, Production
    • Drill down by individual skill within each category
    • Your rank displayed at the bottom with highlighting
    • Scrollable player list for large servers

Balance Changes

  • Leveling Curve Rebalanced - Adjusted baseXpPerLevel and levelScaleMultiplier defaults
    • Level 120 now requires approximately 1 million XP
    • Default levelScaleMultiplier changed from 1.0 to 1.1
    • Creates more meaningful late-game progression
    • Existing servers can adjust via /mmoconfig basexp and /mmoconfig scale commands

Technical

  • Scrollable UI Pattern - LayoutMode: TopScrolling enables vertical scrolling in UI containers
  • New Files:
    • LeaderboardPage.java - Leaderboard page logic with player data gathering and sorting
    • LeaderboardPage.ui - Layout with scrolling player list and filter buttons
    • LeaderboardRow.ui - Template for individual player rank rows
  • ViewXpPage.java - Added Leaderboard tab navigation
  • ViewXpPage.ui - Added Leaderboard tab button
  • LocalizationConfig.java - Added leaderboard localization keys for all 5 languages

v0.3.3

New Features

  • Hungarian Localization - Added Hungarian (Magyar) as a supported language
    • Full translation of all UI text, notifications, skill names, and reward types
  • More Crossbow Tiers Mod Support - Added default XP values for crossbows from the More Crossbow Tiers mod

Bug Fixes

  • Config Reload Command - Fixed /mmoconfig reload overwriting user config edits
    • Manual file edits are now preserved when using reload command
    • Version check only runs on server startup, not manual reloads

Technical

  • Config Version System - Replaced hash-based version tracking with simple version numbers
    • ConfigVersionUtil.CURRENT_CONFIG_VERSION - Bump this constant when defaults change
    • Configs now store configVersion field instead of computed hash
    • More reliable: user edits don't trigger false "defaults changed" detection
  • SkillConfig.java / SkillTreeConfig.java - load(false) skips version check for manual reloads

v0.3.2

New Features

  • Portuguese Localization - Added Portuguese (Português) as a supported language
    • Full translation of all UI text, notifications, skill names, and reward types
    • Select Portuguese in Settings page

Bug Fixes

  • Settings Language Selector - Fixed backup language files appearing in the language selector
    • Files like messages-en_backup.json no longer show as selectable languages
    • Only valid language files (messages-XX.json) are displayed

Technical

  • LocalizationConfig.java - Added filter to exclude _backup files from language scanning
  • LocalizationConfig.java - Added getPortugueseDefaults() with full Portuguese translations

v0.3.1

New Features

  • Tier 7 Rewards - Added Level 65 milestone rewards for all 16 skills
    • Master-tier bonuses: higher luck, health, damage, defense values
    • Each skill gets 5 new reward choices at this tier

Balance Changes

  • Stamina Rewards Rebalanced - Base stamina is 10, so rewards were scaled down
    • Early tiers (5-15): +1 stamina
    • Mid tiers (30-50): +2 stamina
    • Master tier (65): +3 stamina
    • Maximum stamina from all skill trees is now ~15-20 (was 100+)

Bug Fixes

  • Config Backup System - Fixed bug creating nested _backup_backup_backup... files
    • Backup files are now skipped when creating backups
    • Added automatic cleanup of malformed backup files on startup
  • Config Auto-Update - Configs now regenerate from new defaults when mod updates
    • Old configs are backed up to *_backup.json before regeneration
    • Ensures players get new tiers and balance changes automatically

Technical

  • ConfigVersionUtil.java - Added cleanupMalformedBackups() method
  • SkillConfig.java - Regenerates from defaults when hash changes instead of merging
  • SkillTreeConfig.java - Same auto-regeneration behavior
  • SkillTreeDefaults.java - Added tier 7 for all skills, fixed stamina values
  • MMOSkillTreePlugin.java - Calls cleanup on startup for both config dirs

v0.3.0

New Features

  • Luck System (renamed from Double Drop) - Complete overhaul of bonus drop mechanics

    • Renamed RewardType.DOUBLE_DROPRewardType.LUCK throughout codebase
    • New configurable luckLootTable - maps block patterns to specific item drops
    • Block breaks (Mining, Excavation): Only gives luck bonus if loot table match exists
    • Item pickups (Harvesting): Defaults to same item as bonus
    • Default loot table includes all ore tiers (Copper → Onyxium) → raw ore items
    • Default loot table includes all gems (Diamond, Emerald, Ruby, etc.) → gem items
  • Creative Mode XP Disable - XP gains are now disabled by default in creative mode

    • New config option disableXpInCreative (default: true)
    • Toggle via /mmoconfig creative --args=<true|false>
    • Players in creative mode will not gain XP unless this setting is changed

UI/Text Improvements

  • Luck Reward Text - Now specifies which skill the luck bonus applies to
    • Before: "+5% Double Drop" (generic)
    • After: "+5% Mining Luck" (skill-specific)
    • Uses localization system with new reward.luck_suffix key
  • Defense renamed to Block - Clarifies that this stat is different from Hytale's built-in defense
    • All reward text now shows "Block" instead of "Defense"
    • Updated in all three languages (EN: "Block", ES: "Bloqueo", FR: "Blocage")

Breaking Changes

  • Config field doubleDropLootTable renamed to luckLootTable
  • Existing configs will need to rename this field manually

Technical

  • New Files:
    • LuckUtil.java - Luck bonus logic (renamed from DoubleDropUtil)
    • LuckDefaults.java - Default loot table mappings (renamed from DoubleDropDefaults)
  • Renamed Methods:
    • SkillTreeService.getDoubleDropChance()getLuckChance()
    • SkillConfig.getDoubleDropLootTable()getLuckLootTable()
    • SkillConfig.getDoubleDropItem()getLuckItem()
  • SkillConfig.java - Added disableXpInCreative field, renamed loot table fields
  • SkillService.java - Added creative mode check in processTrigger()
  • MMOConfigCommand.java - Added creative subcommand for toggling the setting
  • Messages.java - Added LUCK handling in getRewardDisplayText() to include skill name
  • LocalizationConfig.java - Added reward.luck_suffix, renamed from reward.double_drop_suffix
  • SkillTreeDefaults.java - All DOUBLE_DROP rewards renamed to LUCK

v0.2.9

Bugfixes

  • Fixed critical hit notification - Now shows multiplier (x1.5) instead of total damage amount
  • Fixed lifesteal notification - Removed duplicate + sign that was appearing in heal messages

Technical

  • DoubleDropUtil.java - Extracted double drop logic to shared utility class for DRY
  • PickupItemEventSystem - Refactored to use DoubleDropUtil.tryDoubleDrop() instead of inline implementation

v0.2.8

New Features

  • 4 New Melee Combat Skills - Weapon types split from Swords/Axes for more focused progression:
    • DAGGERS - Daggers, claws, kunai (high crit chance, fast attacks)
    • POLEARMS - Spears, halberds (reach weapons, defensive bonuses)
    • STAVES - Bo staffs, melee staves (disciplined, stamina-focused)
    • BLUNT - Clubs, maces (heavy hitters, high damage and health)

Bugfixes

  • Combat Effect Notifications - Added missing notifications for critical hits, defense blocks, and fall damage reduction (previously only lifesteal had notifications)

Combat Skill Changes

  • SWORDS now covers only longswords and one-handed swords (bladed slashing weapons)
  • AXES now covers only axes and battleaxes (chopping weapons)
  • Daggers, spears, and melee staves moved to their own dedicated skills
  • Clubs and maces moved to new BLUNT skill

Skill Tree Additions

  • 4 New Skill Trees with thematic reward progressions:
    • DAGGERS: High crit scaling (up to +15%), strong lifesteal
    • POLEARMS: Balanced offense/defense, high defense bonuses
    • STAVES: Stamina-focused, good defense and fall reduction
    • BLUNT: Highest raw damage (+14%), highest health (+28%)

Technical

  • Config Version Hashing - Config files now track a defaultsHash to detect when mod defaults change
    • Automatically creates backup (e.g., skill-config_backup.json) before loading if defaults changed
    • Protects user customizations when updating the mod
  • New config files: DaggersDefaults.java, PolearmsDefaults.java, StavesDefaults.java, BluntDefaults.java
  • New utility: ConfigVersionUtil.java for hash generation and backup management
  • Updated SkillType.java with 4 new enum values
  • Updated SkillTreeDefaults.java with 4 new skill tree methods
  • Total implemented skills: 16 (was 12)

v0.2.7

Bugfixes

  • Fixed Archery skill not gaining XP - Archery now correctly awards XP when dealing damage with bows, crossbows, wands, and other ranged weapons
    • Changed Archery trigger type from DEAL_DAMAGE_PROJECTILE to DEAL_DAMAGE_PHYSICAL
    • Removed unused DEAL_DAMAGE_PROJECTILE trigger type

v0.2.6

New Features

  • /setmmoxp Command - Admin command to set player XP directly
    • /setmmoxp <skill> <value> - Set XP for a specific skill
    • /setmmoxp all <value> - Set XP for all skills at once
    • Alias: /setxp
    • Configurable permission via setXpRequiredGameMode in config

Bugfixes

  • Fixed torches giving Woodcutting XP - Torches no longer incorrectly award Woodcutting experience when broken

Configuration

  • setXpRequiredGameMode - New config option in config.json
    • Controls who can use /setmmoxp command
    • Values: "OP" (default), "Adventure", "Creative", etc.
    • Example: Set to "Creative" to allow creative mode players to use the command

v0.2.5

Bugfixes

  • Fixed BONUS_XP reward display - Now correctly shows the target skill name
    • Before: "+5% Bonus XP" (generic)
    • After: "+5% Mining XP" or "+5% Excavation XP" (skill-specific)
    • Extracts skill from reward ID (e.g., excavation_xp_1 → Excavation)
    • Works correctly when skill trees offer XP bonuses for related skills

Technical

  • Messages.extractSkillFromRewardId() - Parses reward ID to determine target skill
  • BONUS_XP rewards now display localized skill name + "XP" suffix

v0.2.4

New Features

  • Localization System - Full i18n support for all UI text

    • Players can select their preferred language in Settings
    • Language preference saved per-player in SkillComponent
    • Auto-generated English, Spanish, and French language files
    • Users can add custom messages-{lang}.json files for additional languages
  • Language Selector - New section in Settings page

    • 6 language button slots in 2 rows of 3
    • Currently selected language highlighted in green
    • Disabled style for unavailable language slots
    • Instant language switching without restart
  • Auto-Generated Language Files - Located in mods/mmoskilltree/localization/

    • messages-en.json - English (auto-generated)
    • messages-es.json - Spanish (auto-generated)
    • messages-fr.json - French (auto-generated)
    • Files auto-update with new keys on server start
  • Localized Reward Text - Skill tree rewards fully localized

    • Reward type names (e.g., "Max Health" → "Santé Max" in French)
    • Formatted values with localized patterns (+5%, +10, +3 blocks)
    • Reward claimed notifications use localized text
  • Hot-Reload Support - /mmoconfig reloadlang command

    • Reload language files without server restart
    • New translations take effect immediately

Technical

  • New i18n/ package:

    • LocalizationConfig.java - Singleton config manager for language files
      • Loads/saves JSON message files using GSON
      • Scans for available messages-*.json files
      • Placeholder substitution with {0}, {1} format
      • Merges file contents with defaults (preserves user customizations while adding new keys)
      • Always falls back to English defaults (never shows raw keys)
    • Messages.java - Static helper class for message access
      • get(skills, key) / get(skills, key, args...) - Get translated message
      • getSkillName(skills, skillType) - Get localized skill name
      • getRewardTypeName(skills, rewardType) - Get localized reward type name
      • getRewardFormattedValue(skills, reward) - Get localized formatted value
      • getRewardDisplayText(skills, reward) - Get full localized reward text
  • SkillComponent.java - Added language field (default: "en")

    • Codec entry for persistence
    • getLanguage() / setLanguage() methods
  • UI Localization - All UI text now uses Messages helper

    • ViewXpPage - Panel titles, tabs, labels, buttons
    • SkillTreePage - Tier labels, status text, buttons
    • SettingsPage - All setting labels and descriptions
    • SkillRow/TierRow templates - Dynamic text via indexed selectors
  • SettingsPage.ui - Added element IDs for dynamic localization

    • #SettingsTitle, #XpNotificationsLabel, #XpNotificationsDesc
    • #CombatEffectsLabel, #CombatEffectsDesc
    • #XpThresholdLabel, #XpThresholdDesc
    • #LanguageLabel, #LanguageDesc
    • #LangBtn0 through #LangBtn5 with @DisabledButtonStyle
  • ViewXpPage.ui - Added #SkillsHeader ID for localization

  • MMOConfigCommand.java - Added reloadlang subcommand

Message Key Structure

{
  "language.name": "English",
  "ui.button.close": "CLOSE",
  "ui.button.back": "< BACK",
  "ui.viewxp.title": "Skill Overview",
  "ui.viewxp.level_prefix": "Lv. {0}",
  "ui.settings.language": "Language",
  "notify.xp_gain": "+{0} {1} XP",
  "notify.level_up": "LEVEL UP! {0} is now Level {1}!",
  "skill.mining": "Mining",
  "reward.stat_health": "Max Health",
  "reward.bonus_xp": "Bonus XP",
  "reward.format.percent": "+{0}%",
  "reward.format.flat": "+{0}"
}

Adding Custom Languages

  1. Create mods/mmoskilltree/localization/messages-{code}.json
  2. Copy structure from messages-en.json
  3. Translate values (keys must remain the same)
  4. Run /mmoconfig reloadlang or restart server
  5. Language appears in Settings selector

v0.2.3

New Features

  • Dynamic Skill Tree Choices - Configurable number of choices per tier (up to 5)

    • New choicesRequired field on SkillTreeNode - how many rewards to pick per tier
    • Global defaultChoicesRequired in config (default: 1)
    • UI shows "Pick X of Y" when tier has multiple selections
    • Tier status shows completion progress (e.g., "1/2" when partially complete)
  • Multi-Select Rewards - Players can now pick multiple rewards per tier

    • Higher tiers offer more choices with multi-select (Pick 2 of 4)
    • Prevents claiming same reward twice
    • Tier only marked complete when all required choices made
  • Dynamic UI Rendering - Choice buttons rendered dynamically

    • New ChoiceButton.ui template appended per choice
    • Buttons use FlexWeight for automatic sizing
    • Supports 2-5 choices per tier
    • Removed hardcoded button limits
  • Expanded Reward Variety - Updated skill tree defaults

    • Tiers 0-1: 2 choices, pick 1
    • Tiers 2-3: 3 choices, pick 1
    • Tiers 4-5: 4 choices, pick 2
    • Tier 6 (Level 50): 5 choices, pick 2 - Elite rewards for all 12 skills
    • More diverse reward options per tier
  • Tier 6 Elite Rewards (Level 50) - All 12 skills now have elite tier rewards

    • Gathering: +20% XP, +15% Double Drops, +20 Health, +15 Stamina, synergy bonuses
    • Combat: +10% Damage, +12-15% Crit, +8-10% Lifesteal, +20 Health
    • Defense: +12% Defense, +30 Health, -40% Fall Damage, +5% Lifesteal
    • Acrobatics: -50% Fall Damage, +20 Health, +8% Defense, +20 Stamina
    • Crafting/Building: +20% XP, +20 Health/Stamina, synergy bonuses

Technical

  • SkillTreeNode.java - Added choicesRequired field with new constructor
  • SkillComponent.java - Multi-claim storage using comma-separated reward IDs per tier
    • getClaimedRewardIds(skill, tier) returns list of claimed IDs
    • getClaimedCount(skill, tier) returns count for tier
    • hasClaimedSpecificReward(skill, tier, rewardId) checks specific claim
  • SkillTreeConfig.java - Added defaultChoicesRequired global setting and JSON codec
  • SkillTreePage.java - Dynamic button rendering with FlexWeight layout
  • SkillTreeService.java - Updated claiming logic for multi-select validation
  • TierRow.ui - Removed hardcoded buttons, added #SelectionInfo label
  • ChoiceButton.ui - New template for dynamic choice buttons

Config Schema Update

{
  "defaultChoicesRequired": 1,
  "skillTrees": {
    "MINING": [{
      "tier": 4,
      "levelRequired": 30,
      "choicesRequired": 2,
      "choices": [...]
    }]
  }
}

Upgrade Notes

Run /mmoconfig reloaddefaults to load the new multi-choice tier defaults.