diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml
index bea51a6e6..bf5972f2f 100644
--- a/.github/workflows/pullrequest.yml
+++ b/.github/workflows/pullrequest.yml
@@ -19,6 +19,8 @@ jobs:
         uses: actions/setup-java@v1
         with:
           java-version: 1.8
+      - name: submodules-init
+        uses: snickerbockers/submodules-init@v4
       - name: Build with Maven
         run: mvn -B package
       - name: Archive artifacts
diff --git a/api/pom.xml b/api/pom.xml
index a0cbdf87f..6d4e1c856 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -10,12 +10,6 @@
     </parent>
     <artifactId>api</artifactId>
     <dependencies>
-        <dependency>
-            <groupId>org.projectlombok</groupId>
-            <artifactId>lombok</artifactId>
-            <version>1.18.4</version>
-            <scope>compile</scope>
-        </dependency>
         <dependency>
             <groupId>com.google.code.gson</groupId>
             <artifactId>gson</artifactId>
diff --git a/common/pom.xml b/common/pom.xml
index 9a972bf22..cd96ad23a 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -9,56 +9,4 @@
         <version>1.0-SNAPSHOT</version>
     </parent>
     <artifactId>common</artifactId>
-    <dependencies>
-        <dependency>
-            <groupId>org.projectlombok</groupId>
-            <artifactId>lombok</artifactId>
-            <version>1.18.4</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.github.steveice10</groupId>
-            <artifactId>opennbt</artifactId>
-            <version>1.3-SNAPSHOT</version>
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.github.steveice10</groupId>
-            <artifactId>packetlib</artifactId>
-            <version>1.4-SNAPSHOT</version>
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.github.steveice10</groupId>
-            <artifactId>mcauthlib</artifactId>
-            <version>1.1-SNAPSHOT</version>
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.github.steveice10</groupId>
-            <artifactId>mcprotocollib</artifactId>
-            <version>1.14.4-SNAPSHOT</version>
-            <scope>compile</scope>
-            <exclusions>
-                <exclusion>
-                    <groupId>com.github.steveice10</groupId>
-                    <artifactId>opennbt</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>com.github.steveice10</groupId>
-                    <artifactId>packetlib</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>com.github.steveice10</groupId>
-                    <artifactId>mcauthlib</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
-            <groupId>com.auth0</groupId>
-            <artifactId>java-jwt</artifactId>
-            <version>3.3.0</version>
-            <scope>compile</scope>
-        </dependency>
-    </dependencies>
 </project>
\ No newline at end of file
diff --git a/connector/pom.xml b/connector/pom.xml
index 60ecfc557..b7a97863e 100644
--- a/connector/pom.xml
+++ b/connector/pom.xml
@@ -44,7 +44,6 @@
             <groupId>net.minecrell</groupId>
             <artifactId>terminalconsoleappender</artifactId>
             <version>1.0.0</version>
-            <type>jar</type>
             <scope>compile</scope>
         </dependency>
         <dependency>
@@ -59,12 +58,6 @@
             <version>1.6.4</version>
             <scope>compile</scope>
         </dependency>
-        <dependency>
-            <groupId>org.projectlombok</groupId>
-            <artifactId>lombok</artifactId>
-            <version>1.18.4</version>
-            <scope>provided</scope>
-        </dependency>
         <dependency>
             <groupId>org.fusesource.jansi</groupId>
             <artifactId>jansi</artifactId>
@@ -74,7 +67,7 @@
         <dependency>
             <groupId>com.nukkitx.protocol</groupId>
             <artifactId>bedrock-v388</artifactId>
-            <version>2.4.0</version>
+            <version>2.4.2</version>
             <scope>compile</scope>
         </dependency>
         <dependency>
@@ -129,7 +122,7 @@
         </dependency>
     </dependencies>
     <build>
-        <finalName>${outputName}-noshade</finalName>
+        <finalName>${project.parent.name}-noshade</finalName>
         <directory>../target</directory>
         <plugins>
             <plugin>
@@ -147,7 +140,7 @@
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-javadoc-plugin</artifactId>
                 <configuration>
-                    <finalName>${outputName}</finalName>
+                    <finalName>${project.parent.name}</finalName>
                 </configuration>
             </plugin>
             <plugin>
@@ -162,7 +155,7 @@
                     </execution>
                 </executions>
                 <configuration>
-                    <finalName>${outputName}</finalName>
+                    <finalName>${project.parent.name}</finalName>
                     <shadedArtifactAttached>true</shadedArtifactAttached>
                     <minimizeJar>true</minimizeJar>
                 </configuration>
diff --git a/connector/src/main/java/org/geysermc/connector/entity/ArrowEntity.java b/connector/src/main/java/org/geysermc/connector/entity/ArrowEntity.java
new file mode 100644
index 000000000..1c70a1429
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/ArrowEntity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class ArrowEntity extends Entity {
+
+    public ArrowEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/Entity.java b/connector/src/main/java/org/geysermc/connector/entity/Entity.java
index ba9fe4ab3..e348e1aa7 100644
--- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java
+++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java
@@ -34,6 +34,8 @@ import com.nukkitx.protocol.bedrock.data.EntityDataDictionary;
 import com.nukkitx.protocol.bedrock.data.EntityFlag;
 import com.nukkitx.protocol.bedrock.data.EntityFlags;
 import com.nukkitx.protocol.bedrock.packet.*;
+import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
+import it.unimi.dsi.fastutil.longs.LongSet;
 import lombok.Getter;
 import lombok.Setter;
 import org.geysermc.connector.console.GeyserLogger;
@@ -62,14 +64,14 @@ public class Entity {
      */
     protected Vector3f rotation;
 
-    protected int scale = 1;
+    protected float scale = 1;
     protected boolean movePending;
 
     protected EntityType entityType;
 
     protected boolean valid;
 
-    protected Set<Long> passengers = new HashSet<>();
+    protected LongSet passengers = new LongOpenHashSet();
     protected Map<AttributeType, Attribute> attributes = new HashMap<>();
     protected EntityDataDictionary metadata = new EntityDataDictionary();
 
@@ -176,7 +178,11 @@ public class Entity {
                     metadata.getFlags().setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08);
                     metadata.getFlags().setFlag(EntityFlag.SWIMMING, (xd & 0x10) == 0x10);
                     metadata.getFlags().setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80);
-                    metadata.getFlags().setFlag(EntityFlag.INVISIBLE, (xd & 0x20) == 0x20);
+                    // metadata.getFlags().setFlag(EntityFlag.INVISIBLE, (xd & 0x20) == 0x20);
+                    if ((xd & 0x20) == 0x20)
+                        metadata.put(EntityData.SCALE, 0.01f);
+                    else
+                        metadata.put(EntityData.SCALE, scale);
                 }
                 break;
             case 2: // custom name
