Your Cart
Loading

SoapsHungerStamina - UPDATE - 1.0.4

- Projectile and throwable stamina costs are in. Shooting a bow, crossbow, trident, or throwing snowballs, eggs, ender pearls, potions, experience bottles, firework rockets, and fishing rods will now drain stamina. Every single item type has its own cost you can tweak, and you can toggle each one on or off. There's a master toggle for projectiles and a separate one for throwables. Bow shots can also scale with how far back you pull the string if you want that.

- New bypass permission: soapsstamina.bypass.projectiles. Give it to players who should be able to shoot without losing stamina.

- Bow, crossbow, and trident cost sliders were added to the Action Settings GUI page so you can tune them visually.

- New toggle commands: /shs toggle projectiles, bow, crossbow, trident, throwables, and bow-scale-with-charge.

- New config set groups: bow, crossbow, trident, throwables, and every individual throwable item cost can be adjusted through commands.

- 11 toggles that were missing from the GUI have been added. Water contact, lava contact, idle regen, overexertion, overexertion scaling, projectiles, bow, bow charge scaling, crossbow, trident, and throwables are all there now. The toggle page has pagination with arrows at the bottom since all 39 toggles don't fit on one page anymore.

- Brand new Projectile Settings page in the GUI. All throwable item costs (snowball, egg, ender pearl, eye of ender, splash potion, lingering potion, experience bottle, firework rocket, fishing rod) plus bow, crossbow, and trident costs can be adjusted directly from the admin panel.

- Water contact drain, lava contact drain, idle regen rate, and regen action cooldown sliders were added to the Action Settings GUI page.

- Cold passive drain and hot passive drain sliders were added to the Effects & Biomes GUI page.

- Six overexertion sliders were added to the System Settings GUI page: threshold, base damage, scaling divisor, max damage, recovery rate, and warning threshold.

- Fifteen new stamina mechanics added as part of a full mechanics audit:

 - Elytra gliding drains stamina per second while airborne. Has its own toggle, drain rate, and bypass (soapsstamina.bypass.elytra). Before this, elytra users paid nothing.

 - Climbing ladders, vines, and scaffolding drains stamina per second. Toggle and bypass: soapsstamina.bypass.climbing.

 - Eating food restores stamina. When you eat anything edible, you get a configurable amount back. Toggle and bypass: soapsstamina.bypass.eating.

 - Mace smash attacks (falling and hitting with a mace) cost extra stamina on top of the regular attack cost. Toggle and bypass: soapsstamina.bypass.mace.

 - Wind charge throwables are tracked as a projectile with their own cost under the throwables section.

 - Potion effect modifiers. Having Speed or Haste active multiplies all stamina drain by a configurable amount. Disabled by default. When turned on, sprinting with Speed II makes everything cost more.

 - Taking damage from fire, fall, drowning, explosions, or anything else drains stamina per heart. Entity attacks excluded since winded covers those. Toggle and bypass: soapsstamina.bypass.damage-intake.

 - Boat paddling drains stamina while you're moving. Sitting still costs nothing. Toggle and bypass: soapsstamina.bypass.boat.

 - Crawling through 1-block gaps drains stamina per second. Toggle and bypass: soapsstamina.bypass.crawling.

 - Riptide trident launches cost stamina. Toggle and bypass: soapsstamina.bypass.riptide.

 - Tool use costs stamina. Tilling dirt with a hoe, shearing entities, and brushing suspicious blocks each have their own cost. One toggle for all three: soapsstamina.bypass.tool-use.

 - Powder snow drains stamina per second while standing in it. Toggle and bypass: soapsstamina.bypass.powder-snow.

 - Slime block bouncing costs stamina each time you bounce. Half-second cooldown so it doesn't double count. Toggle and bypass: soapsstamina.bypass.slime-bounce.

 - Soul sand and soul soil increase all stamina drain by a multiplier while walking on them. Toggle and bypass: soapsstamina.bypass.soul-sand.

 - Honey blocks do the same thing, separate multiplier. Toggle and bypass: soapsstamina.bypass.honey-block.

- All 15 new mechanics have full GUI support with toggle switches (page 3), value sliders on the appropriate pages, and icons with descriptions.

- All of them have /shs toggle and /shs config set commands with tab completion.

- 14 new bypass permissions were added to plugin.yml for per-player control.

