Update: the current implementation can be found by scrolling down to http://forums.bukkit.org/threads/ex...-exp-a-bit-more-intuitive.54450/#post-1128846 - however, it's well worth reading the whole thread to understand some of the issues involved with exp handling in Minecraft & Bukkit. Anyone who's worked with the Bukkit experience API knows that it's a little... odd, although to be fair to the Bukkit team, Mojang need to take the blame for that. The pre-1.0 system is deprecated now, and definitely shouldn't be used for any new plugin development, or indeed any plugin that wants to work with MC 1.0. But the current exp method, player.giveExp() has its own problems: Giving a large amount of exp levels the players in unexpected ways. See Dinnerbone's comment in https://bukkit.atlassian.net/browse/BUKKIT-47 for an explanation of this. Giving a negative amount of exp causes unexpected client behaviour if the player's level decreases due to loss of exp (the client's exp bar doesn't update properly, and the Bukkit player.getLevel() and player.getExp() methods don't return what you might expect). player.getTotalExperience() is unaware of exp loss due to item enchanting. I should give credit to nisovin here for spotting and correcting that problem in my initial implementation. So I created this class: https://github.com/desht/ScrollingM...t/scrollingmenusign/util/ExperienceUtils.java https://github.com/desht/dhutils/bl.../java/me/desht/dhutils/ExperienceManager.java The class creates a private static exp lookup table, mapping levels to the experience needed to attain that level. The calculation is based on observations in https://bukkit.atlassian.net/browse/BUKKIT-47 and corroborated by my own observations and one other user (@hatstand). 0 xp = level 0 7 xp = level 1 17 xp = level 2 31 xp = level 3 48 xp = level 4 ... Each time, the incremement between levels goes up by either 3 or 4, depending on whether or not it's an even or odd level. So the increment is 7, 10, 14, 17, 21 ... Obviously the correctness of this table is critical to the correctness of the whole class, so I'd appreciate any feedback on that! Updated: July 5th 2012 to describe the new API Example usage: PHP: ExperienceManager expMan = new ExperienceManager(player); // give the player 10 expexpMan.changeExp(10);// take 20 exp awayexpMan.changeExp(-20);// set the total exp to 100expMan.setExp(100);// show how much experience the player hasSystem.out.println(expMan.getPlayer().getName() + " has " + expMan.getCurrentExp() + " XP"); As you can see, you create an ExperienceManager object on a player, and then use its methods to manage the player's experience levels. The central methods in ExperienceManager are changeExp() and setExp() - changeExp() adds or subtracts from the player's current experience total, and setExp() sets is to an absolute value. There's also getCurrentExp() to retrieve the player's current experience total, and a few more helper methods. They're all documented (Javadoc) in the source for the class, linked above. The player's correct level is recalculated whenever necessary (this uses a O(log n) binary chop on the lookup tables, so is reasonably efficient; doubling the lookup table size means one extra iteration to find the right level), so it doesn't matter if the player has been levelled up or down by several levels - the client's exp bar should always show the right level and distance through the level. This also avoids the need to loop and give 1 xp at a time to work around Minecraft's bizarre levelling behaviour. These objects cache the player's name, and a weak reference to the Player object. They're primarily intended to be short-lived, but it's OK for them to be long-lived (i.e. beyond the scope of a single method) as long as you're prepared to catch an IllegalStateException, meaning the player that the object was created on is no longer available (logged out). Anybody who wishes is free to use the ExperienceManager class in their own plugin, I'd only request the "@author desht" annotation remains intact if you take a copy. The code is licensed under the LGPL - I'm not imposing any special licensing requirements on your plugin if you use the code, but if you modify and distribute the class itself, please ensure the source of any modifications is published too (and ideally fed back to me). Oh, and please change the class's package if you pull it into your own plugin Don't leave it as as me.desht.dhutils, or you'll end up causing conflicts should later versions of the class be released with different method signatures!