diff --git a/src/engine/gameManager/MultiboxManager.java b/src/engine/gameManager/MultiboxManager.java
new file mode 100644
index 00000000..1e3b2d7d
--- /dev/null
+++ b/src/engine/gameManager/MultiboxManager.java
@@ -0,0 +1,68 @@
+package engine.gameManager;
+
+import engine.objects.PlayerCharacter;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+public class MultiboxManager {
+    public static HashMap<String, ArrayList<PlayerCharacter>> activeCharacters = new HashMap<>();
+    public static ReentrantReadWriteLock updateLock = new ReentrantReadWriteLock();
+
+    public static void addPlayer(PlayerCharacter player){
+        updateLock.writeLock().lock();
+        try {
+
+            //get the machine ID for the key of the map
+            String machineID = player.getClientConnection().machineID;
+
+            //cleanup and remove inactive players from the list
+            ArrayList<PlayerCharacter> purgeList = new ArrayList<>();
+            for(PlayerCharacter pc : activeCharacters.get(machineID))
+                if(!pc.isEnteredWorld() || !pc.isActive())
+                    purgeList.add(pc);
+
+            activeCharacters.get(machineID).removeAll(purgeList);
+
+            //remove empty key
+            if(activeCharacters.get(machineID).size() < 1)
+                activeCharacters.remove(machineID);
+
+
+            if(activeCharacters.containsKey(machineID)){
+                //already has an entry for this machine ID
+                player.isBoxed = true;
+                activeCharacters.get(machineID).add(player);
+            }else{
+                //does not have an entry for this machine ID
+                player.isBoxed = false;
+                ArrayList<PlayerCharacter> newList = new ArrayList<>();
+                newList.add(player);
+                activeCharacters.put(machineID,newList);
+            }
+        } finally {
+            updateLock.writeLock().unlock();
+        }
+    }
+
+    public static void removePlayer(PlayerCharacter player){
+
+        //get the machine ID for the key of the map
+        String machineID = player.getClientConnection().machineID;
+
+        if(activeCharacters.containsKey(machineID)){
+            //remove player from existing list
+            activeCharacters.get(machineID).remove(player);
+
+            //check if there are still players in the machine ID key list
+            if(activeCharacters.get(machineID).size() > 1){
+                //list still has characters, make one of them active
+                activeCharacters.get(machineID).get(0).isBoxed = false;
+            }else{
+                //list is now empty, remove it from the map
+                activeCharacters.remove(machineID);
+            }
+        }
+    }
+}
diff --git a/src/engine/net/client/handlers/RequestEnterWorldHandler.java b/src/engine/net/client/handlers/RequestEnterWorldHandler.java
index 18b48254..cd31a3a8 100644
--- a/src/engine/net/client/handlers/RequestEnterWorldHandler.java
+++ b/src/engine/net/client/handlers/RequestEnterWorldHandler.java
@@ -8,6 +8,7 @@ import engine.db.archive.CharacterRecord;
 import engine.db.archive.DataWarehouse;
 import engine.db.archive.PvpRecord;
 import engine.exception.MsgSendException;
+import engine.gameManager.MultiboxManager;
 import engine.gameManager.SessionManager;
 import engine.math.Vector3fImmutable;
 import engine.net.Dispatch;
@@ -157,6 +158,8 @@ public class RequestEnterWorldHandler extends AbstractClientMsgHandler {
         dispatch = Dispatch.borrow(player, sopm);
         DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
 
+        MultiboxManager.addPlayer(player);
+
         return true;
     }
 
diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java
index c2bda26b..1236db3b 100644
--- a/src/engine/objects/PlayerCharacter.java
+++ b/src/engine/objects/PlayerCharacter.java
@@ -177,6 +177,8 @@ public class PlayerCharacter extends AbstractCharacter {
 
     public float ZergMultiplier = 1.0f;
 
+    public boolean isBoxed = false;
+
     /**
      * No Id Constructor
      */
@@ -4814,6 +4816,10 @@ public class PlayerCharacter extends AbstractCharacter {
 
                 this.safeZone = this.isInSafeZone();
 
+                if(this.isBoxed && !this.containsEffect(1672601862)) {
+                    PowersManager.applyPower(this, this, Vector3fImmutable.ZERO, 1672601862, 40, false);
+                }
+
             } catch (Exception e) {
                 Logger.error(e);
             } finally {
diff --git a/src/engine/server/world/WorldServer.java b/src/engine/server/world/WorldServer.java
index afc06004..8c77ace5 100644
--- a/src/engine/server/world/WorldServer.java
+++ b/src/engine/server/world/WorldServer.java
@@ -656,6 +656,7 @@ public class WorldServer {
 			// TODO log this
 			return;
 
+		MultiboxManager.removePlayer(playerCharacter);
 		//cancel any trade
 		if (playerCharacter.getCharItemManager() != null)
 			playerCharacter.getCharItemManager().endTrade(true);
@@ -705,6 +706,8 @@ public class WorldServer {
 			Logger.error("Unable to find PlayerCharacter to logout");
 			return;
 		}
+
+		MultiboxManager.removePlayer(player);
 		//remove player from loaded mobs agro maps
 		for(AbstractWorldObject awo : WorldGrid.getObjectsInRangePartial(player.getLoc(),MBServerStatics.CHARACTER_LOAD_RANGE,MBServerStatics.MASK_MOB)) {
 			Mob loadedMob = (Mob) awo;