- The weight.yml file now covers a lot more items. All 19 smithing templates, all 23 pottery sherds, all 8 banner patterns, and a bunch of individual items that were missing: echo shards, sniffer eggs, armadillo scutes, dragon eggs, turtle eggs, firework rockets, firework stars, iron bars, creaking hearts, pale hanging moss, beehives, bee nests, and both nylium types from the Nether. If an item isn't in the list, it falls back to the default weight.

- The storage section in weight.yml was reorganized to clearly explain how container weighing works. Shulker boxes and bundles now have comments showing that when container-weight is enabled, the plugin adds up everything inside them on top of the base weight. Bundle base weight was bumped from 0.05 to 0.1 since it was unrealistically light.

- Bundles inside shulker boxes now have their contents weighed properly. Before this, a bundle stuffed with gold blocks sitting in a shulker would only count as the bundle's base weight, ignoring everything inside it.

- Altitude-based stamina drain. Being high up in the sky (above Y 192 by default) simulates thin air and increases all stamina drain plus adds a passive drain that scales the higher you go, maxing out at the world height limit. Going deep underground (below Y 32 by default) does the same thing to simulate heavy, stale cave air, scaling down to the world floor. The comfortable zone in between has no penalty. Both thresholds, multipliers, and passive drain rates are fully configurable. Transition messages tell the player when they enter or leave an altitude zone. Disabled by default so it doesn't surprise anyone on update.

- New bypass permission: soapsstamina.bypass.altitude. Give it to players who should ignore altitude stamina penalties.

- Freeze particle effect for cold biomes. Players in cold biomes now get snowflake particles floating around their head, matching how hot biomes already have sweat (water drip) particles. Has its own toggle and particle count setting. Enabled by default.

- Altitude and freeze-particles toggles were added to the GUI toggle page. Altitude has six value sliders on the Effects & Biomes page: high threshold, high multiplier, high passive drain, low threshold, low multiplier, and low passive drain. Freeze particle count slider is there too.

- New toggle commands: /shs toggle altitude and /shs toggle biome-freeze-particles.

- New config set group: altitude, with all six numeric settings adjustable through commands. Freeze particle count was added to the biomes config set group.

- MMOItems custom weights. You can now assign specific weights to individual MMOItems items in weight.yml using their Type and ID (e.g., SWORD:FIRE_BLADE: 3.5). You can also set a default weight for an entire MMOItems type as a fallback (e.g., all SWORD items weigh 2.0 unless overridden). If an MMOItems item has no custom weight entry, it falls back to the vanilla material weight as usual. The lookup priority is: specific item → type default → vanilla weight. Disabled by default. Toggle it with /shs toggle mmoitems-weight.

- Several default values were lowered so the plugin feels less aggressive out of the box

- The entire config.yml was rewritten with plain English comments explaining every setting, what the values mean, and how they change gameplay. No more guessing.

- Messages.yml got the same treatment with better section headers and placeholder documentation.

- Config.yml formatting was cleaned up, removed extra blank lines.

- The hunger and hunger-bar settings were merged into one option called hunger.mode. You pick between overflow, bar, or disabled. Before this update they were two separate toggles and you could accidentally turn both on at the same time, which made them fight over the food bar. Now it's a single picker so that can't happen. The GUI shows this properly too, toggling one mode shows the other as off. Commands still work the same way: /shs toggle hunger turns on overflow mode, /shs toggle hunger-bar turns on bar mode, running either again sets it to disabled.

- All action settings (sprint, jump, swim, shield, elytra, climbing, eating, mace, potion modifiers, damage intake, boat, crawling, riptide, tool use, powder snow, slime bounce, soul sand, honey block, winded, water contact, lava contact, sneak, idle regen, and regen action cooldown) were moved out of config.yml into their own actions.yml file. Config.yml is way shorter now and all the action tuning lives in one place. Commands, GUI, and toggles still work exactly the same.

- ConfigManager default fallback values now match the shipped config.yml. If a config key was missing before, the code silently used older, harsher defaults instead of the intended ones.

- Eight more default mismatches were fixed. Idle regen defaulted to 0.3 instead of 0.4, regen action cooldown to 1500ms instead of 2000ms, slowness amplifier to 1 (Slowness II) instead of 0, stumble chance to 5% instead of 3%, overexertion scaling divisor to 10 instead of 8, and bow/crossbow/trident costs all had wrong fallbacks. If your config ever got deleted or a key was missing, you would have gotten wrong values without knowing.

