diff --git a/Java/src/main/java/net/hypixel/api/util/IGuildLeveling.java b/Java/src/main/java/net/hypixel/api/util/IGuildLeveling.java
new file mode 100644
index 00000000..2c59cae5
--- /dev/null
+++ b/Java/src/main/java/net/hypixel/api/util/IGuildLeveling.java
@@ -0,0 +1,159 @@
+package net.hypixel.api.util;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public interface IGuildLeveling {
+
+ // TODO: 6/6/20 Finish javadocs and add examples
+
+ /**
+ * An unmodifiable list containing the experience needed to get from each level to the next. For
+ * example, the value at index 0 is the amount of guild experience needed to progress from guild
+ * level 0 to 1. The value at index 7 is the guild exp needed to progress from level 7 -> 8.
+ * Etc.
+ *
+ * The last element in this list is the value used for any levels beyond the size of this list.
+ * For example, if this list has 15 values, then the last value is used for levels 14 -> 15 and
+ * any levels after that.
+ */
+ List EXP_NEEDED = Collections.unmodifiableList(Arrays.asList(
+ 100000, // Lvl 0 -> Lvl 1
+ 150000, // Lvl 1 -> Lvl 2
+ 250000, // Lvl 2 -> Lvl 3
+ 500000, // Etc
+ 750000,
+ 1000000,
+ 1250000,
+ 1500000,
+ 2000000,
+ 2500000,
+ 2500000,
+ 2500000,
+ 2500000,
+ 2500000,
+ 3000000
+ ));
+
+ /**
+ * The last value in {@link #EXP_NEEDED}. This represents exp difference between any two levels
+ * >= {@link #EXP_NEEDED}.size() - 1.
+ *
+ * @see #EXP_NEEDED
+ */
+ int MAX_EXP_NEEDED = EXP_NEEDED.get(EXP_NEEDED.size() - 1);
+
+ /**
+ * This method returns the full level of a guild with that amount of guild experience. This
+ * method does not take into account the guild's progress to the next level, but will return an
+ * integer representing the last whole guild level reached by the guild. If the experience
+ * parameter is less than 0, an {@link IllegalArgumentException} will be thrown.
+ *
+ * @param exp The total experience gathered by a guild; should be >= 0
+ * @return An integer representing the guild's current whole level
+ */
+ static double getLevel(double exp) {
+ if (exp < 0) {
+ throw new IllegalArgumentException("Experience value must be >= 0");
+ }
+
+ for (int level = 0; ; level++) {
+ double needed = getExpFromLevelToNext(level);
+ exp -= needed;
+
+ if (exp < 0) {
+ return level;
+ }
+ }
+ }
+
+ /**
+ * This method returns the precise guild level for that amount of guild experience. This is the
+ * equivalent of adding up the result of {@link #getLevel(double)} and {@link
+ * #getPercentageToNextLevel(double)}. The value returned by this method is a floating point
+ * number greater than or equal to 0, representing the guild's previse level. If the experience
+ * parameter is less than 0, an {@link IllegalArgumentException} may be thrown.
+ *
+ * @param exp The total experience gathered by a guild; should be >= 0
+ * @return Exact level of a guild with that much experience
+ */
+ static double getExactLevel(double exp) {
+ return getLevel(exp) + getPercentageToNextLevel(exp);
+ }
+
+ /**
+ * This method returns the amount of experience needed to go from that level to the next. If the
+ * level parameter is less than 0, an {@link IllegalArgumentException} will be thrown.
+ *
+ * @param level The starting level
+ * @return The amount of guild exp needed to progress from that level to the next level
+ * @see #EXP_NEEDED
+ * @see #MAX_EXP_NEEDED
+ */
+ static double getExpFromLevelToNext(double level) {
+ if (level < 0) {
+ throw new IllegalArgumentException("Level value must be >= 0");
+ }
+
+ return level >= EXP_NEEDED.size() ? MAX_EXP_NEEDED : EXP_NEEDED.get((int) level);
+ }
+
+ /**
+ * This method returns the amount of guild experience needed to reach a precise level. For
+ * example, passing in a level of 10.5 will return the amount of exp needed for level 10 plus
+ * half the amount of exp needed between levels 10 and 11. If the level parameter is less than
+ * 0, an {@link IllegalArgumentException} may be thrown.
+ *
+ * @param level The precise level reached with the returned amount of experience; should be >=
+ * 0
+ * @return The total experience needed to reach that precise level
+ */
+ static double getTotalExpToLevel(double level) {
+ double progress = level - (int) level;
+ return getTotalExpToFullLevel(level) + (progress * getExpFromLevelToNext(level));
+ }
+
+ /**
+ * This method returns the total amount of exp needed for a guild to reach a whole level
+ * (integer). For example, if a guild had 0 experience, this method would return how much
+ * experience they would need before they reached level 5.0. If the level parameter is less than
+ * 0, an {@link IllegalArgumentException} may be thrown.
+ *
+ * @param level The level reached with the returned amount of exp; should be an integer
+ * @return The total amount of experience needed to reach that level
+ */
+ static double getTotalExpToFullLevel(double level) {
+ double expNeeded = 0;
+
+ for (int i = 0; i < (int) level; i++) {
+ expNeeded += getExpFromLevelToNext(i);
+ }
+
+ return expNeeded;
+ }
+
+ /**
+ * This method returns a guild's current progress to the next level as a floating-point number
+ * between 0 (inclusively) and 1 (exclusively). For example, if a guild has an experience value
+ * exactly halfway between the exp needed for their current level (floored) and the exp needed
+ * for the next level (floored), this method will return 0.5. If the experience parameter is
+ * less than 0, an {@link IllegalArgumentException} will be thrown.
+ *
+ * @param exp The total experience gathered by a guild; should be >= 0
+ * @return The guild's progress to the next level as a percentage between 0 and 1
+ */
+ static double getPercentageToNextLevel(double exp) {
+ if (exp < 0) {
+ throw new IllegalArgumentException("Experience value must be >= 0");
+ }
+
+ double currentLvl = getLevel(exp);
+ // Exp needed for the current whole level (excluding progress)
+ double totalExpForCurrentLvl = getTotalExpToFullLevel(currentLvl);
+ // Exp diff between current whole level and next whole level
+ double expToNextLvl = getExpFromLevelToNext(currentLvl);
+
+ return (exp - (totalExpForCurrentLvl)) / expToNextLvl;
+ }
+}