### Fixed - A mistyped or missing effect argument no longer throws out of the enchant. The offending value is logged once, that effect falls back to a default, and the remaining effects on the enchant still run. Previously a single bad argument aborted the whole enchant, and could abort the event that triggered it. - An effect chance of 100 now always procs. The roll was made against 1-101, so a "guaranteed" enchant actually fired about 99% of the time. - Deactivating a HELD enchant no longer errors on effects written as `TYPE;EFFECT`, and no longer runs the wrong effect when the type does not match. Deactivation now mirrors activation exactly. - An enchant now reports that it ran if *any* of its effects ran. Only the last effect counted before, so a held enchant ending in a type-gated effect was never tracked and its deactivation never fired. - EXPLODE no longer shields the caster from the *next* explosion instead of the one it just created, and no longer accumulates caster IDs forever. - RAIN applied one player's radius, damage and mode to every other player's falling blocks. Each volley now carries its own settings. - ROT_DECAY's decay roll damages armor again; it was subtracting durability, which repairs it. It also no longer errors on empty armor slots or when the summoner has logged off. - ROT_DECAY's damaging floor tiles are cleaned up. The cleanup pass looked for a different key than the one stored, so tiles stayed lethal indefinitely. - HIDE_PLAYER added one tracking entry per online player on every proc. - HEALTH now restores the vanilla maximum when the holder quits; the boost was never recorded, so the quit handler could not act on it. - REDUCE_HEARTS now actually blocks regeneration for its duration. Entries were only ever removed from the tracking list, never added. - KNOCKBACK on PLAYER produced an invalid velocity and did nothing. The AMOUNT was also cancelled out by normalising after scaling, so it had no effect on either selector. - IMMUNE's ALL type had no behaviour and never blocked anything. - DROP_HEAD gave creepers an enderman-skinned head. - FIREBALL ignored its AMOUNT argument and always fired one, unattributed fireball. Damage is now credited to the caster. - Reversed or equal min/max ranges no longer throw in HEAL, DAMAGE, FOOD and WRATH; the range is rolled either way round. - REDUCE_HEARTS, FOOD and FEED no longer error when the configured amount falls outside the entity's valid health or hunger range. - Enchants with a soul cost no longer error when triggered by a non-player. - BREAK_TREE walks the tree iteratively and stops at 512 blocks, instead of recursing until the stack runs out on a large canopy. - Nineteen places compared UUIDs by identity rather than value, so effects such as SPAWN, RAIN, DROPS and EXP could silently fail to recognise their own owner. - THROW, ARMOR_CANCEL and RAIN no longer retain entries indefinitely when the event they were waiting for never arrives. ### Changed - Effect strings are parsed once and reused instead of being split on every activation, taking that work out of the combat and mining paths. - An effect that throws is now isolated and logged once, rather than taking the rest of the enchant and its event down with it. - The PLAYER/TARGET selector is consistent across every effect: TARGET selects the target, anything else selects the player. Effects previously disagreed on what an unrecognised value meant. - FROST, ROT_DECAY and WEB send their fake blocks only to players near enough to see them, rather than to everyone online. - DAMAGE_ARC searched a box the square of its radius wide and discarded almost all of it; it now searches the radius it was given. - DAMAGE_INCREASE applies to any projectile the caster fired, not only arrows. - Re-procing FLY extends the flight instead of letting the earlier timer end it early, and RAGE's decay window refreshes on each hit. - SMELT and TELEPORT_DROPS must be listed before TRENCH to apply to the whole cube. This was already true; it is now documented in the code.