- The /shs config set idle regen-action-cooldown command was writing to the wrong path. It wrote to actions.idle.regen-action-cooldown instead of actions.regen-action-cooldown. It looked like it worked but the change never took effect.

- Jump stamina drain could spike after extended jumping. Jumps happening faster than the cooldown would pile up in a hidden counter instead of being tossed out. When the cooldown expired, all the stacked jumps drained at once. Now they're properly discarded.

- Auto-stop sprint at 0 stamina could fail if you were attacking or placing blocks at the same time. The sprint stop timer shared a timestamp with other actions, so doing anything would reset the check. Sprint stopping has its own timer now.

- Encumbrance slowness could accidentally replace a stronger slowness from another system. If exhaustion gave you Slowness II and encumbrance only wanted Slowness I, it would overwrite with the weaker one. Now it only applies if it's genuinely stronger.

- Switching to creative mode while encumbered left the slowness hanging for up to two seconds. The game mode handler cleaned up exhaustion effects but forgot about encumbrance slowness, biome freeze, and darkness. All plugin effects are properly stripped now when you go creative or spectator.

- Plugin reload and server shutdown could leave encumbrance slowness, biome freeze, and darkness stuck on players briefly. Both now clean up properly before stopping.

- The plugin now warns on startup if both hunger and hunger-bar are enabled, since they conflict with each other.

- Stamina drain could silently fail if another plugin cancelled the MMOCore resource event. The plugin thought the drain went through, letting players do stuff for free. Now it checks before and after stamina to verify drains actually happened, and overflows to hunger correctly when they're blocked.

- Hunger overflow could miscalculate if another plugin modified the drain through MMOCore's event system. A skill reducing the cost via setAmount() wouldn't be accounted for in the overflow math. Now it calculates from the actual stamina difference.

- Max stamina was read through a different path than what MMOCore uses internally. Usually the same, but with attribute modifiers or class changes it could disagree, making the plugin think a player had a different max. Now it uses the same stat resolution as MMOCore.

- Players joining the server could get phantom stamina effects for about half a second while MMOCore loads their data. Stamina reads as 0 during that window, which falsely triggered sprint stopping, overexertion, and exhaustion effects. The plugin now waits until MMOCore confirms the data is ready.

- Citizens NPCs or other fake players with no MMOCore data could spam warnings in console. All MMOCore calls now check if data exists before trying to use it.

- The MMOItems double-drain hook tried to access unloaded player data, which could fail silently for players still loading in. Now checks before accessing.

- Holding space bar let players auto-jump for free. The old detection based on velocity and ground checks every few ticks missed the rapid jumps. Now it tracks jumps via the server's built-in statistic so every single one is counted and charged.

- The jump cooldown was letting fast jumps through without charging. Since detection now counts exact jumps instead of polling, the cooldown was removed entirely. Every real jump costs stamina.

- Toggling hunger and hunger-bar at the same time through the GUI no longer breaks things. One turns the other off automatically with a chat warning.

- All 39 toggle items in the GUI now have a short description so you know what each one actually does.

- The /weight info command shows total weight of stacked items now. Holding 32 cobblestone shows the per-item weight times 32 instead of just one piece.

- Encumbrance slowness could leak onto mounted players. Riding a horse while carrying too much would still slow you down even though you're not walking. Skipped entirely while mounted now.

- Knockback from damage could falsely trigger movement-based drains for a split second. The position change from getting knocked around looked like running, causing a tiny burst of stamina loss. There's a half-second suppression window after taking damage now.

- The eating regen toggle and value paths were internally mismatched, so toggling it from GUI or commands could silently fail. Fixed with the configuration restructure.

- Overexertion damage could feed back into itself. The plugin uses player.damage() to hurt overexerting players, but the fall damage and damage intake handlers would pick that up as real damage, updating internal timestamps and potentially draining extra stamina on top. Both handlers now recognize plugin-caused damage and ignore it.

- Disabling the plugin, reloading config, or switching to creative mode used to strip all slowness and darkness from a player, even if it came from a potion, beacon, or another plugin. Now it only removes effects with very short durations that match what the plugin applies. If you had a long Slowness potion active, it stays.

- The exhaustion effect cleanup checked whether effects were enabled in config before removing them. If you toggled slowness off while a player already had it, they'd keep the slowness forever until they relogged. Cleanup now always removes regardless of the current toggle state.