diff --git a/connector/src/main/java/org/geysermc/connector/entity/ItemedFireballEntity.java b/connector/src/main/java/org/geysermc/connector/entity/ItemedFireballEntity.java
new file mode 100644
index 000000000..f3008c12c
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/ItemedFireballEntity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class ItemedFireballEntity extends Entity {
+
+    public ItemedFireballEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java b/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java
new file mode 100644
index 000000000..052e9e98b
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity;
+
+import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
+import com.nukkitx.math.vector.Vector3f;
+import com.nukkitx.protocol.bedrock.data.EntityData;
+import com.nukkitx.protocol.bedrock.data.ItemData;
+import com.nukkitx.protocol.bedrock.packet.MobArmorEquipmentPacket;
+import lombok.Getter;
+import lombok.Setter;
+import org.geysermc.connector.entity.type.EntityType;
+import org.geysermc.connector.network.session.GeyserSession;
+
+@Getter
+@Setter
+public class LivingEntity extends Entity {
+
+    protected ItemData helmet;
+    protected ItemData chestplate;
+    protected ItemData leggings;
+    protected ItemData boots;
+    protected ItemData hand = ItemData.of(0, (short) 0, 0);
+
+    public LivingEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+
+    @Override
+    public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
+        switch (entityMetadata.getId()) {
+            case 8:
+                metadata.put(EntityData.HEALTH, (float) entityMetadata.getValue());
+                break;
+            case 9:
+                metadata.put(EntityData.POTION_COLOR, (int) entityMetadata.getValue());
+                break;
+            case 10:
+                // metadata.put(EntityData.POTION_AMBIENT, (boolean) entityMetadata.getValue());
+                break;
+        }
+
+        super.updateBedrockMetadata(entityMetadata, session);
+    }
+
+    public void updateEquipment(GeyserSession session) {
+        if (!valid)
+            return;
+
+        MobArmorEquipmentPacket armorEquipmentPacket = new MobArmorEquipmentPacket();
+        armorEquipmentPacket.setRuntimeEntityId(geyserId);
+        armorEquipmentPacket.setHelmet(helmet);
+        armorEquipmentPacket.setChestplate(chestplate);
+        armorEquipmentPacket.setLeggings(leggings);
+        armorEquipmentPacket.setBoots(boots);
+
+        session.getUpstream().sendPacket(armorEquipmentPacket);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/MinecartEntity.java b/connector/src/main/java/org/geysermc/connector/entity/MinecartEntity.java
new file mode 100644
index 000000000..4d4fab4dc
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/MinecartEntity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class MinecartEntity extends Entity {
+
+    public MinecartEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java
index 67393114c..afcc45052 100644
--- a/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java
+++ b/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java
@@ -27,9 +27,7 @@ package org.geysermc.connector.entity;
 
 import com.github.steveice10.mc.auth.data.GameProfile;
 import com.nukkitx.math.vector.Vector3f;
-import com.nukkitx.protocol.bedrock.data.ItemData;
 import com.nukkitx.protocol.bedrock.packet.AddPlayerPacket;
-import com.nukkitx.protocol.bedrock.packet.MobArmorEquipmentPacket;
 import com.nukkitx.protocol.bedrock.packet.PlayerListPacket;
 import lombok.Getter;
 import lombok.Setter;
@@ -41,19 +39,13 @@ import org.geysermc.connector.utils.SkinUtils;
 import java.util.UUID;
 
 @Getter @Setter
-public class PlayerEntity extends Entity {
+public class PlayerEntity extends LivingEntity {
     private GameProfile profile;
     private UUID uuid;
     private String username;
     private long lastSkinUpdate = -1;
     private boolean playerList = true;
 
-    private ItemData helmet;
-    private ItemData chestplate;
-    private ItemData leggings;
-    private ItemData boots;
-    private ItemData hand = ItemData.of(0, (short) 0, 0);
-
     public PlayerEntity(GameProfile gameProfile, long entityId, long geyserId, Vector3f position, Vector3f motion, Vector3f rotation) {
         super(entityId, geyserId, EntityType.PLAYER, position, motion, rotation);
 
@@ -63,20 +55,6 @@ public class PlayerEntity extends Entity {
         if (geyserId == 1) valid = true;
     }
 
-    // TODO: Break this into an EquippableEntity class
-    public void updateEquipment(GeyserSession session) {
-        if (!valid) return;
-
-        MobArmorEquipmentPacket armorEquipmentPacket = new MobArmorEquipmentPacket();
-        armorEquipmentPacket.setRuntimeEntityId(geyserId);
-        armorEquipmentPacket.setHelmet(helmet);
-        armorEquipmentPacket.setChestplate(chestplate);
-        armorEquipmentPacket.setLeggings(leggings);
-        armorEquipmentPacket.setBoots(boots);
-
-        session.getUpstream().sendPacket(armorEquipmentPacket);
-    }
-
     @Override
     public boolean despawnEntity(GeyserSession session) {
         super.despawnEntity(session);
diff --git a/connector/src/main/java/org/geysermc/connector/entity/ThrowableEntity.java b/connector/src/main/java/org/geysermc/connector/entity/ThrowableEntity.java
new file mode 100644
index 000000000..c395beba4
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/ThrowableEntity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class ThrowableEntity extends Entity {
+
+    public ThrowableEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/AbstractFishEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/AbstractFishEntity.java
new file mode 100644
index 000000000..db06ce1af
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/AbstractFishEntity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class AbstractFishEntity extends WaterEntity {
+
+    public AbstractFishEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/AbstractHorseEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/AbstractHorseEntity.java
new file mode 100644
index 000000000..7b71d0409
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/AbstractHorseEntity.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living;
+
+import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
+import com.nukkitx.math.vector.Vector3f;
+import com.nukkitx.protocol.bedrock.data.EntityData;
+import org.geysermc.connector.entity.type.EntityType;
+import org.geysermc.connector.network.session.GeyserSession;
+
+public class AbstractHorseEntity extends AnimalEntity {
+
+    public AbstractHorseEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+
+    @Override
+    public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
+        super.updateBedrockMetadata(entityMetadata, session);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/AbstractIllagerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/AbstractIllagerEntity.java
new file mode 100644
index 000000000..04b699d0a
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/AbstractIllagerEntity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class AbstractIllagerEntity extends RaidParticipantEntity {
+
+    public AbstractIllagerEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/AbstractMerchantEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/AbstractMerchantEntity.java
new file mode 100644
index 000000000..9ae0b600c
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/AbstractMerchantEntity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class AbstractMerchantEntity extends AgeableEntity {
+
+    public AbstractMerchantEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/AbstractSkeletonEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/AbstractSkeletonEntity.java
new file mode 100644
index 000000000..ed3d96fe7
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/AbstractSkeletonEntity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class AbstractSkeletonEntity extends MonsterEntity {
+
+    public AbstractSkeletonEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/AgeableEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/AgeableEntity.java
new file mode 100644
index 000000000..926cfde38
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/AgeableEntity.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living;
+
+import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
+import com.nukkitx.math.vector.Vector3f;
+import com.nukkitx.protocol.bedrock.data.EntityFlag;
+import org.geysermc.connector.entity.type.EntityType;
+import org.geysermc.connector.network.session.GeyserSession;
+
+public class AgeableEntity extends CreatureEntity {
+
+    public AgeableEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+
+    @Override
+    public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
+        if (entityMetadata.getId() == 14) {
+            metadata.getFlags().setFlag(EntityFlag.BABY, (boolean) entityMetadata.getValue());
+        }
+
+        super.updateBedrockMetadata(entityMetadata, session);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/AmbientEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/AmbientEntity.java
new file mode 100644
index 000000000..d3cbdbb59
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/AmbientEntity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class AmbientEntity extends InsentientEntity {
+
+    public AmbientEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/AnimalEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/AnimalEntity.java
new file mode 100644
index 000000000..9ce560520
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/AnimalEntity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class AnimalEntity extends AgeableEntity {
+
+    public AnimalEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/ChestedHorseEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/ChestedHorseEntity.java
new file mode 100644
index 000000000..a7eb65216
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/ChestedHorseEntity.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living;
+
+import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
+import com.nukkitx.math.vector.Vector3f;
+import com.nukkitx.protocol.bedrock.data.EntityFlag;
+import org.geysermc.connector.entity.type.EntityType;
+import org.geysermc.connector.network.session.GeyserSession;
+
+public class ChestedHorseEntity extends AbstractHorseEntity {
+
+    public ChestedHorseEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+
+    @Override
+    public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
+        // https://wiki.vg/Entity_metadata#Horse
+        metadata.getFlags().setFlag(EntityFlag.CHESTED, chestplate != null && chestplate.getId() != 0);
+
+        super.updateBedrockMetadata(entityMetadata, session);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/CreatureEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/CreatureEntity.java
new file mode 100644
index 000000000..5d4c45ca5
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/CreatureEntity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class CreatureEntity extends InsentientEntity {
+
+    public CreatureEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/FlyingEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/FlyingEntity.java
new file mode 100644
index 000000000..166d35707
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/FlyingEntity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class FlyingEntity extends InsentientEntity {
+
+    public FlyingEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/GolemEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/GolemEntity.java
new file mode 100644
index 000000000..da7b27125
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/GolemEntity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class GolemEntity extends CreatureEntity {
+
+    public GolemEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/InsentientEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/InsentientEntity.java
new file mode 100644
index 000000000..121174312
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/InsentientEntity.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living;
+
+import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
+import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType;
+import com.nukkitx.math.vector.Vector3f;
+import com.nukkitx.protocol.bedrock.data.EntityFlag;
+import org.geysermc.connector.entity.LivingEntity;
+import org.geysermc.connector.entity.type.EntityType;
+import org.geysermc.connector.network.session.GeyserSession;
+
+public class InsentientEntity extends LivingEntity {
+
+    public InsentientEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+
+    @Override
+    public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
+        if (entityMetadata.getId() == 13 && entityMetadata.getType() == MetadataType.BYTE) {
+            byte xd = (byte) entityMetadata.getValue();
+            metadata.getFlags().setFlag(EntityFlag.NO_AI, (xd & 0x01) == 0x01);
+        }
+
+        super.updateBedrockMetadata(entityMetadata, session);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/MonsterEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/MonsterEntity.java
new file mode 100644
index 000000000..dd0dbc816
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/MonsterEntity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class MonsterEntity extends CreatureEntity {
+
+    public MonsterEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/RaidParticipantEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/RaidParticipantEntity.java
new file mode 100644
index 000000000..b64d55461
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/RaidParticipantEntity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class RaidParticipantEntity extends MonsterEntity {
+
+    public RaidParticipantEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/SpellcasterIllagerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/SpellcasterIllagerEntity.java
new file mode 100644
index 000000000..1b7e16e7a
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/SpellcasterIllagerEntity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class SpellcasterIllagerEntity extends AbstractIllagerEntity {
+
+    public SpellcasterIllagerEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/TameableEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/TameableEntity.java
new file mode 100644
index 000000000..8fd6496c2
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/TameableEntity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class TameableEntity extends AnimalEntity {
+
+    public TameableEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/WaterEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/WaterEntity.java
new file mode 100644
index 000000000..fe66036b5
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/WaterEntity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class WaterEntity extends CreatureEntity {
+
+    public WaterEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/horse/HorseEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/horse/HorseEntity.java
new file mode 100644
index 000000000..3ad0b1145
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/horse/HorseEntity.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living.horse;
+
+import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
+import com.nukkitx.math.vector.Vector3f;
+import com.nukkitx.protocol.bedrock.data.EntityData;
+import org.geysermc.connector.entity.living.AbstractHorseEntity;
+import org.geysermc.connector.entity.type.EntityType;
+import org.geysermc.connector.network.session.GeyserSession;
+
+public class HorseEntity extends AbstractHorseEntity {
+
+    public HorseEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+
+    @Override
+    public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
+        if (entityMetadata.getId() == 17) {
+            metadata.put(EntityData.VARIANT, (int) entityMetadata.getValue());
+        }
+
+        super.updateBedrockMetadata(entityMetadata, session);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/GuardianEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/GuardianEntity.java
new file mode 100644
index 000000000..af6a18327
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/GuardianEntity.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living.monster;
+
+import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
+import com.nukkitx.math.vector.Vector3f;
+import com.nukkitx.protocol.bedrock.data.EntityData;
+import org.geysermc.connector.entity.Entity;
+import org.geysermc.connector.entity.living.MonsterEntity;
+import org.geysermc.connector.entity.type.EntityType;
+import org.geysermc.connector.network.session.GeyserSession;
+
+public class GuardianEntity extends MonsterEntity {
+
+    public GuardianEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+
+    @Override
+    public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
+        if (entityMetadata.getId() == 15) {
+            Entity entity = session.getEntityCache().getEntityByJavaId((int) entityMetadata.getValue());
+            if (entity != null) {
+                metadata.put(EntityData.TARGET_EID, entity.getGeyserId());
+            }
+        }
+
+        super.updateBedrockMetadata(entityMetadata, session);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZombieEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZombieEntity.java
new file mode 100644
index 000000000..162c2272f
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZombieEntity.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.entity.living.monster;
+
+import com.nukkitx.math.vector.Vector3f;
+import org.geysermc.connector.entity.living.MonsterEntity;
+import org.geysermc.connector.entity.type.EntityType;
+
+public class ZombieEntity extends MonsterEntity {
+
+    public ZombieEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
+        super(entityId, geyserId, entityType, position, motion, rotation);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java b/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java
index d3286c8d5..73c484104 100644
--- a/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java
+++ b/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java
@@ -26,137 +26,143 @@
 package org.geysermc.connector.entity.type;
 
 import lombok.Getter;
+import org.geysermc.connector.entity.*;
+import org.geysermc.connector.entity.living.*;
+import org.geysermc.connector.entity.living.horse.HorseEntity;
+import org.geysermc.connector.entity.living.monster.GuardianEntity;
+import org.geysermc.connector.entity.living.monster.ZombieEntity;
 
 @Getter
 public enum EntityType {
 
-    CHICKEN(10, 0.7f, 0.4f),
-    COW(11, 1.4f, 0.9f),
-    PIG(12, 0.9f),
-    SHEEP(13, 1.3f, 0.9f),
-    WOLF(14, 0.85f, 0.6f),
-    VILLAGER(15, 1.8f, 0.6f, 0.6f, 1.62f),
-    MOOSHROOM(16, 1.4f, 0.9f),
-    SQUID(17, 0.8f),
-    RABBIT(18, 0.5f, 0.4f),
-    BAT(19, 0.9f, 0.5f),
-    IRON_GOLEM(20, 2.7f, 1.4f),
-    SNOW_GOLEM(21, 1.9f, 0.7f),
-    OCELOT(22, 0.35f, 0.3f),
-    HORSE(23, 1.6f, 1.3965f),
-    DONKEY(24, 1.6f, 1.3965f),
-    MULE(25, 1.6f, 1.3965f),
-    SKELETON_HORSE(26, 1.6f, 1.3965f),
-    ZOMBIE_HORSE(27, 1.6f, 1.3965f),
-    POLAR_BEAR(28, 1.4f, 1.3f),
-    LLAMA(29, 1.87f, 0.9f),
-    PARROT(30, 0.9f, 0.5f),
-    DOLPHIN(31, 0.6f, 0.9f),
-    ZOMBIE(32, 1.8f, 0.6f, 0.6f, 1.62f),
-    CREEPER(33, 1.7f, 0.6f, 0.6f, 1.62f),
-    SKELETON(34, 1.8f, 0.6f, 0.6f, 1.62f),
-    SPIDER(35, 0.9f, 1.4f, 1.4f, 1f),
-    ZOMBIE_PIGMAN(36, 1.8f, 0.6f, 0.6f, 1.62f),
-    SLIME(37, 0.51f),
-    ENDERMAN(38, 2.9f, 0.6f),
-    SILVERFISH(39, 0.3f, 0.4f),
-    CAVE_SPIDER(40, 0.5f, 0.7f),
-    GHAST(41, 4.0f),
-    MAGMA_CUBE(42, 0.51f),
-    BLAZE(43, 1.8f, 0.6f),
-    ZOMBIE_VILLAGER(44, 1.8f, 0.6f, 0.6f, 1.62f),
-    WITCH(45, 1.8f, 0.6f, 0.6f, 1.62f),
-    STRAY(46, 1.8f, 0.6f, 0.6f, 1.62f),
-    HUSK(47, 1.8f, 0.6f, 0.6f, 1.62f),
-    WITHER_SKELETON(48, 2.4f, 0.7f),
-    GUARDIAN(49, 0.85f),
-    ELDER_GUARDIAN(50, 1.9975f),
-    NPC(51, 1.8f, 0.6f, 0.6f, 1.62f),
-    WITHER(52, 3.5f, 0.9f),
-    ENDER_DRAGON(53, 4f, 13f),
-    SHULKER(54, 1f, 1f),
-    ENDERMITE(55, 0.3f, 0.4f),
-    AGENT(56, 0f),
-    VINDICATOR(57, 1.8f, 0.6f, 0.6f, 1.62f),
-    PILLAGER(114, 1.8f, 0.6f, 0.6f, 1.62f),
-    WANDERING_TRADER(118, 1.8f, 0.6f, 0.6f, 1.62f),
-    PHANTOM(58, 0.5f, 0.9f, 0.9f, 0.6f),
-    RAVAGER(59, 1.9f, 1.2f),
+    CHICKEN(AnimalEntity.class, 10, 0.7f, 0.4f),
+    COW(AnimalEntity.class, 11, 1.4f, 0.9f),
+    PIG(AnimalEntity.class, 12, 0.9f),
+    SHEEP(AnimalEntity.class, 13, 1.3f, 0.9f),
+    WOLF(AnimalEntity.class, 14, 0.85f, 0.6f),
+    VILLAGER(AbstractMerchantEntity.class, 15, 1.8f, 0.6f, 0.6f, 1.62f),
+    MOOSHROOM(AnimalEntity.class, 16, 1.4f, 0.9f),
+    SQUID(WaterEntity.class, 17, 0.8f),
+    RABBIT(AnimalEntity.class, 18, 0.5f, 0.4f),
+    BAT(AmbientEntity.class, 19, 0.9f, 0.5f),
+    IRON_GOLEM(GolemEntity.class, 20, 2.7f, 1.4f),
+    SNOW_GOLEM(GolemEntity.class, 21, 1.9f, 0.7f),
+    OCELOT(TameableEntity.class, 22, 0.35f, 0.3f),
+    HORSE(HorseEntity.class, 23, 1.6f, 1.3965f),
+    DONKEY(ChestedHorseEntity.class, 24, 1.6f, 1.3965f),
+    MULE(ChestedHorseEntity.class, 25, 1.6f, 1.3965f),
+    SKELETON_HORSE(AbstractHorseEntity.class, 26, 1.6f, 1.3965f),
+    ZOMBIE_HORSE(AbstractHorseEntity.class, 27, 1.6f, 1.3965f),
+    POLAR_BEAR(AnimalEntity.class, 28, 1.4f, 1.3f),
+    LLAMA(ChestedHorseEntity.class, 29, 1.87f, 0.9f),
+    PARROT(TameableEntity.class, 30, 0.9f, 0.5f),
+    DOLPHIN(WaterEntity.class, 31, 0.6f, 0.9f),
+    ZOMBIE(ZombieEntity.class, 32, 1.8f, 0.6f, 0.6f, 1.62f),
+    CREEPER(MonsterEntity.class, 33, 1.7f, 0.6f, 0.6f, 1.62f),
+    SKELETON(AbstractSkeletonEntity.class, 34, 1.8f, 0.6f, 0.6f, 1.62f),
+    SPIDER(MonsterEntity.class, 35, 0.9f, 1.4f, 1.4f, 1f),
+    ZOMBIE_PIGMAN(MonsterEntity.class, 36, 1.8f, 0.6f, 0.6f, 1.62f),
+    SLIME(InsentientEntity.class, 37, 0.51f),
+    ENDERMAN(MonsterEntity.class, 38, 2.9f, 0.6f),
+    SILVERFISH(MonsterEntity.class, 39, 0.3f, 0.4f),
+    CAVE_SPIDER(MonsterEntity.class, 40, 0.5f, 0.7f),
+    GHAST(FlyingEntity.class, 41, 4.0f),
+    MAGMA_CUBE(InsentientEntity.class, 42, 0.51f),
+    BLAZE(MonsterEntity.class, 43, 1.8f, 0.6f),
+    ZOMBIE_VILLAGER(ZombieEntity.class, 44, 1.8f, 0.6f, 0.6f, 1.62f),
+    WITCH(RaidParticipantEntity.class, 45, 1.8f, 0.6f, 0.6f, 1.62f),
+    STRAY(AbstractSkeletonEntity.class, 46, 1.8f, 0.6f, 0.6f, 1.62f),
+    HUSK(ZombieEntity.class, 47, 1.8f, 0.6f, 0.6f, 1.62f),
+    WITHER_SKELETON(AbstractSkeletonEntity.class, 48, 2.4f, 0.7f),
+    GUARDIAN(MonsterEntity.class, 49, 0.85f),
+    ELDER_GUARDIAN(GuardianEntity.class, 50, 1.9975f),
+    NPC(PlayerEntity.class, 51, 1.8f, 0.6f, 0.6f, 1.62f),
+    WITHER(MonsterEntity.class, 52, 3.5f, 0.9f),
+    ENDER_DRAGON(InsentientEntity.class, 53, 4f, 13f),
+    SHULKER(GolemEntity.class, 54, 1f, 1f),
+    ENDERMITE(MonsterEntity.class, 55, 0.3f, 0.4f),
+    AGENT(Entity.class, 56, 0f),
+    VINDICATOR(AbstractIllagerEntity.class, 57, 1.8f, 0.6f, 0.6f, 1.62f),
+    PILLAGER(AbstractIllagerEntity.class, 114, 1.8f, 0.6f, 0.6f, 1.62f),
+    WANDERING_TRADER(AbstractMerchantEntity.class, 118, 1.8f, 0.6f, 0.6f, 1.62f),
+    PHANTOM(FlyingEntity.class, 58, 0.5f, 0.9f, 0.9f, 0.6f),
+    RAVAGER(RaidParticipantEntity.class, 59, 1.9f, 1.2f),
 
-    ARMOR_STAND(61, 0f),
-    TRIPOD_CAMERA(62, 0f),
-    PLAYER(63, 1.8f, 0.6f, 0.6f, 1.62f),
-    ITEM(64, 0.25f, 0.25f),
-    TNT(65, 0.98f, 0.98f),
-    FALLING_BLOCK(66, 0.98f, 0.98f),
-    MOVING_BLOCK(67, 0f),
-    EXPERIENCE_BOTTLE(68, 0.25f, 0.25f),
-    EXPERIENCE_ORB(69, 0f),
-    EYE_OF_ENDER(70, 0f),
-    END_CRYSTAL(71, 0f),
-    FIREWORK_ROCKET(72, 0f),
-    TRIDENT(73, 0f),
-    TURTLE(74, 0.4f, 1.2f),
-    // TODO CAT (need to figure out how to deal with baby cats) https://github.com/NukkitX/Nukkit/blob/master/src/main/java/cn/nukkit/entity/passive/EntityCat.java
+    ARMOR_STAND(LivingEntity.class, 61, 0f),
+    TRIPOD_CAMERA(Entity.class, 62, 0f),
+    PLAYER(PlayerEntity.class, 63, 1.8f, 0.6f, 0.6f, 1.62f),
+    ITEM(ItemEntity.class, 64, 0.25f, 0.25f),
+    TNT(Entity.class, 65, 0.98f, 0.98f),
+    FALLING_BLOCK(Entity.class, 66, 0.98f, 0.98f),
+    MOVING_BLOCK(Entity.class, 67, 0f),
+    EXPERIENCE_BOTTLE(ThrowableEntity.class, 68, 0.25f, 0.25f),
+    EXPERIENCE_ORB(ExpOrbEntity.class, 69, 0f),
+    EYE_OF_ENDER(Entity.class, 70, 0f),
+    END_CRYSTAL(Entity.class, 71, 0f),
+    FIREWORK_ROCKET(Entity.class, 72, 0f),
+    TRIDENT(ArrowEntity.class, 73, 0f),
+    TURTLE(AnimalEntity.class, 74, 0.4f, 1.2f),
+    CAT(TameableEntity.class, 75, 0.35f, 0.3f),
+    SHULKER_BULLET(Entity.class, 76, 0f),
+    FISHING_BOBBER(Entity.class, 77, 0f),
+    CHALKBOARD(Entity.class, 78, 0f),
+    DRAGON_FIREBALL(ItemedFireballEntity.class, 79, 0f),
+    ARROW(ArrowEntity.class, 80, 0.25f, 0.25f),
+    SNOWBALL(ThrowableEntity.class, 81, 0f),
+    EGG(ThrowableEntity.class, 82, 0f),
+    PAINTING(PaintingEntity.class, 83, 0f),
+    MINECART(MinecartEntity.class, 84, 0f),
+    FIREBALL(ItemedFireballEntity.class, 85, 0f),
+    SPLASH_POTION(ThrowableEntity.class, 86, 0f),
+    ENDER_PEARL(ThrowableEntity.class, 87, 0f),
+    LEASH_KNOT(Entity.class, 88, 0f),
+    WITHER_SKULL(Entity.class, 89, 0f),
+    BOAT(Entity.class, 90, 0.7f, 1.6f, 1.6f, 0.35f),
+    WITHER_SKULL_DANGEROUS(Entity.class, 91, 0f),
+    LIGHTNING_BOLT(Entity.class, 93, 0f),
+    SMALL_FIREBALL(ItemedFireballEntity.class, 94, 0f),
+    AREA_EFFECT_CLOUD(Entity.class, 95, 0f),
+    HOPPER_MINECART(MinecartEntity.class, 96, 0f),
+    TNT_MINECART(MinecartEntity.class, 97, 0f),
+    CHEST_MINECART(MinecartEntity.class, 98, 0f),
 
-    SHULKER_BULLET(76, 0f),
-    FISHING_BOBBER(77, 0f),
-    CHALKBOARD(78, 0f),
-    DRAGON_FIREBALL(79, 0f),
-    ARROW(80, 0.25f, 0.25f),
-    SNOWBALL(81, 0f),
-    EGG(82, 0f),
-    PAINTING(83, 0f),
-    MINECART(84, 0f),
-    FIREBALL(85, 0f),
-    SPLASH_POTION(86, 0f),
-    ENDER_PEARL(87, 0f),
-    LEASH_KNOT(88, 0f),
-    WITHER_SKULL(89, 0f),
-    BOAT(90, 0.7f, 1.6f, 1.6f, 0.35f),
-    WITHER_SKULL_DANGEROUS(91, 0f),
-    LIGHTNING_BOLT(93, 0f),
-    SMALL_FIREBALL(94, 0f),
-    AREA_EFFECT_CLOUD(95, 0f),
-    HOPPER_MINECART(96, 0f),
-    TNT_MINECART(97, 0f),
-    CHEST_MINECART(98, 0f),
-
-    COMMAND_BLOCK_MINECART(100, 0f),
-    LINGERING_POTION(101, 0f),
-    LLAMA_SPIT(102, 0f),
-    EVOKER_FANGS(103, 0f),
-    EVOKER(104, 0f),
-    VEX(105, 0f),
-    ICE_BOMB(106, 0f),
-    BALLOON(107, 0f), //TODO
-    PUFFERFISH(108, 0.7f, 0.7f),
-    SALMON(109, 0.5f, 0.7f),
-    DROWNED(110, 1.95f, 0.6f),
-    TROPICAL_FISH(111, 0.6f, 0.6f),
-    COD(112, 0.25f, 0.5f),
-    PANDA(113, 1.25f, 1.125f, 1.825f),
-    FOX(121, 0.5f, 1.25f);
+    COMMAND_BLOCK_MINECART(MinecartEntity.class, 100, 0f),
+    LINGERING_POTION(ThrowableEntity.class, 101, 0f),
+    LLAMA_SPIT(Entity.class, 102, 0f),
+    EVOKER_FANGS(Entity.class, 103, 0f),
+    EVOKER(SpellcasterIllagerEntity.class, 104, 0f),
+    VEX(MonsterEntity.class, 105, 0f),
+    ICE_BOMB(Entity.class, 106, 0f),
+    BALLOON(Entity.class, 107, 0f), //TODO
+    PUFFERFISH(AbstractFishEntity.class, 108, 0.7f, 0.7f),
+    SALMON(AbstractFishEntity.class, 109, 0.5f, 0.7f),
+    DROWNED(ZombieEntity.class, 110, 1.95f, 0.6f),
+    TROPICAL_FISH(AbstractFishEntity.class, 111, 0.6f, 0.6f),
+    COD(AbstractFishEntity.class, 112, 0.25f, 0.5f),
+    PANDA(AnimalEntity.class, 113, 1.25f, 1.125f, 1.825f),
+    FOX(AnimalEntity.class, 121, 0.5f, 1.25f);
 
+    private Class<? extends Entity> entityClass;
     private final int type;
     private final float height;
     private final float width;
     private final float length;
     private final float offset;
 
-    EntityType(int type, float height) {
-        this(type, height, 0f);
+    EntityType(Class<? extends Entity> entityClass, int type, float height) {
+        this(entityClass, type, height, 0f);
     }
 
-    EntityType(int type, float height, float width) {
-        this(type, height, width, width);
+    EntityType(Class<? extends Entity> entityClass, int type, float height, float width) {
+        this(entityClass, type, height, width, width);
     }
 
-    EntityType(int type, float height, float width, float length) {
-        this(type, height, width, length, 0f);
+    EntityType(Class<? extends Entity> entityClass, int type, float height, float width, float length) {
+        this(entityClass, type, height, width, length, 0f);
     }
 
-    EntityType(int type, float height, float width, float length, float offset) {
+    EntityType(Class<? extends Entity> entityClass, int type, float height, float width, float length, float offset) {
+        this.entityClass = entityClass;
         this.type = type;
         this.height = height;
         this.width = width;
diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java
index 11e1852a7..14654c6a4 100644
--- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java
+++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java
@@ -340,7 +340,7 @@ public class GeyserSession implements Player {
         startGamePacket.setLevelGamemode(0);
         startGamePacket.setDifficulty(1);
         startGamePacket.setDefaultSpawn(Vector3i.ZERO);
-        startGamePacket.setAcheivementsDisabled(true);
+        startGamePacket.setAchievementsDisabled(true);
         startGamePacket.setTime(-1);
         startGamePacket.setEduEditionOffers(0);
         startGamePacket.setEduFeaturesEnabled(false);
diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/EntityCache.java b/connector/src/main/java/org/geysermc/connector/network/session/cache/EntityCache.java
index 80b965007..fd0bd7c5a 100644
--- a/connector/src/main/java/org/geysermc/connector/network/session/cache/EntityCache.java
+++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/EntityCache.java
@@ -25,6 +25,10 @@
 
 package org.geysermc.connector.network.session.cache;
 
+import it.unimi.dsi.fastutil.longs.Long2LongMap;
+import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap;
+import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
+import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
 import lombok.Getter;
 import org.geysermc.connector.entity.Entity;
 import org.geysermc.connector.entity.PlayerEntity;
@@ -41,8 +45,8 @@ public class EntityCache {
     private GeyserSession session;
 
     @Getter
-    private Map<Long, Entity> entities = new HashMap<>();
-    private Map<Long, Long> entityIdTranslations = new HashMap<>();
+    private Long2ObjectMap<Entity> entities = new Long2ObjectOpenHashMap<>();
+    private Long2LongMap entityIdTranslations = new Long2LongOpenHashMap();
     private Map<UUID, PlayerEntity> playerEntities = new HashMap<>();
     private Map<UUID, Long> bossbars = new HashMap<>();
 
@@ -62,12 +66,10 @@ public class EntityCache {
 
     public boolean removeEntity(Entity entity, boolean force) {
         if (entity != null && entity.isValid() && (force || entity.despawnEntity(session))) {
-            Long geyserId = entityIdTranslations.remove(entity.getEntityId());
-            if (geyserId != null) {
-                entities.remove(geyserId);
-                if (entity.is(PlayerEntity.class)) {
-                    playerEntities.remove(entity.as(PlayerEntity.class).getUuid());
-                }
+            long geyserId = entityIdTranslations.remove(entity.getEntityId());
+            entities.remove(geyserId);
+            if (entity.is(PlayerEntity.class)) {
+                playerEntities.remove(entity.as(PlayerEntity.class).getUuid());
             }
             return true;
         }
diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/WindowCache.java b/connector/src/main/java/org/geysermc/connector/network/session/cache/WindowCache.java
index fc7de6144..5d21c55ca 100644
--- a/connector/src/main/java/org/geysermc/connector/network/session/cache/WindowCache.java
+++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/WindowCache.java
@@ -26,6 +26,8 @@
 package org.geysermc.connector.network.session.cache;
 
 import com.nukkitx.protocol.bedrock.packet.ModalFormRequestPacket;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
 import lombok.Getter;
 import org.geysermc.connector.network.session.GeyserSession;
 import org.geysermc.api.window.FormWindow;
@@ -38,7 +40,7 @@ public class WindowCache {
     private GeyserSession session;
 
     @Getter
-    private Map<Integer, FormWindow> windows = new HashMap<Integer, FormWindow>();
+    private Int2ObjectMap<FormWindow> windows = new Int2ObjectOpenHashMap<>();
 
     public WindowCache(GeyserSession session) {
         this.session = session;
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java
index 4f6e21e76..a19de3f29 100644
--- a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java
@@ -112,6 +112,7 @@ public class TranslatorsInit {
         Registry.registerJava(ServerEntityHeadLookPacket.class, new JavaEntityHeadLookTranslator());
         Registry.registerJava(ServerEntityMetadataPacket.class, new JavaEntityMetadataTranslator());
         Registry.registerJava(ServerEntityStatusPacket.class, new JavaEntityStatusTranslator());
+        Registry.registerJava(ServerEntityEquipmentPacket.class, new JavaEntityEquipmentTranslator());
         Registry.registerJava(ServerBossBarPacket.class, new JavaBossBarTranslator());
 
         Registry.registerJava(ServerSpawnExpOrbPacket.class, new JavaSpawnExpOrbTranslator());
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMovePlayerTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMovePlayerTranslator.java
index 678956d7c..d07e922d4 100644
--- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMovePlayerTranslator.java
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMovePlayerTranslator.java
@@ -64,7 +64,7 @@ public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPack
         double javaY = packet.getPosition().getY() - EntityType.PLAYER.getOffset();
 
         ClientPlayerPositionRotationPacket playerPositionRotationPacket = new ClientPlayerPositionRotationPacket(
-                packet.isOnGround(), packet.getPosition().getX(), Math.ceil(javaY * 2) / 2,
+                packet.isOnGround(), packet.getPosition().getX(), javaY,
                 packet.getPosition().getZ(), packet.getRotation().getY(), packet.getRotation().getX()
         );
 
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java
index b8d56ccff..204210598 100644
--- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java
@@ -79,7 +79,7 @@ public class ItemTranslator {
     }
 
     public ItemEntry getItem(ItemData data) {
-        for (ItemEntry itemEntry : Toolbox.ITEM_ENTRIES.valueCollection()) {
+        for (ItemEntry itemEntry : Toolbox.ITEM_ENTRIES.values()) {
             if (itemEntry.getBedrockId() == data.getId() && itemEntry.getBedrockData() == data.getDamage()) {
                 return itemEntry;
             }
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityEquipmentTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityEquipmentTranslator.java
new file mode 100644
index 000000000..8197b8a6d
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityEquipmentTranslator.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.network.translators.java.entity;
+
+import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityEquipmentPacket;
+import com.nukkitx.protocol.bedrock.data.ItemData;
+import org.geysermc.connector.entity.Entity;
+import org.geysermc.connector.entity.LivingEntity;
+import org.geysermc.connector.network.session.GeyserSession;
+import org.geysermc.connector.network.translators.PacketTranslator;
+import org.geysermc.connector.network.translators.TranslatorsInit;
+
+public class JavaEntityEquipmentTranslator extends PacketTranslator<ServerEntityEquipmentPacket> {
+
+    @Override
+    public void translate(ServerEntityEquipmentPacket packet, GeyserSession session) {
+        Entity entity = session.getEntityCache().getEntityByJavaId(packet.getEntityId());
+        if (packet.getEntityId() == session.getPlayerEntity().getEntityId()) {
+            entity = session.getPlayerEntity();
+        }
+
+        if (entity == null)
+            return;
+
+        if (!(entity instanceof LivingEntity)) {
+            session.getConnector().getLogger().debug("Attempted to add armor to a non-living entity type (" +
+                    entity.getEntityType().name() + ").");
+            return;
+        }
+
+        LivingEntity livingEntity = (LivingEntity) entity;
+        ItemData item = TranslatorsInit.getItemTranslator().translateToBedrock(packet.getItem());
+        switch (packet.getSlot()) {
+            case HELMET:
+                livingEntity.setHelmet(item);
+                break;
+            case CHESTPLATE:
+                livingEntity.setChestplate(item);
+                break;
+            case LEGGINGS:
+                livingEntity.setLeggings(item);
+                break;
+            case BOOTS:
+                livingEntity.setBoots(item);
+                break;
+            case MAIN_HAND:
+                livingEntity.setHand(item);
+                break;
+            case OFF_HAND:
+                // TODO: livingEntity.setOffHand(item);
+                break;
+        }
+
+        livingEntity.updateEquipment(session);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnMobTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnMobTranslator.java
index e5c68ecaf..352d8b748 100644
--- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnMobTranslator.java
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnMobTranslator.java
@@ -34,6 +34,9 @@ import org.geysermc.connector.network.session.GeyserSession;
 import org.geysermc.connector.network.translators.PacketTranslator;
 import org.geysermc.connector.utils.EntityUtils;
 
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
 public class JavaSpawnMobTranslator extends PacketTranslator<ServerSpawnMobPacket> {
 
     @Override
@@ -48,11 +51,17 @@ public class JavaSpawnMobTranslator extends PacketTranslator<ServerSpawnMobPacke
             return;
         }
 
-        Entity entity = new Entity(
-                packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(),
-                type, position, motion, rotation
-        );
+        Class<? extends Entity> entityClass = type.getEntityClass();
+        try {
+            Constructor<? extends Entity> entityConstructor = entityClass.getConstructor(long.class, long.class, EntityType.class,
+                    Vector3f.class, Vector3f.class, Vector3f.class);
 
-        session.getEntityCache().spawnEntity(entity);
+            Entity entity = entityConstructor.newInstance(packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(),
+                    type, position, motion, rotation
+            );
+            session.getEntityCache().spawnEntity(entity);
+        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException ex) {
+            ex.printStackTrace();
+        }
     }
 }
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnObjectTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnObjectTranslator.java
index 57571bed4..a2c0c6538 100644
--- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnObjectTranslator.java
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnObjectTranslator.java
@@ -30,12 +30,14 @@ import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.Serve
 import com.nukkitx.math.vector.Vector3f;
 import org.geysermc.connector.console.GeyserLogger;
 import org.geysermc.connector.entity.Entity;
-import org.geysermc.connector.entity.ItemEntity;
 import org.geysermc.connector.entity.type.EntityType;
 import org.geysermc.connector.network.session.GeyserSession;
 import org.geysermc.connector.network.translators.PacketTranslator;
 import org.geysermc.connector.utils.EntityUtils;
 
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
 public class JavaSpawnObjectTranslator extends PacketTranslator<ServerSpawnObjectPacket> {
 
     @Override
@@ -53,17 +55,17 @@ public class JavaSpawnObjectTranslator extends PacketTranslator<ServerSpawnObjec
             return;
         }
 
-        long geyserId = session.getEntityCache().getNextEntityId().incrementAndGet();
-        Entity entity;
-        switch (type) {
-            case ITEM:
-                entity = new ItemEntity(packet.getEntityId(), geyserId, type, position, motion, rotation);
-                break;
-            default:
-                entity = new Entity(packet.getEntityId(), geyserId, type, position, motion, rotation);
-                break;
-        }
+        Class<? extends Entity> entityClass = type.getEntityClass();
+        try {
+            Constructor<? extends Entity> entityConstructor = entityClass.getConstructor(long.class, long.class, EntityType.class,
+                    Vector3f.class, Vector3f.class, Vector3f.class);
 
-        session.getEntityCache().spawnEntity(entity);
+            Entity entity = entityConstructor.newInstance(packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(),
+                    type, position, motion, rotation
+            );
+            session.getEntityCache().spawnEntity(entity);
+        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException ex) {
+            ex.printStackTrace();
+        }
     }
 }
diff --git a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java
index e42ca473e..05f9c67de 100644
--- a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java
+++ b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java
@@ -7,12 +7,12 @@ import com.nukkitx.protocol.bedrock.data.SerializedSkin;
 import com.nukkitx.protocol.bedrock.packet.PlayerListPacket;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
-import org.apache.commons.codec.Charsets;
 import org.geysermc.api.AuthType;
 import org.geysermc.api.Geyser;
 import org.geysermc.connector.entity.PlayerEntity;
 import org.geysermc.connector.network.session.GeyserSession;
 
+import java.nio.charset.StandardCharsets;
 import java.util.Base64;
 import java.util.Collections;
 import java.util.UUID;
@@ -80,7 +80,7 @@ public class SkinUtils {
             try {
                 GameProfile.Property skinProperty = profile.getProperty("textures");
 
-                JsonObject skinObject = SkinProvider.GSON.fromJson(new String(Base64.getDecoder().decode(skinProperty.getValue()), Charsets.UTF_8), JsonObject.class);
+                JsonObject skinObject = SkinProvider.GSON.fromJson(new String(Base64.getDecoder().decode(skinProperty.getValue()), StandardCharsets.UTF_8), JsonObject.class);
                 JsonObject textures = skinObject.getAsJsonObject("textures");
 
                 JsonObject skinTexture = textures.getAsJsonObject("SKIN");
diff --git a/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java b/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java
index 849ecc568..74a1be96f 100644
--- a/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java
+++ b/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java
@@ -7,8 +7,8 @@ import com.nukkitx.nbt.tag.CompoundTag;
 import com.nukkitx.nbt.tag.ListTag;
 import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
 
-import gnu.trove.map.TIntObjectMap;
-import gnu.trove.map.hash.TIntObjectHashMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
 import org.geysermc.connector.GeyserConnector;
 import org.geysermc.connector.console.GeyserLogger;
 import org.geysermc.connector.network.translators.block.BlockEntry;
@@ -23,8 +23,8 @@ public class Toolbox {
     public static final Collection<StartGamePacket.ItemEntry> ITEMS = new ArrayList<>();
     public static ListTag<CompoundTag> BLOCKS;
 
-    public static final TIntObjectMap<ItemEntry> ITEM_ENTRIES = new TIntObjectHashMap<>();
-    public static final TIntObjectMap<BlockEntry> BLOCK_ENTRIES = new TIntObjectHashMap<>();
+    public static final Int2ObjectMap<ItemEntry> ITEM_ENTRIES = new Int2ObjectOpenHashMap<>();
+    public static final Int2ObjectMap<BlockEntry> BLOCK_ENTRIES = new Int2ObjectOpenHashMap<>();
 
     public static void init() {
         InputStream stream = GeyserConnector.class.getClassLoader().getResourceAsStream("bedrock/runtime_block_states.dat");
diff --git a/connector/src/main/java/org/geysermc/connector/world/chunk/BlockStorage.java b/connector/src/main/java/org/geysermc/connector/world/chunk/BlockStorage.java
index db38d4bb0..dbb967d4e 100644
--- a/connector/src/main/java/org/geysermc/connector/world/chunk/BlockStorage.java
+++ b/connector/src/main/java/org/geysermc/connector/world/chunk/BlockStorage.java
@@ -1,12 +1,15 @@
 package org.geysermc.connector.world.chunk;
 
 import com.nukkitx.network.VarInts;
-import gnu.trove.list.array.TIntArrayList;
 import io.netty.buffer.ByteBuf;
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+import it.unimi.dsi.fastutil.ints.IntList;
 import org.geysermc.connector.world.GlobalBlockPalette;
 import org.geysermc.connector.world.chunk.bitarray.BitArray;
 import org.geysermc.connector.world.chunk.bitarray.BitArrayVersion;
 
+import java.util.function.IntConsumer;
+
 /**
  * Adapted from NukkitX: https://github.com/NukkitX/Nukkit
  */
@@ -14,7 +17,7 @@ public class BlockStorage {
 
     private static final int SIZE = 4096;
 
-    private final TIntArrayList palette;
+    private final IntList palette;
     private BitArray bitArray;
 
     public BlockStorage() {
@@ -23,11 +26,11 @@ public class BlockStorage {
 
     public BlockStorage(BitArrayVersion version) {
         this.bitArray = version.createPalette(SIZE);
-        this.palette = new TIntArrayList(16, -1);
+        this.palette = new IntArrayList(16);
         this.palette.add(0); // Air is at the start of every palette.
     }
 
-    private BlockStorage(BitArray bitArray, TIntArrayList palette) {
+    private BlockStorage(BitArray bitArray, IntArrayList palette) {
         this.palette = palette;
         this.bitArray = bitArray;
     }
@@ -57,10 +60,7 @@ public class BlockStorage {
         }
 
         VarInts.writeInt(buffer, palette.size());
-        palette.forEach(id -> {
-            VarInts.writeInt(buffer, id);
-            return true;
-        });
+        palette.forEach((IntConsumer) id -> VarInts.writeInt(buffer, id));
     }
 
     private void onResize(BitArrayVersion version) {
@@ -109,6 +109,6 @@ public class BlockStorage {
     }
 
     public BlockStorage copy() {
-        return new BlockStorage(this.bitArray.copy(), new TIntArrayList(this.palette));
+        return new BlockStorage(this.bitArray.copy(), new IntArrayList(this.palette));
     }
 }
\ No newline at end of file
diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings
index 5ec6f1f33..3d4147f00 160000
--- a/connector/src/main/resources/mappings
+++ b/connector/src/main/resources/mappings
@@ -1 +1 @@
-Subproject commit 5ec6f1f339506129514de59d0e09e9b2c612e8be
+Subproject commit 3d4147f001266d01eae6b8479428ca77bb5bf0c3
diff --git a/pom.xml b/pom.xml
index 79b7b5a1a..2f394b5a9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
     <artifactId>geyser-parent</artifactId>
     <version>1.0-SNAPSHOT</version>
     <packaging>pom</packaging>
-    <name>GeyserMC</name>
+    <name>Geyser</name>
     <description>Allows for players from Minecraft Bedrock Edition to join Minecraft Java Edition servers.</description>
     <url>https://geysermc.org</url>
 
@@ -83,33 +83,16 @@
         </snapshotRepository>
     </distributionManagement>
 
+    <dependencies>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.4</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
     <build>
         <defaultGoal>clean install</defaultGoal>
-        <resources>
-            <resource>
-                <directory>src/main/resources/</directory>
-                <filtering>false</filtering>
-            </resource>
-        </resources>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <version>3.7.0</version>
-                <configuration>
-                    <source>1.8</source>
-                    <target>1.8</target>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-shade-plugin</artifactId>
-                <version>3.1.0</version>
-                <configuration>
-                    <createDependencyReducedPom>false</createDependencyReducedPom>
-                    <minimizeJar>true</minimizeJar>
-                </configuration>
-            </plugin>
-        </plugins>
     </build>
 </project>