diff --git a/src/main/java/de/towerdefence/server/match/Enemy.java b/src/main/java/de/towerdefence/server/match/Enemy.java
new file mode 100644
index 0000000..c1997ff
--- /dev/null
+++ b/src/main/java/de/towerdefence/server/match/Enemy.java
@@ -0,0 +1,13 @@
+package de.towerdefence.server.match;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+@AllArgsConstructor
+public class Enemy {
+    private int poxX;
+    private int posY;
+}
diff --git a/src/main/java/de/towerdefence/server/match/GameSession.java b/src/main/java/de/towerdefence/server/match/GameSession.java
new file mode 100644
index 0000000..050ed31
--- /dev/null
+++ b/src/main/java/de/towerdefence/server/match/GameSession.java
@@ -0,0 +1,45 @@
+package de.towerdefence.server.match;
+
+import de.towerdefence.server.match.callbacks.PlayerMoneyCallback;
+import de.towerdefence.server.match.exeptions.InvalidPlacementException;
+import de.towerdefence.server.match.exeptions.InvalidPlacementReason;
+import de.towerdefence.server.player.Player;
+import lombok.Getter;
+
+public class GameSession {
+    final static int START_MONEY = 50;
+    final static int MAP_SIZE_X = 10;
+    final static int MAP_SIZE_Y = 20;
+
+    private final Tower[][] towers = new Tower[MAP_SIZE_X][MAP_SIZE_Y];
+
+    private final Player player;
+    @Getter
+    private int money;
+    private final PlayerMoneyCallback moneyCallback;
+
+    public GameSession(Player player, PlayerMoneyCallback moneyCallback) {
+        this.player = player;
+        this.moneyCallback = moneyCallback;
+        this.money = START_MONEY;
+    }
+
+    public void placeTower(Tower tower, int x, int y) throws InvalidPlacementException {
+        if (x < 0 || y < 0 || x + 1 > MAP_SIZE_X || y + 1 > MAP_SIZE_Y) {
+            throw new InvalidPlacementException(InvalidPlacementReason.OUT_OF_BOUNDS);
+        }
+        if (towers[x][y] != null) {
+            throw new InvalidPlacementException(InvalidPlacementReason.LOCATION_USED);
+        }
+        if (money < Tower.COST) {
+            throw new InvalidPlacementException(InvalidPlacementReason.NOT_ENOUGH_MONEY);
+        }
+        money -= Tower.COST;
+        moneyCallback.call(player, money);
+        towers[x][y] = tower;
+    }
+
+    public void addMoney(int amount) {
+        money += amount;
+    }
+}
diff --git a/src/main/java/de/towerdefence/server/match/Match.java b/src/main/java/de/towerdefence/server/match/Match.java
index 7deb5d6..fb4ff50 100644
--- a/src/main/java/de/towerdefence/server/match/Match.java
+++ b/src/main/java/de/towerdefence/server/match/Match.java
@@ -1,9 +1,7 @@
 package de.towerdefence.server.match;
 
+import de.towerdefence.server.match.callbacks.PlayerMoneyCallback;
 import de.towerdefence.server.player.Player;
-import de.towerdefence.server.server.channels.match.money.PlayerMoneyCallback;
-import de.towerdefence.server.server.channels.match.placing.InvalidPlacementReason;
-import de.towerdefence.server.server.channels.match.placing.Tower;
 import lombok.Getter;
 
 import java.util.Optional;