- Altitude drain math used hardcoded 320 for world ceiling and -64 for world floor. Custom dimensions or datapacks with different world height limits would get completely wrong scaling. Now it reads the actual world height and minimum from the world itself.

- Water contact and lava contact drain were both gated behind the swim bypass permission. A player given soapsstamina.bypass.swim to skip swimming drain also skipped standing-in-water and standing-in-lava drain, which are separate mechanics. Each one has its own permission now: soapsstamina.bypass.water-contact and soapsstamina.bypass.lava-contact. Both were added to plugin.yml.

- Using an Eye of Ender on an End portal frame block drained stamina as if you threw it into the sky. It now only triggers on right-click-air, so inserting eyes into portal frames costs nothing.

- Critical hit detection for the winded system only checked if the attacker was falling. In vanilla, sprinting also guarantees a critical hit, but sprint-crits weren't being counted as crits. Players could sprint-attack and avoid the critical winded tier entirely. Now both falling and sprinting are checked.

- Sweat particles from hot biomes and exhaustion, and snowflake particles from cold biomes, were spawned through the world and visible to every nearby player. If ten players stood together, each one would see nine other people's particle effects on top of their own. Now particles are sent only to the affected player.

- The biome type cycle in the GUI went Cold, Hot, Cold with no way to set a biome back to Neutral. If you accidentally changed a neutral biome to cold, you had to edit the file manually. The cycle is now Cold, Hot, Neutral, Cold.

- Tab completion hints for /shs config set always showed 0 for weight.yml settings instead of the actual current value. The hint lookup was only checking config.yml. Now it reads from weight.yml when the setting lives there.

- The dead jump cooldown config entry was still in the /shs config set command list and the debug log even though the cooldown was removed. Cleaned up so it doesn't confuse anyone poking around in commands or logs.

- Seven tracking fields left over from the old jump detection and state-tracking systems were sitting in every player's profile doing nothing. Removed to keep things tidy.

- The fall damage handler updated the last-damage timestamp even for the plugin's own overexertion damage, which would extend the knockback movement suppression window when it shouldn't have.

- Three bypass permissions that the code already checked for were missing from plugin.yml: soapsstamina.bypass.overexertion, soapsstamina.bypass.winded, and soapsstamina.bypass.idle. Permission plugins like LuckPerms couldn't see them, so admins had no way to discover or assign them through the permission UI. All three are registered now.

- Double semicolon typo in the message loading code. Harmless, but cleaned up.

- The stamina engine caches the player's location, the block at their feet, and the block below them once per tick now. Before, powder snow, slime bounce, soul sand, honey block, and biome detection each did their own lookup, up to seven per player per tick. Down to two.

- Biome lookups for drain multipliers, passive drain, category, and effects were each independently fetching the biome. Four redundant lookups per tick. All share one cached biome now.

- The movement and winded systems each called System.currentTimeMillis() on their own even though the timestamp was already stored. Both reuse the same cached one now.

- Weight.yml was being loaded from disk every single time the plugin needed to read a value during gameplay. Checking armor weight, item weight, or any weight setting meant a full file parse. Now it's cached in memory after the first load and only refreshed on plugin reload or after a settings change.

- All deprecated API calls were removed. Registry.BIOME (deprecated since 1.21.3) was replaced with Paper's RegistryAccess. Player.isOnGround() (deprecated for being client-sent and unreliable) was replaced with the Entity version. MMOCore's old isFullyLoaded(), setStamina(double), giveStamina(double, UpdateReason), and UpdateReason enum were all swapped for the modern versions: isSessionReady(), setStamina with ResourceUpdateReason, giveStamina with ResourceUpdateReason, and the ResourceUpdateReason class from MythicLib. Zero deprecation warnings.

- MythicLib dependency was updated from 1.6.2 to 1.7.1 to stay compatible with the latest MMOCore snapshot.

- The plugin compiles against Paper 1.21.11 and works with Minecraft 26.1.1. No code changes were needed for the new version format.

- Deep Dark, Pale Garden, and Swamp were added to the default biome config. Deep Dark and Pale Garden are set as cold, Swamp as hot. They were missing from the defaults even though the biome system already supported them if you added them yourself.

- Biome config comments were improved with short syntax examples and a note that all vanilla biomes from any Minecraft version are supported.

