diff --git a/README.md b/README.md
index 69625de7934d607289e90646606803cc8faefb41..d351a7e1c76dec53336acb562d9f67b5c8075daf 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,4 @@
 ## Hier könnte ihre Werbung stehn
+
+### Known issues
+ - Videos sometimes don't load in windows 11 especially on weaker systems
diff --git a/pom.xml b/pom.xml
index 4f37f2aaef6c006c1cdabb857ae7787128d71766..a1fe802d25b92f3c95961e9719ba2f9c6b28a779 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,6 +46,13 @@
             <scope>test</scope>
         </dependency>
 
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-junit-jupiter</artifactId>
+            <version>5.8.0</version>
+            <scope>test</scope>
+        </dependency>
+
         <dependency>
             <groupId>org.apache.logging.log4j</groupId>
             <artifactId>log4j-core</artifactId>
@@ -75,6 +82,12 @@
             <artifactId>gson</artifactId>
             <version>2.10.1</version>
         </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>RELEASE</version>
+            <scope>test</scope>
+        </dependency>
 
     </dependencies>
 
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Controller/Enum/GameMode.java b/src/main/java/de/hdm_stuttgart/battlearena/Controller/Enum/GameMode.java
new file mode 100644
index 0000000000000000000000000000000000000000..1979fc24fa3fbaf955b93b4b53942edfd080080c
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Controller/Enum/GameMode.java
@@ -0,0 +1,6 @@
+package de.hdm_stuttgart.battlearena.Controller.Enum;
+
+public enum GameMode {
+    LOCAL,
+    NETWORK
+}
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Controller/Enum/GameState.java b/src/main/java/de/hdm_stuttgart/battlearena/Controller/Enum/GameState.java
new file mode 100644
index 0000000000000000000000000000000000000000..1ea713b41a90fa593348760d6a6be8c9f0ed1a62
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Controller/Enum/GameState.java
@@ -0,0 +1,9 @@
+package de.hdm_stuttgart.battlearena.Controller.Enum;
+
+public enum GameState {
+    MENU,
+    PAUSE,
+    PLAYING,
+    LOST,
+    WON
+}
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Controller/Enum/PlayerMode.java b/src/main/java/de/hdm_stuttgart/battlearena/Controller/Enum/PlayerMode.java
new file mode 100644
index 0000000000000000000000000000000000000000..fb864e26dcdce0777bc7301cfeb51007063ba46f
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Controller/Enum/PlayerMode.java
@@ -0,0 +1,6 @@
+package de.hdm_stuttgart.battlearena.Controller.Enum;
+
+public enum PlayerMode {
+    PLAYER_ONE,
+    PLAYER_TWO
+}
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java b/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java
index 2d90bb00e2c3503261084d7acf6b1dfd98593c61..dc9b88e85c746bab7c651e5a6baae246eb4b94c4 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java
@@ -1,5 +1,9 @@
 package de.hdm_stuttgart.battlearena.Controller;
 
+import de.hdm_stuttgart.battlearena.Controller.Enum.GameMode;
+import de.hdm_stuttgart.battlearena.Controller.Enum.GameState;
+import de.hdm_stuttgart.battlearena.Controller.Enum.PlayerMode;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.RuntimeInfo;
 import de.hdm_stuttgart.battlearena.Model.Entity.EntityClass;
 import de.hdm_stuttgart.battlearena.Model.Entity.EntityFactory;
 import de.hdm_stuttgart.battlearena.Model.Entity.EntityType;
