diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 4139f29..5913b97 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -5,10 +5,8 @@
   </component>
   <component name="ChangeListManager">
     <list default="true" id="9d5d9b6f-43c8-41a4-bb42-a66ffc96c9b0" name="Changes" comment="">
-      <change afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPlayer.java" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperExperienceOrbEntity.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperExperienceOrbEntity.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/WorldWrapper.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/WorldWrapper.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPlayer.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPlayer.java" afterDir="false" />
       <change beforePath="$PROJECT_DIR$/common/src/main/java/me/tofaa/entitylib/common/AbstractWorldWrapper.java" beforeDir="false" afterPath="$PROJECT_DIR$/common/src/main/java/me/tofaa/entitylib/common/AbstractWorldWrapper.java" afterDir="false" />
     </list>
     <option name="SHOW_DIALOG" value="false" />
@@ -294,7 +292,7 @@
       <workItem from="1706784821835" duration="7882000" />
       <workItem from="1706858181164" duration="925000" />
       <workItem from="1707159905372" duration="3391000" />
-      <workItem from="1707210065718" duration="1026000" />
+      <workItem from="1707210065718" duration="1328000" />
     </task>
     <servers />
   </component>
diff --git a/api/src/main/java/me/tofaa/entitylib/WorldWrapper.java b/api/src/main/java/me/tofaa/entitylib/WorldWrapper.java
index 7578c8f..b3d0ae3 100644
--- a/api/src/main/java/me/tofaa/entitylib/WorldWrapper.java
+++ b/api/src/main/java/me/tofaa/entitylib/WorldWrapper.java
@@ -1,11 +1,13 @@
 package me.tofaa.entitylib;
 
 import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
+import com.github.retrooper.packetevents.protocol.player.UserProfile;
 import com.github.retrooper.packetevents.protocol.world.Dimension;
 import com.github.retrooper.packetevents.protocol.world.Location;
 import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
 import me.tofaa.entitylib.tick.TickContainer;
 import me.tofaa.entitylib.wrapper.WrapperEntity;
+import me.tofaa.entitylib.wrapper.WrapperPlayer;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -20,6 +22,8 @@ import java.util.UUID;
  */
 public interface WorldWrapper<W> {
 
+    @NotNull WrapperPlayer spawnPlayer(UserProfile profile, Location location);
+
     @NotNull <T extends WrapperEntity> T spawnEntity(@NotNull Class<T> wrapperClass, @NotNull EntityType entityType, @NotNull Location location);
 
     @NotNull WrapperEntity spawnEntity(@NotNull EntityType entityType, @NotNull Location location);
diff --git a/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPlayer.java b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPlayer.java
index d7d1c57..7b35b3f 100644
--- a/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPlayer.java
+++ b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperPlayer.java
@@ -1,10 +1,12 @@
 package me.tofaa.entitylib.wrapper;
 
 import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
+import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
 import com.github.retrooper.packetevents.protocol.player.*;
 import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfo;
 import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoRemove;
 import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate;
+import me.tofaa.entitylib.EntityLib;
 import me.tofaa.entitylib.meta.EntityMeta;
 import net.kyori.adventure.text.Component;
 
@@ -17,8 +19,8 @@ public class WrapperPlayer extends WrapperLivingEntity {
     private Component displayName;
 
 
-    public WrapperPlayer(UserProfile profile,  int entityId, EntityType entityType, EntityMeta entityMeta) {
-        super(entityId, profile.getUUID(), entityType, entityMeta);
+    public WrapperPlayer(UserProfile profile, int entityId) {
+        super(entityId, profile.getUUID(), EntityTypes.PLAYER, EntityMeta.createMeta(entityId, EntityTypes.PLAYER));
         this.profile = profile;
     }
 
diff --git a/common/src/main/java/me/tofaa/entitylib/common/AbstractWorldWrapper.java b/common/src/main/java/me/tofaa/entitylib/common/AbstractWorldWrapper.java
index 4cd4b0a..b7a29fd 100644
--- a/common/src/main/java/me/tofaa/entitylib/common/AbstractWorldWrapper.java
+++ b/common/src/main/java/me/tofaa/entitylib/common/AbstractWorldWrapper.java
@@ -1,6 +1,8 @@
 package me.tofaa.entitylib.common;
 
 import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
+import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
+import com.github.retrooper.packetevents.protocol.player.UserProfile;
 import com.github.retrooper.packetevents.protocol.world.Dimension;
 import com.github.retrooper.packetevents.protocol.world.Location;
 import me.tofaa.entitylib.EntityLib;
@@ -12,6 +14,7 @@ import me.tofaa.entitylib.meta.types.PlayerMeta;
 import me.tofaa.entitylib.wrapper.WrapperEntity;
 import me.tofaa.entitylib.wrapper.WrapperExperienceOrbEntity;
 import me.tofaa.entitylib.wrapper.WrapperLivingEntity;
+import me.tofaa.entitylib.wrapper.WrapperPlayer;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -37,6 +40,22 @@ public abstract class AbstractWorldWrapper<W> implements WorldWrapper<W> {
         this.entitiesById = new ConcurrentHashMap<>();
     }
 
+    @Override
+    public @NotNull WrapperPlayer spawnPlayer(UserProfile profile, Location location) {
+        if (getEntity(profile.getUUID()) != null) {
+            throw new IllegalArgumentException("Entity with UUID " + profile.getUUID() + " already exists in this world.");
+        }
+
+        int id = EntityLib.getPlatform().getEntityIdProvider().provide(profile.getUUID(), EntityTypes.PLAYER);
+        while (entitiesById.containsKey(id)) {
+            id = EntityLib.getPlatform().getEntityIdProvider().provide(profile.getUUID(), EntityTypes.PLAYER);
+        }
+        WrapperPlayer player = new WrapperPlayer(profile, id);
+        player.spawn(this, location);
+        entities.put(player.getUuid(), player);
+        entitiesById.put(player.getEntityId(), player);
+        return player;
+    }
 
     @Override
     public <T extends WrapperEntity> @NotNull T spawnEntity(@NotNull T entity, @NotNull Location location) {