- The "Jump Cooldown (ms)" slider was still sitting in the Action Settings GUI page, reading and writing to a config path that no longer exists. Clicking it did absolutely nothing since the jump cooldown was removed in the first round of fixes. The slider, the dead actions.yml entry (cooldown: 300 under the jump section), and the matching messages.yml label have all been scrubbed out.

- The removePluginPotionEffects method (the one that strips only short-duration slowness and darkness when switching to creative or reloading) was copy-pasted identically in both the main plugin class and the player listener. Same constant, same logic, duplicated across two files. Consolidated into one shared method in the main class so future changes only need to happen in one place.

- BiomeManager had four convenience methods that accepted a Player and internally looked up their biome before calling the real method. The stamina engine already resolves the biome once per tick and passes it directly, so none of these Player-accepting overloads were ever called. All four were removed to cut the dead code.

- The Java fallback defaults for cold-passive-drain and hot-passive-drain were out of sync with the values shipped in config.yml. If someone's config was missing those keys, the code would silently use 0.5 and 0.4 instead of the intended 0.6 and 0.5. Now the fallback values match exactly what's in the default config.

- Tab completion for /shs config set was showing nothing as the current value hint for every action-related setting (sprint, jump, swim, attack, and all the others in actions.yml). The hint lookup was reading from config.yml instead of actions.yml, so it always came back null. Now it correctly reads the actual current value from actions.yml.

- Eating food in hunger-bar mode gave stamina twice. The eating-regen handler gave a flat amount, and then the food-level-change handler also converted the food gain into stamina on top of that. Players were getting both payouts stacked. The eating-regen handler now skips entirely when hunger-bar mode is active since the food-level converter already handles it.

- Cold passive drain and hot passive drain were missing from the /shs config set biomes command. You could see them in the GUI and they worked in gameplay, but there was no way to adjust them through commands. Both are registered now.

- Swim slowness bonus and container weight were missing from /shs weight encumbrance. Both exist in weight.yml and work during gameplay, but the command didn't know about them. Added swim-slowness-bonus (integer) and container-weight (boolean) to the encumbrance key list.

- The hunger conflict warning message was loaded from messages.yml but never actually sent anywhere. When toggling hunger mode on while hunger-bar was already active (or vice versa), the mode would silently switch with no feedback. Now both the /shs toggle command and the GUI toggle send the warning message telling the admin the other mode was automatically disabled.

- The overexertion damage tick message was loaded from messages.yml but never used. When a player was taking ongoing overexertion damage, they only got the initial "your body is breaking down" message and then silence while damage kept ticking. Now they get a periodic reminder every 3 seconds ("your muscles tear from the strain") so they know the damage hasn't stopped.

- 16 action values were invisible in the GUI. The Action Settings page only had room for 21 items but there are 37 total action values. Everything past winded regen lock (elytra drain, climbing drain, eating regen, mace cost, speed multiplier, haste multiplier, damage intake, boat drain, crawling drain, riptide cost, hoe cost, shears cost, brush cost, powder snow drain, slime bounce cost, soul sand multiplier, and honey block multiplier) could never be seen or adjusted through the admin panel. The page now has proper pagination with arrow buttons at the bottom, same as the toggle page.

- Dying with the BossBar UI active left a ghost stamina bar stuck on screen after death. The death handler was resetting internal tracking and clearing exhaustion effects, but it never told the UI system to hide the bar. It also didn't remove plugin-applied potion effects (slowness, darkness) or clear biome freeze ticks. All three are properly cleaned up on death now, matching what already happened when switching to creative mode.

- Tab completion for /shs weight encumbrance container-weight was suggesting numbers (1, 2, 5, 10) instead of true/false. The hint logic only checked for block-sprint-severe as a boolean key, missing container-weight entirely. Both boolean encumbrance keys now get the correct true/false suggestions.

- Lowering the exhaustion slowness amplifier in config left the old stronger slowness stuck on players. The cleanup method compared the player's current slowness amplifier against the config value, so if you changed it from Slowness II down to Slowness I, the old Slowness II was ignored because 2 > 1 and the check said "not mine." Now it uses duration instead of amplifier to identify plugin-applied effects, consistent with how potion cleanup works everywhere else.

- The biome type cycle lore in the GUI said "Click to cycle: Cold / Hot" but the actual cycle goes Cold, Hot, Neutral. If you didn't know Neutral was an option you'd never find it. Updated to show all three.