@@ -11,21 +9,12 @@ import java.util.Optional;
 @Getter
 public class Match {
 
-    public static final int TOWER_PRICE = 20;
-    public final static int MAP_SIZE_X = 10;
-    public final static int MAP_SIZE_Y = 20;
-    public final static int START_MONEY = 50;
     private final String matchId;
     private final Player player1;
     private final Player player2;
-    private int player1Money = START_MONEY;
-    private int player2Money = START_MONEY;
-    private PlayerMoneyCallback player1MoneyCallback;
-    private PlayerMoneyCallback player2MoneyCallback;
-    private final Tower[][] player1Map = new Tower[MAP_SIZE_X][MAP_SIZE_Y];
-    private final Tower[][] player2Map = new Tower[MAP_SIZE_X][MAP_SIZE_Y];
-    private boolean isPlayer1Connected = false;
-    private boolean isPlayer2Connected = false;
+
+    private GameSession player1Session;
+    private GameSession player2Session;
 
     public Match(String matchId, Player player1, Player player2) {
         this.matchId = matchId;
@@ -33,100 +22,48 @@ public class Match {
         this.player2 = player2;
     }
 
-    public Player getOpponent(Player player) {
+    public Optional<Player> getOpponent(Player player) {
         boolean isPlayer1 = player1.equals(player);
         boolean isPlayer2 = player2.equals(player);
         if (!isPlayer1 && !isPlayer2) {
-            return null;
-        }
-        if (isPlayer1) {
-            return player2;
-        }
-        return player1;
-    }
-
-    /**
-     * @return opponent
-     */
-    public Player addTower(Player player, Tower tower, int x, int y) throws InvalidPlacementException {
-        if (player != player1 && player != player2) {
-            return null;
-        }
-        if (x < 0 || y < 0 || x + 1 > Match.MAP_SIZE_X || y + 1 > Match.MAP_SIZE_Y) {
-            throw new InvalidPlacementException(InvalidPlacementReason.OUT_OF_BOUNDS);
-        }
-        if (player == player1) {
-            if (player1Map[x][y] != null) {
-                throw new InvalidPlacementException(InvalidPlacementReason.LOCATION_USED);
-            }
-            removeMoney(player, TOWER_PRICE);
-            player1MoneyCallback.call(player1, player1Money);
-            player1Map[x][y] = tower;
-        } else {
-            if (player2Map[x][y] != null) {
-                throw new InvalidPlacementException(InvalidPlacementReason.LOCATION_USED);
-            }
-            removeMoney(player, TOWER_PRICE);
-            player2MoneyCallback.call(player2, player2Money);
-            player2Map[x][y] = tower;
-        }
-        return getOpponent(player);
-    }
-
-    // INFO: MoneyHandling
-
-    public Optional<Integer> getPlayerMoney(Player player) {
-        if (player != player1 && player != player2) {
             return Optional.empty();
         }
-        if (player == player1) {
-            return Optional.of(player1Money);
-        } else {
-            return Optional.of(player2Money);
+        if (isPlayer1) {
+            return Optional.of(player2);
+        }
+        return Optional.of(player1);
+    }
+
+    public Optional<GameSession> getPlayerGameSession(Player player) {
+        boolean isPlayer1 = player1.equals(player);
+        boolean isPlayer2 = player2.equals(player);
+        if (!isPlayer1 && !isPlayer2) {
+            return Optional.empty();
+        }
+        if (isPlayer1) {
+            return Optional.of(player1Session);
+        }
+        return Optional.of(player2Session);
+
+    }
+
+    public void connectPlayer(Player player, PlayerMoneyCallback moneyCallback) {
+        boolean isPlayer1 = player1.equals(player);
+        boolean isPlayer2 = player2.equals(player);
+        if (!isPlayer1 && !isPlayer2) {
+            return;
+        }
+        if (isPlayer1 && player1Session == null) {
+            this.player1Session = new GameSession(player, moneyCallback);
+            return;
+        }
+        if (isPlayer2 && player2Session == null) {
+            this.player2Session = new GameSession(player, moneyCallback);
+            return;
         }
     }
 
-    public void addMoney(int money) {
-        player1Money += money;
-        player2Money += money;
-    }
-
-    public void removeMoney(Player player, int price) throws InvalidPlacementException {
-        if (player == player1) {
-            if (price < player1Money) {
-                player1Money -= price;
-            } else {
-                throw new InvalidPlacementException(InvalidPlacementReason.NOT_ENOUGH_MONEY);
-            }
-        }
-        if (player == player2) {
-            if (price < player2Money) {
-                player2Money -= price;
-            } else {
-                throw new InvalidPlacementException(InvalidPlacementReason.NOT_ENOUGH_MONEY);
-            }
-        }
-    }
-
-    public void setPlayerMoneyCallback(Player player, PlayerMoneyCallback playerMoneyCallback) {
-        if (player == player1) {
-            this.player1MoneyCallback = playerMoneyCallback;
-        }
-        if (player == player2) {
-            this.player2MoneyCallback = playerMoneyCallback;
-        }
-    }
-
-    /**
-     * @return true if both players are connected
-     */
-    public boolean setPlayerConnected(Player player) {
-        if (player == player1) {
-            isPlayer1Connected = true;
-        }
-        if (player == player2) {
-            isPlayer2Connected = true;
-        }
-        return isPlayer1Connected && isPlayer2Connected;
+    public boolean hasMatchStarted() {
+        return player1Session != null && player2Session != null;
     }
 }
diff --git a/src/main/java/de/towerdefence/server/match/MatchService.java b/src/main/java/de/towerdefence/server/match/MatchService.java
index 234392c..dacb7d9 100644
--- a/src/main/java/de/towerdefence/server/match/MatchService.java
+++ b/src/main/java/de/towerdefence/server/match/MatchService.java
@@ -1,8 +1,10 @@
 package de.towerdefence.server.match;
 
+import de.towerdefence.server.match.callbacks.PlayerMoneyCallback;
+import de.towerdefence.server.match.exeptions.InvalidPlacementException;
+import de.towerdefence.server.match.exeptions.InvalidPlacementReason;
+import de.towerdefence.server.match.exeptions.NotInMatchException;
 import de.towerdefence.server.player.Player;
-import de.towerdefence.server.server.channels.match.money.PlayerMoneyCallback;
-import de.towerdefence.server.server.channels.match.placing.Tower;
 import org.springframework.stereotype.Service;
 
 import java.util.HashMap;
@@ -29,33 +31,53 @@ public class MatchService {
     /**
      * @return opponent
      */
-    public Player placeTower(Player player, int x, int y) throws InvalidPlacementException{
-        return playerMatches.get(player).addTower(player, new Tower(), x, y);
+    public Player placeTower(Player player, int x, int y) throws NotInMatchException, InvalidPlacementException {
+        Match match = playerMatches.get(player);
+        if (!match.hasMatchStarted()) {
+            throw new InvalidPlacementException(InvalidPlacementReason.MATCH_NOT_STARTED);
+        }
+        Optional<GameSession> playerSession = match.getPlayerGameSession(player);
+        if (playerSession.isEmpty()) {
+            throw new NotInMatchException();
+        }
+        Optional<Player> opponent = match.getOpponent(player);
+        if (opponent.isEmpty()) {
+            throw new NotInMatchException();
+        }
+        playerSession.get().placeTower(new Tower(), x, y);
+        return opponent.get();
     }
 
-
-    public void playerConnected(Player player, PlayerMoneyCallback callback) {
+    public void playerConnected(Player player, PlayerMoneyCallback moneyCallback) {
         Match match = playerMatches.get(player);
-        Optional<Integer> currentMoney = match.getPlayerMoney(player);
-        if (currentMoney.isEmpty()) {
+        match.connectPlayer(player, moneyCallback);
+        Optional<GameSession> optionalPlayerSession = match.getPlayerGameSession(player);
+        if (optionalPlayerSession.isEmpty()) {
             return;
         }
-        match.setPlayerMoneyCallback(player, callback);
-        callback.call(player, currentMoney.get());
-        boolean matchStarted =match.setPlayerConnected(player);
-        if (!matchStarted) {
+        GameSession playerSession = optionalPlayerSession.get();
+        moneyCallback.call(player, playerSession.getMoney());
+        if (!match.hasMatchStarted()) {
             return;
         }
+        Optional<Player> optionalOpponent = match.getOpponent(player);
+        if (optionalOpponent.isEmpty()) {
+            return;
+        }
+        Player opponent = optionalOpponent.get();
+        Optional<GameSession> optionalOpponentSession = match.getPlayerGameSession(opponent);
+        if (optionalOpponentSession.isEmpty()) {
+            return;
+        }
+        GameSession opponentSession = optionalOpponentSession.get();
         ScheduledFuture<?> moneyTask = scheduler.scheduleAtFixedRate(
-            () -> {
-                match.addMoney(3);
-                match.getPlayer1MoneyCallback().call(match.getPlayer1(), match.getPlayer1Money());
-                match.getPlayer2MoneyCallback().call(match.getPlayer2(), match.getPlayer2Money());
-            },
-            5,
-            5,
-            TimeUnit.SECONDS
-        );
+                () -> {
+                    playerSession.addMoney(3);
+                    opponentSession.addMoney(3);
+                },
+                5,
+                5,
+                TimeUnit.SECONDS);
         moneyTasks.put(match, moneyTask);
     }
 }
diff --git a/src/main/java/de/towerdefence/server/match/Tower.java b/src/main/java/de/towerdefence/server/match/Tower.java
new file mode 100644
index 0000000..ae8b146
--- /dev/null
+++ b/src/main/java/de/towerdefence/server/match/Tower.java
@@ -0,0 +1,5 @@
+package de.towerdefence.server.match;
+
+public class Tower {
+    public static final int COST = 20;
+}
diff --git a/src/main/java/de/towerdefence/server/server/channels/match/money/PlayerMoneyCallback.java b/src/main/java/de/towerdefence/server/match/callbacks/PlayerMoneyCallback.java
similarity index 72%
rename from src/main/java/de/towerdefence/server/server/channels/match/money/PlayerMoneyCallback.java
rename to src/main/java/de/towerdefence/server/match/callbacks/PlayerMoneyCallback.java
index dc1fb46..ae35600 100644
--- a/src/main/java/de/towerdefence/server/server/channels/match/money/PlayerMoneyCallback.java
+++ b/src/main/java/de/towerdefence/server/match/callbacks/PlayerMoneyCallback.java
@@ -1,4 +1,4 @@
-package de.towerdefence.server.server.channels.match.money;
+package de.towerdefence.server.match.callbacks;
 
 import de.towerdefence.server.player.Player;
 
diff --git a/src/main/java/de/towerdefence/server/match/InvalidPlacementException.java b/src/main/java/de/towerdefence/server/match/exeptions/InvalidPlacementException.java
similarity index 62%
rename from src/main/java/de/towerdefence/server/match/InvalidPlacementException.java
rename to src/main/java/de/towerdefence/server/match/exeptions/InvalidPlacementException.java
index ede36f3..eea167d 100644
--- a/src/main/java/de/towerdefence/server/match/InvalidPlacementException.java
+++ b/src/main/java/de/towerdefence/server/match/exeptions/InvalidPlacementException.java
@@ -1,6 +1,5 @@
-package de.towerdefence.server.match;
+package de.towerdefence.server.match.exeptions;
 
-import de.towerdefence.server.server.channels.match.placing.InvalidPlacementReason;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 
diff --git a/src/main/java/de/towerdefence/server/server/channels/match/placing/InvalidPlacementReason.java b/src/main/java/de/towerdefence/server/match/exeptions/InvalidPlacementReason.java
similarity index 74%
rename from src/main/java/de/towerdefence/server/server/channels/match/placing/InvalidPlacementReason.java
rename to src/main/java/de/towerdefence/server/match/exeptions/InvalidPlacementReason.java
index 5c16215..f741f39 100644
--- a/src/main/java/de/towerdefence/server/server/channels/match/placing/InvalidPlacementReason.java
+++ b/src/main/java/de/towerdefence/server/match/exeptions/InvalidPlacementReason.java
@@ -1,4 +1,4 @@
-package de.towerdefence.server.server.channels.match.placing;
+package de.towerdefence.server.match.exeptions;
 
 import lombok.AllArgsConstructor;
 import lombok.Getter;
@@ -6,6 +6,7 @@ import lombok.Getter;
 @Getter
 @AllArgsConstructor
 public enum InvalidPlacementReason {
+    MATCH_NOT_STARTED("match-not-started"),
     OUT_OF_BOUNDS("out-of-bounds"),
     LOCATION_USED("location-used"),
     NOT_ENOUGH_MONEY("not-enough-money");
diff --git a/src/main/java/de/towerdefence/server/match/exeptions/NotInMatchException.java b/src/main/java/de/towerdefence/server/match/exeptions/NotInMatchException.java
new file mode 100644
index 0000000..8297e23
--- /dev/null
+++ b/src/main/java/de/towerdefence/server/match/exeptions/NotInMatchException.java
@@ -0,0 +1,4 @@
+package de.towerdefence.server.match.exeptions;
+
+public class NotInMatchException extends RuntimeException {
+}
diff --git a/src/main/java/de/towerdefence/server/server/JsonWebsocketHandler.java b/src/main/java/de/towerdefence/server/server/JsonWebsocketHandler.java
index 29fd481..9359663 100644
--- a/src/main/java/de/towerdefence/server/server/JsonWebsocketHandler.java
+++ b/src/main/java/de/towerdefence/server/server/JsonWebsocketHandler.java
@@ -39,6 +39,7 @@ public abstract class JsonWebsocketHandler extends TextWebSocketHandler {
     protected void closeSession(WebSocketSession session, CloseStatus reason){
         if(session.isOpen()){
             try{
+                sessionPlayers.remove(session);
                 session.close(reason);
             } catch (Exception exception) {
                 logger.info("Unable to Close the Session", exception);
diff --git a/src/main/java/de/towerdefence/server/server/channels/match/MatchWebsocketHandler.java b/src/main/java/de/towerdefence/server/server/channels/match/MatchWebsocketHandler.java
index c02da6a..f9e48a0 100644
--- a/src/main/java/de/towerdefence/server/server/channels/match/MatchWebsocketHandler.java
+++ b/src/main/java/de/towerdefence/server/server/channels/match/MatchWebsocketHandler.java
@@ -1,8 +1,9 @@
 package de.towerdefence.server.server.channels.match;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
-import de.towerdefence.server.match.InvalidPlacementException;
 import de.towerdefence.server.match.MatchService;
+import de.towerdefence.server.match.exeptions.InvalidPlacementException;
+import de.towerdefence.server.match.exeptions.NotInMatchException;
 import de.towerdefence.server.player.Player;
 import de.towerdefence.server.server.JsonWebsocketHandler;
 import de.towerdefence.server.server.channels.match.money.PlayerMoneyMessage;
@@ -47,6 +48,13 @@ public class MatchWebsocketHandler extends JsonWebsocketHandler {
         }
     }
 
+    @Override
+    protected void closeSession(WebSocketSession session, CloseStatus reason) {
+        Player player = sessionPlayers.get(session);
+        super.closeSession(session, reason);
+        playerSessions.remove(player);
+    }
+
     @Override
     protected void handleTextMessage(WebSocketSession session, TextMessage message) {
         try {
@@ -80,6 +88,9 @@ public class MatchWebsocketHandler extends JsonWebsocketHandler {
         } catch (InvalidPlacementException exception) {
             new InvalidPlacementMessage(msg.getX(), msg.getY(), exception.getReason()).send(session);
             return;
+        } catch (NotInMatchException ignored) {
+            this.closeSession(session, CloseStatus.BAD_DATA);
+            return;
         }
         WebSocketSession opponentSession = playerSessions.get(opponent);
         new TowerPlacedMessage(msg.getX(), msg.getY(), GamePlayerMap.PLAYER).send(session);
diff --git a/src/main/java/de/towerdefence/server/server/channels/match/PlayerMoneyMessage.java b/src/main/java/de/towerdefence/server/server/channels/match/PlayerMoneyMessage.java
new file mode 100644
index 0000000..cc7428f
--- /dev/null
+++ b/src/main/java/de/towerdefence/server/server/channels/match/PlayerMoneyMessage.java
@@ -0,0 +1,26 @@
+package de.towerdefence.server.server.channels.match;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import de.towerdefence.server.server.JsonMessage;
+import lombok.AllArgsConstructor;
+
+import java.util.Map;
+
+@AllArgsConstructor
+public class PlayerMoneyMessage extends JsonMessage {
+
+    private final int playerMoney;
+
+    @Override
+    protected String getMessageId() {
+        return "PlayerMoney";
+    }
+
+    @Override
+    protected Map<String, JsonNode> getData(JsonNodeFactory factory) {
+        return Map.of(
+            "playerMoney", factory.numberNode(this.playerMoney)
+        );
+    }
+}
diff --git a/src/main/java/de/towerdefence/server/server/channels/match/placing/InvalidPlacementMessage.java b/src/main/java/de/towerdefence/server/server/channels/match/placing/InvalidPlacementMessage.java
index 9570a47..e96f542 100644
--- a/src/main/java/de/towerdefence/server/server/channels/match/placing/InvalidPlacementMessage.java
+++ b/src/main/java/de/towerdefence/server/server/channels/match/placing/InvalidPlacementMessage.java
@@ -2,6 +2,8 @@ package de.towerdefence.server.server.channels.match.placing;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+
+import de.towerdefence.server.match.exeptions.InvalidPlacementReason;
 import de.towerdefence.server.server.JsonMessage;
 import lombok.AllArgsConstructor;
 
@@ -22,9 +24,8 @@ public class InvalidPlacementMessage extends JsonMessage {
     @Override
     protected Map<String, JsonNode> getData(JsonNodeFactory factory) {
         return Map.of(
-            "x", factory.numberNode(this.x),
-            "y", factory.numberNode(this.y),
-            "reason", factory.textNode(this.reason.getJsonName())
-        );
+                "x", factory.numberNode(this.x),
+                "y", factory.numberNode(this.y),
+                "reason", factory.textNode(this.reason.getJsonName()));
     }
 }
diff --git a/src/main/java/de/towerdefence/server/server/channels/match/placing/Tower.java b/src/main/java/de/towerdefence/server/server/channels/match/placing/Tower.java
deleted file mode 100644
index d3008e9..0000000
--- a/src/main/java/de/towerdefence/server/server/channels/match/placing/Tower.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package de.towerdefence.server.server.channels.match.placing;
-
-public class Tower {
-}
diff --git a/src/main/resources/spotbugs-exclude.xml b/src/main/resources/spotbugs-exclude.xml
index 033d812..d737fbf 100644
--- a/src/main/resources/spotbugs-exclude.xml
+++ b/src/main/resources/spotbugs-exclude.xml
@@ -19,4 +19,10 @@
         <Class name="de.towerdefence.server.match.confirmation.MatchConfirmationService"/>
         <Bug code="M,D,SF"/>
     </Match>
+    <Match>
+        <!-- This is Only a Placeholder Object, thus it's not a bad practice to instance it-->
+        <Class name="de.towerdefence.server.match.MatchService"/>
+        <Method name="placeTower"/>
+        <Bug code="L,B,ISC"/>
+    </Match>
 </FindBugsFilter>
diff --git a/ws/ws.yml b/ws/ws.yml
index a0a9743..138364a 100644
--- a/ws/ws.yml
+++ b/ws/ws.yml
@@ -216,6 +216,7 @@ channels:
             reason:
               type: string
               enum:
+                - "match-not-started"
                 - "out-of-bounds"
                 - "location-used"
                 - "not-enough-money"