diff --git a/connector/src/main/java/org/geysermc/connector/registry/AbstractMappedRegistry.java b/connector/src/main/java/org/geysermc/connector/registry/AbstractMappedRegistry.java
index 034eef706..c5c7cf87f 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/AbstractMappedRegistry.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/AbstractMappedRegistry.java
@@ -27,21 +27,54 @@ package org.geysermc.connector.registry;
 
 import org.geysermc.connector.registry.loader.RegistryLoader;
 
+import javax.annotation.Nullable;
 import java.util.Map;
 
-public abstract class AbstractMappedRegistry<K, V, C extends Map<K, V>> extends Registry<C> {
-    protected <I> AbstractMappedRegistry(I input, RegistryLoader<I, C> registryLoader) {
+/**
+ * An abstract registry holding a map of various registrations as defined by {@link M}.
+ * The M represents the map class, which can be anything that extends {@link Map}. The
+ * {@link K} and {@link V} generics are the key and value respectively.
+ *
+ * @param <K> the key
+ * @param <V> the value
+ * @param <M> the map
+ */
+public abstract class AbstractMappedRegistry<K, V, M extends Map<K, V>> extends Registry<M> {
+    protected <I> AbstractMappedRegistry(I input, RegistryLoader<I, M> registryLoader) {
         super(input, registryLoader);
     }
 
+    /**
+     * Returns the value registered by the given key.
+     *
+     * @param key the key
+     * @return the value registered by the given key.
+     */
+    @Nullable
     public V get(K key) {
         return this.mappings.get(key);
     }
 
+    /**
+     * Returns the value registered by the given key or the default value
+     * specified if null.
+     *
+     * @param key the key
+     * @param defaultValue the default value
+     * @return the value registered by the given key or the default value
+     *         specified if null.
+     */
     public V getOrDefault(K key, V defaultValue) {
         return this.mappings.getOrDefault(key, defaultValue);
     }
 
+    /**
+     * Registers a new value into this registry with the given key.
+     *
+     * @param key the key
+     * @param value the value
+     * @return a new value into this registry with the given key.
+     */
     public V register(K key, V value) {
         return this.mappings.put(key, value);
     }
diff --git a/connector/src/main/java/org/geysermc/connector/registry/BlockRegistries.java b/connector/src/main/java/org/geysermc/connector/registry/BlockRegistries.java
index bc92f4b93..0b5b2bf8d 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/BlockRegistries.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/BlockRegistries.java
@@ -36,6 +36,9 @@ import org.geysermc.connector.registry.populator.BlockRegistryPopulator;
 import org.geysermc.connector.registry.type.BlockMapping;
 import org.geysermc.connector.registry.type.BlockMappings;
 
+/**
+ * Holds all the block registries in Geyser.
+ */
 public class BlockRegistries {
     public static final VersionedRegistry<BlockMappings> BLOCKS = VersionedRegistry.create(RegistryLoaders.empty(Int2ObjectOpenHashMap::new));
 
diff --git a/connector/src/main/java/org/geysermc/connector/registry/MappedRegistry.java b/connector/src/main/java/org/geysermc/connector/registry/MappedRegistry.java
index 41d831f98..523024ab3 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/MappedRegistry.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/MappedRegistry.java
@@ -30,28 +30,78 @@ import org.geysermc.connector.registry.loader.RegistryLoader;
 import java.util.Map;
 import java.util.function.Supplier;
 
-public class MappedRegistry<K, V, C extends Map<K, V>> extends AbstractMappedRegistry<K, V, C> {
-    protected <I> MappedRegistry(I input, RegistryLoader<I, C> registryLoader) {
+/**
+ * An public registry holding a map of various registrations as defined by {@link M}.
+ * The M represents the map class, which can be anything that extends {@link Map}. The
+ * {@link K} and {@link V} generics are the key and value respectively.
+ *
+ * @param <K> the key
+ * @param <V> the value
+ * @param <M> the map
+ */
+public class MappedRegistry<K, V, M extends Map<K, V>> extends AbstractMappedRegistry<K, V, M> {
+    protected <I> MappedRegistry(I input, RegistryLoader<I, M> registryLoader) {
         super(input, registryLoader);
     }
 
-    public static <I, K, V, C extends Map<K, V>> MappedRegistry<K, V, C> createEmpty() {
-        return new MappedRegistry<>(null, input -> null);
-    }
-
-    public static <I, K, V, C extends Map<K, V>> MappedRegistry<K, V, C> create(RegistryLoader<I, C> registryLoader) {
+    /**
+     * Creates a new mapped registry with the given {@link RegistryLoader}. The
+     * input type is not specified here, meaning the loader return type is either
+     * predefined, or the registry is populated at a later point.
+     *
+     * @param registryLoader the registry loader
+     * @param <I> the input
+     * @param <K> the map key
+     * @param <V> the map value
+     * @param <M> the returned mappings type, a map in this case
+     * @return a new registry with the given RegistryLoader
+     */
+    public static <I, K, V, M extends Map<K, V>> MappedRegistry<K, V, M> create(RegistryLoader<I, M> registryLoader) {
         return new MappedRegistry<>(null, registryLoader);
     }
 
-    public static <I, K, V, C extends Map<K, V>> MappedRegistry<K, V, C> create(I input, RegistryLoader<I, C> registryLoader) {
+    /**
+     * Creates a new mapped registry with the given {@link RegistryLoader} and input.
+     *
+     * @param input the input
+     * @param registryLoader the registry loader
+     * @param <I> the input
+     * @param <K> the map key
+     * @param <V> the map value
+     * @param <M> the returned mappings type, a map in this case
+     * @return a new registry with the given RegistryLoader
+     */
+    public static <I, K, V, M extends Map<K, V>> MappedRegistry<K, V, M> create(I input, RegistryLoader<I, M> registryLoader) {
         return new MappedRegistry<>(input, registryLoader);
     }
 
-    public static <I, K, V, C extends Map<K, V>> MappedRegistry<K, V, C> create(Supplier<RegistryLoader<I, C>> registryLoader) {
+    /**
+     * Creates a new mapped registry with the given {@link RegistryLoader} supplier.
+     * The input type is not specified here, meaning the loader return type is either
+     * predefined, or the registry is populated at a later point.
+     *
+     * @param registryLoader the registry loader supplier
+     * @param <I> the input
+     * @param <K> the map key
+     * @param <V> the map value
+     * @param <M> the returned mappings type, a map in this case
+     * @return a new registry with the given RegistryLoader supplier
+     */
+    public static <I, K, V, M extends Map<K, V>> MappedRegistry<K, V, M> create(Supplier<RegistryLoader<I, M>> registryLoader) {
         return new MappedRegistry<>(null, registryLoader.get());
     }
 
-    public static <I, K, V, C extends Map<K, V>> MappedRegistry<K, V, C> create(I input, Supplier<RegistryLoader<I, C>> registryLoader) {
+    /**
+     * Creates a new mapped registry with the given {@link RegistryLoader} and input.
+     *
+     * @param registryLoader the registry loader
+     * @param <I> the input
+     * @param <K> the map key
+     * @param <V> the map value
+     * @param <M> the returned mappings type, a map in this case
+     * @return a new registry with the given RegistryLoader supplier
+     */
+    public static <I, K, V, M extends Map<K, V>> MappedRegistry<K, V, M> create(I input, Supplier<RegistryLoader<I, M>> registryLoader) {
         return new MappedRegistry<>(input, registryLoader.get());
     }
 }
\ No newline at end of file
diff --git a/connector/src/main/java/org/geysermc/connector/registry/Registries.java b/connector/src/main/java/org/geysermc/connector/registry/Registries.java
index 6a0498a79..e3adb2e16 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/Registries.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/Registries.java
@@ -52,6 +52,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+/**
+ * Holds all the common registries in Geyser.
+ */
 public class Registries {
     public static final SimpleRegistry<NbtMap> BIOMES = SimpleRegistry.create("bedrock/biome_definitions.dat", RegistryLoaders.NBT);
 
diff --git a/connector/src/main/java/org/geysermc/connector/registry/Registry.java b/connector/src/main/java/org/geysermc/connector/registry/Registry.java
index ca3d22373..0e999442f 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/Registry.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/Registry.java
@@ -29,17 +29,71 @@ import org.geysermc.connector.registry.loader.RegistryLoader;
 
 import java.util.function.Consumer;
 
+/**
+ * A wrapper around a value which is loaded based on the output from the provided
+ * {@link RegistryLoader}. This class is primarily designed to hold a registration
+ * of some kind, however no limits are set on what it can hold, as long as the
+ * specified RegistryLoader returns the same value type that is specified in the
+ * generic.
+ *
+ * <p>
+ * Below, a RegistryLoader is taken in the constructor. RegistryLoaders have two
+ * generic types: the input, and the output. The input is what it takes in, whether
+ * it be a string which references to a file, or nothing more than an integer. The
+ * output is what it generates based on the input, and should be the same type as
+ * the {@link M} generic specified in the registry.
+ *
+ * <p>
+ * Registries can be very simple to create. Here is an example that simply parses a
+ * number given a string:
+ *
+ * <pre>
+ * {@code
+ *     public static final SimpleRegistry<Integer> STRING_TO_INT = SimpleRegistry.create("5", Integer::parseInt);
+ * }
+ * </pre>
+ *
+ * <p>
+ * This is a simple example which really wouldn't have much of a practical use,
+ * however it demonstrates a fairly basic use case of how this system works. Typically
+ * though, the first parameter would be a location of some sort, such as a file path
+ * where the loader will load the mappings from. The NBT registry is a good reference
+ * point for something both simple and practical. See {@link Registries#BIOMES} and
+ * {@link org.geysermc.connector.registry.loader.NbtRegistryLoader}.
+ *
+ * @param <M> the value being held by the registry
+ */
 public abstract class Registry<M> {
     protected final M mappings;
 
+    /**
+     * Creates a new instance of this class with the given input and
+     * {@link RegistryLoader}. The input specified is what the registry
+     * loader needs to take in.
+     *
+     * @param input the input
+     * @param registryLoader the registry loader
+     * @param <I> the input type
+     */
     protected <I> Registry(I input, RegistryLoader<I, M> registryLoader) {
         this.mappings = registryLoader.load(input);
     }
 
+    /**
+     * Gets the underlying value held by this registry.
+     *
+     * @return the underlying value held by this registry.
+     */
     public M get() {
         return this.mappings;
     }
 
+    /**
+     * Registers what is specified in the given
+     * {@link Consumer} into the underlying value.
+     *
+     * @param consumer the consumer
+     */
     public void register(Consumer<M> consumer) {
         consumer.accept(this.mappings);
     }
diff --git a/connector/src/main/java/org/geysermc/connector/registry/SimpleMappedRegistry.java b/connector/src/main/java/org/geysermc/connector/registry/SimpleMappedRegistry.java
index 1188b3590..938450014 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/SimpleMappedRegistry.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/SimpleMappedRegistry.java
@@ -30,23 +30,72 @@ import org.geysermc.connector.registry.loader.RegistryLoader;
 import java.util.Map;
 import java.util.function.Supplier;
 
+/**
+ * A variant of {@link AbstractMappedRegistry} with {@link Map} as the defined type. Unlike
+ * {@link MappedRegistry}, this registry does not support specifying your own Map class,
+ * and only permits operations the {@link Map} interface does, unless you manually cast.
+ *
+ * @param <K> the key
+ * @param <V> the value
+ */
 public class SimpleMappedRegistry<K, V> extends AbstractMappedRegistry<K, V, Map<K, V>> {
     protected <I> SimpleMappedRegistry(I input, RegistryLoader<I, Map<K, V>> registryLoader) {
         super(input, registryLoader);
     }
 
+    /**
+     * Creates a new mapped registry with the given {@link RegistryLoader}. The
+     * input type is not specified here, meaning the loader return type is either
+     * predefined, or the registry is populated at a later point.
+     *
+     * @param registryLoader the registry loader
+     * @param <I> the input
+     * @param <K> the map key
+     * @param <V> the map value
+     * @return a new registry with the given RegistryLoader
+     */
     public static <I, K, V> SimpleMappedRegistry<K, V> create(RegistryLoader<I, Map<K, V>> registryLoader) {
         return new SimpleMappedRegistry<>(null, registryLoader);
     }
 
+    /**
+     * Creates a new mapped registry with the given {@link RegistryLoader} and input.
+     *
+     * @param input the input
+     * @param registryLoader the registry loader
+     * @param <I> the input
+     * @param <K> the map key
+     * @param <V> the map value
+     * @return a new registry with the given RegistryLoader
+     */
     public static <I, K, V> SimpleMappedRegistry<K, V> create(I input, RegistryLoader<I, Map<K, V>> registryLoader) {
         return new SimpleMappedRegistry<>(input, registryLoader);
     }
 
+    /**
+     * Creates a new mapped registry with the given {@link RegistryLoader} supplier.
+     * The input type is not specified here, meaning the loader return type is either
+     * predefined, or the registry is populated at a later point.
+     *
+     * @param registryLoader the registry loader supplier
+     * @param <I> the input
+     * @param <K> the map key
+     * @param <V> the map value
+     * @return a new registry with the given RegistryLoader supplier
+     */
     public static <I, K, V> SimpleMappedRegistry<K, V> create(Supplier<RegistryLoader<I, Map<K, V>>> registryLoader) {
         return new SimpleMappedRegistry<>(null, registryLoader.get());
     }
 
+    /**
+     * Creates a new mapped registry with the given {@link RegistryLoader} and input.
+     *
+     * @param registryLoader the registry loader
+     * @param <I> the input
+     * @param <K> the map key
+     * @param <V> the map value
+     * @return a new registry with the given RegistryLoader supplier
+     */
     public static <I, K, V> SimpleMappedRegistry<K, V> create(I input, Supplier<RegistryLoader<I, Map<K, V>>> registryLoader) {
         return new SimpleMappedRegistry<>(input, registryLoader.get());
     }
diff --git a/connector/src/main/java/org/geysermc/connector/registry/SimpleRegistry.java b/connector/src/main/java/org/geysermc/connector/registry/SimpleRegistry.java
index 1bea97954..16bf24f79 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/SimpleRegistry.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/SimpleRegistry.java
@@ -29,23 +29,69 @@ import org.geysermc.connector.registry.loader.RegistryLoader;
 
 import java.util.function.Supplier;
 
+/**
+ * A simple registry with no defined mapping or input type. Designed to allow
+ * for simple registrations of any given type without restrictions on what
+ * the input or output can be.
+ *
+ * @param <M> the value being held by the registry
+ */
 public class SimpleRegistry<M> extends Registry<M> {
     private <I> SimpleRegistry(I input, RegistryLoader<I, M> registryLoader) {
         super(input, registryLoader);
     }
 
+    /**
+     * Creates a new registry with the given {@link RegistryLoader} supplier. The
+     * input type is not specified here, meaning the loader return type is either
+     * predefined, or the registry is populated at a later point.
+     *
+     * @param registryLoader the registry loader supplier
+     * @param <I> the input type
+     * @param <M> the returned mappings type
+     * @return a new registry with the given RegistryLoader supplier
+     */
     public static <I, M> SimpleRegistry<M> create(Supplier<RegistryLoader<I, M>> registryLoader) {
         return new SimpleRegistry<>(null, registryLoader.get());
     }
 
+    /**
+     * Creates a new registry with the given {@link RegistryLoader} supplier
+     * and input.
+     *
+     * @param input the input
+     * @param registryLoader the registry loader supplier
+     * @param <I> the input type
+     * @param <M> the returned mappings type
+     * @return a new registry with the given RegistryLoader supplier
+     */
     public static <I, M> SimpleRegistry<M> create(I input, Supplier<RegistryLoader<I, M>> registryLoader) {
         return new SimpleRegistry<>(input, registryLoader.get());
     }
 
+    /**
+     * Creates a new registry with the given {@link RegistryLoader}. The
+     * input type is not specified here, meaning the loader return type is either
+     * predefined, or the registry is populated at a later point.
+     *
+     * @param registryLoader the registry loader
+     * @param <I> the input type
+     * @param <M> the returned mappings type
+     * @return a new registry with the given RegistryLoader supplier
+     */
     public static <I, M> SimpleRegistry<M> create(RegistryLoader<I, M> registryLoader) {
         return new SimpleRegistry<>(null, registryLoader);
     }
 
+    /**
+     * Creates a new registry with the given {@link RegistryLoader} and input.
+     *
+     * @param input the input
+     * @param registryLoader the registry loader
+     * @param <I> the input type
+     * @param <M> the returned mappings type
+     * @return a new registry with the given RegistryLoader supplier
+     */
     public static <I, M> SimpleRegistry<M> create(I input, RegistryLoader<I, M> registryLoader) {
         return new SimpleRegistry<>(input, registryLoader);
     }
diff --git a/connector/src/main/java/org/geysermc/connector/registry/VersionedRegistry.java b/connector/src/main/java/org/geysermc/connector/registry/VersionedRegistry.java
index 7bdc372ed..91b969df3 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/VersionedRegistry.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/VersionedRegistry.java
@@ -28,13 +28,32 @@ package org.geysermc.connector.registry;
 import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import org.geysermc.connector.registry.loader.RegistryLoader;
 
+import java.util.Map;
 import java.util.function.Supplier;
 
+/**
+ * A versioned, mapped registry. Like {@link SimpleMappedRegistry}, the {@link Map} interface is
+ * not able to be specified here, but unlike it, it does not have support for specialized
+ * instances, and ONLY supports {@link Int2ObjectMap} for optimal performance to prevent boxing
+ * of integers.
+ *
+ * @param <V> the value
+ */
 public class VersionedRegistry<V> extends AbstractMappedRegistry<Integer, V, Int2ObjectMap<V>> {
     protected <I> VersionedRegistry(I input, RegistryLoader<I, Int2ObjectMap<V>> registryLoader) {
         super(input, registryLoader);
     }
 
+    /**
+     * Gets the closest value for the specified version. Only
+     * returns versions higher up than the specified if one
+     * does not exist for the given one. Useful in the event
+     * that you want to get a resource which is guaranteed for
+     * older versions, but not on newer ones.
+     *
+     * @param version the version
+     * @return the closest value for the specified version
+     */
     public V forVersion(int version) {
         V value = null;
         for (Int2ObjectMap.Entry<V> entry : this.mappings.int2ObjectEntrySet()) {
@@ -49,18 +68,54 @@ public class VersionedRegistry<V> extends AbstractMappedRegistry<Integer, V, Int
         return value;
     }
 
+    /**
+     * Creates a new versioned registry with the given {@link RegistryLoader}. The
+     * input type is not specified here, meaning the loader return type is either
+     * predefined, or the registry is populated at a later point.
+     *
+     * @param registryLoader the registry loader
+     * @param <I> the input
+     * @param <V> the map value
+     * @return a new registry with the given RegistryLoader
+     */
     public static <I, V> VersionedRegistry<V> create(RegistryLoader<I, Int2ObjectMap<V>> registryLoader) {
         return new VersionedRegistry<>(null, registryLoader);
     }
 
+    /**
+     * Creates a new versioned registry with the given {@link RegistryLoader} and input.
+     *
+     * @param registryLoader the registry loader
+     * @param <I> the input
+     * @param <V> the map value
+     * @return a new registry with the given RegistryLoader
+     */
     public static <I, V> VersionedRegistry<V> create(I input, RegistryLoader<I, Int2ObjectMap<V>> registryLoader) {
         return new VersionedRegistry<>(input, registryLoader);
     }
 
+    /**
+     * Creates a new versioned registry with the given {@link RegistryLoader} supplier.
+     * The input type is not specified here, meaning the loader return type is either
+     * predefined, or the registry is populated at a later point.
+     *
+     * @param registryLoader the registry loader
+     * @param <I> the input
+     * @param <V> the map value
+     * @return a new registry with the given RegistryLoader supplier
+     */
     public static <I, V> VersionedRegistry< V> create(Supplier<RegistryLoader<I, Int2ObjectMap<V>>> registryLoader) {
         return new VersionedRegistry<>(null, registryLoader.get());
     }
 
+    /**
+     * Creates a new versioned registry with the given {@link RegistryLoader} supplier and input.
+     *
+     * @param registryLoader the registry loader
+     * @param <I> the input
+     * @param <V> the map value
+     * @return a new registry with the given RegistryLoader supplier
+     */
     public static <I, V> VersionedRegistry< V> create(I input, Supplier<RegistryLoader<I, Int2ObjectMap<V>>> registryLoader) {
         return new VersionedRegistry<>(input, registryLoader.get());
     }
diff --git a/connector/src/main/java/org/geysermc/connector/registry/loader/AnnotatedRegistryLoader.java b/connector/src/main/java/org/geysermc/connector/registry/loader/AnnotatedRegistryLoader.java
index 4f6354af5..483bb773b 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/loader/AnnotatedRegistryLoader.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/loader/AnnotatedRegistryLoader.java
@@ -34,6 +34,26 @@ import java.lang.annotation.Annotation;
 import java.util.Map;
 import java.util.function.Function;
 
+/**
+ * A mapped registry loader which takes in a {@link String} and returns a transformed
+ * {@link Annotation} as the value. The {@link R} represents the final result as mapped
+ * by the {@link A}, the annotation. This function exists in this registry loader for
+ * the purpose of annotations not often being used as a map key. The {@link V} generic
+ * represents the actual map value of what is expected. The function transformation done
+ * is used for transforming the key, however the value is not expected to be transformed.
+ *
+ * <p>
+ * Keep in mind that this annotation transforming does NOT need to be done, and can be
+ * replaced with a simple <code>Function.identity()</code> if not desired.
+ *
+ * <p>
+ * See {@link BlockEntityRegistryLoader} and {@link SoundHandlerRegistryLoader} as a
+ * good example of these registry loaders in use.
+ *
+ * @param <R> the final result as transformed by the function
+ * @param <A> the raw annotation itself can be transformed
+ * @param <V> the value
+ */
 public class AnnotatedRegistryLoader<R, A extends Annotation, V> implements RegistryLoader<String, Map<R, V>> {
     private final Class<A> annotation;
     private final Function<A, R> mapper;
diff --git a/connector/src/main/java/org/geysermc/connector/registry/loader/BlockEntityRegistryLoader.java b/connector/src/main/java/org/geysermc/connector/registry/loader/BlockEntityRegistryLoader.java
index 6824d611d..a58cca7ca 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/loader/BlockEntityRegistryLoader.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/loader/BlockEntityRegistryLoader.java
@@ -28,6 +28,9 @@ package org.geysermc.connector.registry.loader;
 import org.geysermc.connector.network.translators.world.block.entity.BlockEntity;
 import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator;
 
+/**
+ * Loads block entities from the given classpath.
+ */
 public class BlockEntityRegistryLoader extends AnnotatedRegistryLoader<String, BlockEntity, BlockEntityTranslator> {
     public BlockEntityRegistryLoader() {
         super(BlockEntity.class, BlockEntity::name);
diff --git a/connector/src/main/java/org/geysermc/connector/registry/loader/CollisionRegistryLoader.java b/connector/src/main/java/org/geysermc/connector/registry/loader/CollisionRegistryLoader.java
index 70ba8b253..3b342fba8 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/loader/CollisionRegistryLoader.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/loader/CollisionRegistryLoader.java
@@ -48,6 +48,9 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.regex.Pattern;
 
+/**
+ * Loads collision data from the given resource path.
+ */
 public class CollisionRegistryLoader extends MultiResourceRegistryLoader<String, Map<Integer, BlockCollision>> {
 
     @Override
diff --git a/connector/src/main/java/org/geysermc/connector/registry/loader/EffectRegistryLoader.java b/connector/src/main/java/org/geysermc/connector/registry/loader/EffectRegistryLoader.java
index 5e9e435f3..0dc5345d1 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/loader/EffectRegistryLoader.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/loader/EffectRegistryLoader.java
@@ -33,6 +33,11 @@ import java.io.InputStream;
 import java.util.Map;
 import java.util.WeakHashMap;
 
+/**
+ * An abstract registry loader for loading effects from a resource path.
+ *
+ * @param <T> the value
+ */
 public abstract class EffectRegistryLoader<T> implements RegistryLoader<String, T> {
     private static final Map<String, JsonNode> loadedFiles = new WeakHashMap<>();
 
diff --git a/connector/src/main/java/org/geysermc/connector/registry/loader/MultiResourceRegistryLoader.java b/connector/src/main/java/org/geysermc/connector/registry/loader/MultiResourceRegistryLoader.java
index a2bb23696..48076d791 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/loader/MultiResourceRegistryLoader.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/loader/MultiResourceRegistryLoader.java
@@ -27,5 +27,11 @@ package org.geysermc.connector.registry.loader;
 
 import it.unimi.dsi.fastutil.Pair;
 
+/**
+ * A RegistryLoader that loads data from two different locations, yet with the same input type.
+ *
+ * @param <I> the input type
+ * @param <V> the value
+ */
 public abstract class MultiResourceRegistryLoader<I, V> implements RegistryLoader<Pair<I, I>, V> {
 }
\ No newline at end of file
diff --git a/connector/src/main/java/org/geysermc/connector/registry/loader/NbtRegistryLoader.java b/connector/src/main/java/org/geysermc/connector/registry/loader/NbtRegistryLoader.java
index 773ee1038..b8ec65697 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/loader/NbtRegistryLoader.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/loader/NbtRegistryLoader.java
@@ -32,6 +32,9 @@ import org.geysermc.connector.utils.FileUtils;
 
 import java.io.InputStream;
 
+/**
+ * Loads NBT data from the given resource path.
+ */
 public class NbtRegistryLoader implements RegistryLoader<String, NbtMap> {
 
     @Override
diff --git a/connector/src/main/java/org/geysermc/connector/registry/loader/ParticleTypesRegistryLoader.java b/connector/src/main/java/org/geysermc/connector/registry/loader/ParticleTypesRegistryLoader.java
index 3c3188236..4284506f9 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/loader/ParticleTypesRegistryLoader.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/loader/ParticleTypesRegistryLoader.java
@@ -34,6 +34,9 @@ import org.geysermc.connector.registry.type.ParticleMapping;
 import java.util.Iterator;
 import java.util.Map;
 
+/**
+ * Loads particle types from the given resource path.
+ */
 public class ParticleTypesRegistryLoader extends EffectRegistryLoader<Map<ParticleType, ParticleMapping>> {
 
     @Override
diff --git a/connector/src/main/java/org/geysermc/connector/registry/loader/RegistryLoader.java b/connector/src/main/java/org/geysermc/connector/registry/loader/RegistryLoader.java
index 495895789..f10b143aa 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/loader/RegistryLoader.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/loader/RegistryLoader.java
@@ -26,12 +26,22 @@
 package org.geysermc.connector.registry.loader;
 
 /**
- * Represents a registry loader.
+ * Represents a registry loader. {@link I} is the input value, which can be anything,
+ * but is commonly a file path or something similar. {@link O} represents the output
+ * type returned by this, which can also be anything. See {@link NbtRegistryLoader}
+ * as a good and simple example of how this system works.
  *
  * @param <I> the input to load the registry from
  * @param <O> the output of the registry
  */
 @FunctionalInterface
 public interface RegistryLoader<I, O> {
+
+    /**
+     * Loads an output from the given input.
+     *
+     * @param input the input
+     * @return the output
+     */
     O load(I input);
 }
\ No newline at end of file
diff --git a/connector/src/main/java/org/geysermc/connector/registry/loader/RegistryLoaders.java b/connector/src/main/java/org/geysermc/connector/registry/loader/RegistryLoaders.java
index 9a9634157..22fe0bb1d 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/loader/RegistryLoaders.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/loader/RegistryLoaders.java
@@ -27,10 +27,24 @@ package org.geysermc.connector.registry.loader;
 
 import java.util.function.Supplier;
 
+/**
+ * Holds common {@link RegistryLoader}s or utility methods surrounding them.
+ */
 public class RegistryLoaders {
+    /**
+     * The {@link RegistryLoader} responsible for loading NBT.
+     */
     public static NbtRegistryLoader NBT = new NbtRegistryLoader();
 
-    public static <V> RegistryLoader<Object, V> empty(Supplier<V> value) {
-        return input -> value.get();
+    /**
+     * Wraps the surrounding {@link Supplier} in a {@link RegistryLoader} which does
+     * not take in any input value.
+     *
+     * @param supplier the supplier
+     * @param <V> the value
+     * @return a RegistryLoader wrapping the given Supplier
+     */
+    public static <V> RegistryLoader<Object, V> empty(Supplier<V> supplier) {
+        return input -> supplier.get();
     }
 }
\ No newline at end of file
diff --git a/connector/src/main/java/org/geysermc/connector/registry/loader/SoundEffectsRegistryLoader.java b/connector/src/main/java/org/geysermc/connector/registry/loader/SoundEffectsRegistryLoader.java
index 8103ece8b..22070ee7a 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/loader/SoundEffectsRegistryLoader.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/loader/SoundEffectsRegistryLoader.java
@@ -39,6 +39,9 @@ import org.geysermc.connector.network.translators.effect.SoundLevelEffect;
 import java.util.Iterator;
 import java.util.Map;
 
+/**
+ * Loads sound effects from the given resource path.
+ */
 public class SoundEffectsRegistryLoader extends EffectRegistryLoader<Map<SoundEffect, Effect>> {
 
     @Override
diff --git a/connector/src/main/java/org/geysermc/connector/registry/loader/SoundHandlerRegistryLoader.java b/connector/src/main/java/org/geysermc/connector/registry/loader/SoundHandlerRegistryLoader.java
index 42c10c2ce..110cd2c3b 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/loader/SoundHandlerRegistryLoader.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/loader/SoundHandlerRegistryLoader.java
@@ -30,6 +30,9 @@ import org.geysermc.connector.network.translators.sound.SoundInteractionHandler;
 
 import java.util.function.Function;
 
+/**
+ * Loads sound handlers from the given classpath.
+ */
 public class SoundHandlerRegistryLoader extends AnnotatedRegistryLoader<SoundHandler, SoundHandler, SoundInteractionHandler<?>> {
     public SoundHandlerRegistryLoader() {
         super(SoundHandler.class, Function.identity());
diff --git a/connector/src/main/java/org/geysermc/connector/registry/loader/SoundRegistryLoader.java b/connector/src/main/java/org/geysermc/connector/registry/loader/SoundRegistryLoader.java
index 4dc1dab58..b78947189 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/loader/SoundRegistryLoader.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/loader/SoundRegistryLoader.java
@@ -36,11 +36,14 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 
+/**
+ * Loads sounds from the given input.
+ */
 public class SoundRegistryLoader implements RegistryLoader<String, Map<String, SoundMapping>> {
 
     @Override
     public Map<String, SoundMapping> load(String input) {
-        InputStream stream  = FileUtils.getResource("mappings/sounds.json");
+        InputStream stream  = FileUtils.getResource(input);
         JsonNode soundsTree;
         try {
             soundsTree = GeyserConnector.JSON_MAPPER.readTree(stream);
diff --git a/connector/src/main/java/org/geysermc/connector/registry/populator/BlockRegistryPopulator.java b/connector/src/main/java/org/geysermc/connector/registry/populator/BlockRegistryPopulator.java
index 305e89a15..c119967fa 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/populator/BlockRegistryPopulator.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/populator/BlockRegistryPopulator.java
@@ -52,6 +52,9 @@ import java.util.Map;
 import java.util.function.BiFunction;
 import java.util.zip.GZIPInputStream;
 
+/**
+ * Populates the block registries.
+ */
 public class BlockRegistryPopulator {
     private static final ImmutableMap<String, BiFunction<String, NbtMapBuilder, String>> STATE_MAPPER;
 
diff --git a/connector/src/main/java/org/geysermc/connector/registry/populator/ItemRegistryPopulator.java b/connector/src/main/java/org/geysermc/connector/registry/populator/ItemRegistryPopulator.java
index 4715b6915..d495121c6 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/populator/ItemRegistryPopulator.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/populator/ItemRegistryPopulator.java
@@ -57,6 +57,9 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.*;
 
+/**
+ * Populates the item registries.
+ */
 public class ItemRegistryPopulator {
     private static final Map<String, PaletteVersion> PALETTE_VERSIONS;
 
diff --git a/connector/src/main/java/org/geysermc/connector/registry/populator/RecipeRegistryPopulator.java b/connector/src/main/java/org/geysermc/connector/registry/populator/RecipeRegistryPopulator.java
index 97eeccece..4533ecc6a 100644
--- a/connector/src/main/java/org/geysermc/connector/registry/populator/RecipeRegistryPopulator.java
+++ b/connector/src/main/java/org/geysermc/connector/registry/populator/RecipeRegistryPopulator.java
@@ -54,6 +54,9 @@ import java.util.*;
 
 import static org.geysermc.connector.utils.InventoryUtils.LAST_RECIPE_NET_ID;
 
+/**
+ * Populates the recipe registry.
+ */
 public class RecipeRegistryPopulator {
 
     public static void populate() {