- The stagger expiry message (telling a player the regen lock from a critical winded hit has ended) used a fragile timing window that could miss entirely if the server tick was delayed. It compared timestamps within a narrow margin and any lag spike wider than 50ms would silently swallow the message. Replaced with a proper flag that gets set the moment the lock expires and consumed when the message is sent, so it never gets lost.

- Using a hoe or brush near certain Paper edge cases could throw a null pointer error. The tool use handler assumed the clicked block was always non-null on a RIGHT_CLICK_BLOCK action, but Paper can occasionally send a null in specific conditions. Added a guard check.

- Player tracking state wasn't fully reset on death or gamemode change. The expected food level and sprint stop timer from before the event were carried over, which could cause brief false positives in food interference detection or sprint stopping on the first tick after respawning. Both are properly cleared now.

- plugin.yml was still claiming version 1.0.4 even though V1.0.5 shipped with fixes. Updated to 1.0.6.

- The exhaustion effect cleanup was ripping darkness off players unconditionally. If you had a darkness potion from a Warden, a deep dark shrine, or another plugin, recovering from exhaustion would strip it instantly. The slowness cleanup already checked duration before removing, but darkness skipped that check entirely. Now it only removes darkness with a short duration matching what the plugin applies, same as slowness.

- Altitude drain math could divide by zero and produce infinite or NaN drain values. If the high altitude threshold was set equal to the world ceiling, or the low threshold equal to the world floor, the scaling formula divided by zero. This affected both the altitude drain multiplier and the passive altitude drain, four separate calculations total. All four now check for a zero range and default to full multiplier instead of crashing the math.

- Damage intake was ignoring all entity attacks even when winded was disabled. The handler had a blanket check that skipped every EntityDamageByEntityEvent to avoid double-counting with the winded system. But if winded was toggled off, entity attack damage was silently dropped with no stamina cost at all. Now the skip only applies when winded is actually enabled, so turning off winded lets damage-intake pick up melee hits properly.

- Dropping items to go from severely encumbered to just encumbered gave the player zero feedback. The transition message code checked if the player was newly encumbered, but going from severe to normal-encumbered didn't count as "newly encumbered" since the encumbered flag was already set during severe. Players had no idea their weight status changed. Now there's a dedicated check for the severe-to-encumbered downgrade that sends the encumbered message.

- The winded toggle description in the GUI said "Axe hits cause extra drain and stagger" which is wrong. Winded triggers on any entity attack, not just axes. Updated to "Getting hit causes stamina drain and stagger" to match what the system actually does.

- Setting overexertion scaling-divisor to 0 through commands was possible even though the GUI enforced a minimum of 1. With a divisor of 0, the scaling formula silently skipped, leaving only the base damage with no indication anything was wrong. The config loader now clamps the value to at least 1.0 so the math always works.

- The three parallel arrays that define GUI toggle items (definitions, icons, and lore text) had no validation that they stayed the same length. Adding a toggle to one array and forgetting the others would cause an ArrayIndexOutOfBoundsException at runtime with no useful error message. The GUI now checks array lengths on startup and logs a clear error if they're mismatched.

- Leaving a cold biome left freeze ticks to decay naturally through vanilla mechanics instead of clearing them immediately. Walking into a neutral biome from a frozen one meant you'd stay visually frozen for several seconds while the ticks ticked down. Now freeze ticks are zeroed the moment you leave a cold biome, whether you walk into a hot biome or a neutral one.

- Dying or switching to creative mode didn't reset the UI message cooldown timer. If you died right after a stamina update, the UI wouldn't show again for the full cooldown duration after respawning. The cooldown timer is now cleared along with everything else in the tracking reset.

- The MMOItems double-drain detection was fundamentally broken. It compared a player's current stamina against the stamina recorded at their previous attack, which could be several seconds earlier. Any stamina lost between attacks from sprinting, swimming, or any other SHS drain made the hook think MMOItems had already consumed stamina for the new attack. Players who were active between attacks regularly got free melee hits because the plugin skipped its own drain when it shouldn't have. The detection now snapshots stamina immediately before and after each MythicLib attack event so it only sees stamina changes caused by that specific attack.