@@ -30,11 +34,15 @@ public class GameSceneController implements Initializable {
 
     InputHandler inputHandler = InputHandler.getInstance();
 
+    RuntimeInfo runtimeInfo = RuntimeInfo.getInstance();
+
+    GameMode gameMode = runtimeInfo.getGameMode();
+
     IEntity player;
     IEntity enemy;
 
-    EntityClass playerClass = EntityClass.HUMAN;
-    EntityClass enemyClass = EntityClass.HUMAN;
+    EntityClass playerOneClass = runtimeInfo.getPlayerOneClass();
+    EntityClass playerTwoClass = runtimeInfo.getPlayerTwoClass();
 
     TileManager tileManager;
 
@@ -46,7 +54,7 @@ public class GameSceneController implements Initializable {
                         "4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 1 2 3 " +
                         "4 1 1 1 2 2 4 1 3 3 3 1 1 1 3 2 2 3 " +
                         "4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 2 1 3 " +
-                        "4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 1 3 " +
+                        "4 1 5 1 2 2 4 3 3 1 4 3 3 3 3 2 1 3 " +
                         "4 1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 " +
                         "4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 1 3 " +
                         "4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 1 1 3 " +
@@ -59,7 +67,7 @@ public class GameSceneController implements Initializable {
                         "4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3";
     int horizontalTileCount = 18;
     int verticalTileCount = 18;
-    int diffTileCount = 5;
+    int diffTileCount = 6;
     int scaledTileSize = 48;
 
 
@@ -68,11 +76,20 @@ public class GameSceneController implements Initializable {
         graphicsContext2D = canvas2D.getGraphicsContext2D();
         graphicsContext2D.setImageSmoothing(false);
 
-        player = EntityFactory.createEntity(EntityType.PLAYER, graphicsContext2D, inputHandler, playerClass, this);
-        enemy = EntityFactory.createEntity(EntityType.ENEMY_PLAYER, graphicsContext2D, inputHandler, enemyClass, this);
+        player = EntityFactory.createEntity(EntityType.PLAYER, graphicsContext2D, inputHandler,
+                playerOneClass, this, PlayerMode.PLAYER_ONE);
+        if (gameMode == GameMode.NETWORK) {
+            enemy = EntityFactory.createEntity(EntityType.NETWORK_PLAYER_TWO, graphicsContext2D, inputHandler,
+                    playerTwoClass, this, PlayerMode.PLAYER_TWO);
+        } else {
+            enemy = EntityFactory.createEntity(EntityType.PLAYER, graphicsContext2D, inputHandler,
+                    playerTwoClass, this, PlayerMode.PLAYER_TWO);
+        }
 
         tileManager = new TileManager(graphicsContext2D, diffTileCount, horizontalTileCount, verticalTileCount, mapString);
 
+        runtimeInfo.setGameState(GameState.PLAYING);
+
         AnimationTimer gameLoop = new AnimationTimer() {
             @Override
             public void handle(long l) {
@@ -89,18 +106,25 @@ public class GameSceneController implements Initializable {
         player.updateEntityMovement(this);
         enemy.updateEntityMovement(this);
         player.attack(enemy, graphicsContext2D);
+        enemy.attack(player, graphicsContext2D);
     }
 
     private void renderContent(GraphicsContext graphicsContext) {
         tileManager.renderMap();
         player.renderEntity(graphicsContext);
         enemy.renderEntity(graphicsContext);
+        player.checkHealTile(player, graphicsContext2D);
+        enemy.checkHealTile(enemy, graphicsContext2D);
     }
 
     public IEntity getEnemy() {
         return enemy;
     }
 
+    public IEntity getPlayer() {
+        return player;
+    }
+
     public TileManager getTileManager() {
         return tileManager;
     }
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AppSettings.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AppSettings.java
index 24d7de8bba503c2d58df72b95d3de8901cd7a91b..710cf9ca3be97bbf21ff8aa00304dff1f8c19b87 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AppSettings.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AppSettings.java
@@ -2,19 +2,27 @@ package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
 
 public class AppSettings {
 
-    private Double sfxVolume;
-    private int musicVolume;
+    private int sfxVolume;      //values from 0 to 100 (volume in percent)
+    private int musicVolume;    //values from 0 to 100 (volume in percent)
 
 
-    public AppSettings(Double sfxVolume, int musicVolume) {
+    public AppSettings(int sfxVolume, int musicVolume) {
         this.sfxVolume = sfxVolume;
         this.musicVolume = musicVolume;
     }
 
-    public Double getSfxVolume() {
+    public void setSfxVolume(int sfxVolume) {
+        this.sfxVolume = sfxVolume;
+    }
+
+    public int getSfxVolume() {
         return sfxVolume;
     }
 
+    public void setMusicVolume(int musicVolume) {
+        this.musicVolume = musicVolume;
+    }
+
     public int getMusicVolume() {
         return musicVolume;
     }
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AzureDB.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AzureDB.java
index b138e76967b758555477fbde0c736ff98e2f7690..f75e8d1d4f322ef6b6c6302549337ea8b2a550b4 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AzureDB.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AzureDB.java
@@ -1,35 +1,30 @@
 package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
 
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities.CryptoUtils;
 import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.CryptoException;
 import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.SQLException;
-import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities.CryptoUtils;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
 import java.io.File;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
+import java.sql.*;
 import java.util.ArrayList;
 
-public class AzureDB implements ISQLDataBase {
+/*this class is only here for showcasing the interchangeability of the DBMS. AzureDB could be used as fallback database when primary database is unreachable*/
 
-    /*this class is only here for showcasing the interchangeability of the DBMS*/
+public class AzureDB implements ISQLDataBase {
 
     private static String user="";
     private static String password="";
     private static String[] parts= new String[2];
-
     static File encryptedFile = new File("src\\main\\resources\\database\\AzureDB_logindetails");
-
     private static final Logger log = LogManager.getLogger(OracleDB.class);
 
     public static void getLoginData() throws CryptoException {
         parts = CryptoUtils.decrypt(encryptedFile);
         user = parts[0];
         password = parts[1];
-        log.info("AzureDB_logindetails:  user: " + user + "  password: " +  password);
+        //log.info("AzureDB_logindetails:  user: " + user + "  password: " +  password);
     }
 
     @Override
@@ -37,18 +32,17 @@ public class AzureDB implements ISQLDataBase {
         try {
             getLoginData();
             String url = "jdbc:sqlserver://battlearena.database.windows.net;encrypt=true;user=" + user + ";password=" + password + ";databaseName=battleArena;";
-
-            log.info("Connecting to the database!");
             Connection connection = DriverManager.getConnection(url);
-            log.info("Database connection test" + connection.getCatalog());
-
+            //log.info("Database connection test" + connection.getCatalog());
             connection.setAutoCommit(true);
 
+            log.info("Connecting to SQL database ...");
+
             return connection;
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("SQL Connection Error! " + e.getMessage());
+            throw new SQLException("SQL connection error! " + e.getMessage());
         }
     }
 
@@ -59,20 +53,20 @@ public class AzureDB implements ISQLDataBase {
             String sql = "SELECT * FROM CoreMaps";
             PreparedStatement stmt = connection.prepareStatement(sql);
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             ResultSet rs = stmt.executeQuery();
 
             while(rs.next()){
                 newMaps.add(new MapData(rs.getString("map_id"), rs.getString("map_name"), rs.getInt("map_width"), rs.getInt("map_height"), rs.getString("map_data")));
             }
-            log.info("SQL query successful");
             rs.close();
             stmt.close();
+            log.info("Core-Maps retrieved successfully from SQL server!");
             return newMaps;
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving Coremaps! " + e.getMessage());
+            throw new SQLException("Error retrieving Core-Maps from SQL server! " + e.getMessage());
         }
     }
 
@@ -83,7 +77,7 @@ public class AzureDB implements ISQLDataBase {
             String sql = "SELECT map_id, map_name, map_width, map_height, map_downloads FROM communitymaps";
             PreparedStatement stmt = connection.prepareStatement(sql);
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             ResultSet rs = stmt.executeQuery();
 
             while(rs.next()){
@@ -91,12 +85,39 @@ public class AzureDB implements ISQLDataBase {
             }
             rs.close();
             stmt.close();
-            log.info("Community map names retrieved successfully");
+            log.info("Community-Map names retrieved successfully from SQL server!");
             return tempList;
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving community map names! " + e.getMessage());
+            throw new SQLException("Error retrieving Community-Map names from SQL server! " + e.getMessage());
+        }
+    }
+
+    @Override
+    public PlayerStatistics getStatistics(String playerName) throws SQLException {
+        try(Connection connection = connect()) {
+            String sql = "SELECT games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time FROM players WHERE player_name = ?";
+            PreparedStatement stmt = connection.prepareStatement(sql);
+            stmt.setString(1, playerName);
+
+            log.info("Sending SQL statement.");
+            ResultSet rs = stmt.executeQuery();
+            if(rs.next() == false){             //if no data matches
+                throw new SQLException("No match on SQL database!");
+            }
+            PlayerStatistics stats = new PlayerStatistics(0, 0, 0, 0, 0, 0);
+            while(rs.next()) {
+                stats = new PlayerStatistics(rs.getInt("games_won"), rs.getInt("games_lost"), rs.getInt("kills"), rs.getInt("deaths"), rs.getInt("blocks_destroyed"), rs.getInt("ingame_time"));
+            }
+            rs.close();
+            stmt.close();
+            log.info("Player statistics retrieved successfully from SQL server!");
+            return stats;
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("Error retrieving player statistics from SQL server! " + e.getMessage());
         }
     }
 
@@ -107,151 +128,143 @@ public class AzureDB implements ISQLDataBase {
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, mapID);
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             ResultSet rs = stmt.executeQuery();
             MapData mapChosen = new MapData("", "",0,0, "");
             if(rs.next() == false){             //if no data matches
-                throw new SQLException("No match on Database");
+                throw new SQLException("No match on SQL database!");
             }
             while(rs.next()) {
                 mapChosen = new MapData(rs.getString("map_id"), rs.getString("map_name"), rs.getInt("map_width"), rs.getInt("map_height"), rs.getString("map_data"));
             }
             rs.close();
             stmt.close();
-            log.info("Community map retrieved successfully");
+            log.info("Community-Map retrieved successfully from SQL server!");
 
             String sql2 = "UPDATE communitymaps SET map_downloads = map_downloads + 1 WHERE map_id = ?";
             PreparedStatement stmt2 = connection.prepareStatement(sql2);
             stmt2.setString(1, mapID);
             stmt2.executeQuery();
-            log.info("Sending SQL statement to update Download-Counter");
+            log.info("Sending SQL statement to update Download-Counter for downloaded map.");
             stmt2.close();
 
             return mapChosen;
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving community map! " + e.getMessage());
+            throw new SQLException("Error retrieving Community-Map from SQL server! " + e.getMessage());
         }
     }
 
     @Override
-    public void uploadCommunityMap(MapData map) throws SQLException {
+    public String checkCredentials(String playerName) throws SQLException {
         try(Connection connection = connect()) {
-            String sql = "INSERT INTO communitymaps (map_id, map_name, map_width, map_height, map_data) VALUES (?, ?, ?, ?, ?)";
+            String sql = "SELECT player_pw FROM players WHERE player_name = ?";
             PreparedStatement stmt = connection.prepareStatement(sql);
-            stmt.setString(1, map.getMapID());
-            stmt.setString(2, map.getMapName());
-            stmt.setInt(3, map.getMapWidth());
-            stmt.setInt(4, map.getMapHeight());
-            stmt.setString(5, map.getMapData());
+            stmt.setString(1, playerName);
 
-            log.info("Sending SQL statement");
-            stmt.executeQuery();
+            log.info("Sending SQL statement.");
+            ResultSet rs = stmt.executeQuery();
 
+            String password = "";
+            while(rs.next()) {
+                password = rs.getString("player_pw");
+            }
+            rs.close();
             stmt.close();
-            log.info("Community Map uploaded successfully");
+            log.info("Player credentials retrieved successfully from SQL server!");
+            return password;
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error uploading created community map! " + e.getMessage());
+            throw new SQLException("Error retrieving retrieving player credentials from SQL server! " + e.getMessage());
         }
     }
 
     @Override
-    public void createPlayer(String playerName, String playerPW) throws SQLException {
+    public void uploadCommunityMap(MapData map) throws SQLException {
         try(Connection connection = connect()) {
-            String sql = "INSERT INTO players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time) VALUES (?, ?, 0, 0, 0, 0, 0, 0)";
+            String sql = "INSERT INTO communitymaps (map_id, map_name, map_width, map_height, map_data, map_downloads) VALUES (?, ?, ?, ?, ?, 0)";
             PreparedStatement stmt = connection.prepareStatement(sql);
-            stmt.setString(1, playerName);
-            stmt.setString(2, playerPW);
+            stmt.setString(1, map.getMapID());
+            stmt.setString(2, map.getMapName());
+            stmt.setInt(3, map.getMapWidth());
+            stmt.setInt(4, map.getMapHeight());
+            stmt.setString(5, map.getMapData());
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             stmt.executeQuery();
 
             stmt.close();
-            log.info("Online account created successfully");
+            log.info("Community-Map uploaded successfully to SQL server!");
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error creating online account! " + e.getMessage());
+            throw new SQLException("Error uploading created Community-Map to SQL server! " + e.getMessage());
         }
     }
 
     @Override
-    public String checkCredentials(String playerName) throws SQLException {
+    public void createPlayer(String playerName, String playerPW) throws SQLException {
         try(Connection connection = connect()) {
-            String sql = "SELECT player_pw FROM players WHERE player_name = ?";
+            String sql = "INSERT INTO players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time) VALUES (?, ?, 0, 0, 0, 0, 0, 0)";
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, playerName);
+            stmt.setString(2, playerPW);
 
-            log.info("Sending SQL statement");
-            ResultSet rs = stmt.executeQuery();
+            log.info("Sending SQL statement.");
+            stmt.executeQuery();
 
-            String password = "";
-            while(rs.next()) {
-                password = rs.getString("player_pw");
-            }
-            rs.close();
             stmt.close();
-            log.info("Player credentials retrieved successfully");
-            return password;
+            log.info("Online account created successfully on SQL server!");
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving retrieving player credentials! " + e.getMessage());
+            throw new SQLException("Error creating online account on SQL server! " + e.getMessage());
         }
     }
 
     @Override
-    public PlayerStatistics getStatistics(String playerName) throws SQLException {
+    public void updatePlayerStats(PlayerStatistics stats, PlayerAccount account) throws SQLException {
         try(Connection connection = connect()) {
-            String sql = "SELECT games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time FROM players WHERE player_name = ?";
+            String sql = "UPDATE players SET games_won = ?, games_lost = ?, kills = ?, deaths = ?, blocks_destroyed = ?, ingame_time = ? WHERE player_name = ?";
             PreparedStatement stmt = connection.prepareStatement(sql);
-            stmt.setString(1, playerName);
+            stmt.setInt(1, stats.getGamesWon());
+            stmt.setInt(2, stats.getGamesLost());
+            stmt.setInt(3, stats.getKills());
+            stmt.setInt(4, stats.getDeaths());
+            stmt.setInt(5, stats.getBlocksDestroyed());
+            stmt.setInt(6, stats.getGameTime());
+            stmt.setString(7, account.getPlayerName());
+
+            log.info("Sending SQL statement.");
+            stmt.executeQuery();
 
-            log.info("Sending SQL statement");
-            ResultSet rs = stmt.executeQuery();
-            if(rs.next() == false){             //if no data matches
-                throw new SQLException("No match on Database");
-            }
-            PlayerStatistics stats = new PlayerStatistics(0, 0, 0, 0, 0, 0);
-            while(rs.next()) {
-                stats = new PlayerStatistics(rs.getInt("games_won"), rs.getInt("games_lost"), rs.getInt("kills"), rs.getInt("deaths"), rs.getInt("blocks_destroyed"), rs.getInt("ingame_time"));
-            }
-            rs.close();
             stmt.close();
-            log.info("Player statistics retrieved successfully");
-            return stats;
+            log.info("Player statistics updated successfully on SQL server!");
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving player statistics! " + e.getMessage());
+            throw new SQLException("Error updating player statistics on SQL server! " + e.getMessage());
         }
     }
 
     @Override
-    public void updatePlayerStats(PlayerStatistics stats, PlayerAccount account) throws SQLException {
+    public void resetPlayerStats(PlayerAccount account) throws SQLException{        //verification of player credentials necessary beforehand (use methode "verifyAccountData" in "Persistence.java)
         try(Connection connection = connect()) {
-            String sql = "UPDATE players SET games_won = ?, games_lost = ?, kills = ?, deaths = ?, blocks_destroyed = ?, ingame_time = ? WHERE player_name = ?";
+            String sql = "UPDATE players SET games_won = 0, games_lost = 0, kills = 0, deaths = 0, blocks_destroyed = 0, ingame_time = 0 WHERE player_name = ?";
             PreparedStatement stmt = connection.prepareStatement(sql);
-            stmt.setInt(1, stats.getGamesWon());
-            stmt.setInt(2, stats.getGamesLost());
-            stmt.setInt(3, stats.getKills());
-            stmt.setInt(4, stats.getDeaths());
-            stmt.setInt(5, stats.getBlocksDestroyed());
-            stmt.setInt(6, stats.getGameTime());
-            stmt.setString(7, account.getPlayerName());
+            stmt.setString(1, account.getPlayerName());
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             stmt.executeQuery();
 
             stmt.close();
-            log.info("Player statistics updated successfully");
+            log.info("Player statistics reset successfully on SQL server!");
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error updating player statistics! " + e.getMessage());
+            throw new SQLException("Error resetting player statistics on SQL server! " + e.getMessage());
         }
     }
 
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/GsonHandler.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/GsonHandler.java
index b330be1f110d65125e9dfb9b413adcac5c90a10e..308b553a68422590c8a0619baa336e91ee513bb2 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/GsonHandler.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/GsonHandler.java
@@ -37,12 +37,18 @@ public class GsonHandler {
         }
         try (FileReader reader = new FileReader(filePath)) {
             ArrayList<MapData> maps = gson.fromJson(reader, mapDataType);
-            log.info("GSON - Maps successfully loaded from JSON");
+            log.info("GSON - Maps successfully loaded from JSON!");
             return maps;
         } catch (Exception e) {
             log.info(e);
-            log.info("GSON - Loading maps from JSON failed");
-            throw new GSONException("Error loading maps!");
+            if(type == MapType.COREMAP){
+                log.info("GSON - Loading Core-Maps from JSON failed!");
+                throw new GSONException("Loading Core-Maps from JSON failed!");
+            }
+            else{
+                log.info("GSON - Loading Community-Maps from JSON failed!");
+                throw new GSONException("Loading Community-Maps from JSON failed!");
+            }
         }
     }
 
@@ -56,80 +62,86 @@ public class GsonHandler {
         }
         try (FileWriter writer = new FileWriter(filePath)) {
             gson.toJson(maps, writer);
-            log.info("GSON - Maps successfully saved to JSON");
+            log.info("GSON - Maps successfully saved to JSON!");
         } catch (Exception e) {
             log.info(e);
-            log.info("GSON - Saving maps to JSON failed");
-            throw new GSONException("Error saving maps!");
+            if(type == MapType.COREMAP){
+                log.info("GSON - Saving Core-Maps to JSON failed!");
+                throw new GSONException("Saving Core-Maps to JSON failed!");
+            }
+            else{
+                log.info("GSON - Saving Community-Maps to JSON failed!");
+                throw new GSONException("Saving Community-Maps to JSON failed!");
+            }
         }
     }
 
     public PlayerStatistics loadStats() throws GSONException {
         try (FileReader reader = new FileReader(filePathPlayerStats)) {
             PlayerStatistics stats = gson.fromJson(reader, playerStatsType);
-            log.info("GSON - Player statistics successfully loaded from JSON");
+            log.info("GSON - Player statistics successfully loaded from JSON!");
             return stats;
         } catch (Exception e) {
             log.info(e);
-            log.info("GSON - Loading player statistics from JSON failed");
-            throw new GSONException("Error loading player statistics!");
+            log.info("GSON - Loading player statistics from JSON failed!");
+            throw new GSONException("Loading player statistics from JSON failed!");
         }
     }
 
     public void saveStats(PlayerStatistics stats) throws GSONException {
         try (FileWriter writer = new FileWriter(filePathPlayerStats)) {
             gson.toJson(stats, writer);
-            log.info("GSON - Player statistics successfully saved to JSON");
+            log.info("GSON - Player statistics successfully saved to JSON!");
         } catch (Exception e) {
             log.info(e);
-            log.info("GSON - Saving player statistics to JSON failed");
-            throw new GSONException("Error saving player statistics!");
+            log.info("GSON - Saving player statistics to JSON failed!");
+            throw new GSONException("Saving player statistics to JSON failed!");
         }
     }
 
     public AppSettings loadSettings() throws GSONException {
         try (FileReader reader = new FileReader(filePathSettings)) {
             AppSettings settings = gson.fromJson(reader, settingsType);
-            log.info("GSON - Settings successfully loaded from JSON");
+            log.info("GSON - Settings successfully loaded from JSON!");
             return settings;
         } catch (Exception e) {
             log.info(e);
-            log.info("GSON - Loading settings from JSON failed");
-            throw new GSONException("Error Loading settings!");
+            log.info("GSON - Loading settings from JSON failed!");
+            throw new GSONException("Loading settings from JSON failed!");
         }
     }
 
     public void saveSettings(AppSettings settings) throws GSONException {
         try (FileWriter writer = new FileWriter(filePathSettings)) {
             gson.toJson(settings, writer);
-            log.info("GSON - Settings successfully saved to JSON");
+            log.info("GSON - Settings successfully saved to JSON!");
         } catch (Exception e) {
             log.info(e);
-            log.info("GSON - Saving settings to JSON failed");
-            throw new GSONException("Error saving settings!");
+            log.info("GSON - Saving settings to JSON failed!");
+            throw new GSONException("Saving settings to JSON failed!");
         }
     }
 
     public PlayerAccount loadAccount() throws GSONException {
         try (FileReader reader = new FileReader(filePathPlayerAccount)) {
             PlayerAccount account = gson.fromJson(reader, accountType);
-            log.info("GSON - Player account information successfully loaded from JSON");
+            log.info("GSON - Player account information successfully loaded from JSON!");
             return account;
         } catch (Exception e) {
             log.info(e);
-            log.info("GSON - Loading player account information from JSON failed");
-            throw new GSONException("Error loading player account information!");
+            log.info("GSON - Loading player account information from JSON failed!");
+            throw new GSONException("Loading player account information from JSON failed!");
         }
     }
 
     public void saveAccount(PlayerAccount account) throws GSONException {
         try (FileWriter writer = new FileWriter(filePathPlayerAccount)) {
             gson.toJson(account, writer);
-            log.info("GSON - Player account information successfully saved to JSON");
+            log.info("GSON - Player account information successfully saved to JSON!");
         } catch (Exception e) {
             log.info(e);
-            log.info("GSON - Saving player account information to JSON failed");
-            throw new GSONException("Error loading player account information!");
+            log.info("GSON - Saving player account information to JSON failed!");
+            throw new GSONException("Saving player account information to JSON failed!");
         }
     }
 
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/ISQLDataBase.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/ISQLDataBase.java
index dd7bb2f0eb72ddd6eac0a59ce72e0654f522a3ab..7a169c9b21d76b2a7eba64b8899dbb5e397b22cb 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/ISQLDataBase.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/ISQLDataBase.java
@@ -19,5 +19,6 @@ public interface ISQLDataBase {
     String checkCredentials(String playerName) throws SQLException;
     PlayerStatistics getStatistics(String playerName) throws SQLException;
     void updatePlayerStats(PlayerStatistics stats, PlayerAccount account) throws SQLException;
+    void resetPlayerStats(PlayerAccount account) throws SQLException;
 
 }
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/OracleDB.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/OracleDB.java
index 070e42d3bbd2fcbed93881fea80a7e5aac077733..856fe24df247e972c4ed074ddddce4fd1f71a1ce 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/OracleDB.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/OracleDB.java
@@ -12,18 +12,14 @@ import java.util.ArrayList;
 
 import oracle.jdbc.pool.OracleDataSource;
 
-
 public class OracleDB implements ISQLDataBase {
+
     private static String user="";
     private static String password="";
     private static String[] parts= new String[2];
-
     static File encryptedFile = new File("src\\main\\resources\\database\\OracleDB_logindetails");
-
-    //static File encryptedFile = new File("src\\main\\resources\\database\\document.encrypted");
-    //static File decryptedFile = new File("src\\main\\resources\\database\\document.decrypted");
-
     private static final Logger log = LogManager.getLogger(OracleDB.class);
+
     public static void getLoginData() throws CryptoException {
         parts = CryptoUtils.decrypt(encryptedFile);
         user = parts[0];
@@ -41,7 +37,7 @@ public class OracleDB implements ISQLDataBase {
             ods.setPassword(password);
             Connection conn = ods.getConnection();
 
-            log.info("Connecting to the database!");
+            log.info("Connecting to SQL database ...");
 
             return conn;
         }
@@ -58,20 +54,20 @@ public class OracleDB implements ISQLDataBase {
             String sql = "SELECT * FROM battlearenadata.coremaps";
             PreparedStatement stmt = connection.prepareStatement(sql);
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             ResultSet rs = stmt.executeQuery();
 
             while(rs.next()){
-             newMaps.add(new MapData(rs.getString("map_id"), rs.getString("map_name"), rs.getInt("map_width"), rs.getInt("map_height"), rs.getString("map_data")));
+                newMaps.add(new MapData(rs.getString("map_id"), rs.getString("map_name"), rs.getInt("map_width"), rs.getInt("map_height"), rs.getString("map_data")));
             }
             rs.close();
             stmt.close();
-            log.info("Coremaps retrieved successfully");
+            log.info("Core-Maps retrieved successfully from SQL server!");
             return newMaps;
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving coremaps! " + e.getMessage());
+            throw new SQLException("Error retrieving Core-Maps from SQL server! " + e.getMessage());
         }
     }
 
@@ -82,7 +78,7 @@ public class OracleDB implements ISQLDataBase {
             String sql = "SELECT map_id, map_name, map_width, map_height, map_downloads FROM battlearenadata.communitymaps";
             PreparedStatement stmt = connection.prepareStatement(sql);
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             ResultSet rs = stmt.executeQuery();
 
             while(rs.next()){
@@ -90,12 +86,39 @@ public class OracleDB implements ISQLDataBase {
             }
             rs.close();
             stmt.close();
-            log.info("Community map names retrieved successfully");
+            log.info("Community-Map names retrieved successfully from SQL server!");
             return tempList;
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving community map names! " + e.getMessage());
+            throw new SQLException("Error retrieving Community-Map names from SQL server! " + e.getMessage());
+        }
+    }
+
+    @Override
+    public PlayerStatistics getStatistics(String playerName) throws SQLException {
+        try(Connection connection = connect()) {
+            String sql = "SELECT games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time FROM battlearenadata.players WHERE player_name = ?";
+            PreparedStatement stmt = connection.prepareStatement(sql);
+            stmt.setString(1, playerName);
+
+            log.info("Sending SQL statement.");
+            ResultSet rs = stmt.executeQuery();
+            if(rs.next() == false){             //if no data matches
+                throw new SQLException("No match on SQL database!");
+            }
+            PlayerStatistics stats = new PlayerStatistics(0, 0, 0, 0, 0, 0);
+            while(rs.next()) {
+                stats = new PlayerStatistics(rs.getInt("games_won"), rs.getInt("games_lost"), rs.getInt("kills"), rs.getInt("deaths"), rs.getInt("blocks_destroyed"), rs.getInt("ingame_time"));
+            }
+            rs.close();
+            stmt.close();
+            log.info("Player statistics retrieved successfully from SQL server!");
+            return stats;
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("Error retrieving player statistics from SQL server! " + e.getMessage());
         }
     }
 
@@ -106,151 +129,143 @@ public class OracleDB implements ISQLDataBase {
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, mapID);
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             ResultSet rs = stmt.executeQuery();
             MapData mapChosen = new MapData("", "",0,0, "");
             if(rs.next() == false){             //if no data matches
-                throw new SQLException("No match on Database");
+                throw new SQLException("No match on SQL database!");
             }
             while(rs.next()) {
                 mapChosen = new MapData(rs.getString("map_id"), rs.getString("map_name"), rs.getInt("map_width"), rs.getInt("map_height"), rs.getString("map_data"));
             }
             rs.close();
             stmt.close();
-            log.info("Community map retrieved successfully");
+            log.info("Community-Map retrieved successfully from SQL server!");
 
             String sql2 = "UPDATE battlearenadata.communitymaps SET map_downloads = map_downloads + 1 WHERE map_id = ?";
             PreparedStatement stmt2 = connection.prepareStatement(sql2);
             stmt2.setString(1, mapID);
             stmt2.executeQuery();
-            log.info("Sending SQL statement to update Download-Counter");
+            log.info("Sending SQL statement to update Download-Counter for downloaded map!");
             stmt2.close();
 
             return mapChosen;
         }
         catch(Exception e){
-            log.error(e.getMessage());
-            throw new SQLException("Error retrieving community map! " + e.getMessage());
+            log.error(e);
+            throw new SQLException("Error retrieving Community-Map from SQL server! " + e.getMessage());
         }
     }
 
     @Override
-    public void uploadCommunityMap(MapData map) throws SQLException {
+    public String checkCredentials(String playerName) throws SQLException {
         try(Connection connection = connect()) {
-            String sql = "INSERT INTO battlearenadata.communitymaps (map_id, map_name, map_width, map_height, map_data) VALUES (?, ?, ?, ?, ?)";
+            String sql = "SELECT player_pw FROM battlearenadata.players WHERE player_name = ?";
             PreparedStatement stmt = connection.prepareStatement(sql);
-            stmt.setString(1, map.getMapID());
-            stmt.setString(2, map.getMapName());
-            stmt.setInt(3, map.getMapWidth());
-            stmt.setInt(4, map.getMapHeight());
-            stmt.setString(5, map.getMapData());
+            stmt.setString(1, playerName);
 
-            log.info("Sending SQL statement");
-            stmt.executeQuery();
+            log.info("Sending SQL statement.");
+            ResultSet rs = stmt.executeQuery();
 
+            String password = "";
+            while(rs.next()) {
+                password = rs.getString("player_pw");
+            }
+            rs.close();
             stmt.close();
-            log.info("Community Map uploaded successfully");
+            log.info("Player credentials retrieved successfully from SQL server!");
+            return password;
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error uploading created community map! " + e.getMessage());
+            throw new SQLException("Error retrieving retrieving player credentials from SQL server! " + e.getMessage());
         }
     }
 
     @Override
-    public void createPlayer(String playerName, String playerPW) throws SQLException {
+    public void uploadCommunityMap(MapData map) throws SQLException {
         try(Connection connection = connect()) {
-            String sql = "INSERT INTO battlearenadata.players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time) VALUES (?, ?, 0, 0, 0, 0, 0, 0)";
+            String sql = "INSERT INTO battlearenadata.communitymaps (map_id, map_name, map_width, map_height, map_data, map_downloads) VALUES (?, ?, ?, ?, ?, 0)";
             PreparedStatement stmt = connection.prepareStatement(sql);
-            stmt.setString(1, playerName);
-            stmt.setString(2, playerPW);
+            stmt.setString(1, map.getMapID());
+            stmt.setString(2, map.getMapName());
+            stmt.setInt(3, map.getMapWidth());
+            stmt.setInt(4, map.getMapHeight());
+            stmt.setString(5, map.getMapData());
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             stmt.executeQuery();
 
             stmt.close();
-            log.info("Online account created successfully");
+            log.info("Community-Map uploaded successfully to SQL server!");
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error creating online account! " + e.getMessage());
+            throw new SQLException("Error uploading created Community-Map to SQL server! " + e.getMessage());
         }
     }
 
     @Override
-    public String checkCredentials(String playerName) throws SQLException {
+    public void createPlayer(String playerName, String playerPW) throws SQLException {
         try(Connection connection = connect()) {
-            String sql = "SELECT player_pw FROM battlearenadata.players WHERE player_name = ?";
+            String sql = "INSERT INTO battlearenadata.players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time) VALUES (?, ?, 0, 0, 0, 0, 0, 0)";
             PreparedStatement stmt = connection.prepareStatement(sql);
             stmt.setString(1, playerName);
+            stmt.setString(2, playerPW);
 
-            log.info("Sending SQL statement");
-            ResultSet rs = stmt.executeQuery();
+            log.info("Sending SQL statement.");
+            stmt.executeQuery();
 
-            String password = "";
-            while(rs.next()) {
-                password = rs.getString("player_pw");
-            }
-            rs.close();
             stmt.close();
-            log.info("Player credentials retrieved successfully");
-            return password;
+            log.info("Online account created successfully on SQL server!");
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving retrieving player credentials! " + e.getMessage());
+            throw new SQLException("Error creating online account on SQL server! " + e.getMessage());
         }
     }
 
     @Override
-    public PlayerStatistics getStatistics(String playerName) throws SQLException {
+    public void updatePlayerStats(PlayerStatistics stats, PlayerAccount account) throws SQLException {
         try(Connection connection = connect()) {
-            String sql = "SELECT games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time FROM battlearenadata.players WHERE player_name = ?";
+            String sql = "UPDATE battlearenadata.players SET games_won = ?, games_lost = ?, kills = ?, deaths = ?, blocks_destroyed = ?, ingame_time = ? WHERE player_name = ?";
             PreparedStatement stmt = connection.prepareStatement(sql);
-            stmt.setString(1, playerName);
+            stmt.setInt(1, stats.getGamesWon());
+            stmt.setInt(2, stats.getGamesLost());
+            stmt.setInt(3, stats.getKills());
+            stmt.setInt(4, stats.getDeaths());
+            stmt.setInt(5, stats.getBlocksDestroyed());
+            stmt.setInt(6, stats.getGameTime());
+            stmt.setString(7, account.getPlayerName());
+
+            log.info("Sending SQL statement.");
+            stmt.executeQuery();
 
-            log.info("Sending SQL statement");
-            ResultSet rs = stmt.executeQuery();
-            if(rs.next() == false){             //if no data matches
-                throw new SQLException("No match on database");
-            }
-            PlayerStatistics stats = new PlayerStatistics(0, 0, 0, 0, 0, 0);
-            while(rs.next()) {
-                stats = new PlayerStatistics(rs.getInt("games_won"), rs.getInt("games_lost"), rs.getInt("kills"), rs.getInt("deaths"), rs.getInt("blocks_destroyed"), rs.getInt("ingame_time"));
-            }
-            rs.close();
             stmt.close();
-            log.info("Player statistics retrieved successfully");
-            return stats;
+            log.info("Player statistics updated successfully on SQL server!");
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error retrieving player statistics! " + e.getMessage());
+            throw new SQLException("Error updating player statistics on SQL server! " + e.getMessage());
         }
     }
 
     @Override
-    public void updatePlayerStats(PlayerStatistics stats, PlayerAccount account) throws SQLException {
+    public void resetPlayerStats(PlayerAccount account) throws SQLException{        //verification of player credentials necessary beforehand (use methode "verifyAccountData" in "Persistence.java)
         try(Connection connection = connect()) {
-            String sql = "UPDATE battlearenadata.players SET games_won = ?, games_lost = ?, kills = ?, deaths = ?, blocks_destroyed = ?, ingame_time = ? WHERE player_name = ?";
+            String sql = "UPDATE battlearenadata.players SET games_won = 0, games_lost = 0, kills = 0, deaths = 0, blocks_destroyed = 0, ingame_time = 0 WHERE player_name = ?";
             PreparedStatement stmt = connection.prepareStatement(sql);
-            stmt.setInt(1, stats.getGamesWon());
-            stmt.setInt(2, stats.getGamesLost());
-            stmt.setInt(3, stats.getKills());
-            stmt.setInt(4, stats.getDeaths());
-            stmt.setInt(5, stats.getBlocksDestroyed());
-            stmt.setInt(6, stats.getGameTime());
-            stmt.setString(7, account.getPlayerName());
+            stmt.setString(1, account.getPlayerName());
 
-            log.info("Sending SQL statement");
+            log.info("Sending SQL statement.");
             stmt.executeQuery();
 
             stmt.close();
-            log.info("Player statistics updated successfully");
+            log.info("Player statistics reset successfully on SQL server!");
         }
         catch(Exception e){
             log.error(e);
-            throw new SQLException("Error updating player statistics! " + e.getMessage());
+            throw new SQLException("Error resetting player statistics on SQL server! " + e.getMessage());
         }
     }
 
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Persistence.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Persistence.java
index d8dd5bf0303003f3ab525b04a8b2ea6db4588403..821e550fa965efefc270d13d7c332146c6cfc208 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Persistence.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Persistence.java
@@ -16,12 +16,15 @@ public class Persistence {
     private static final Logger log = LogManager.getLogger(Persistence.class);
     private static final Persistence persistenceSingleton = new Persistence();
     private final GsonHandler gsonHandler = new GsonHandler();
-    protected OracleDB db = new OracleDB(); //evtl. Methoden von OracleDB static machen und von GSON Handler
-    protected ArrayList<MapData> coreMaps;
-    protected ArrayList<MapData> communityMaps;
-    protected PlayerStatistics statistics;
-    protected PlayerAccount account;
+    protected OracleDB db = new OracleDB(); //evtl. Methoden von OracleDB static machen und von GSON Handler ; "protected" for testing purposes to showcase Mockito tests
+    private ArrayList<MapData> coreMaps;
+    private ArrayList<MapData> communityMaps;
+    private PlayerStatistics statistics;
+    private PlayerAccount account;
     private AppSettings settings;
+    //protected ArrayList<String> coreMapsListLocal;      //for drop-down list -- kommt eigentlich eher in RuntimeInfo
+    //protected ArrayList<String> communityMapsListLocal;  //for drop-down list -- kommt eigentlich eher in RuntimeInfo
+    protected ArrayList<MapInfo> communityMapsListRemote;  //for community map browser
 
 
 
@@ -31,10 +34,70 @@ public class Persistence {
         return persistenceSingleton;
     }
 
+    public ArrayList<MapData> getCoreMaps() {
+        return coreMaps;
+    }
+
+    public ArrayList<MapData> getCommunityMaps() {
+        return communityMaps;
+    }
+
+    public PlayerStatistics getStatistics() {
+        return statistics;
+    }
+
+    public PlayerAccount getAccount() {
+        return account;
+    }
+
+    public AppSettings getSettings() {
+        return settings;
+    }
+
+    public ArrayList<MapInfo> getCommunityMapsListRemote() {
+        return communityMapsListRemote;
+    }
+
+    public void loadPlayerAccount() throws DatabaseException {
+        try {
+            gsonHandler.loadAccount();
+            log.info("Player account successfully loaded!");
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new DatabaseException("Loading player account data from local storage failed!");
+        }
+    }
+
+    public void loadPlayerStatistics() throws DatabaseException {
+        try {
+            if (account.getAccountType() == AccountType.LOCAL) {
+                statistics = gsonHandler.loadStats();
+            } else {
+                statistics = db.getStatistics(account.getPlayerName());
+            }
+            log.info("Player statistics successfully loaded!");
+        }
+        catch(SQLException e){
+            log.error(e);
+            if(e.getMessage().contains("ORA-17868") | e.getMessage().contains("ORA-01017")){
+                throw new DatabaseException("No connection to SQL server!");
+            }
+            else{
+                throw new DatabaseException("Unknown Database Error. Retrieving statistics from SQL server failed!");
+            }
+        }
+        catch(GSONException e){
+            log.error(e);
+            throw new DatabaseException(e.getMessage());
+        }
+    }
+
     public void loadCoreMaps() throws DatabaseException {
         try {
             coreMaps = gsonHandler.loadMaps(MapType.COREMAP);
-            log.info("Core-Maps successfully loaded from file");
+            log.info("Core-Maps successfully loaded from file!");
+            //createCoreMapsList();
         }
         catch(Exception e){
             log.error(e);
@@ -45,7 +108,8 @@ public class Persistence {
     public void loadCommunityMaps() throws DatabaseException {
         try {
             communityMaps = gsonHandler.loadMaps(MapType.COMMUNITYMAP);
-            log.info("Community-Maps successfully loaded from file");
+            log.info("Community-Maps successfully loaded from file!");
+            //createLocalCommunityMapsList();
         }
         catch(Exception e){
             log.error(e);
@@ -53,11 +117,23 @@ public class Persistence {
         }
     }
 
+    public void loadSettings() throws DatabaseException {
+        try {
+            settings = gsonHandler.loadSettings();
+            log.info("Application settings successfully loaded from file!");
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new DatabaseException("Loading settings from local storage failed!");
+        }
+    }
+
     public void updateCoreMaps() throws DatabaseException {
         try {
             coreMaps = db.getCoreMaps();
             gsonHandler.saveMaps(coreMaps, MapType.COREMAP);
-            log.info("Maps successfully updated from SQL-Server");
+            //createCoreMapsList();
+            log.info("Core-Maps successfully updated from SQL-Server!");
         }
         catch(Exception e){
             log.error(e);
@@ -79,6 +155,7 @@ public class Persistence {
         try {
             communityMaps.add(db.getCommunityMapByID(mapID));
             gsonHandler.saveMaps(communityMaps, MapType.COMMUNITYMAP);
+            //createLocalCommunityMapsList();
             log.info("Community Map successfully retrieved from SQL-Server!");
         }
         catch(Exception e){
@@ -86,7 +163,7 @@ public class Persistence {
             if(e.getMessage().contains("ORA-17868") | e.getMessage().contains("ORA-01017")){
                 throw new DatabaseException("No connection to SQL server!");
             }
-            else if(e.getMessage().equals("No match on Database")){
+            else if(e.getMessage().equals("No match on Database!")){
                 throw new DatabaseException("No map existing for mapID: " + mapID);
             }
             else{
@@ -95,6 +172,39 @@ public class Persistence {
         }
     }
 
+    public MapData getGameMap(String mapSelected, boolean choseCoremaps) throws DatabaseException{
+
+        String mapID = mapSelected.substring(mapSelected.indexOf("(") + 1, mapSelected.length() - 1);
+        if (choseCoremaps) {
+            for (int index = 0; index < coreMaps.size(); index++) {
+                if (coreMaps.get(index).getMapID().equals(mapID)) {
+                    return coreMaps.get(index);
+                }
+            }
+        } else {
+            for (int index = 0; index < communityMaps.size(); index++) {
+                if (communityMaps.get(index).getMapID().equals(mapID)) {
+                    return coreMaps.get(index);
+                }
+            }
+        }
+        throw new DatabaseException("Database error - Map not found!");
+    }
+
+    public void savePlayerStatistics() throws DatabaseException{     //on shutdown of game
+        try {
+            if (account.getAccountType() == AccountType.LOCAL) {
+                gsonHandler.saveStats(statistics);
+            } else if (account.getAccountType() == AccountType.ONLINE) {
+                db.updatePlayerStats(statistics, account);
+            }
+            log.info("Statistics successfully saved!");
+        }
+        catch(Exception e){
+            log.error(e);
+        }
+    }
+
     public void saveCreatedMapLocally(MapData map) throws DatabaseException {
         try {
             for(int i = 0; communityMaps.size() > i; i++){
@@ -104,7 +214,8 @@ public class Persistence {
             }
             communityMaps.add(map);
             gsonHandler.saveMaps(communityMaps, MapType.COMMUNITYMAP);
-            log.info("Newly created map stored successfully in JSON");
+            //createLocalCommunityMapsList();
+            log.info("Newly created map stored successfully in JSON!");
         }
         catch(Exception e){
             log.error(e);
@@ -136,15 +247,18 @@ public class Persistence {
         }
     }
 
-    public void loadSettings() throws DatabaseException {
-        try {
-            settings = gsonHandler.loadSettings();
-            log.info("Application settings successfully loaded from file");
+    public void updatePlayerStatistics(int kills, int deaths, int gameTime, int blocksDestroyed, boolean gameWon) throws DatabaseException{  //after game round
+        statistics.addKills(kills);
+        statistics.addDeaths(deaths);
+        statistics.addGameTime(gameTime);
+        statistics.addBlocksDestroyed(blocksDestroyed);
+        if(gameWon){
+            statistics.addGamesWon();
         }
-        catch(Exception e){
-            log.error(e);
-            throw new DatabaseException("Loading settings from local storage failed!");
+        else{
+            statistics.addGamesLost();
         }
+        log.info("Statistics successfully updated!");
     }
 
     public void createAccount(String playerName, String password, AccountType type) throws DatabaseException {
@@ -163,6 +277,7 @@ public class Persistence {
                 throw new DatabaseException("Corrupted Account-Type. Please restart game.");
             }
             gsonHandler.saveAccount(account);
+            log.info("Player account successfully created!");
         }
         catch(ParserException e){
             log.error(e);
@@ -186,25 +301,41 @@ public class Persistence {
         }
     }
 
-    public void loadPlayerAccount() throws DatabaseException {
+    public void createRemoteCommunityMapsList(){        //for Map-Browser
         try {
-            gsonHandler.loadAccount();
+            communityMapsListRemote = db.getCommunityMapsList();
+            log.info("MapList successfully retrieved from server!");
+            //log.info(communityMapsListRemote.get(0).getMapName());                 //for testing purposes
         }
         catch(Exception e){
             log.error(e);
-            throw new DatabaseException("Loading player account data from local storage failed!");
         }
     }
 
+    //kommen beide eigentlich eher in die RuntimeInfo
+/*    public void createCoreMapsList(){               //for dropdown list in "create" scene
+        coreMapsListLocal = new ArrayList<String>();
+        for(int i = 0; i < coreMaps.size(); i++){
+            coreMapsListLocal.add(coreMaps.get(i).getMapName() + " (" + coreMaps.get(i).getMapID() + ")");
+        }
+    }
+
+    public void createLocalCommunityMapsList(){     //for dropdown list in "create" scene
+        communityMapsListLocal = new ArrayList<String>();
+        for (int i = 0; i < communityMaps.size(); i++) {
+            communityMapsListLocal.add(communityMaps.get(i).getMapName() + " (" + communityMaps.get(i).getMapID() + ")");
+        }
+    }*/
+
     public void verifyPlayerAccount() throws DatabaseException {
         try {
             if (account.getAccountType() == AccountType.NONE) {
-                throw new DatabaseException("Must create playerAccount first");
+                throw new DatabaseException("Must create playerAccount first!");
             } else if (account.getAccountType() == AccountType.LOCAL) {
                 Parser.usernameValid(account.getPlayerName());
             } else if (account.getAccountType() == AccountType.ONLINE) {
                 Parser.usernameValid(account.getPlayerName());
-                Parser.sha1HashValid(account.getAccountPassword());
+                Parser.sha1HexHashValid(account.getAccountPassword());
                 if (!(account.getAccountPassword().equals(db.checkCredentials(account.getPlayerName())))){
                     throw new DatabaseException("Locally stored password does not match online password. Please reenter credentials!");
                 }
@@ -212,6 +343,7 @@ public class Persistence {
             else{
                 throw new DatabaseException("AccountType invalid - accountData corrupted! Please create new Account or login with existing!");
             }
+            log.info("Player account successfully verified!");
         }
         catch(ParserException e){
             log.error(e);
@@ -222,7 +354,7 @@ public class Persistence {
             if(e.getMessage().contains("ORA-17868") | e.getMessage().contains("ORA-01017")){
                 throw new DatabaseException("No connection to SQL server! Do you want to continue without tracking statistics?");
             }
-            else if(e.getMessage().contains("No match on Database")){
+            else if(e.getMessage().contains("No match on SQL database!")){
                 throw new DatabaseException("No entry for player name " + account.getPlayerName() + " on SQL server. Please create account or login with different username!");
             }
             else{
@@ -235,48 +367,101 @@ public class Persistence {
         }
     }
 
-    public void loadPlayerStatistics() throws DatabaseException {
+    public void verifyCoreMaps() throws DatabaseException{
         try {
-            if (account.getAccountType() == AccountType.LOCAL) {
-                statistics = gsonHandler.loadStats();
-            } else {
-                statistics = db.getStatistics(account.getPlayerName());
+            for (int i = 0; coreMaps.size() > i; i++) {
+                Parser.mapDataValid(coreMaps.get(i).getMapData());
+                Parser.mapNameValid(coreMaps.get(i).getMapName());
+                Parser.sha1HexHashValid(coreMaps.get(i).getMapID());
+                if(!HashGenerator.hashAndHex(coreMaps.get(i).getMapData()).equals(coreMaps.get(i).getMapID())){
+                    throw new DatabaseException("mapData Hash does not match mapID!");
+                }
             }
+            log.info("Core-Maps data is valid!");
         }
-        catch(SQLException e){
+        catch(Exception e){
             log.error(e);
-            if(e.getMessage().contains("ORA-17868") | e.getMessage().contains("ORA-01017")){
-                throw new DatabaseException("No connection to SQL server!");
-            }
-            else{
-                throw new DatabaseException("Unknown Database Error. Retrieving statistics from SQL server failed!");
+            throw new DatabaseException(e.getMessage());
+        }
+    }
+
+    public void verifyCommunityMaps() throws DatabaseException{
+        try {
+            for (int i = 0; communityMaps.size() > i; i++) {
+                Parser.mapDataValid(communityMaps.get(i).getMapData());
+                Parser.mapNameValid(communityMaps.get(i).getMapName());
+                Parser.sha1HexHashValid(communityMaps.get(i).getMapID());
+                if(!HashGenerator.hashAndHex(communityMaps.get(i).getMapData()).equals(communityMaps.get(i).getMapID())){
+                    throw new DatabaseException("mapData Hash does not match mapID!");
+                }
             }
+            log.info("Community-Maps data is valid!");
         }
-        catch(GSONException e){
+        catch(Exception e){
             log.error(e);
             throw new DatabaseException(e.getMessage());
         }
     }
 
-    public void updatePlayerStatistics(int kills, int deaths, int gameTime, boolean gameWon){  //after game round
-        statistics.setKills(statistics.getKills() + kills);
-        statistics.setDeaths(statistics.getDeaths() + deaths);
-        statistics.setGameTime(statistics.getGameTime() + gameTime);
-        if(gameWon){
-            statistics.setGamesWon(statistics.getGamesWon() + 1);
+    public void verifyAppSettings() throws DatabaseException{
+        try {
+            Parser.volumeValid(settings.getSfxVolume());
+            Parser.volumeValid(settings.getMusicVolume());
+            log.info("Settings data is valid!");
         }
-        else{
-            statistics.setGamesWon(statistics.getGamesLost() + 1);
+        catch(Exception e){
+            log.error(e);
+            throw new DatabaseException(e.getMessage());
         }
     }
 
-    public void savePlayerStatistics(){     //on shutdown of game
+    public void resetPlayerStatistics() throws DatabaseException{
         try {
+            verifyPlayerAccount();
             if (account.getAccountType() == AccountType.LOCAL) {
+                statistics = new PlayerStatistics(0, 0, 0, 0, 0, 0);
                 gsonHandler.saveStats(statistics);
             } else if (account.getAccountType() == AccountType.ONLINE) {
-                db.updatePlayerStats(statistics, account);
+                db.resetPlayerStats(account);
+                statistics = new PlayerStatistics(0, 0, 0, 0, 0, 0);
             }
+            log.info("Player statistics successfully reset on local storage!");
+        }
+        catch(Exception e){
+            log.error(e);
+        }
+    }
+
+    public void resetSettings(){
+        settings = new AppSettings(50, 50);
+        try {
+            gsonHandler.saveSettings(settings);
+        }
+        catch(Exception e){
+            log.error(e);
+        }
+    }
+
+    public void resetCoreMaps(){
+        try {
+            coreMaps = new ArrayList<MapData>();
+            coreMaps.add(new MapData("09a02b54d05b5b7ebc29a4383ca12d3dda846b72", "Arena1", 18, 18, "12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+            coreMaps.add(new MapData("0ab15557ab6dc4be60dfe6a9b0288bac3036bd97", "Arena2", 18, 18, "12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 5 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+            gsonHandler.saveMaps(coreMaps, MapType.COREMAP);
+            log.info("Core maps successfully reset on local storage!");
+        }
+        catch(Exception e){
+            log.error(e);
+        }
+    }
+
+    public void resetCommunityMaps(){
+        try {
+            communityMaps = new ArrayList<MapData>();
+            communityMaps.add(new MapData("fbf44184867512faecc195ae75ca55d5ab7bad2d", "Arena3", 18, 18, "12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 8 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+            communityMaps.add(new MapData("1c23b362fd666c5fb7ed60ca611b17246424e49f", "Arena4", 18, 18, "12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 8 4 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+            gsonHandler.saveMaps(communityMaps, MapType.COMMUNITYMAP);
+            log.info("Community maps successfully reset on local storage!");
         }
         catch(Exception e){
             log.error(e);
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PlayerStatistics.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PlayerStatistics.java
index 532324238dd5b1b7a19c8de5a0555bc3e2c83fba..4f8783f2ee9afb7e50e038047615d63f4eaa8d20 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PlayerStatistics.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PlayerStatistics.java
@@ -11,7 +11,7 @@ public class PlayerStatistics {
     private int kills = 0;
     private int deaths = 0;
     private int blocksDestroyed = 0;
-    private int gameTime = 0;
+    private int gameTime = 0;   //in seconds
 
     public PlayerStatistics(int gamesLost, int gamesWon, int kills, int deaths, int blocksDestroyed, int gameTime) {
         this.gamesLost = gamesLost;
@@ -27,48 +27,52 @@ public class PlayerStatistics {
         return gamesLost;
     }
 
-    public void setGamesLost(int gamesLost) {
-        this.gamesLost = gamesLost;
+    protected void addGamesLost() {
+        gamesLost = gamesLost + 1;
     }
 
     public int getGamesWon() {
         return gamesWon;
     }
 
-    public void setGamesWon(int gamesWon) {
-        this.gamesWon = gamesWon;
+    protected void addGamesWon() {
+        gamesWon = gamesWon + 1;
     }
 
     public int getKills() {
         return kills;
     }
 
-    public void setKills(int kills) {
-        this.kills = kills;
+    protected void addKills(int kills) {
+        this.kills = this.kills + kills;
     }
 
     public int getDeaths() {
         return deaths;
     }
 
-    public void setDeaths(int deaths) {
-        this.deaths = deaths;
+    protected void addDeaths(int deaths) {
+        this.deaths = this.deaths + deaths;
     }
 
     public int getBlocksDestroyed() {
         return blocksDestroyed;
     }
 
-    public void setBlocksDestroyed(int blocksDestroyed) {
-        this.blocksDestroyed = blocksDestroyed;
+    protected void addBlocksDestroyed(int blocksDestroyed) {
+        this.blocksDestroyed = this.blocksDestroyed + blocksDestroyed;
     }
 
     public int getGameTime() {
         return gameTime;
     }
 
-    public void setGameTime(int gameTime) {
-        this.gameTime = gameTime;
+    public int getGameTimeInHours(){
+        return gameTime / 3600;
+    }
+
+    protected void addGameTime(int gameTime) {
+        this.gameTime = this.gameTime + gameTime;
     }
 
 }
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/RuntimeInfo.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/RuntimeInfo.java
index 641449a5164e3aaa72e5aef97324569ec1c7b3c2..bc2625856682cb2c90e56e0c5d57d8e1f602db8b 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/RuntimeInfo.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/RuntimeInfo.java
@@ -1,23 +1,28 @@
 package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
 
+import de.hdm_stuttgart.battlearena.Controller.Enum.GameMode;
+import de.hdm_stuttgart.battlearena.Controller.Enum.GameState;
 import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.ParserException;
 import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities.HashGenerator;
 import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities.Parser;
+import de.hdm_stuttgart.battlearena.Model.Entity.EntityClass;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
-import java.util.ArrayList;
-
 public class RuntimeInfo {
 
     private static final Logger log = LogManager.getLogger(RuntimeInfo.class);
     private static final RuntimeInfo runtimeInfoSingleton = new RuntimeInfo();
     private final Persistence persistenceInst = Persistence.getInstance();
-    protected ArrayList<String> coreMapsListLocal;      //for drop-down list
-    protected ArrayList<String> communityMapsListLocal;  //for drop-down list
-    protected ArrayList<MapInfo> communityMapsListRemote;  //for community map browser
-    protected String mapDataGame;
-    protected boolean offlineMode;  //if Account-Type is online but no SQL connection: start game without stats tracking
+    private String mapDataGame;
+    private MapData mapGame;
+    private boolean offlineMode;  //if Account-Type is online but no SQL connection: start game without stats tracking
+    private GameState gameState = GameState.MENU; //Default value: MENU
+    private GameMode gameMode = GameMode.LOCAL; //Default value: LOCAL
+
+    //Default value: HUMAN
+    private EntityClass playerOneClass = EntityClass.HUMAN;
+    private EntityClass playerTwoClass = EntityClass.HUMAN;
 
 
     private RuntimeInfo(){};
@@ -30,7 +35,7 @@ public class RuntimeInfo {
         return mapDataGame;
     }
 
-    public MapData createMap(String mapName, String mapData) throws ParserException {
+    public MapData generateMap(String mapName, String mapData) throws ParserException {
         try {
             Parser.mapDataValid(mapData);
             Parser.mapNameValid(mapName);
@@ -43,47 +48,45 @@ public class RuntimeInfo {
     }
 
     public void setGameMap(String mapSelected, boolean choseCoremaps){
-        String mapID = mapSelected.substring(mapSelected.indexOf("(") + 1, mapSelected.length() - 1);
-
-        if(choseCoremaps) {
-            for (int index = 0; index < persistenceInst.coreMaps.size(); index++) {
-                if (persistenceInst.coreMaps.get(index).getMapID().equals(mapID)) {
-                    mapDataGame = persistenceInst.coreMaps.get(index).getMapID();
-                }
-            }
+        try {
+            mapGame = persistenceInst.getGameMap(mapSelected, choseCoremaps);
+            mapDataGame = mapGame.getMapData();
         }
-        else  {
-            for (int index = 0; index < persistenceInst.communityMaps.size(); index++) {
-                if (persistenceInst.communityMaps.get(index).getMapID().equals(mapID)) {
-                    mapDataGame = persistenceInst.coreMaps.get(index).getMapID();
-                }
-            }
+        catch(Exception e){
+            log.error(e);
         }
     }
 
-    public void createCoreMapsList(){               //for dropdown list in "create" scene
-        coreMapsListLocal = new ArrayList<String>();
-        for(int i = 0; i < persistenceInst.coreMaps.size(); i++){
-            coreMapsListLocal.add(persistenceInst.coreMaps.get(i).getMapName() + " (" + persistenceInst.coreMaps.get(i).getMapID() + ")");
-        }
+    public GameState getGameState() {
+        return gameState;
     }
 
-    public void createLocalCommunityMapsList(){     //for dropdown list in "create" scene
-        communityMapsListLocal = new ArrayList<String>();
-        for (int i = 0; i < persistenceInst.communityMaps.size(); i++) {
-            communityMapsListLocal.add(persistenceInst.communityMaps.get(i).getMapName() + " (" + persistenceInst.communityMaps.get(i).getMapID() + ")");
-        }
+    public void setGameState(GameState gameState) {
+        this.gameState = gameState;
     }
 
-    public void createRemoteCommunityMapsList(){        //for Map-Browser
-        try {
-            communityMapsListRemote = persistenceInst.db.getCommunityMapsList();
-            log.info("MapList successfully retrieved from server!");
-            //log.info(communityMapsListRemote.get(0).getMapName());                 //for testing purposes
-        }
-        catch(Exception e){
-            log.error(e);
-        }
+    public GameMode getGameMode() {
+        return gameMode;
+    }
+
+    public void setGameMode(GameMode gameMode) {
+        this.gameMode = gameMode;
+    }
+
+    public EntityClass getPlayerOneClass() {
+        return playerOneClass;
+    }
+
+    public void setPlayerOneClass(EntityClass playerOneClass) {
+        this.playerOneClass = playerOneClass;
+    }
+
+    public EntityClass getPlayerTwoClass() {
+        return playerTwoClass;
+    }
+
+    public void setPlayerTwoClass(EntityClass playerTwoClass) {
+        this.playerTwoClass = playerTwoClass;
     }
 
 }
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/StartupThread.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/StartupThread.java
new file mode 100644
index 0000000000000000000000000000000000000000..a7ad2fddfea2cc499a0de9994f1bfe2b193f87aa
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/StartupThread.java
@@ -0,0 +1,28 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+public class StartupThread extends Thread{
+
+    private static final Logger log = LogManager.getLogger(StartupThread.class);
+
+    @Override
+    public void run() {
+
+        Persistence persistenceInst = Persistence.getInstance();
+
+        try {
+            persistenceInst.loadSettings();
+            persistenceInst.loadCoreMaps();
+            persistenceInst.loadCommunityMaps();
+            persistenceInst.verifyAppSettings();
+            persistenceInst.verifyCoreMaps();
+            persistenceInst.verifyCommunityMaps();
+            log.info("Startup routine part1 complete!");
+        } catch (Exception e) {
+            log.error(e);
+        }
+    }
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/Parser.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/Parser.java
index 4ccec6fc0d9eb8956792cdcc5290cbc1455dae10..29639d0bbadd65532cfa8b4b99c247c36ca1f634 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/Parser.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/Parser.java
@@ -1,6 +1,7 @@
 package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities;
 
 import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.ParserException;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.PlayerStatistics;
 
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -17,12 +18,14 @@ public class Parser {
     */
 
     public static void usernameValid(String username) throws ParserException {
+        int minUsernameLength = 4;
+        int maxUsernameLength = 40;
 
-        if(username.length() < 4){
-            throw new ParserException("Username too short! Min length is 4 characters.");
+        if(username.length() < minUsernameLength){
+            throw new ParserException("Username too short! Min length is " + minUsernameLength + " characters.");
         }
-        if(username.length() > 40){
-            throw new ParserException("Username too long! Max length is 40 characters.");
+        if(username.length() > maxUsernameLength){
+            throw new ParserException("Username too long! Max length is " + maxUsernameLength + " characters.");
         }
 
         Pattern pat = Pattern.compile("[^a-z0-9_-]", Pattern.CASE_INSENSITIVE);
@@ -34,12 +37,14 @@ public class Parser {
     }
 
     public static void passwordValid(String password) throws ParserException {
+        int minPasswordLength = 4;
+        int maxPasswordLength = 40;
 
-        if(password.length() < 4){
-            throw new ParserException("Password too short! Min length is 4 characters.");
+        if(password.length() < minPasswordLength){
+            throw new ParserException("Password too short! Min length is " + minPasswordLength + " characters.");
         }
-        if(password.length() > 40){
-            throw new ParserException("Password too long! Max length is 40 characters.");
+        if(password.length() > maxPasswordLength){
+            throw new ParserException("Password too long! Max length is " + maxPasswordLength + " characters.");
         }
 
         Pattern pat = Pattern.compile("[^a-z0-9_-]", Pattern.CASE_INSENSITIVE);
@@ -51,12 +56,14 @@ public class Parser {
     }
 
     public static void mapNameValid(String mapName) throws ParserException {
+        int minMapNameLength = 4;
+        int maxMapNameLength = 30;
 
-        if(mapName.length() < 4){
-            throw new ParserException("Map-Name too short! Min length is 4 characters.");
+        if(mapName.length() < minMapNameLength){
+            throw new ParserException("Map-Name too short! Min length is " + minMapNameLength + " characters.");
         }
-        if(mapName.length() > 30){
-            throw new ParserException("Map-Name too long! Max length is 30 characters.");
+        if(mapName.length() > maxMapNameLength){
+            throw new ParserException("Map-Name too long! Max length is " + maxMapNameLength + " characters.");
         }
 
         Pattern pat = Pattern.compile("[^a-z0-9_-]", Pattern.CASE_INSENSITIVE);
@@ -67,10 +74,11 @@ public class Parser {
         }
     }
 
-    public static void sha1HashValid(String mapID) throws ParserException {
+    public static void sha1HexHashValid(String mapID) throws ParserException {
+        int hashLength = 40;
 
-        if(!(mapID.length() == 40)){
-            throw new ParserException("Map-ID length not correct. Must have length of 40 characters!");
+        if(mapID.length() != hashLength){
+            throw new ParserException("Map-ID length not correct. Must have length of " + hashLength + " characters!");
         }
 
         Pattern pat = Pattern.compile("[^a-f0-9]");         //maybe make case-insensitive -> letters can be uppercase and still be valid hex number
@@ -83,112 +91,271 @@ public class Parser {
 
     public static void ipAddressValid(String address) throws ParserException {
 
+        int addressMinLength = 7;
+        int addressMaxLength = 15;
+        int addressLength = address.length();
+        int octetMinDecValue = 0;
+        int octetMaxDecValue = 255;
+
         if(address.equals("localhost")){
             return;
         }
 
-        if(address.length() > 15){
-            throw new ParserException("IP-Address too long. Must have length of 15 characters including octet dividers (.) !");
+        if(addressLength > addressMaxLength){
+            throw new ParserException("IP-Address too long. Must have maximum length of " + addressMaxLength + " characters including octet dividers (.) !");
         }
 
-        if(address.length() < 7){
-            throw new ParserException("IP-Address too short. Must have length of 7 characters including octet dividers (.) !");
+        if(addressLength < addressMinLength){
+            throw new ParserException("IP-Address too short. Must have minimum length of " + addressMinLength + " characters including octet dividers (.) !");
         }
 
-        if(address.charAt(0) == '.' | address.charAt(address.length()-1) == '.'){
+        if(address.charAt(0) == '.' | address.charAt(addressLength - 1) == '.'){
             throw new ParserException("IP-Address must not start nor end with octet dividers (.) !");
         }
 
         int counter = 0;
-        for(int i = 0; address.length() > i ; i++){
+        for(int i = 0; addressLength > i ; i++){
             if(address.charAt(i) == '.'){
                 counter++;
             }
         }
-        if(!(counter == 3)){
+        if(counter != 3){
             throw new ParserException("IP-Address must contain exactly 3 octet dividers (.) !");
         }
 
-        Pattern pat = Pattern.compile("[^0-9]");
-        for(int i = 0; address.length() > i ; i++){
-            if(!(address.charAt(i) == '.')){
-                Matcher mat = pat.matcher(address.substring(i, i+1));
-                boolean result = mat.find();
-                if(result){
-                    throw new ParserException("IP address does not consist out of numbers 0-9 and separators (.))!");
-                }
+        for(int i = 0; addressLength > i ; i++){
+            if(address.charAt(i) == '.' && address.charAt(i + 1) == '.'){
+                throw new ParserException("IP-Address must not contain two or more consecutive dividers (.) without number in between!");
+            }
+        }
+
+        Pattern pat = Pattern.compile("[^0-9.]");
+        for(int i = 0; addressLength > i ; i++){
+            Matcher mat = pat.matcher(address.substring(i, i+1));
+            boolean result = mat.find();
+            if(result){
+                throw new ParserException("IP address must consist out of numbers 0-9 and separators (.) !");
             }
         }
 
         counter = 0;
-        int[] positions = new int[5];
+        int[] positions = new int[4];
         positions[0] = 0;
-        positions[4] = address.length();
-        for(int i = 0; address.length() > i ; i++){
+        for(int i = 0; addressLength > i ; i++){
             if(address.charAt(i) == '.'){
                 counter++;
-                positions[counter] = i;
+                positions[counter] = i + 1;
             }
         }
-        for(int i = 0; 4 > i; i++){
-            if(Integer.parseInt(address.substring(positions[i], positions[i+1])) > 255){
-                throw new ParserException("Octets of IP-address must not exceed 255!");
+        for(int i = 0; positions.length > i; i++){
+            if(positions.length - 1 > i) {
+                if (Integer.parseInt(address.substring(positions[i], positions[i + 1] - 1)) > octetMaxDecValue) {
+                    throw new ParserException("Octets of IP-address must not exceed 255!");
+                }
             }
-            if(i < 3) {
-                positions[i + 1] = positions[i + 1] + 1;
+            else{
+                if (Integer.parseInt(address.substring(positions[i], addressLength)) > octetMaxDecValue) {
+                    throw new ParserException("Octets of IP-address must not exceed 255!");
+                }
             }
         }
     }
 
     public static void mapDataValid(String mapData) throws ParserException {
 
-        if(!(mapData.length() == 647)){
-            throw new ParserException("Map-Data corrupted - must have length of 647 chars including spaces!");
+        //values could be handed to method (Instance of MapData Class)
+        int actualMapDataLength = mapData.length();
+        int mapWidth = 18;         //Tiles
+        int mapHeight = 18;        //Tiles
+        int spacesAmount = (mapHeight * mapWidth) - 1;      //space used as separator
+        int totalTilesAmount = mapHeight * mapWidth;
+        int borderTilesAmount = (2 * mapWidth) + (2 * (mapHeight - 2));
+        int spawnTilesAmount = 4;
+        int fieldTilesAmount = totalTilesAmount - borderTilesAmount - spawnTilesAmount;
+        int maxTileNumberDigits = 2;  //Tile-Numbers are max 2 digits: 10 to 29
+        int minTileNumberDigits = 1; //Tile-Numbers are min 1 digit: 0 to 9
+        int minTileNumber = 0;
+        int maxTileNumber = 29;
+        int walkableTileMinNumber = 0;
+        int walkableTileMaxNumber = 9;
+        int indestructibleTileMinNumber = 10;
+        int indestructibleTileMaxNumber = 19;
+        int destructibleTileMinNumber = 20;
+        int destructibleTileMaxNumber = 29;
+        int maxMapDataLength = spacesAmount + borderTilesAmount * Integer.toString(indestructibleTileMaxNumber).length() + spawnTilesAmount * Integer.toString(walkableTileMaxNumber).length() + fieldTilesAmount * Integer.toString(destructibleTileMaxNumber).length();           //"Integer.toString(destructibleTileMaxNumber).length()" results in number of digits of destructibleTileMaxNumber
+        int minMapDataLength = spacesAmount + borderTilesAmount * Integer.toString(indestructibleTileMinNumber).length() + spawnTilesAmount * Integer.toString(walkableTileMinNumber).length() + fieldTilesAmount * Integer.toString(walkableTileMinNumber).length();
+
+        if(actualMapDataLength > maxMapDataLength){
+            throw new ParserException("Map-Data corrupted - mapData String must not exceed length of " + maxMapDataLength + " chars including spaces for " + mapWidth + "x" + mapHeight + " Tiles map!");
+        }
+
+        if(actualMapDataLength < minMapDataLength){
+            throw new ParserException("Map-Data corrupted - minimum length of mapData String must be " + minMapDataLength + " chars including spaces for " + mapWidth + "x" + mapHeight + " Tiles map!");
+        }
+
+        if(mapData.charAt(0) == ' ' | mapData.charAt(actualMapDataLength - 1) == ' '){
+            throw new ParserException("Map-Data corrupted - must not start nor end with space!");
+        }
+
+        for(int i = 0; actualMapDataLength > i ; i++){
+            if(mapData.charAt(i) == ' ' && mapData.charAt(i + 1) == ' '){
+                throw new ParserException("Map-Data corrupted - must not contain two or more consecutive spaces without number in between!");
+            }
+        }
+
+        int counter = 0;
+        for(int i = 0; i < actualMapDataLength; i++){
+            if((mapData.charAt(i) == ' ')){
+                counter++;
+            }
+        }
+        if(counter != spacesAmount){
+            throw new ParserException("Map-Data corrupted - number of spaces must be " + spacesAmount + "!");
         }
 
-        for(int i = 1; i < 647; i = i + 2){
-            if(!(mapData.charAt(i) == ' ')){
-                throw new ParserException("Map-Data corrupted - must use space every other character!");
+        Pattern pat = Pattern.compile("[^0-9 ]");
+        for(int i = 0; actualMapDataLength > i ; i++){
+            Matcher mat = pat.matcher(mapData.substring(i, i+1));
+            boolean result = mat.find();
+            if(result){
+                throw new ParserException("Map-Data corrupted - must consist out of numbers 0-9 and space as separator!");
             }
         }
 
-        for(int i = 0; i < 647; i = i + 2){
-            if((Integer.parseInt(mapData.substring(i, i+1)) > 4) | (Integer.parseInt(mapData.substring(i, i+1)) <= 0)){
-                throw new ParserException("Map-Data corrupted - Tile number must be between 1 and 4!");
+        counter = 0;
+        int[] positions = new int[totalTilesAmount];
+        positions[0] = 0;
+        for(int i = 0; actualMapDataLength > i ; i++){
+            if(mapData.charAt(i) == ' '){
+                counter++;
+                positions[counter] = i + 1;
+            }
+        }
+        for(int i = 0; positions.length > i; i++){
+            if(positions.length - 1 > i) {
+                if (Integer.parseInt(mapData.substring(positions[i], positions[i + 1] - 1)) > maxTileNumber | Integer.parseInt(mapData.substring(positions[i], positions[i + 1] - 1)) < minTileNumber) {
+                    throw new ParserException("Map-Data corrupted - Tile number must be between " + minTileNumber + " and " + maxTileNumber + "!");
+                }
+            }
+            else{
+                if (Integer.parseInt(mapData.substring(positions[i], actualMapDataLength)) > maxTileNumber | Integer.parseInt(mapData.substring(positions[i], actualMapDataLength)) < minTileNumber) {
+                    throw new ParserException("Map-Data corrupted - Tile number must be between " + minTileNumber + " and " + maxTileNumber + "!");
+                }
             }
         }
 
-        for(int i = 0; i < 18; i = i + 2){
-            if(!(Integer.parseInt(mapData.substring(i, i+1)) == 3)){
+        //Alternative code for checking if tile number is between minTileNumber and maxTileNumber:
+
+        /*
+        String combinedNumbers = "";
+        for(int i = 0; i < actualMapDataLength - 1; i++){
+            if(mapData.charAt(i+1) == ' '){
+                combinedNumbers = combinedNumbers + mapData.charAt(i);
+                if((Integer.parseInt(combinedNumbers) > maxTileNumber) | (Integer.parseInt(combinedNumbers) < minTileNumber)){
+                    throw new ParserException("Map-Data corrupted - Tile number must be between " + minTileNumber + " and " + maxTileNumber + "!");
+                }
+                combinedNumbers = "";
+                if(i < actualMapDataLength - 1){
+                    i++;
+                }
+            }
+            else if(i >= actualMapDataLength - 2){
+                combinedNumbers = combinedNumbers + mapData.charAt(i) + mapData.charAt(i+1);
+                if((Integer.parseInt(combinedNumbers) > maxTileNumber) | (Integer.parseInt(combinedNumbers) < minTileNumber)){
+                    throw new ParserException("Map-Data corrupted - Tile number must be between " + minTileNumber + " and " + maxTileNumber + "!");
+                }
+            }
+            else{
+                combinedNumbers = combinedNumbers + mapData.charAt(i);
+            }
+        }
+        */
+
+        //corner Tiles included
+        for(int i = 0; i < mapWidth; i++){
+            if(Integer.parseInt(mapData.substring(positions[i], positions[i+1] - 1)) > indestructibleTileMaxNumber | Integer.parseInt(mapData.substring(positions[i], positions[i+1] - 1)) < indestructibleTileMinNumber){
                 throw new ParserException("Map-Data corrupted - Top-Line must be border tiles!");
             }
         }
 
-        for(int i = 628; i < 647; i = i + 2){
-            if(!(Integer.parseInt(mapData.substring(i, i+1)) == 3)){
-                throw new ParserException("Map-Data corrupted - Bottom-Line must be border tiles!");
+        //corner Tiles included
+        for(int i = positions.length - mapWidth; i < positions.length; i++){
+            if(positions.length - 1 > i) {
+                if (Integer.parseInt(mapData.substring(positions[i], positions[i + 1] - 1)) > indestructibleTileMaxNumber | Integer.parseInt(mapData.substring(positions[i], positions[i + 1] - 1)) < indestructibleTileMinNumber) {
+                    throw new ParserException("Map-Data corrupted - Bottom-Line must be border tiles!");
+                }
+            }
+            else{
+                if (Integer.parseInt(mapData.substring(positions[i], actualMapDataLength)) > indestructibleTileMaxNumber | Integer.parseInt(mapData.substring(positions[i], actualMapDataLength)) < indestructibleTileMinNumber) {
+                    throw new ParserException("Map-Data corrupted - Bottom-Line must be border tiles!");
+                }
             }
         }
 
-        for(int i = 0; i < 647; i = i + 2){
-            if(i % 36 == 0 && !(Integer.parseInt(mapData.substring(i, i+1)) == 3)){
+        //corner Tiles excluded
+        for(int i = mapWidth; i < positions.length - mapWidth; i = i + mapWidth){
+            if(i % mapWidth == 0 && Integer.parseInt(mapData.substring(positions[i], positions[i + 1] - 1)) > indestructibleTileMaxNumber | Integer.parseInt(mapData.substring(positions[i], positions[i + 1] - 1)) < indestructibleTileMinNumber){
                 throw new ParserException("Map-Data corrupted - Left Edge must be border tiles!");
             }
         }
 
-        for(int i = 2; i < 647; i = i + 2){
-            if(i % 36 == 0 && !(Integer.parseInt(mapData.substring(i-2, i-1)) == 3)){
+        //corner Tiles excluded
+        for(int i = mapWidth - 1; i < positions.length - mapWidth; i = i + mapWidth){
+            if((i + 1) % mapWidth == 0 && Integer.parseInt(mapData.substring(positions[i], positions[i + 1] - 1)) > indestructibleTileMaxNumber | Integer.parseInt(mapData.substring(positions[i], positions[i + 1] - 1)) < indestructibleTileMinNumber){
                 throw new ParserException("Map-Data corrupted - Right Edge must be border tiles!");
             }
         }
 
-        if(!(Integer.parseInt(mapData.substring(38, 39)) == 1) | !(Integer.parseInt(mapData.substring(68, 69)) == 1)){
-            throw new ParserException("Map-Data corrupted - Player spawn must use walkable tile!");
+        if(Integer.parseInt(mapData.substring(positions[mapWidth + 1], positions[mapWidth + 2] - 1)) < walkableTileMinNumber | Integer.parseInt(mapData.substring(positions[mapWidth + 1], positions[mapWidth + 2] - 1)) > walkableTileMaxNumber){
+            throw new ParserException("Map-Data corrupted - Player spawn top left must use walkable tile!");
         }
 
-        if(!(Integer.parseInt(mapData.substring(578, 579)) == 1) | !(Integer.parseInt(mapData.substring(608, 609)) == 1)){
-            throw new ParserException("Map-Data corrupted - Player spawn must use walkable tile!");
+        if(Integer.parseInt(mapData.substring(positions[(mapWidth*2) - 2], positions[(mapWidth*2) - 1] - 1)) < walkableTileMinNumber | Integer.parseInt(mapData.substring(positions[(mapWidth*2) - 2], positions[(mapWidth*2) - 1] - 1)) > walkableTileMaxNumber){
+            throw new ParserException("Map-Data corrupted - Player spawn top right must use walkable tile!");
+        }
+
+        if(Integer.parseInt(mapData.substring(positions[positions.length - (mapWidth*2) + 1], positions[positions.length - (mapWidth*2) + 2] - 1)) < walkableTileMinNumber | Integer.parseInt(mapData.substring(positions[positions.length - (mapWidth*2) + 1], positions[positions.length - (mapWidth*2) + 2] - 1)) > walkableTileMaxNumber) {
+            throw new ParserException("Map-Data corrupted - Player spawn bottom left must use walkable tile!");
+        }
+
+        if(Integer.parseInt(mapData.substring(positions[positions.length - mapWidth - 2], positions[positions.length - mapWidth - 1] - 1)) < walkableTileMinNumber | Integer.parseInt(mapData.substring(positions[positions.length - mapWidth - 2], positions[positions.length - mapWidth - 1] - 1)) > walkableTileMaxNumber){
+            throw new ParserException("Map-Data corrupted - Player spawn bottom right must use walkable tile!");
+        }
+    }
+
+    public static void playerStatsValid(PlayerStatistics stats) throws ParserException{
+
+        if(stats.getGamesLost() < 0){
+            throw new ParserException("Player statistics data corrupted - Minimum value for lost games is 0!");
         }
+
+        if(stats.getGamesWon() < 0){
+            throw new ParserException("Player statistics data corrupted - Minimum value for won games is 0!");
+        }
+
+        if(stats.getKills() < 0){
+            throw new ParserException("Player statistics data corrupted - Minimum value for kills is 0!");
+        }
+
+        if(stats.getDeaths() < 0){
+            throw new ParserException("Player statistics data corrupted - Minimum value for deaths is 0!");
+        }
+
+        if(stats.getBlocksDestroyed() < 0){
+            throw new ParserException("Player statistics data corrupted - Minimum value for destroyed blocks is 0!");
+        }
+
+        if(stats.getGameTime() < 0){
+            throw new ParserException("Player statistics data corrupted - Minimum value for ingame time is 0 seconds!");
+        }
+    }
+
+    public static void volumeValid(int volume) throws ParserException{
+
+        if(volume > 100 | volume < 0){
+            throw new ParserException("Volume must be between 0 and 100!");
+        }
+
     }
 
 }
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_AzureDB.sql b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_AzureDB.sql
index 64e90f19dee42b333ff193b2041cbe3e29723604..3ee29cb25e3cc97a8a8f53e352dd1f90ff5a5707 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_AzureDB.sql
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_AzureDB.sql
@@ -11,14 +11,14 @@ CREATE TABLE coremaps(
                                          map_name VARCHAR(30) NOT NULL,
                                          map_width INTEGER NOT NULL,
                                          map_height INTEGER NOT NULL,
-                                         map_data VARCHAR(1682) NOT NULL UNIQUE); --allows for map size up to 29x29
+                                         map_data VARCHAR(1082) NOT NULL UNIQUE); --allows for map size up to 19x19 (when using double digit numbers for tiles)
 
 CREATE TABLE communitymaps(
                                               map_id CHAR(40) NOT NULL UNIQUE, --SHA1 hash is 40 chars length in hex
                                               map_name VARCHAR(30) NOT NULL,
                                               map_width INTEGER NOT NULL,
                                               map_height INTEGER NOT NULL,
-                                              map_data VARCHAR(1682) NOT NULL UNIQUE,  --allows for map size up to 29x29
+                                              map_data VARCHAR(1082) NOT NULL UNIQUE,  --allows for map size up to 19x19 (when using double digit numbers for tiles)
                                               map_downloads INTEGER NOT NULL);
 
 CREATE TABLE players(
@@ -33,25 +33,33 @@ CREATE TABLE players(
 
 
 INSERT INTO coremaps (map_id, map_name, map_width, map_height, map_data)
-VALUES ('72e1c81687463ab159b4cb8d935e347a26d7fe40',
+VALUES ('09a02b54d05b5b7ebc29a4383ca12d3dda846b72',
         'Arena1',
         18,
         18,
-        '3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3');
+        '12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12');
 
 INSERT INTO coremaps (map_id, map_name, map_width, map_height, map_data)
-VALUES ('f7e1fc56cefbacacb9ba403220476f3ac258de06',
+VALUES ('0ab15557ab6dc4be60dfe6a9b0288bac3036bd97',
         'Arena2',
         18,
         18,
-        '3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 3 3 1 1 1 1 1 3 1 3 3 3 1 1 1 3 1 1 3 3 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3');
+        '12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 5 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12');
 
 INSERT INTO communitymaps (map_id, map_name, map_width, map_height, map_data, map_downloads)
-VALUES ('c8ce8e85e4a9b99e4fa956e2486e55df73b2cf08',
-        'Arena1',
+VALUES ('fbf44184867512faecc195ae75ca55d5ab7bad2d',
+        'Arena3',
+        18,
+        18,
+        '12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 8 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12',
+        0);
+
+INSERT INTO communitymaps (map_id, map_name, map_width, map_height, map_data, map_downloads)
+VALUES ('1c23b362fd666c5fb7ed60ca611b17246424e49f',
+        'Arena4',
         18,
         18,
-        '3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 3 3 3 3 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 3 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3',
+        '12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 8 4 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12',
         0);
 
 INSERT INTO players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time)
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_Oracle.sql b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_Oracle.sql
index af8c0ca3e9ee71ca652b85f47c5ad018fa79725e..2e1959bf86f5d739a14878f45ae62ca8b2d04344 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_Oracle.sql
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_Oracle.sql
@@ -17,14 +17,14 @@ CREATE TABLE battlearenadata.coremaps(
                                          map_name VARCHAR(30) NOT NULL,
                                          map_width INTEGER NOT NULL,
                                          map_height INTEGER NOT NULL,
-                                         map_data VARCHAR(1682) NOT NULL UNIQUE); --allows for map size up to 29x29
+                                         map_data VARCHAR(1082) NOT NULL UNIQUE); --allows for map size up to 19x19 (when using double digit numbers for tiles)
 
 CREATE TABLE battlearenadata.communitymaps(
                                               map_id CHAR(40) NOT NULL UNIQUE, --SHA1 hash is 40 chars length in hex
                                               map_name VARCHAR(30) NOT NULL,
                                               map_width INTEGER NOT NULL,
                                               map_height INTEGER NOT NULL,
-                                              map_data VARCHAR(1682) NOT NULL UNIQUE,  --allows for map size up to 29x29
+                                              map_data VARCHAR(1082) NOT NULL UNIQUE,  --allows for map size up to 19x19 (when using double digit numbers for tiles)
                                               map_downloads INTEGER NOT NULL);
 
 CREATE TABLE battlearenadata.players(
@@ -42,25 +42,33 @@ ALTER USER battlearenadata QUOTA 500M ON communitymaps;
 ALTER USER battlearenadata QUOTA 500M ON players;
 
 INSERT INTO battlearenadata.coremaps (map_id, map_name, map_width, map_height, map_data)
-VALUES ('72e1c81687463ab159b4cb8d935e347a26d7fe40',
+VALUES ('09a02b54d05b5b7ebc29a4383ca12d3dda846b72',
         'Arena1',
         18,
         18,
-        '3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3');
+        '12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12');
 
 INSERT INTO battlearenadata.coremaps (map_id, map_name, map_width, map_height, map_data)
-VALUES ('f7e1fc56cefbacacb9ba403220476f3ac258de06',
+VALUES ('0ab15557ab6dc4be60dfe6a9b0288bac3036bd97',
         'Arena2',
         18,
         18,
-        '3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 3 3 1 1 1 1 1 3 1 3 3 3 1 1 1 3 1 1 3 3 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3');
+        '12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 5 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12');
 
 INSERT INTO battlearenadata.communitymaps (map_id, map_name, map_width, map_height, map_data, map_downloads)
-VALUES ('c8ce8e85e4a9b99e4fa956e2486e55df73b2cf08',
-        'Arena1',
+VALUES ('fbf44184867512faecc195ae75ca55d5ab7bad2d',
+        'Arena3',
+        18,
+        18,
+        '12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 8 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12',
+        0);
+
+INSERT INTO battlearenadata.communitymaps (map_id, map_name, map_width, map_height, map_data, map_downloads)
+VALUES ('1c23b362fd666c5fb7ed60ca611b17246424e49f',
+        'Arena4',
         18,
         18,
-        '3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 3 3 3 3 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 3 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3',
+        '12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 8 4 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12',
         0);
 
 INSERT INTO battlearenadata.players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time)
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/EntityFactory.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/EntityFactory.java
index d5b4b382213c197e503a598e855940aa18821998..2e49bcaca57667a7fbea0431ff0fe8c91b356ac5 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/EntityFactory.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/EntityFactory.java
@@ -1,5 +1,6 @@
 package de.hdm_stuttgart.battlearena.Model.Entity;
 
+import de.hdm_stuttgart.battlearena.Controller.Enum.PlayerMode;
 import de.hdm_stuttgart.battlearena.Controller.GameSceneController;
 import de.hdm_stuttgart.battlearena.Model.Inputs.InputHandler;
 
@@ -12,13 +13,14 @@ public class EntityFactory {
 
     private static final Logger log = LogManager.getLogger(EntityFactory.class);
 
-    public static IEntity createEntity(EntityType entityType, GraphicsContext gameScene, InputHandler inputHandler, EntityClass entityClass, GameSceneController gameSceneController) {
+    public static IEntity createEntity(EntityType entityType, GraphicsContext gameScene, InputHandler inputHandler,
+                                       EntityClass entityClass, GameSceneController gameSceneController, PlayerMode playerMode) {
         if (entityType == EntityType.PLAYER) {
             log.debug("Entity " + entityType + " created");
-            return new Player(gameScene, inputHandler, entityClass, gameSceneController);
-        } else if (entityType == EntityType.ENEMY_PLAYER) {
+            return new Player(gameScene, inputHandler, entityClass, gameSceneController, playerMode);
+        } else if (entityType == EntityType.NETWORK_PLAYER_TWO) {
             log.debug("Entity " + entityType + " created");
-            return new EnemyHandler();
+            return new NetworkPlayerTwo();
         }
 
         throw new IllegalArgumentException ("Entity type not supported " + entityType);
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/EntityType.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/EntityType.java
index 3e8560772b2e9f049e217bdeca99c30c24150e11..108c4c2037dbcb53d090dc19a59b9b79450d6b68 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/EntityType.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/EntityType.java
@@ -2,5 +2,6 @@ package de.hdm_stuttgart.battlearena.Model.Entity;
 
 public enum EntityType {
     PLAYER,
-    ENEMY_PLAYER
+    NETWORK_PLAYER_TWO,
+    LOKAL_PLAYER_TWO
 }
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/IEntity.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/IEntity.java
index 92ca5b53906697c1bad96c2cbb59524b7bc2c40b..f98ddeb7452f60866c2dfe661dff29162c0004b7 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/IEntity.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/IEntity.java
@@ -12,19 +12,23 @@ public interface IEntity {
 
    void updateEntityMovement(GameSceneController gameScene);
 
+   void checkHealTile(IEntity entity, GraphicsContext graphicsContext);
+
    void attack(IEntity entity, GraphicsContext graphicsContext);
 
    void updateEntityWalkAnimation();
 
    void renderEntity(GraphicsContext graphicsContext);
 
-   BoundingBox getBoxCollider();
+    void healPlayer(int heal);
+
+    BoundingBox getBoxCollider();
 
    EntityDirection getEntityDirection();
 
    int getEntitySpeed();
 
-   int gotHit(int damageDone);
+   void gotHit(int damageDone);
 
    int getMapPosX();
 
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/EnemyHandler.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/NetworkPlayerTwo.java
similarity index 75%
rename from src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/EnemyHandler.java
rename to src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/NetworkPlayerTwo.java
index c8fc714cc5aa2eefe30e616b5211fe76e6457ff2..d045a108bf051f2e40573e084199808f2edbc630 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/EnemyHandler.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/NetworkPlayerTwo.java
@@ -9,9 +9,9 @@ import javafx.scene.paint.Color;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.LogManager;
 
-class EnemyHandler implements IEntity{
+class NetworkPlayerTwo implements IEntity{
 
-    private static final Logger log = LogManager.getLogger(EnemyHandler.class);
+    private static final Logger log = LogManager.getLogger(NetworkPlayerTwo.class);
 
     private final BoundingBox boxCollider = new BoundingBox(300, 200, 48, 48);
 
@@ -36,6 +36,11 @@ class EnemyHandler implements IEntity{
 
     }
 
+    @Override
+    public void checkHealTile(IEntity entity, GraphicsContext graphicsContext) {
+
+    }
+
     @Override
     public void attack(IEntity entity, GraphicsContext graphicsContext) {
 
@@ -52,6 +57,12 @@ class EnemyHandler implements IEntity{
         graphicsContext.fillRect(300, 200, 48, 48);
     }
 
+    @Override
+    public void healPlayer(int heal) {
+        log.info("Network player health: " + health);
+        health -= heal;
+    }
+
     @Override
     public BoundingBox getBoxCollider() {
         return boxCollider;
@@ -68,9 +79,9 @@ class EnemyHandler implements IEntity{
     }
 
     @Override
-    public int gotHit(int damageDone) {
-        log.debug(health);
-        return health -= damageDone;
+    public void gotHit(int damageDone) {
+        log.debug("Network player health: " + health);
+        health -= damageDone;
     }
 
     @Override
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/Player.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/Player.java
index fffccf712e14e8a655bbc72622fae7e4c0d5d3b8..0eaf4b2ca5c23f540e284e5ef6e80bf1be36037f 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/Player.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Entity/Player.java
@@ -1,8 +1,10 @@
 package de.hdm_stuttgart.battlearena.Model.Entity;
 
+import de.hdm_stuttgart.battlearena.Controller.Enum.PlayerMode;
 import de.hdm_stuttgart.battlearena.Controller.GameSceneController;
 import de.hdm_stuttgart.battlearena.Model.Inputs.InputHandler;
 
+import de.hdm_stuttgart.battlearena.Model.Map.TileManager;
 import javafx.geometry.BoundingBox;
 import javafx.scene.canvas.GraphicsContext;
 import javafx.scene.image.Image;
@@ -16,6 +18,8 @@ class Player implements IEntity {
 
     private static final Logger log = LogManager.getLogger(Player.class);
 
+    private final PlayerMode PLAYER_MODE;
+
     InputHandler inputHandler;
     CollisionHandler collisionHandler = new CollisionHandler();
 
@@ -51,17 +55,24 @@ class Player implements IEntity {
 
     private int mapPosX;
     private int mapPosY;
+
+    private int lastMapPosX;
+    private int lastMapPosY;
+
     private int playerSpeed;
     private EntityDirection playerDirection;
 
-    private int health = 10;
-    private int damage = 1;
+    private int health;
+    private  int maxPlayerHealth;
+    private int damage;
 
-    public Player(GraphicsContext gameScene, InputHandler inputHandler, EntityClass entityClass, GameSceneController gameSceneController) {
+    public Player(GraphicsContext gameScene, InputHandler inputHandler, EntityClass entityClass,
+                  GameSceneController gameSceneController, PlayerMode PLAYER_MODE) {
         this.gameScene = gameScene;
         this.inputHandler = inputHandler;
         this.entityClass = entityClass;
         this.gameSceneController = gameSceneController;
+        this.PLAYER_MODE = PLAYER_MODE;
 
         initializeEntity();
         loadEntitySprites();
@@ -70,13 +81,45 @@ class Player implements IEntity {
     @Override
     public void initializeEntity() {
         scaledTileSize = gameSceneController.getScaledTileSize();
-        mapPosX = 60;
-        mapPosY = 60;
-        boxCollider = new BoundingBox(mapPosX+15,mapPosY+10, playerWidth, playerHeight);
-        playerSpeed = 5;
+        if (PLAYER_MODE == PlayerMode.PLAYER_ONE) {
+            mapPosX = 60;
+            mapPosY = 60;
+        } else if (PLAYER_MODE == PlayerMode.PLAYER_TWO) {
+            mapPosX = 760;
+            mapPosY = 735;
+        }
+
+        initializePlayerStats();
+
+        boxCollider = new BoundingBox(mapPosX + 15, mapPosY + 10, playerWidth, playerHeight);
         playerDirection = EntityDirection.DOWN;
     }
 
+    //Values result from balancing
+    private void initializePlayerStats() {
+        if (entityClass == EntityClass.HUMAN) {
+            maxPlayerHealth = 50;
+            health = 50;
+            damage = 5;
+            playerSpeed = 5;
+        } else if (entityClass == EntityClass.HIGH_BORN) {
+            maxPlayerHealth = 100;
+            health = 75;
+            damage = 2;
+            playerSpeed = 3;
+        } else if (entityClass == EntityClass.LOW_BORN) {
+            maxPlayerHealth = 10;
+            health = 10;
+            damage = 10;
+            playerSpeed = 7;
+        } else {
+            maxPlayerHealth = 40;
+            health = 15;
+            damage = 7;
+            playerSpeed = 5;
+        }
+    }
+
     @Override
     public void loadEntitySprites() {
         try {
@@ -99,19 +142,19 @@ class Player implements IEntity {
     }
 
     private void loadHumanSprites() {
-        directionDownOne = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/HumanDown01.png")));
-        directionDownTwo = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/HumanDown02.png")));
-        directionUpOne = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/upOne.png")));
-        directionUpTwo = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/upTwo.png")));
-        directionLeftOne = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/leftOne.png")));
-        directionLeftTwo = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/leftTwo.png")));
-        directionRightOne = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/rightOne.png")));
-        directionRightTwo = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/rightTwo.png")));
+        directionDownOne = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/human/HumanDown00.png")));
+        directionDownTwo = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/human/HumanDown01.png")));
+        directionUpOne = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/human/HumanUp00.png")));
+        directionUpTwo = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/human/HumanUp01.png")));
+        directionLeftOne = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/human/HumanLeft00.png")));
+        directionLeftTwo = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/human/HumanLeft01.png")));
+        directionRightOne = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/human/HumanRight00.png")));
+        directionRightTwo = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/human/HumanRight01.png")));
     }
 
     private void loadHighBornSprites() {
-        directionDownOne = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/HumanDown01.png")));
-        directionDownTwo = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/HumanDown02.png")));
+        directionDownOne = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/high_born/HighBornDown00.png")));
+        directionDownTwo = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/high_born/HighBornDown01.png")));
         directionUpOne = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/upOne.png")));
         directionUpTwo = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/upTwo.png")));
         directionLeftOne = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/leftOne.png")));
@@ -132,15 +175,15 @@ class Player implements IEntity {
     }
 
     private void loadSentinelsSprites() {
-        directionDownOne = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/HumanDown01.png")));
-        directionDownTwo = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/HumanDown02.png")));
+        directionDownOne = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/sentinels/SentinelDown00.png")));
+        directionDownTwo = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/sentinels/SentinelDown01.png")));
         directionUpOne = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/upOne.png")));
         directionUpTwo = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/upTwo.png")));
         directionLeftOne = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/leftOne.png")));
         directionLeftTwo = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/leftTwo.png")));
         directionRightOne = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/rightOne.png")));
         directionRightTwo = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/player/rightTwo.png")));
-        }
+    }
 
     private void loadWeaponSprites() {
         swordUp = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/weapons/SwordUp.png")));
@@ -151,57 +194,99 @@ class Player implements IEntity {
 
     @Override
     public void updateEntityMovement(GameSceneController gameScene) {
-        if (inputHandler.isMoveUp() || inputHandler.isMoveDown() || inputHandler.isMoveLeft() || inputHandler.isMoveRight()) {
-            if (inputHandler.isMoveUp()) {
-                playerDirection = EntityDirection.UP;
-            } else if (inputHandler.isMoveDown()) {
-                playerDirection = EntityDirection.DOWN;
-            } else if (inputHandler.isMoveLeft()) {
-                playerDirection = EntityDirection.LEFT;
-            } else {
-                playerDirection = EntityDirection.RIGHT;
-            }
-
-            boolean isWalkableTile = collisionHandler.handleMapCollision(this, scaledTileSize, gameSceneController);
-
-            int lastMapPosX = mapPosX;
-            int lastMapPosY = mapPosY;
-
-            if (isWalkableTile) {
-                switch (playerDirection) {
-                    case UP:
-                        mapPosY -= playerSpeed;
-                        break;
-                    case DOWN:
-                        mapPosY += playerSpeed;
-                        break;
-                    case LEFT:
-                        mapPosX -= playerSpeed;
-                        break;
-                    case RIGHT:
-                        mapPosX += playerSpeed;
+        if (PLAYER_MODE == PlayerMode.PLAYER_ONE) {
+            if (inputHandler.isMoveUp() || inputHandler.isMoveDown() || inputHandler.isMoveLeft() || inputHandler.isMoveRight()) {
+                if (inputHandler.isMoveUp()) {
+                    playerDirection = EntityDirection.UP;
+                } else if (inputHandler.isMoveDown()) {
+                    playerDirection = EntityDirection.DOWN;
+                } else if (inputHandler.isMoveLeft()) {
+                    playerDirection = EntityDirection.LEFT;
+                } else if (inputHandler.isMoveRight()) {
+                    playerDirection = EntityDirection.RIGHT;
                 }
-            }
 
-            boolean isEntityCollision = boxCollider.intersects(gameScene.getEnemy().getBoxCollider());
-            //boolean isEntityCollision = collisionHandler.handleBoxCollision(boxCollider, gameScene.getEnemy().getBoxCollider());
-
-            if (isEntityCollision) {
-                if (playerDirection == EntityDirection.UP) {
-                    mapPosY = lastMapPosY + 30;
-                } else if (playerDirection == EntityDirection.DOWN) {
-                    mapPosY = lastMapPosY - 30;
-                } else if (playerDirection == EntityDirection.LEFT) {
-                    mapPosX = lastMapPosX + 30;
-                } else {
-                    mapPosX = lastMapPosX - 30;
+                boolean isWalkableTile = collisionHandler.handleMapCollision(this, scaledTileSize, gameSceneController);
+
+                performEntityMovement(isWalkableTile);
+
+                boolean isEntityCollision = boxCollider.intersects(gameScene.getEnemy().getBoxCollider());
+                //boolean isEntityCollision = collisionHandler.handleBoxCollision(boxCollider, gameScene.getEnemy().getBoxCollider());
+
+                performEntityCollision(isEntityCollision);
+
+                updateEntityWalkAnimation();
+            }
+        } else if (PLAYER_MODE == PlayerMode.PLAYER_TWO) {
+            if (inputHandler.isSdMoveUp() || inputHandler.isSdMoveDown() || inputHandler.isSdMoveLeft() || inputHandler.isSdMoveRight()) {
+                if (inputHandler.isSdMoveUp()) {
+                    playerDirection = EntityDirection.UP;
+                } else if (inputHandler.isSdMoveDown()) {
+                    playerDirection = EntityDirection.DOWN;
+                } else if (inputHandler.isSdMoveLeft()) {
+                    playerDirection = EntityDirection.LEFT;
+                } else if (inputHandler.isSdMoveRight()) {
+                    playerDirection = EntityDirection.RIGHT;
                 }
+
+                boolean isWalkableTile = collisionHandler.handleMapCollision(this, scaledTileSize, gameSceneController);
+
+                performEntityMovement(isWalkableTile);
+
+                boolean isEntityCollision = boxCollider.intersects(gameScene.getPlayer().getBoxCollider());
+                //boolean isEntityCollision = collisionHandler.handleBoxCollision(boxCollider, gameScene.getEnemy().getBoxCollider());
+
+                performEntityCollision(isEntityCollision);
+
+                updateEntityWalkAnimation();
             }
+        }
+    }
 
-            boxCollider = new BoundingBox(mapPosX+15,mapPosY+10, playerWidth, playerHeight);
+    private void performEntityMovement(boolean isWalkableTile) {
+        lastMapPosX = mapPosX;
+        lastMapPosY = mapPosY;
+
+        if (isWalkableTile) {
+            switch (playerDirection) {
+                case UP:
+                    mapPosY -= playerSpeed;
+                    break;
+                case DOWN:
+                    mapPosY += playerSpeed;
+                    break;
+                case LEFT:
+                    mapPosX -= playerSpeed;
+                    break;
+                case RIGHT:
+                    mapPosX += playerSpeed;
+            }
+        }
+    }
 
-            updateEntityWalkAnimation();
+    private void performEntityCollision(boolean isEntityCollision) {
+        if (isEntityCollision) {
+            if (playerDirection == EntityDirection.UP) {
+                mapPosY = lastMapPosY + 30;
+            } else if (playerDirection == EntityDirection.DOWN) {
+                mapPosY = lastMapPosY - 30;
+            } else if (playerDirection == EntityDirection.LEFT) {
+                mapPosX = lastMapPosX + 30;
+            } else {
+                mapPosX = lastMapPosX - 30;
+            }
+        }
 
+        boxCollider = new BoundingBox(mapPosX + 15, mapPosY + 10, playerWidth, playerHeight);
+    }
+    @Override
+    public void checkHealTile(IEntity entity, GraphicsContext graphicsContext){
+        int xTile = entity.getMapPosX() / gameSceneController.getScaledTileSize();
+        int yTile = entity.getMapPosY() / gameSceneController.getScaledTileSize();
+        if(TileManager.tileMap[yTile][xTile +1 ] == 5){
+            entity.healPlayer(1);
+            TileManager.tileMap[yTile][xTile +1] = 2;
+            log.info("Healed +1: " + health);
         }
     }
 
@@ -209,47 +294,82 @@ class Player implements IEntity {
     public void attack(IEntity entity, GraphicsContext graphicsContext) {
         BoundingBox hitBox;
 
+        int xTile = mapPosX / gameSceneController.getScaledTileSize();
+        int yTile = mapPosY / gameSceneController.getScaledTileSize();
+        //log.info(xTile);
+        //log.info(yTile);
+        //int xTile = (int) (Math.random() * (18 - 1));   //Get xTile Coordinate +1 /-1 of playerTile
+        //int yTile = (int) (Math.random() * (18 - 1));   //Get yTile Coordinate +1 /-1 of playerTile
+        double dropChance = 0.5;
+        double randomDropChance = Math.random() * 1;
+        //log.info(randomDropChance);
+
         //Added and subtracted numbers from variables are the pixel insets of the player sprite
 
         int attackRange = 30;
         int attackWidth = 10;
 
-        if (inputHandler.isAttack()){
+        if (inputHandler.isAttack() && PLAYER_MODE == PlayerMode.PLAYER_ONE ||
+                inputHandler.isSdAttack() && PLAYER_MODE == PlayerMode.PLAYER_TWO) {
             if (playerDirection == EntityDirection.UP) {
-                hitBox = new BoundingBox(mapPosX+playerWidth, mapPosY-10, attackWidth, attackRange);
-                graphicsContext.strokeRect(mapPosX+playerWidth, mapPosY-10, attackWidth, attackRange);
-                graphicsContext.drawImage(swordUp, mapPosX+8, mapPosY-10, 32, 32);
+                hitBox = new BoundingBox(mapPosX + playerWidth, mapPosY - 10, attackWidth, attackRange);
+                graphicsContext.strokeRect(mapPosX + playerWidth, mapPosY - 10, attackWidth, attackRange);
+                graphicsContext.drawImage(swordUp, mapPosX + 8, mapPosY - 10, 32, 32);
                 if (hitBox.intersects(entity.getBoxCollider())) {
                     entity.gotHit(damage);
                     graphicsContext.strokeText("Hit", 10, 10);
+
+                    if (((TileManager.tileMap[xTile][yTile] == 3) && randomDropChance > dropChance)||
+                            ((TileManager.tileMap[xTile][yTile] == 1)  && randomDropChance > dropChance))
+                        TileManager.tileMap[yTile-1][xTile+1] = 5;
+                    //TileManager.tileMap[yTile-2][xTile] = 5;
+                    //TileManager.tileMap[yTile-3][xTile] = 5;
                 }
             } else if (playerDirection == EntityDirection.DOWN) {
-                hitBox = new BoundingBox(mapPosX+playerWidth, mapPosY+playerHeight, attackWidth, attackRange);
-                graphicsContext.strokeRect(mapPosX+playerWidth, mapPosY+playerHeight, attackWidth, attackRange);
-                graphicsContext.drawImage(swordDown, mapPosX+8, mapPosY+playerHeight, 32, 32);
+                hitBox = new BoundingBox(mapPosX + playerWidth, mapPosY + playerHeight, attackWidth, attackRange);
+                graphicsContext.strokeRect(mapPosX + playerWidth, mapPosY + playerHeight, attackWidth, attackRange);
+                graphicsContext.drawImage(swordDown, mapPosX + 8, mapPosY + playerHeight, 32, 32);
                 if (hitBox.intersects(entity.getBoxCollider())) {
                     entity.gotHit(damage);
                     graphicsContext.strokeText("Hit", 10, 10);
+
+                    if (((TileManager.tileMap[xTile][yTile] == 3) && randomDropChance > dropChance)||
+                            ((TileManager.tileMap[xTile][yTile] == 1)  && randomDropChance > dropChance))
+                        TileManager.tileMap[yTile-1][xTile+1] = 5;
+                    //TileManager.tileMap[yTile-2][xTile] = 5;
+                    //TileManager.tileMap[yTile-3][xTile] = 5;
                 }
             } else if (playerDirection == EntityDirection.LEFT) {
-                hitBox = new BoundingBox(mapPosX-attackWidth, mapPosY+((double) playerHeight /2),
+                hitBox = new BoundingBox(mapPosX - attackWidth, mapPosY + ((double) playerHeight / 2),
                         attackRange, attackWidth);
-                graphicsContext.strokeRect(mapPosX-attackWidth, mapPosY+((double) playerHeight /2),
+                graphicsContext.strokeRect(mapPosX - attackWidth, mapPosY + ((double) playerHeight / 2),
                         attackRange, attackWidth);
-                graphicsContext.drawImage(swordLeft, mapPosX-8, mapPosY+8, 32, 32);
+                graphicsContext.drawImage(swordLeft, mapPosX - 8, mapPosY + 8, 32, 32);
                 if (hitBox.intersects(entity.getBoxCollider())) {
                     entity.gotHit(damage);
                     graphicsContext.strokeText("Hit", 10, 10);
+
+                    if (((TileManager.tileMap[xTile][yTile] == 3) && randomDropChance > dropChance)||
+                            ((TileManager.tileMap[xTile][yTile] == 1)  && randomDropChance > dropChance))
+                        TileManager.tileMap[yTile-1][xTile+1] = 5;
+                    //TileManager.tileMap[yTile-2][xTile] = 5;
+                    //TileManager.tileMap[yTile-3][xTile] = 5;
                 }
             } else {
-                hitBox = new BoundingBox(mapPosX+playerWidth+attackWidth, mapPosY+((double) playerHeight /2),
+                hitBox = new BoundingBox(mapPosX + playerWidth + attackWidth, mapPosY + ((double) playerHeight / 2),
                         attackRange, attackWidth);
-                graphicsContext.strokeRect(mapPosX+playerWidth+attackWidth, mapPosY+((double) playerHeight /2),
+                graphicsContext.strokeRect(mapPosX + playerWidth + attackWidth, mapPosY + ((double) playerHeight / 2),
                         attackRange, attackWidth);
-                graphicsContext.drawImage(swordRight, mapPosX+playerWidth+8, mapPosY+8, 32, 32);
+                graphicsContext.drawImage(swordRight, mapPosX + playerWidth + 8, mapPosY + 8, 32, 32);
                 if (hitBox.intersects(entity.getBoxCollider())) {
                     entity.gotHit(damage);
                     graphicsContext.strokeText("Hit", 10, 10);
+
+                    if (((TileManager.tileMap[xTile][yTile] == 3) && randomDropChance > dropChance)||
+                            ((TileManager.tileMap[xTile][yTile] == 1)  && randomDropChance > dropChance))
+                        TileManager.tileMap[yTile-1][xTile+1] = 5;
+                    //TileManager.tileMap[yTile-2][xTile] = 5;
+                    //TileManager.tileMap[yTile-3][xTile] = 5;
                 }
             }
         }
@@ -274,7 +394,7 @@ class Player implements IEntity {
         Image playerSprite = null;
 
         //for debugging collision
-        graphicsContext.strokeRect(mapPosX+15,mapPosY+10, playerWidth, playerHeight);
+        graphicsContext.strokeRect(mapPosX + 15, mapPosY + 10, playerWidth, playerHeight);
 
         switch (playerDirection) {
             case UP:
@@ -314,6 +434,22 @@ class Player implements IEntity {
         graphicsContext.drawImage(playerSprite, mapPosX, mapPosY, 48, 48);
     }
 
+    @Override
+    public void gotHit(int damageDone) {
+        health -= damageDone;
+    }
+    @Override
+    public void healPlayer(int healthRegenerated) {
+        int regeneratedHealth = health + healthRegenerated;
+
+        if (regeneratedHealth < maxPlayerHealth) {
+            health += healthRegenerated;
+        } else {
+            health = maxPlayerHealth;
+        }
+        log.info(health);
+    }
+
     @Override
     public BoundingBox getBoxCollider() {
         return boxCollider;
@@ -329,11 +465,6 @@ class Player implements IEntity {
         return playerSpeed;
     }
 
-    @Override
-    public int gotHit(int damageDone) {
-        return health -= damageDone;
-    }
-
     @Override
     public int getMapPosX() {
         return mapPosX;
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Inputs/InputHandler.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Inputs/InputHandler.java
index 8dfd2f3d3d51063e409488e71a25814030ed2f68..a66f47e852aac620010f786bbff62a0700292535 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Inputs/InputHandler.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Inputs/InputHandler.java
@@ -18,26 +18,51 @@ public class InputHandler {
         return inputHandler;
     }
 
+    //Local Player/Player one controls
     private boolean moveUp, moveDown, moveLeft, moveRight, attack;
 
+    //Local player two controls
+    private boolean sdMoveUp, sdMoveDown, sdMoveLeft, sdMoveRight, sdAttack;
+
     public void handleKeyPress(KeyEvent event) {
         KeyCode code = event.getCode();
 
         switch (code) {
             case W:
                 moveUp = true;
+                log.debug("Player move up");
                 break;
             case S:
                 moveDown = true;
+                log.debug("Player move down");
                 break;
             case A:
                 moveLeft = true;
+                log.debug("Player move left");
                 break;
             case D:
                 moveRight = true;
+                log.debug("Player move right");
                 break;
-            case SPACE:
+            case E:
                 attack = true;
+                log.debug("Player attack");
+                break;
+            case UP:
+                sdMoveUp = true;
+                break;
+            case DOWN:
+                sdMoveDown = true;
+                break;
+            case LEFT:
+                sdMoveLeft = true;
+                break;
+            case RIGHT:
+                sdMoveRight = true;
+                break;
+            case MINUS:
+                sdAttack = true;
+                break;
         }
     }
 
@@ -57,8 +82,24 @@ public class InputHandler {
             case D:
                 moveRight = false;
                 break;
-            case SPACE:
+            case E:
                 attack = false;
+                break;
+            case UP:
+                sdMoveUp = false;
+                break;
+            case DOWN:
+                sdMoveDown = false;
+                break;
+            case LEFT:
+                sdMoveLeft = false;
+                break;
+            case RIGHT:
+                sdMoveRight = false;
+                break;
+            case MINUS:
+                sdAttack = false;
+                break;
         }
     }
 
@@ -81,4 +122,24 @@ public class InputHandler {
     public boolean isAttack() {
         return attack;
     }
+
+    public boolean isSdMoveUp() {
+        return sdMoveUp;
+    }
+
+    public boolean isSdMoveDown() {
+        return sdMoveDown;
+    }
+
+    public boolean isSdMoveLeft() {
+        return sdMoveLeft;
+    }
+
+    public boolean isSdMoveRight() {
+        return sdMoveRight;
+    }
+
+    public boolean isSdAttack() {
+        return sdAttack;
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/BackgroundTile.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/BackgroundTile.java
index c7fd6bc3ad273c2e2667a9398a33c94764947ea7..b17fb79d9742336e3d008bce528846433d1db394 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/BackgroundTile.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/BackgroundTile.java
@@ -10,11 +10,12 @@ class BackgroundTile implements ITile{
     private static final Logger log = LogManager.getLogger(BackgroundTile.class);
 
     private final Image tileSprite;
-    private final boolean isWalkable;
+    private final boolean isWalkable, isDestructible;
 
-    public BackgroundTile(Image tileSprite, boolean isWalkable) {
+    public BackgroundTile(Image tileSprite, boolean isWalkable, boolean isDestructible) {
         this.tileSprite = tileSprite;
         this.isWalkable = isWalkable;
+        this.isDestructible = isDestructible;
     }
 
     @Override
@@ -22,6 +23,11 @@ class BackgroundTile implements ITile{
         log.debug("Collision type: " + isWalkable + " returned.");
         return isWalkable;
     }
+    @Override
+    public boolean getDestruction() {
+        log.debug("Collision type: " + isDestructible + " returned.");
+        return isWalkable;
+    }
 
     @Override
     public Image getTileSprite() {
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/ITile.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/ITile.java
index f33750bed5ede99e059da2a7fb4e31f33bb735ad..58f711083e43f6be1046bd4d394adf7a3b6e8825 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/ITile.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/ITile.java
@@ -4,5 +4,6 @@ import javafx.scene.image.Image;
 
 public interface ITile {
     boolean getCollision();
+    boolean getDestruction();
     Image getTileSprite();
 }
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/TileFactory.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/TileFactory.java
index 842781646eb4c59e1ba537d172414c7437b498b2..0da1a1558d0e6888a73fa456d3dd81f021d936fc 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/TileFactory.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/TileFactory.java
@@ -9,13 +9,19 @@ public class TileFactory {
 
     private static final Logger log = LogManager.getLogger(TileFactory.class);
 
-    public static ITile createTile(TileType tileType, Image tileSprite) {
-        if (tileType == TileType.WALKABLE) {
-            log.debug("Tile with type: " + tileType + " created.");
-            return new BackgroundTile(tileSprite, true);
-        } else if (tileType == TileType.NON_WALKABLE) {
-            log.debug("Tile with type: " + tileType + " created.");
-            return new BackgroundTile(tileSprite, false);
+    public static ITile createTile(TileType tileType, TileType tileType2, Image tileSprite) {
+        if (tileType == TileType.WALKABLE && tileType2 == TileType.DESTRUCTIBLE) {
+            log.info("Tile with type: " + tileType + " " + tileType2 + " created.");
+            return new BackgroundTile(tileSprite, true, true);
+        }else if (tileType == TileType.WALKABLE && tileType2 == TileType.NON_DESTRUCTIBLE) {
+            log.info("Tile with type: " + tileType + " " + tileType2 +" created.");
+            return new BackgroundTile(tileSprite, true, false);
+        }else if (tileType == TileType.NON_WALKABLE && tileType2 == TileType.DESTRUCTIBLE) {
+            log.info("Tile with type: " + tileType + " " + tileType2 +" created.");
+            return new BackgroundTile(tileSprite, false, true);
+        }else if (tileType == TileType.NON_WALKABLE && tileType2 == TileType.NON_DESTRUCTIBLE) {
+            log.info("Tile with type: " + tileType + " " + tileType2 +" created.");
+            return new BackgroundTile(tileSprite, false, false);
         }
 
         log.error("TileType: " + tileType + " not supported!");
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/TileManager.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/TileManager.java
index 480478d51823c0a4992de930e4eea5f2b73f82d8..0ac687dab223e1933fe99bbf42db3dfd3ed8b8b5 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/TileManager.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/TileManager.java
@@ -14,7 +14,7 @@ public class TileManager {
 
     private final GraphicsContext graphicsContext2D;
     private final ITile[] tileSet;
-    private final int[][] tileMap;
+    public static int[][] tileMap;
 
     private final int horizontalTileCount;
     private final int verticalTileCount;
@@ -34,16 +34,18 @@ public class TileManager {
 
     private void createTiles() {
         try {
-            tileSet[0] = TileFactory.createTile(TileType.WALKABLE,
+            tileSet[0] = TileFactory.createTile(TileType.WALKABLE, TileType.NON_DESTRUCTIBLE,
                     new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/Grass01.png"))));
-            tileSet[1] = TileFactory.createTile(TileType.WALKABLE,
+            tileSet[1] = TileFactory.createTile(TileType.WALKABLE, TileType.NON_DESTRUCTIBLE,
                     new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/Grass02.png"))));
-            tileSet[2] = TileFactory.createTile(TileType.WALKABLE,
+            tileSet[2] = TileFactory.createTile(TileType.WALKABLE, TileType.NON_DESTRUCTIBLE,
                     new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/Grass04.png"))));
-            tileSet[3] = TileFactory.createTile(TileType.NON_WALKABLE,
+            tileSet[3] = TileFactory.createTile(TileType.NON_WALKABLE, TileType.DESTRUCTIBLE,
                     new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/Stone01.png"))));
-            tileSet[4] = TileFactory.createTile(TileType.NON_WALKABLE,
+            tileSet[4] = TileFactory.createTile(TileType.NON_WALKABLE, TileType.DESTRUCTIBLE,
                     new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/Stone02.png"))));
+            tileSet[5] = TileFactory.createTile(TileType.WALKABLE,TileType.NON_DESTRUCTIBLE,
+                    new Image(Objects.requireNonNull(getClass().getResourceAsStream("/textures/map/finalheart.png"))));
         } catch (Exception e) {
             log.error(e);
         }
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/TileType.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/TileType.java
index 17e95c7e93fc890a5f993cc53b7eb6cfd1f4bd6b..efe35788d26be5839df9efee6934ce54ec2c0d63 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/TileType.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Map/TileType.java
@@ -2,5 +2,8 @@ package de.hdm_stuttgart.battlearena.Model.Map;
 
 public enum TileType {
     WALKABLE,
-    NON_WALKABLE
+    NON_WALKABLE,
+    DESTRUCTIBLE,
+    NON_DESTRUCTIBLE
+
 }
\ No newline at end of file
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
index 6fb857169bf3b818c95f9a1a9ada8ad3b39b0d58..9a77de28c30d210dadfd85f28a594d9e5621d9c8 100644
--- a/src/main/resources/log4j2.xml
+++ b/src/main/resources/log4j2.xml
@@ -16,6 +16,7 @@
         </Logger>
         <Root level="info">
             <AppenderRef ref="STDOUT"/>
+            <AppenderRef ref="A1"/>
         </Root>
     </Loggers>
 </Configuration>
\ No newline at end of file
diff --git a/src/main/resources/maps/communityMaps.json b/src/main/resources/maps/communityMaps.json
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9c99ec44154627bf856e8eff30053efa9d624f9f 100644
--- a/src/main/resources/maps/communityMaps.json
+++ b/src/main/resources/maps/communityMaps.json
@@ -0,0 +1,16 @@
+[
+  {
+    "mapID": "fbf44184867512faecc195ae75ca55d5ab7bad2d",
+    "mapName": "Arena3",
+    "mapWidth": 18,
+    "mapHeight": 18,
+    "mapData": "12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 8 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"
+  },
+  {
+    "mapID": "1c23b362fd666c5fb7ed60ca611b17246424e49f",
+    "mapName": "Arena4",
+    "mapWidth": 18,
+    "mapHeight": 18,
+    "mapData": "12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 8 4 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"
+  }
+]
\ No newline at end of file
diff --git a/src/main/resources/maps/coreMaps.json b/src/main/resources/maps/coreMaps.json
index 84828ae2b407d2ff4b089fdb479656a518e3a688..ba63b040f5afc06edf39a660e0cd815b3bb7963b 100644
--- a/src/main/resources/maps/coreMaps.json
+++ b/src/main/resources/maps/coreMaps.json
@@ -1,16 +1,16 @@
 [
   {
-    "mapID": "a593cafd1d061f0f463a2d2051bf4718aaaf5c48",
+    "mapID": "09a02b54d05b5b7ebc29a4383ca12d3dda846b72",
     "mapName": "Arena1",
     "mapWidth": 18,
     "mapHeight": 18,
-    "mapData": "4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 2 1 1 1 1 1 2 2 2 1 1 1 1 2 1 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 1 2 3 4 1 1 1 2 2 4 1 3 3 3 1 1 1 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 2 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 1 3 4 1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 1 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 1 1 4 3 3 1 3 3 3 3 3 1 2 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 2 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"
+    "mapData": "12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"
   },
   {
-    "mapID": "e559d8fbb53b333f5839cb3c6c0c515395afe344",
+    "mapID": "0ab15557ab6dc4be60dfe6a9b0288bac3036bd97",
     "mapName": "Arena2",
     "mapWidth": 18,
     "mapHeight": 18,
-    "mapData": "4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 2 4 2 1 1 1 1 1 2 2 2 1 1 1 1 2 3 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 1 2 3 4 1 1 1 2 2 4 1 3 3 3 1 1 1 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 2 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 1 3 4 1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 1 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 1 1 4 3 3 1 3 3 3 3 3 1 2 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 2 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"
+    "mapData": "12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 5 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"
   }
 ]
\ No newline at end of file
diff --git a/src/main/resources/player/appSettings.json b/src/main/resources/player/appSettings.json
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ac6b7e58fa58ee25e2070c5cdfb9b8324bdddc6b 100644
--- a/src/main/resources/player/appSettings.json
+++ b/src/main/resources/player/appSettings.json
@@ -0,0 +1,4 @@
+{
+  "sfxVolume": 50,
+  "musicVolume": 50
+}
\ No newline at end of file
diff --git a/src/main/resources/textures/map/finalheart.png b/src/main/resources/textures/map/finalheart.png
new file mode 100644
index 0000000000000000000000000000000000000000..b861b145ceb949abdd7222a2679fe8e10756340f
Binary files /dev/null and b/src/main/resources/textures/map/finalheart.png differ
diff --git a/src/main/resources/textures/player/high_born/HighBornDown00.png b/src/main/resources/textures/player/high_born/HighBornDown00.png
new file mode 100644
index 0000000000000000000000000000000000000000..b87b19b2ffe1ce2048c6d8bc96d1e4a66fd4c4af
Binary files /dev/null and b/src/main/resources/textures/player/high_born/HighBornDown00.png differ
diff --git a/src/main/resources/textures/player/high_born/HighBornDown01.png b/src/main/resources/textures/player/high_born/HighBornDown01.png
new file mode 100644
index 0000000000000000000000000000000000000000..787b4603347dac4b2d5f2c1063b3e3a3551fed4a
Binary files /dev/null and b/src/main/resources/textures/player/high_born/HighBornDown01.png differ
diff --git a/src/main/resources/textures/player/human/HumanDown00.png b/src/main/resources/textures/player/human/HumanDown00.png
new file mode 100644
index 0000000000000000000000000000000000000000..980612cb998a80e7710798fbd2f8a81791ef7322
Binary files /dev/null and b/src/main/resources/textures/player/human/HumanDown00.png differ
diff --git a/src/main/resources/textures/player/human/HumanDown01.png b/src/main/resources/textures/player/human/HumanDown01.png
new file mode 100644
index 0000000000000000000000000000000000000000..54792ff64f25e5c6e48e35f90502ff2d7fea9893
Binary files /dev/null and b/src/main/resources/textures/player/human/HumanDown01.png differ
diff --git a/src/main/resources/textures/player/human/HumanLeft00.png b/src/main/resources/textures/player/human/HumanLeft00.png
new file mode 100644
index 0000000000000000000000000000000000000000..2d259ebb0c88259967e361c93138dd3367bcfe1b
Binary files /dev/null and b/src/main/resources/textures/player/human/HumanLeft00.png differ
diff --git a/src/main/resources/textures/player/human/HumanLeft01.png b/src/main/resources/textures/player/human/HumanLeft01.png
new file mode 100644
index 0000000000000000000000000000000000000000..3e25fce1c897aa94297d73248a54b1c09700d8d2
Binary files /dev/null and b/src/main/resources/textures/player/human/HumanLeft01.png differ
diff --git a/src/main/resources/textures/player/human/HumanRight00.png b/src/main/resources/textures/player/human/HumanRight00.png
new file mode 100644
index 0000000000000000000000000000000000000000..f20b2b692e98c68bc6671b0294a3582b4de65f0b
Binary files /dev/null and b/src/main/resources/textures/player/human/HumanRight00.png differ
diff --git a/src/main/resources/textures/player/human/HumanRight01.png b/src/main/resources/textures/player/human/HumanRight01.png
new file mode 100644
index 0000000000000000000000000000000000000000..ba2dd289825604b6730186ffb862592b2d94bb12
Binary files /dev/null and b/src/main/resources/textures/player/human/HumanRight01.png differ
diff --git a/src/main/resources/textures/player/human/HumanUp00.png b/src/main/resources/textures/player/human/HumanUp00.png
new file mode 100644
index 0000000000000000000000000000000000000000..bf2042d6a68463fa8c392c03d5cfaa973f9d1ae4
Binary files /dev/null and b/src/main/resources/textures/player/human/HumanUp00.png differ
diff --git a/src/main/resources/textures/player/human/HumanUp01.png b/src/main/resources/textures/player/human/HumanUp01.png
new file mode 100644
index 0000000000000000000000000000000000000000..c21f00058a48f3c99b1eeaae7f2d93f8baef1471
Binary files /dev/null and b/src/main/resources/textures/player/human/HumanUp01.png differ
diff --git a/src/main/resources/textures/player/sentinels/SentinelDown00.png b/src/main/resources/textures/player/sentinels/SentinelDown00.png
new file mode 100644
index 0000000000000000000000000000000000000000..c2fb803e03f3d459baeb4188975192ef83aa3b71
Binary files /dev/null and b/src/main/resources/textures/player/sentinels/SentinelDown00.png differ
diff --git a/src/main/resources/textures/player/sentinels/SentinelDown01.png b/src/main/resources/textures/player/sentinels/SentinelDown01.png
new file mode 100644
index 0000000000000000000000000000000000000000..bb87d3b89b7a54dd62fde0c509d9d0ae09e549c4
Binary files /dev/null and b/src/main/resources/textures/player/sentinels/SentinelDown01.png differ
diff --git a/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PersistenceTest.java b/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PersistenceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..79b599da6c201b66ffe5d1c21293f44b9ee244e4
--- /dev/null
+++ b/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PersistenceTest.java
@@ -0,0 +1,48 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
+
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.DatabaseException;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.SQLException;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.Before;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class PersistenceTest {
+
+    private static final Logger log = LogManager.getLogger(PersistenceTest.class);
+    Persistence persistenceSingleton;
+
+    OracleDB inst = new OracleDB();
+
+    @Before
+    public void setup() throws SQLException {
+        persistenceSingleton = Persistence.getInstance();
+        persistenceSingleton.db = inst;
+        ArrayList<MapData> maps = new ArrayList<MapData>();
+        maps.add(new MapData("09a02b54d05b5b7ebc29a4383ca12d3dda846b72", "Arena1", 18, 18, "12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+        maps.add(new MapData("0ab15557ab6dc4be60dfe6a9b0288bac3036bd97", "Arena2", 18, 18, "12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 5 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+        when(inst.getCoreMaps()).thenReturn(maps);
+    }
+
+    @Test
+    void updateCoreMaps() throws RuntimeException, DatabaseException {
+            persistenceSingleton.updateCoreMaps();
+            assertEquals("09a02b54d05b5b7ebc29a4383ca12d3dda846b72", persistenceSingleton.getCoreMaps().get(0).getMapID());
+            assertEquals("0ab15557ab6dc4be60dfe6a9b0288bac3036bd97", persistenceSingleton.getCoreMaps().get(1).getMapID());
+    }
+
+    @Test
+    void loadPlayerStatistics() {
+    }
+
+
+
+
+}
\ No newline at end of file
diff --git a/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/ParserTest.java b/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/ParserTest.java
index 62f0b705af1053613a39adfe2a296fc69099dd98..07406e5ea3be3324dd621c19aa1748b53f37acaa 100644
--- a/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/ParserTest.java
+++ b/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/ParserTest.java
@@ -1,6 +1,7 @@
 package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities;
 
 import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.ParserException;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.PlayerStatistics;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.ValueSource;
@@ -8,21 +9,20 @@ import org.junit.jupiter.params.provider.ValueSource;
 import static org.junit.jupiter.api.Assertions.*;
 class ParserTest {
 
-
     @ParameterizedTest
     @ValueSource(strings = {"Player1",
                             "Player2",
-                            "HelloWorld"})
+                            "0123456789012345678901234567890123456789"})
     void usernameValid(String test){
         assertDoesNotThrow(() -> Parser.usernameValid(test));
     }
 
     @Test
-    void usernameValidException() {
-        ParserException testMe = assertThrows(ParserException.class, () -> Parser.usernameValid("hi"));
+    void usernameInvalid() {
+        ParserException testMe = assertThrows(ParserException.class, () -> Parser.usernameValid("lol"));
         assertTrue(testMe.getMessage().contains("Username too short! Min length is 4 characters."));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.usernameValid("jiaodjidsfjoisjdiofjsiofjidosfijsodfjisdfjoi"));
+        testMe = assertThrows(ParserException.class, () -> Parser.usernameValid("01234567890123456789012345678901234567890"));
         assertTrue(testMe.getMessage().contains("Username too long! Max length is 40 characters."));
 
         testMe = assertThrows(ParserException.class, () -> Parser.usernameValid("SELECT * FROM"));
@@ -32,17 +32,17 @@ class ParserTest {
     @ParameterizedTest
     @ValueSource(strings = {"pw123456",
                             "Passwort",
-                            "lololol"})
+                            "0123456789012345678901234567890123456789"})
     void passwordValid(String test){
         assertDoesNotThrow(() -> Parser.passwordValid(test));
     }
 
     @Test
-    void passwordValidException() {
-        ParserException testMe = assertThrows(ParserException.class, () -> Parser.passwordValid("hi"));
+    void passwordInvalid() {
+        ParserException testMe = assertThrows(ParserException.class, () -> Parser.passwordValid("lol"));
         assertTrue(testMe.getMessage().contains("Password too short! Min length is 4 characters."));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.passwordValid("jiaodjidsfjoisjdiofjsiofjidosfijsodfjisdfjoi"));
+        testMe = assertThrows(ParserException.class, () -> Parser.passwordValid("01234567890123456789012345678901234567890"));
         assertTrue(testMe.getMessage().contains("Password too long! Max length is 40 characters."));
 
         testMe = assertThrows(ParserException.class, () -> Parser.passwordValid("SELECT * FROM"));
@@ -50,7 +50,7 @@ class ParserTest {
     }
 
     @ParameterizedTest
-    @ValueSource(strings = {"Map_1",
+    @ValueSource(strings = {"012345678901234567890123456789",
                             "de_dust",
                             "Ziba-Tower"})
     void mapNameValid(String test){
@@ -58,11 +58,11 @@ class ParserTest {
     }
 
     @Test
-    void mapNameValidException() {
-        ParserException testMe = assertThrows(ParserException.class, () -> Parser.mapNameValid("hi"));
+    void mapNameInvalid() {
+        ParserException testMe = assertThrows(ParserException.class, () -> Parser.mapNameValid("lol"));
         assertTrue(testMe.getMessage().contains("Map-Name too short! Min length is 4 characters."));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.mapNameValid("jiaodjidsfjoisjdiofjsiofjidosfijsodfjisdfjoi"));
+        testMe = assertThrows(ParserException.class, () -> Parser.mapNameValid("0123456789012345678901234567890"));
         assertTrue(testMe.getMessage().contains("Map-Name too long! Max length is 30 characters."));
 
         testMe = assertThrows(ParserException.class, () -> Parser.mapNameValid("SELECT * FROM"));
@@ -74,16 +74,19 @@ class ParserTest {
                             "e559d8fbb53b333f5839cb3c6c0c515395afe344",
                             "a593cafd1d061f0f463a2d2051bf4718aaaf5c48"})
     void mapIDValid(String test){
-        assertDoesNotThrow(() -> Parser.sha1HashValid(test));
+        assertDoesNotThrow(() -> Parser.sha1HexHashValid(test));
     }
 
     @Test
-    void mapIDValidException() {
+    void mapIDInvalid() {
+
+        ParserException testMe = assertThrows(ParserException.class, () -> Parser.sha1HexHashValid("01234567890123456789012345678901234567890"));
+        assertTrue(testMe.getMessage().contains("Map-ID length not correct. Must have length of 40 characters!"));
 
-        ParserException testMe = assertThrows(ParserException.class, () -> Parser.sha1HashValid("jiaodjidsfjoisjdiofjsiofjidosfijsodfjisdfjoi"));
+        testMe = assertThrows(ParserException.class, () -> Parser.sha1HexHashValid("012345678901234567890123456789012345678"));
         assertTrue(testMe.getMessage().contains("Map-ID length not correct. Must have length of 40 characters!"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.sha1HashValid("XYZ3cafd1d061f0f463a2d2051bf4718aaaf5c48"));
+        testMe = assertThrows(ParserException.class, () -> Parser.sha1HexHashValid("XYZ3cafd1d061f0f463a2d2051bf4718aaaf5c48"));
         assertTrue(testMe.getMessage().contains("Forbidden characters used! Map ID only consists out of letters a-f and/or numbers 0-9!"));
     }
 
@@ -97,70 +100,170 @@ class ParserTest {
     }
 
     @Test
-    void ipAddressValidException() {
+    void ipAddressInvalid() {
 
-        ParserException testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("255.255.255.255.255.255"));
-        assertTrue(testMe.getMessage().contains("IP-Address too long. Must have length of 15 characters including octet dividers (.) !"));
+        ParserException testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("255.255.255.2555"));
+        assertTrue(testMe.getMessage().contains("IP-Address too long. Must have maximum length of 15 characters including octet dividers (.) !"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("0.0.0"));
-        assertTrue(testMe.getMessage().contains("IP-Address too short. Must have length of 7 characters including octet dividers (.) !"));
+        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("0.0.12"));
+        assertTrue(testMe.getMessage().contains("IP-Address too short. Must have minimum length of 7 characters including octet dividers (.) !"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid(".25.255.25."));
+        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid(".25.255.25"));
+        assertTrue(testMe.getMessage().contains("IP-Address must not start nor end with octet dividers (.) !"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("25.255.25."));
         assertTrue(testMe.getMessage().contains("IP-Address must not start nor end with octet dividers (.) !"));
 
         testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("12.3.0.12.12"));
         assertTrue(testMe.getMessage().contains("IP-Address must contain exactly 3 octet dividers (.) !"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("255.ff.12.12"));
-        assertTrue(testMe.getMessage().contains("IP address does not consist out of numbers 0-9 and separators (.))!"));
+        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("12.12..2"));
+        assertTrue(testMe.getMessage().contains("IP-Address must not contain two or more consecutive dividers (.) without number in between!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("f1.12.12.12"));
+        assertTrue(testMe.getMessage().contains("IP address must consist out of numbers 0-9 and separators (.) !"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("12.12.12.1f"));
+        assertTrue(testMe.getMessage().contains("IP address must consist out of numbers 0-9 and separators (.) !"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("256.12.12.12"));
+        assertTrue(testMe.getMessage().contains("Octets of IP-address must not exceed 255!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("12.12.12.256"));
+        assertTrue(testMe.getMessage().contains("Octets of IP-address must not exceed 255!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("2500.12.12.12"));
+        assertTrue(testMe.getMessage().contains("Octets of IP-address must not exceed 255!"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("2555.800.12.12"));
+        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("12.12.12.2500"));
         assertTrue(testMe.getMessage().contains("Octets of IP-address must not exceed 255!"));
     }
 
     @ParameterizedTest
-    @ValueSource(strings = {"3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3",
-                            "3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 3 3 1 1 1 1 1 3 1 3 3 3 1 1 1 3 1 1 3 3 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3",
-                            "3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 3 3 3 3 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 3 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"})
+    @ValueSource(strings = {"12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12",
+                            "12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 5 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12",
+                            "12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 8 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"})
     void mapDataValid(String test){
         assertDoesNotThrow(() -> Parser.mapDataValid(test));
     }
 
     @Test
-    void mapDataValidException() {
-        ParserException testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("hi"));
-        assertTrue(testMe.getMessage().contains("Map-Data corrupted - must have length of 647 chars including spaces!"));
+    void mapDataInvalid() {
+        ParserException testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 12 12 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 12 12 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 12 12 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 12 12 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 12 12 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 12 12 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 12 12 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 12 12 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 12 12 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 12 12 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 12 12 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 12 12 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 12 12 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 12 12 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 12 12 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - mapData String must not exceed length of 967 chars including spaces for 18x18 Tiles map!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("1 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 8 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - minimum length of mapData String must be 715 chars including spaces for 18x18 Tiles map!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid(" 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - must not start nor end with space!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 "));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - must not start nor end with space!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("12  10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - must not contain two or more consecutive spaces without number in between!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 11 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10  12"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - must not contain two or more consecutive spaces without number in between!"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 3 3 3a3a3a3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"));
-        assertTrue(testMe.getMessage().contains("Map-Data corrupted - must use space every other character!"));
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 13"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - number of spaces must be 323!"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 3 8 9 7 7 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"));
-        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Tile number must be between 1 and 4!"));
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("10 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - number of spaces must be 323!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("a2 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - must consist out of numbers 0-9 and space as separator!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 1d"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - must consist out of numbers 0-9 and space as separator!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("42 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Tile number must be between 0 and 29!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 42"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Tile number must be between 0 and 29!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("22 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Top-Line must be border tiles!"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"));
+        //don't forget to reach minimum length with test String! Otherwise, wrong Exception will be thrown!
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 5 12 1 1 1 1 1 12 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
         assertTrue(testMe.getMessage().contains("Map-Data corrupted - Top-Line must be border tiles!"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 1 1 1 1 1 3 3 3 3 3 3"));
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 22"));
         assertTrue(testMe.getMessage().contains("Map-Data corrupted - Bottom-Line must be border tiles!"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"));
+        //don't forget to reach minimum length with test String! Otherwise, wrong Exception will be thrown!
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 12 1 1 1 1 1 1 1 1 12 8 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Bottom-Line must be border tiles!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 22 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Left Edge must be border tiles!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 22 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
         assertTrue(testMe.getMessage().contains("Map-Data corrupted - Left Edge must be border tiles!"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"));
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 22 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Right Edge must be border tiles!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 22 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
         assertTrue(testMe.getMessage().contains("Map-Data corrupted - Right Edge must be border tiles!"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"));
-        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Player spawn must use walkable tile!"));
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 25 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Player spawn top left must use walkable tile!"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"));
-        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Player spawn must use walkable tile!"));
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 25 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Player spawn top right must use walkable tile!"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"));
-        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Player spawn must use walkable tile!"));
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 25 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Player spawn bottom left must use walkable tile!"));
 
-        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"));
-        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Player spawn must use walkable tile!"));
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 25 12 12 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 12"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Player spawn bottom right must use walkable tile!"));
+    }
+
+    @Test
+    void statsValid(){
+        PlayerStatistics stats = new PlayerStatistics(0, 0, 0, 0, 0, 0);
+        assertDoesNotThrow(() -> Parser.playerStatsValid(stats));
+    }
+
+    @Test
+    void statsInvalid(){
+        ParserException testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(-1, 0, 0, 0, 0, 0)));
+        assertTrue(testMe.getMessage().contains("Player statistics data corrupted - Minimum value for lost games is 0!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(0, -1, 0, 0, 0, 0)));
+        assertTrue(testMe.getMessage().contains("Player statistics data corrupted - Minimum value for won games is 0!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(0, 0, -1, 0, 0, 0)));
+        assertTrue(testMe.getMessage().contains("Player statistics data corrupted - Minimum value for kills is 0!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(0, 0, 0, -1, 0, 0)));
+        assertTrue(testMe.getMessage().contains("Player statistics data corrupted - Minimum value for deaths is 0!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(0, 0, 0, 0, -1, 0)));
+        assertTrue(testMe.getMessage().contains("Player statistics data corrupted - Minimum value for destroyed blocks is 0!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.playerStatsValid(new PlayerStatistics(0, 0, 0, 0, 0, -1)));
+        assertTrue(testMe.getMessage().contains("Player statistics data corrupted - Minimum value for ingame time is 0 seconds!"));
+    }
+
+    @ParameterizedTest
+    @ValueSource(ints = {0, 100, 50})
+    void volumeValid(int test){
+        assertDoesNotThrow(() -> Parser.volumeValid(test));
+    }
+
+    @Test
+    void volumeInvalid(){
+        ParserException testMe = assertThrows(ParserException.class, () -> Parser.volumeValid(-1));
+        assertTrue(testMe.getMessage().contains("Volume must be between 0 and 100!"));
 
+        testMe = assertThrows(ParserException.class, () -> Parser.volumeValid(101));
+        assertTrue(testMe.getMessage().contains("Volume must be between 0 and 100!"));
     }
 
 }
\ No newline at end of file