- MMOItems AoE weapons and multi-target abilities only suppressed the SHS drain for the first entity hit. MMOItems fires one attack event but Minecraft fires a separate damage event per target. The hook was consuming its record on the first check, so the second and third targets got drained by SHS on top of whatever MMOItems already charged. The record now stays active for the full grace window so all hits from the same attack are correctly handled.

- Event-based stamina drains (block place, block break, melee attack, bow shot, winded, damage intake, riptide, tool use, and everything else triggered by player events) didn't check whether MMOCore had finished loading the player's data. During the brief window right after login, drains silently failed because MMOCore returned zero stamina, but the plugin still marked the action as having happened. This poisoned the regen cooldown timer and let players perform actions for free until the next engine tick noticed. All event handlers now wait for MMOCore data to be ready before processing.

- The hunger-bar food interceptor had the same missing check. If a player ate food in hunger-bar mode before MMOCore data loaded, the food level change was cancelled (food lost) but the stamina conversion did nothing because max stamina read as zero. The brief login window could eat a food item with no benefit. Now it lets vanilla handle the food normally until data is ready.

- If MythicLib's PlayerAttackEvent class was missing or renamed in a different version, creating the MMOItems hook would throw a hard error that crashed the entire plugin on startup. MMOItems is listed as a soft dependency so this should never take down the whole plugin. The hook creation is now wrapped in a safety catch that logs a warning and continues without MMOItems support.

- Shield blocking now has a minimum stamina threshold. When a player's stamina drops to or below the configured minimum (default 1.0), the shield is forcefully lowered so players can't hide behind a shield at zero stamina indefinitely. The threshold is adjustable in actions.yml under shield-block.min-stamina.

- Taking damage while actively blocking with a shield now costs extra stamina on top of the regular shield drain. Every hit absorbed while blocking drains a configurable amount (default 0.8). This makes tanking hits with a shield a real stamina commitment. Adjustable in actions.yml under shield-block.damage-cost.

- Shield block default costs were lowered. The initial raise cost went from 0.6 to 0.3 and the per-second drain from 0.3 to 0.15. Shields were too punishing out of the box for how common they are.

- Boat paddling default drain was lowered from 0.3 to 0.1 per second. Boats are a basic travel method and the old cost made long river trips unpleasant.

- Flint and steel now costs stamina when used. It was completely free before even though hoes, shears, and brushes all had costs. Default cost is 0.15, adjustable in actions.yml under tool-use.flint-and-steel-cost.

- Running /shs reload printed two messages to the console: one from the reload method itself and one from the command handler that called it. The redundant internal message was removed so reloading only shows one confirmation.

- The eating-regen feature was removed entirely. It gave a flat stamina boost every time a player ate food, but this is redundant since the hunger system already handles stamina recovery through food. Having both meant players could double-dip on stamina from eating, especially in overflow mode. The toggle, config setting, GUI slider, bypass permission, and /shs config set command were all cleaned out.

- actions.yml got a full formatting pass. All actions are now grouped into clear sections (Movement, Combat, Interactions, Environment, Recovery) with box-drawn headers so you can find what you're looking for without scrolling through the whole file. Every single action now lists its bypass permission in the comment directly above it, so you don't have to cross-reference plugin.yml anymore. A few comments were tightened up or corrected — the jump section no longer mentions a cooldown that doesn't exist, winded says "Taking Hits" instead of "Taking Damage" to avoid confusion with the separate damage-intake system, and the damage-intake description now explains that entity attacks fall through to it when winded is disabled. No values or keys were changed, just the comments and layout.

- Biome config restructured. The freeze, sweat, and freeze-particles settings were floating as siblings next to cold and hot in the biomes section, which was confusing since they directly belong to those biome types. Freeze and freeze-particles are now nested under cold, and sweat is nested under hot. If you've customized these values, you'll need to move them to their new location under the matching biome type. Config paths changed from biomes.freeze.* to biomes.cold.freeze.*, biomes.sweat.* to biomes.hot.sweat.*, and biomes.freeze-particles.* to biomes.cold.freeze-particles.*. The GUI toggles and /shs toggle commands adjust automatically.

- ConfigManager was loading freeze-particles settings into its own fields even though BiomeManager already reads and uses those values directly. The duplicate fields, config loading, and unused getter methods were removed. No behavior change, just less dead code.

- BiomeManager had two identical methods for classifying a biome: getBiomeCategory and getCategoryOf. Both did the exact same set lookup. getCategoryOf now delegates to getBiomeCategory instead of duplicating the logic.