diff --git a/tetrecs/localscores.txt b/tetrecs/localscores.txt
deleted file mode 100644
index 580fb291bd0d28dd72d860177e825cc8f8f52f66..0000000000000000000000000000000000000000
--- a/tetrecs/localscores.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-w:21950
-2:21850
-test6:21850
-test1234:2700
-Ayaz:2690
-aa:2290
-Player2:1890
-Player1:540
-t:540
-a:450
-rtwe:350
diff --git a/tetrecs/scores.txt b/tetrecs/scores.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fa50493f9e0e70b8374273024091103556c47729
--- /dev/null
+++ b/tetrecs/scores.txt
@@ -0,0 +1,11 @@
+test10:10000
+test9:9000
+test8:8000
+test7:7000
+test6:6000
+test5:5000
+test4:4000
+test3:3000
+Ayaz:2320
+rrr:2240
+test2:2000
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/App.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/App.java
index aa834864199b060c4604914d1de6719af368ec67..012c0ba65eb01dcdabf70ae371b671b534e843dd 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/App.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/App.java
@@ -13,69 +13,72 @@ import uk.ac.soton.comp1206.ui.GameWindow;
  */
 public class App extends Application {
 
-    /**
-     * Base resolution width
-     */
-    private final int width = 800;
-
-    /**
-     * Base resolution height
-     */
-    private final int height = 600;
-
-    private static App instance;
-    private static final Logger logger = LogManager.getLogger(App.class);
-    private Stage stage;
-
-    /**
-     * Start the game
-     * @param args commandline arguments
-     */
-    public static void main(String[] args) {
-        logger.info("Starting client");
-        launch();
-    }
-
-    /**
-     * Called by JavaFX with the primary stage as a parameter. Begins the game by opening the Game Window
-     * @param stage the default stage, main window
-     */
-    @Override
-    public void start(Stage stage) {
-        instance = this;
-        this.stage = stage;
-
-        //Open game window
-        openGame();
-    }
-
-    /**
-     * Create the GameWindow with the specified width and height
-     */
-    public void openGame() {
-        logger.info("Opening game window");
-
-        //Change the width and height in this class to change the base rendering resolution for all game parts
-        var gameWindow = new GameWindow(stage,width,height);
-
-        //Display the GameWindow
-        stage.show();
-    }
-
-    /**
-     * Shutdown the game
-     */
-    public void shutdown() {
-        logger.info("Shutting down");
-        System.exit(0);
-    }
-
-    /**
-     * Get the singleton App instance
-     * @return the app
-     */
-    public static App getInstance() {
-        return instance;
-    }
+  /**
+   * Base resolution width
+   */
+  private final int width = 800;
+
+  /**
+   * Base resolution height
+   */
+  private final int height = 600;
+
+  private static App instance;
+  private static final Logger logger = LogManager.getLogger(App.class);
+  private Stage stage;
+
+  /**
+   * Start the game
+   *
+   * @param args commandline arguments
+   */
+  public static void main(String[] args) {
+    logger.info("Starting client");
+    launch();
+  }
+
+  /**
+   * Called by JavaFX with the primary stage as a parameter. Begins the game by opening the Game Window
+   *
+   * @param stage the default stage, main window
+   */
+  @Override
+  public void start(Stage stage) {
+    instance = this;
+    this.stage = stage;
+
+    //Open game window
+    openGame();
+  }
+
+  /**
+   * Create the GameWindow with the specified width and height
+   */
+  public void openGame() {
+    logger.info("Opening game window");
+
+    //Change the width and height in this class to change the base rendering resolution for all game parts
+    var gameWindow = new GameWindow(stage, width, height);
+
+    //Display the GameWindow
+    stage.show();
+  }
+
+  /**
+   * Shutdown the game
+   */
+  public void shutdown() {
+    logger.info("Shutting down");
+    System.exit(0);
+  }
+
+  /**
+   * Get the singleton App instance
+   *
+   * @return the app
+   */
+  public static App getInstance() {
+    return instance;
+  }
 
 }
\ No newline at end of file
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/Launcher.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/Launcher.java
index 4fd4e2193586008fb87b04d044dfbba690a82b23..d3c1e0fde69dde479e280b64a4bc4dcc69c08ed9 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/Launcher.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/Launcher.java
@@ -6,12 +6,13 @@ package uk.ac.soton.comp1206;
  */
 public class Launcher {
 
-    /**
-     * Launch the JavaFX Application, passing through the commandline arguments
-     * @param args commandline arguments
-     */
-    public static void main(String[] args) {
-        App.main(args);
-    }
+  /**
+   * Launch the JavaFX Application, passing through the commandline arguments
+   *
+   * @param args commandline arguments
+   */
+  public static void main(String[] args) {
+    App.main(args);
+  }
 
 }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameBlock.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameBlock.java
index a234baa73c732eea793dcf4c9bf14edfad7ae214..49a1b08488d1ed01471248d7345eceebcfd6d07a 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameBlock.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameBlock.java
@@ -120,10 +120,12 @@ public class GameBlock extends Canvas {
       paintColor(COLOURS[value.get()]);
     }
 
+    //Paint the block if the user is hovering on it
     if (isHovering) {
       paintHoverTile();
     }
 
+    //Paint the centre of a piece
     if (isCentre) {
       paintCentreCircle();
     }
@@ -165,38 +167,47 @@ public class GameBlock extends Canvas {
     gc.setFill(colour);
     gc.fillRect(0, 0, width, height);
 
-    gc.setFill(Color.color(1,1,1,0.3));
+    gc.setFill(Color.color(1, 1, 1, 0.3));
     gc.fillPolygon(new double[]{0, width, 0}, new double[]{0, 0, height}, 3);
 
-    gc.setFill(Color.color(1,1,1,0.6));
+    gc.setFill(Color.color(1, 1, 1, 0.6));
     gc.fillRect(width - 3, 0, width, height);
 
-    gc.setFill(Color.color(1,1,1,0.6));
-    gc.fillRect(0,0, width, 3);
+    gc.setFill(Color.color(1, 1, 1, 0.6));
+    gc.fillRect(0, 0, width, 3);
 
-    gc.setFill(Color.color(0,0,0,0.4));
+    gc.setFill(Color.color(0, 0, 0, 0.4));
     gc.fillRect(0, height - 3, width, height);
 
-    gc.setFill(Color.color(0,0,0,0.4));
-    gc.fillRect(0,0, 3, height);
+    gc.setFill(Color.color(0, 0, 0, 0.4));
+    gc.fillRect(0, 0, 3, height);
 
     //Border
-    gc.setStroke(Color.color(0,0,0,0.4));
+    gc.setStroke(Color.color(0, 0, 0, 0.4));
     gc.strokeRect(0, 0, width, height);
   }
 
+  /**
+   * Paint the centre circle of a piece
+   */
   private void paintCentreCircle() {
     GraphicsContext gc = getGraphicsContext2D();
     gc.setFill(Color.color(1.0, 1.0, 1.0, 0.6));
     gc.fillOval(this.width / 4, this.height / 4, this.width / 2, this.height / 2);
   }
 
+  /**
+   * Paints a hover graphic on a tile if the user is hovering on it
+   */
   private void paintHoverTile() {
     GraphicsContext gc = getGraphicsContext2D();
     gc.setFill(Color.color(1.0, 1.0, 1.0, 0.4));
-    gc.fillRect(0,0, width, height);
+    gc.fillRect(0, 0, width, height);
   }
 
+  /**
+   * Sets the block to a centre block
+   */
   public void setCentre() {
     this.isCentre = true;
     paint();
@@ -207,11 +218,17 @@ public class GameBlock extends Canvas {
     paint();
   }
 
+  /**
+   * Starts fade out animation when a line is cleared
+   */
   public void startAnim() {
     FadeAnimation fadeAnimation = new FadeAnimation();
     fadeAnimation.start();
   }
 
+  /**
+   * Custom animation class which paints the block empty then paints it green which then fades out
+   */
   private class FadeAnimation extends AnimationTimer {
     double opacity = 1.0;
 
@@ -226,16 +243,16 @@ public class GameBlock extends Canvas {
       opacity = opacity - 0.03;
       if (this.opacity > 0) {
         GraphicsContext gc = GameBlock.this.getGraphicsContext2D();
-        gc.setFill(Color.color(0,1,0,opacity));
-        gc.fillRect(0,0, GameBlock.this.getWidth(), GameBlock.this.getHeight());
+        gc.setFill(Color.color(0, 1, 0, opacity));
+        gc.fillRect(0, 0, GameBlock.this.getWidth(), GameBlock.this.getHeight());
       } else {
         stop();
+        GameBlock.this.paint();
       }
 
     }
   }
 
-
   /**
    * Get the column of this block
    *
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameBoard.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameBoard.java
index 0a5913c9e7d7b571acf6ad400d6d0a1432fe3c19..ab638eb6e532ed62101ba97f2a49323d2bee6aca 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameBoard.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameBoard.java
@@ -1,13 +1,13 @@
 package uk.ac.soton.comp1206.component;
 
 import javafx.scene.input.MouseButton;
-import javafx.scene.input.MouseEvent;
 import javafx.scene.layout.GridPane;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import uk.ac.soton.comp1206.event.BlockClickedListener;
+import uk.ac.soton.comp1206.event.BoardHoverListener;
 import uk.ac.soton.comp1206.event.RightClickListener;
-import uk.ac.soton.comp1206.game.Game;
+import uk.ac.soton.comp1206.game.GamePiece;
 import uk.ac.soton.comp1206.game.Grid;
 
 /**
@@ -55,15 +55,15 @@ public class GameBoard extends GridPane {
   GameBlock[][] blocks;
 
   /**
-   * The listener to call when a specific block is clicked
+   * The listeners to call when a specific block is clicked, right clicked or hovered over
    */
   protected BlockClickedListener blockClickedListener;
 
   protected RightClickListener rightClickListener;
 
-  protected boolean isPieceBoard = false;
+  protected BoardHoverListener boardHoverListener;
 
-  private GameBlock hoveringBlock;
+  protected boolean isPieceBoard = false;
 
   /**
    * Create a new GameBoard, based off a given grid, with a visual width and height.
@@ -156,9 +156,7 @@ public class GameBoard extends GridPane {
     //Link the GameBlock component to the corresponding value in the Grid
     block.bind(grid.getGridProperty(x, y));
 
-    //Add a mouse click handler to the block to trigger GameBoard blockClicked method
-    //block.setOnMouseClicked((e) -> blockClicked(e, block));
-
+    //Mouse clicked handler which rotates or places a block
     block.setOnMouseClicked(e -> {
       if (e.getButton() == MouseButton.PRIMARY) {
         blockClicked(block);
@@ -167,9 +165,11 @@ public class GameBoard extends GridPane {
       }
     });
 
-    block.setOnMouseEntered(e -> setHover(block, true));
+    //Shows a piece hovering when the mouse enters a block
+    block.setOnMouseEntered(e -> blockHover(block, true));
 
-    block.setOnMouseExited(e -> setHover(block, false));
+    //Removes piece hovering when mouse leaves a block
+    block.setOnMouseExited(e -> blockHover(block, false));
 
     return block;
   }
@@ -183,10 +183,24 @@ public class GameBoard extends GridPane {
     this.blockClickedListener = listener;
   }
 
+  /**
+   * Sets the right click listener to handle right click events
+   *
+   * @param listener listener to add
+   */
   public void setOnRightClick(RightClickListener listener) {
     this.rightClickListener = listener;
   }
 
+  /**
+   * Set the hover listener to handle block hover events
+   *
+   * @param listener listener to add
+   */
+  public void setOnHover(BoardHoverListener listener) {
+    this.boardHoverListener = listener;
+  }
+
   /**
    * Triggered when a block is clicked. Call the attached listener.
    *
@@ -198,25 +212,83 @@ public class GameBoard extends GridPane {
     }
   }
 
+  /**
+   * Triggered when a block is right clicked and calls the attached listener
+   *
+   * @param block block right clicked on
+   */
   private void blockRightClicked(GameBlock block) {
     if (this.rightClickListener != null) {
-      this.rightClickListener.rightClicked();
+      this.rightClickListener.rightClicked(block);
+    }
+  }
+
+  /**
+   * Triggered when the user hovers over a block and calls the attached listener
+   *
+   * @param block block which the user hovers over
+   */
+  private void blockHover(GameBlock block, boolean isHovering) {
+    if (this.boardHoverListener != null) {
+      this.boardHoverListener.pieceHovering(block, isHovering);
     }
   }
 
-  public void setHover(GameBlock block, boolean isHovering) {
+  /**
+   * Starts fade out animation
+   *
+   * @param block block which has been cleared in a line
+   */
+  public void fadeOutAnim(GameBlock block) {
+    block.startAnim();
+  }
+
+  /**
+   * Sets a piece to hover or unhover
+   *
+   * @param currentPiece Piece to show hovering
+   * @param block block which the user is hovering over
+   * @param isHovering boolean which determines whether to hover or unhover
+   */
+  public void setHover(GamePiece currentPiece, GameBlock block, boolean isHovering) {
     if (isPieceBoard) return;
 
-    if (this.hoveringBlock != null) {
-      this.hoveringBlock.setHovering(false);
+    int[][] pieceBlocks = currentPiece.getBlocks();
+    int placeX = block.getX() - 1;
+    int placeY = block.getY() - 1;
+
+    for (int x = 0; x < pieceBlocks.length; x++) {
+      for (int y = 0; y < pieceBlocks[x].length; y++) {
+        int value = pieceBlocks[x][y];
+        if (value == 0) continue;
+        try {
+          blocks[x + placeX][y + placeY].setHovering(isHovering);
+        } catch (Exception ignored) {
+        }
+      }
     }
+  }
+
+  /**
+   * Unhovers any blocks on the board
+   */
+  public void unhover() {
+    for (GameBlock[] row : blocks) {
+      for (GameBlock block : row) {
+        block.setHovering(false);
+      }
+    }
+  }
 
-    this.hoveringBlock = block;
-    block.setHovering(isHovering);
+  public int getCols() {
+    return cols;
   }
 
-  public void fadeOutAnim(GameBlock block) {
-    block.startAnim();
+  public int getRows() {
+    return rows;
   }
 
+  public Grid getGrid() {
+    return grid;
+  }
 }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameLoopTimer.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameLoopTimer.java
index 767d31fa1465557f404e03c18e9fdfda00ff0551..8a2b62490dcd1d130401f422a65056e2cc58dae9 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameLoopTimer.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameLoopTimer.java
@@ -5,19 +5,30 @@ import javafx.scene.paint.Color;
 import javafx.scene.shape.Rectangle;
 import javafx.util.Duration;
 
-import java.security.Key;
-
 
+/**
+ * Timer for the game which resets at the end of each game loop or when the user places a block
+ */
 public class GameLoopTimer extends Rectangle {
   double width;
   Timeline tl;
   KeyFrame[] frames;
 
+  /**
+   * Create a game loop timer
+   *
+   * @param width The width of the timer
+   */
   public GameLoopTimer(double width) {
     this.width = width;
     setHeight(20);
   }
 
+  /**
+   * Creates the key frames of the timer animation
+   *
+   * @param duration The duration of the timer animation
+   */
   public void setupFrames(int duration) {
     KeyValue widthVal = new KeyValue(this.widthProperty(), width);
     KeyFrame widthStart = new KeyFrame(Duration.ZERO, widthVal);
@@ -29,17 +40,16 @@ public class GameLoopTimer extends Rectangle {
     KeyFrame greenStart = new KeyFrame(Duration.ZERO, colourVal);
 
     colourVal = new KeyValue(this.fillProperty(), Color.YELLOW);
-    KeyFrame yellowMid = new KeyFrame(Duration.millis(duration/2), colourVal);
+    KeyFrame yellowMid = new KeyFrame(Duration.millis(duration / 2), colourVal);
 
     colourVal = new KeyValue(this.fillProperty(), Color.RED);
     KeyFrame redEnd = new KeyFrame(Duration.millis(duration), colourVal);
 
-    frames = new KeyFrame[] {widthStart, widthFrame, greenStart, yellowMid, redEnd};
+    frames = new KeyFrame[]{widthStart, widthFrame, greenStart, yellowMid, redEnd};
   }
 
   public void startAnimation() {
     tl = new Timeline(frames);
     tl.play();
   }
-
 }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/component/LoadingBoard.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/component/LetterBoard.java
similarity index 59%
rename from tetrecs/src/main/java/uk/ac/soton/comp1206/component/LoadingBoard.java
rename to tetrecs/src/main/java/uk/ac/soton/comp1206/component/LetterBoard.java
index e10808a7faf2cb984d0f87fbc220830271f20fe3..588e3b2eefacb7cac86bbc75e059820754e193e7 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/component/LoadingBoard.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/component/LetterBoard.java
@@ -2,9 +2,13 @@ package uk.ac.soton.comp1206.component;
 
 import uk.ac.soton.comp1206.game.GamePiece;
 
-public class LoadingBoard extends GameBoard{
-  public LoadingBoard(double width, double height) {
-    super(5,5, width, height);
+/**
+ * Letter board which is a 5x5 grid which displays a letter
+ * It is used in the loading screen and the menu to display the logos
+ */
+public class LetterBoard extends GameBoard {
+  public LetterBoard(double width, double height) {
+    super(5, 5, width, height);
     this.isPieceBoard = true;
   }
 
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/component/PieceBoard.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/component/PieceBoard.java
index 1a8b872733e69851353703e1798479c7b754e41f..9d90e9c34ccb6a055f5cc2676eb27780070e1af4 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/component/PieceBoard.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/component/PieceBoard.java
@@ -3,6 +3,9 @@ package uk.ac.soton.comp1206.component;
 import uk.ac.soton.comp1206.event.BlockClickedListener;
 import uk.ac.soton.comp1206.game.GamePiece;
 
+/**
+ * Piece board which displays the current and next pieces to play
+ */
 public class PieceBoard extends GameBoard {
 
   public PieceBoard(double width, double height) {
@@ -23,12 +26,19 @@ public class PieceBoard extends GameBoard {
     this.grid.clear();
   }
 
-  public void setOnClick(BlockClickedListener handler) {
-    this.blockClickedListener = handler;
+  /**
+   * Set the listener to handle an event when the piece board is clicked
+   *
+   * @param listener listener to add
+   */
+  public void setOnClick(BlockClickedListener listener) {
+    this.blockClickedListener = listener;
   }
 
+  /**
+   * Draws the centre circle on the piece
+   */
   public void drawCentre() {
     this.blocks[1][1].setCentre();
   }
-
 }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/event/BoardHoverListener.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/event/BoardHoverListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..8119d7a83e0311dfd711736dd382993ec35be825
--- /dev/null
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/event/BoardHoverListener.java
@@ -0,0 +1,18 @@
+package uk.ac.soton.comp1206.event;
+
+import uk.ac.soton.comp1206.component.GameBlock;
+
+/**
+ * The Board Hover listener is used to handle when a user hovers over a block in the game board.
+ * It passes the game block which is being hovered over the a boolean to determine whether to hover or unhover
+ */
+public interface BoardHoverListener {
+
+  /**
+   * Handle a block hover event
+   *
+   * @param block the block that was clicked
+   * @param isHovering boolean which determines whether to hover or unhover
+   */
+  void pieceHovering(GameBlock block, boolean isHovering);
+}
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/event/BoardUpdatedListener.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/event/BoardUpdatedListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..b4013de624f0d5e37ff00d67f6573593f8d2ba24
--- /dev/null
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/event/BoardUpdatedListener.java
@@ -0,0 +1,5 @@
+package uk.ac.soton.comp1206.event;
+
+public interface BoardUpdatedListener {
+  void updateBoard(String playerName, String[] values);
+}
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/event/GameLoopListener.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/event/GameLoopListener.java
index bccf5f939fda0218b05a5a4d1a549e0cb4f6d261..690e82a71b768f904b7c26cd36a53dd4bb46de2e 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/event/GameLoopListener.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/event/GameLoopListener.java
@@ -1,5 +1,14 @@
 package uk.ac.soton.comp1206.event;
 
+/**
+ * The Game loop listener is used to listen for the end of a game loop
+ */
 public interface GameLoopListener {
+
+  /**
+   * Handles when a game loop is finished
+   *
+   * @param delay the delay of the game loop
+   */
   void gameLoop(int delay);
 }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/event/GameOverListener.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/event/GameOverListener.java
index 6f3a397e7a9f1a2ad04f363a0aa919a8d086402c..dadc970ba260023b4cba8c9a4ac11f1c4a158125 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/event/GameOverListener.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/event/GameOverListener.java
@@ -1,5 +1,9 @@
 package uk.ac.soton.comp1206.event;
 
+
+/**
+ * The Game over listener is used to listen for when the game ends
+ */
 public interface GameOverListener {
   void gameOver();
 }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/event/LineClearedListener.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/event/LineClearedListener.java
index 14cfeb59ce88e1f2f08ad0de8753f2519735aa11..b2d5624c75779069722425af2b23dab761d2bcb6 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/event/LineClearedListener.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/event/LineClearedListener.java
@@ -4,6 +4,16 @@ import uk.ac.soton.comp1206.component.GameBlockCoordinate;
 
 import java.util.HashSet;
 
+
+/**
+ * The line cleared listener is used to listen for when a line is cleared in the game
+ */
 public interface LineClearedListener {
+
+  /**
+   * Clears a line when the listener is called
+   *
+   * @param blocksToRemove Set of blocks which will be removed when the line is cleared
+   */
   void lineCleared(HashSet<GameBlockCoordinate> blocksToRemove);
 }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/event/NextPieceListener.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/event/NextPieceListener.java
index 77fc3c91c8c568c75114d240290192215a793db2..8b8ef2f2ad09346c7dd135c962a3b2c88d35aa39 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/event/NextPieceListener.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/event/NextPieceListener.java
@@ -2,6 +2,15 @@ package uk.ac.soton.comp1206.event;
 
 import uk.ac.soton.comp1206.game.GamePiece;
 
+/**
+ * The next piece listener is used to handle when the next piece is spawned
+ */
 public interface NextPieceListener {
+
+  /**
+   * Handles the next piece spawned
+   *
+   * @param piece The next piece spawned which needs to be handled
+   */
   void nextPiece(GamePiece piece);
 }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/event/RightClickListener.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/event/RightClickListener.java
index 9b2c5abb20bc053d570ece6d50f1230353e4f2a8..a716819cbdcd636eb11178b6cbda15d05503b5b1 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/event/RightClickListener.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/event/RightClickListener.java
@@ -1,5 +1,16 @@
 package uk.ac.soton.comp1206.event;
 
+import uk.ac.soton.comp1206.component.GameBlock;
+
+/**
+ * The right click listener is used for listening to right clicks on the game board
+ */
 public interface RightClickListener {
-  void rightClicked();
+
+  /**
+   * Handles a block right-clicked event
+   *
+   * @param block The block which has been right clicked
+   */
+  void rightClicked(GameBlock block);
 }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/event/ScoreUpdatedListener.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/event/ScoreUpdatedListener.java
index 18576c5c61d2a1308f8f3a97ea76bba5eaaa21ed..9a74229aacfd362e0b6b54507617054572d44378 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/event/ScoreUpdatedListener.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/event/ScoreUpdatedListener.java
@@ -1,6 +1,9 @@
 package uk.ac.soton.comp1206.event;
 
+
+/**
+ * The score updated listener is used for listening to score updates in the game
+ */
 public interface ScoreUpdatedListener {
   void updateScore();
-
 }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/game/ChallengeGame.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/game/ChallengeGame.java
index 5f6be97cccaca1aca26f53d6356187a06d1ee545..2873393fd36b8b2d8b4b237d44ec1092beb92e90 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/game/ChallengeGame.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/game/ChallengeGame.java
@@ -2,11 +2,16 @@ package uk.ac.soton.comp1206.game;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
+import uk.ac.soton.comp1206.event.BoardUpdatedListener;
 
 import java.util.Random;
 
-public class ChallengeGame extends Game{
+/**
+ * Challenge game is the single player version of the game
+ */
+public class ChallengeGame extends Game {
   private static final Logger logger = LogManager.getLogger(ChallengeGame.class);
+
   /**
    * Create a new game with the specified rows and columns. Creates a corresponding grid model.
    *
@@ -17,6 +22,11 @@ public class ChallengeGame extends Game{
     super(cols, rows);
   }
 
+  /**
+   * Method to spawn a piece in the Challenge game
+   *
+   * @return current piece
+   */
   @Override
   public GamePiece spawnPiece() {
     Random rand = new Random();
@@ -25,6 +35,16 @@ public class ChallengeGame extends Game{
     return piece;
   }
 
+  @Override
+  public void setScore(int score) {
+    logger.info("Score is now " + score);
+    this.score.set(score);
+
+    if (this.scoreUpdatedListener != null) {
+      scoreUpdatedListener.updateScore();
+    }
+  }
+
   @Override
   public void sendChatMessage(String message) {
   }
@@ -32,4 +52,8 @@ public class ChallengeGame extends Game{
   @Override
   public void updateLeaderboard(String[] data) {
   }
+
+  @Override
+  public void setBoardUpdatedListener(BoardUpdatedListener listener) {
+  }
 }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/game/Game.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/game/Game.java
index f3561547919ae8f5019ea7298b57c4b1c0f9e4e2..42f2f75c851442af5c1e9f22e31c2d3c5729e15a 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/game/Game.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/game/Game.java
@@ -1,6 +1,5 @@
 package uk.ac.soton.comp1206.game;
 
-import javafx.application.Platform;
 import javafx.beans.property.IntegerProperty;
 import javafx.beans.property.SimpleIntegerProperty;
 import javafx.beans.property.SimpleStringProperty;
@@ -93,6 +92,7 @@ public abstract class Game {
     this.lives.set(3);
     this.multiplier.set(1);
 
+    //Spawns new pieces to set as the current and next piece
     this.nextPiece = spawnPiece();
     nextPiece();
   }
@@ -107,7 +107,7 @@ public abstract class Game {
     int x = gameBlock.getX();
     int y = gameBlock.getY();
 
-    //Get the new value for this block
+    //Places the piece if it is possible and then restarts the game loop and spawns a new piece
     logger.info("Block clicked at x = {}  y = {}", x, y);
     boolean placed = grid.playPiece(currentPiece, x, y);
     if (placed) {
@@ -124,6 +124,9 @@ public abstract class Game {
 
   abstract GamePiece spawnPiece();
 
+  /**
+   * Spawns a new piece to set as the next piece and changes the current piece
+   */
   public void nextPiece() {
     this.currentPiece = this.nextPiece;
     this.nextPiece = spawnPiece();
@@ -134,21 +137,21 @@ public abstract class Game {
 
     logger.info("Current piece is : {}", this.currentPiece);
     logger.info("Next piece is: {}", this.nextPiece);
-
   }
 
+  /**
+   * Checks the board after a piece is placed to check for any full lines
+   */
   public void afterPiece() {
     ArrayList<Integer> fullCols = new ArrayList<>();
     ArrayList<Integer> fullRows = new ArrayList<>();
 
     HashSet<GameBlockCoordinate> blocksToClear = new HashSet<>();
 
-    /*
-     * Check each vertical column to see if it is full
-     */
-    for (int x = 0; x < grid.getCols(); x++) {
+    //Check each vertical column to see if it is full
+    for (int x = 0; x < this.cols; x++) {
       boolean full = true;
-      for (int y = 0; y < grid.getRows(); y++) {
+      for (int y = 0; y < this.rows; y++) {
         if (grid.get(x, y) == 0) {
           full = false;
         }
@@ -158,12 +161,10 @@ public abstract class Game {
       }
     }
 
-    /*
-     * Check each horizontal row to see if it is full
-     */
-    for (int y = 0; y < grid.getCols(); y++) {
+    //Check each horizontal row to see if it is full
+    for (int y = 0; y < this.cols; y++) {
       boolean full = true;
-      for (int x = 0; x < grid.getRows(); x++) {
+      for (int x = 0; x < this.rows; x++) {
         if (grid.get(x, y) == 0) {
           full = false;
         }
@@ -175,11 +176,10 @@ public abstract class Game {
 
     int numGridBlocks = 0;
 
-    /*
-     * Removes all columns which are full
-     */
+
+    //Removes all columns which are full
     for (int x : fullCols) {
-      for (int y = 0; y < grid.getCols(); y++) {
+      for (int y = 0; y < this.cols; y++) {
         if (grid.get(x, y) != 0) {
           blocksToClear.add(new GameBlockCoordinate(x, y));
           grid.set(x, y, 0);
@@ -188,11 +188,9 @@ public abstract class Game {
       }
     }
 
-    /*
-      Removes all rows which are full
-     */
+    //Removes all rows which are full
     for (int y : fullRows) {
-      for (int x = 0; x < grid.getCols(); x++) {
+      for (int x = 0; x < this.cols; x++) {
         if (grid.get(x, y) != 0) {
           blocksToClear.add(new GameBlockCoordinate(x, y));
           grid.set(x, y, 0);
@@ -201,10 +199,11 @@ public abstract class Game {
       }
     }
 
-
+    //Calculates and sets the new score based on how many lines were cleared
     int newScore = score.get() + (fullCols.size() + fullRows.size()) * numGridBlocks * 10 * multiplier.get();
     this.setScore(newScore);
 
+    //Sets the user level depending on their score
     this.setLevel(Math.floorDiv(this.score.get(), 1000));
 
     if (fullCols.size() != 0 || fullRows.size() != 0) {
@@ -216,17 +215,24 @@ public abstract class Game {
       }
     }
 
+    //Calls the line cleared listener which runs the line clear animation in the game scene
     if (this.lineClearedListener != null) {
       this.lineClearedListener.lineCleared(blocksToClear);
     }
   }
 
+  /**
+   * Swaps the current and next piece
+   */
   public void swapPiece() {
     GamePiece tempPiece = this.currentPiece;
     this.currentPiece = this.nextPiece;
     this.nextPiece = tempPiece;
   }
 
+  /**
+   * Starts a game loop which decreases the user's lives and spawns a new piece when the timer finishes
+   */
   public void startGameLoop() {
     timer = new Timer();
     logger.info("Starting game loop with delay: {}", getTimerDelay());
@@ -237,13 +243,16 @@ public abstract class Game {
       }
     };
 
-    timer.schedule(gameLoopTask , getTimerDelay());
+    timer.schedule(gameLoopTask, getTimerDelay());
 
     if (this.gameLoopListener != null) {
       this.gameLoopListener.gameLoop(getTimerDelay());
     }
   }
 
+  /**
+   * Runs when the game loop timer finishes
+   */
   public void gameLoop() {
     if (this.multiplier.get() > 1) {
       this.setMultiplier(1);
@@ -261,16 +270,25 @@ public abstract class Game {
     }
   }
 
+  /**
+   * Restarts the game loop
+   */
   public void restartLoop() {
     stopTimer();
     startGameLoop();
   }
 
+  /**
+   * Stops the game loop timer
+   */
   public void stopTimer() {
     timer.cancel();
     timer.purge();
   }
 
+  /**
+   * Calls the game over listener to end the game
+   */
   public void endGame() {
     if (this.gameOverListener != null) {
       this.gameOverListener.gameOver();
@@ -304,22 +322,45 @@ public abstract class Game {
     return rows;
   }
 
+  /**
+   * Get the current piece
+   *
+   * @return current piece
+   */
   public GamePiece getCurrentPiece() {
     return currentPiece;
   }
 
+  /**
+   * Get the next piece
+   *
+   * @return next piece
+   */
   public GamePiece getNextPiece() {
     return nextPiece;
   }
 
+  /**
+   * Gets the leaderboard of scores in a multiplayer game
+   *
+   * @return leaderboard list
+   */
   public ObservableList<Pair<String, Integer>> getLeaderboardList() {
     return leaderboardList;
   }
 
+  /**
+   * Gets the chat message sent in a multiplayer game
+   *
+   * @return chat message
+   */
   public SimpleStringProperty getChatMessage() {
     return chatMessage;
   }
 
+  /**
+   * Method to send a chat message
+   */
   public abstract void sendChatMessage(String message);
 
   public void setNextPieceListener(NextPieceListener listener) {
@@ -342,6 +383,9 @@ public abstract class Game {
     this.scoreUpdatedListener = listener;
   }
 
+  /**
+   * Rotates a piece based on the number of rotations
+   */
   public void rotatePiece(int rotations) {
     this.currentPiece.rotate(rotations);
   }
@@ -366,23 +410,27 @@ public abstract class Game {
     return myName;
   }
 
+  /**
+   * Sets the user's name
+   */
   public void setMyName(String name) {
     this.myName.set(name);
   }
 
+  /**
+   * Get the game loop timer delay
+   *
+   * @return timer delay
+   */
   public int getTimerDelay() {
     return Math.max(2500, 12000 - 500 * this.level.get());
   }
 
-  public void setScore(int score) {
-    logger.info("Score is now " + score);
-    this.score.set(score);
-
-    if (this.scoreUpdatedListener != null) {
-      scoreUpdatedListener.updateScore();
-    }
-  }
+  abstract void setScore(int score);
 
+  /**
+   * Sets the user's level
+   */
   public void setLevel(int level) {
     if (level > this.level.get()) {
       logger.info("Increasing level to " + level);
@@ -391,11 +439,17 @@ public abstract class Game {
     this.level.set(level);
   }
 
+  /**
+   * Decreases the user's lives
+   */
   public void decreaseLives(int lives) {
     Multimedia.playSound("lifelose.wav");
     this.lives.set(lives);
   }
 
+  /**
+   * Sets the multiplier
+   */
   public void setMultiplier(int multiplier) {
     if (multiplier != 1) {
       logger.info("Increasing multiplier to " + multiplier);
@@ -405,5 +459,7 @@ public abstract class Game {
     this.multiplier.set(multiplier);
   }
 
-  public abstract void updateLeaderboard(String[] data);
+  abstract void updateLeaderboard(String[] data);
+
+  public abstract void setBoardUpdatedListener(BoardUpdatedListener listener);
 }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/game/GamePiece.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/game/GamePiece.java
index d7fa689ab321eba3dc0d6ce57282c2907865aca5..8e33490ae429bd32f75beaee6451ac3d53272daf 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/game/GamePiece.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/game/GamePiece.java
@@ -132,39 +132,39 @@ public class GamePiece {
     throw new IndexOutOfBoundsException("No such piece: " + piece);
   }
 
-  public static GamePiece createLoadingPiece(String letter, int colour) {
+  public static GamePiece createLetterPiece(String letter, int colour) {
     switch (letter) {
       case "T" -> {
-        int[][] blocks = {{1,0,0,0,0},{1,0,0,0,0},{1,1,1,1,1},{1,0,0,0,0},{1,0,0,0,0}};
+        int[][] blocks = {{1, 0, 0, 0, 0}, {1, 0, 0, 0, 0}, {1, 1, 1, 1, 1}, {1, 0, 0, 0, 0}, {1, 0, 0, 0, 0}};
         return new GamePiece("T", blocks, colour);
       }
       case "E" -> {
-        int[][] blocks = {{0,0,0,0,0},{1,1,1,1,1},{1,0,1,0,1},{1,0,1,0,1},{0,0,0,0,0}};
-        return new GamePiece("E", blocks,colour);
+        int[][] blocks = {{0, 0, 0, 0, 0}, {1, 1, 1, 1, 1}, {1, 0, 1, 0, 1}, {1, 0, 1, 0, 1}, {0, 0, 0, 0, 0}};
+        return new GamePiece("E", blocks, colour);
       }
       case "R" -> {
-        int[][] blocks = {{0,0,0,0,0},{1,1,1,1,1},{1,0,1,0,0},{1,0,1,1,0},{1,1,0,1,1}};
-        return new GamePiece("R", blocks,colour);
+        int[][] blocks = {{0, 0, 0, 0, 0}, {1, 1, 1, 1, 1}, {1, 0, 1, 0, 0}, {1, 0, 1, 1, 0}, {1, 1, 0, 1, 1}};
+        return new GamePiece("R", blocks, colour);
       }
       case "C" -> {
-        int[][] blocks = {{0,0,0,0,0},{1,1,1,1,1},{1,0,0,0,1},{1,0,0,0,1},{0,0,0,0,0}};
-        return new GamePiece("C", blocks,colour);
+        int[][] blocks = {{0, 0, 0, 0, 0}, {1, 1, 1, 1, 1}, {1, 0, 0, 0, 1}, {1, 0, 0, 0, 1}, {0, 0, 0, 0, 0}};
+        return new GamePiece("C", blocks, colour);
       }
       case "S" -> {
-        int[][] blocks = {{0,0,0,0,0},{1,1,1,0,1},{1,0,1,0,1},{1,0,1,1,1},{0,0,0,0,0}};
-        return new GamePiece("S", blocks,colour);
+        int[][] blocks = {{0, 0, 0, 0, 0}, {1, 1, 1, 0, 1}, {1, 0, 1, 0, 1}, {1, 0, 1, 1, 1}, {0, 0, 0, 0, 0}};
+        return new GamePiece("S", blocks, colour);
       }
       case "M" -> {
-        int[][] blocks = {{1,1,1,1,1},{1,0,0,0,0},{0,1,1,0,0},{1,0,0,0,0},{1,1,1,1,1}};
-        return new GamePiece("M", blocks,colour);
+        int[][] blocks = {{1, 1, 1, 1, 1}, {1, 0, 0, 0, 0}, {0, 1, 1, 0, 0}, {1, 0, 0, 0, 0}, {1, 1, 1, 1, 1}};
+        return new GamePiece("M", blocks, colour);
       }
       case "A" -> {
-        int[][] blocks = {{0,0,0,0,0},{1,1,1,1,1},{1,0,1,0,0},{1,1,1,1,1},{0,0,0,0,0}};
-        return new GamePiece("A", blocks,colour);
+        int[][] blocks = {{0, 0, 0, 0, 0}, {1, 1, 1, 1, 1}, {1, 0, 1, 0, 0}, {1, 1, 1, 1, 1}, {0, 0, 0, 0, 0}};
+        return new GamePiece("A", blocks, colour);
       }
       case "G" -> {
-        int[][] blocks = {{0,0,0,0,0},{1,1,1,1,1},{1,0,0,0,1},{1,0,1,0,1},{1,0,1,1,1}};
-        return new GamePiece("G", blocks,colour);
+        int[][] blocks = {{0, 0, 0, 0, 0}, {1, 1, 1, 1, 1}, {1, 0, 0, 0, 1}, {1, 0, 1, 0, 1}, {1, 0, 1, 1, 1}};
+        return new GamePiece("G", blocks, colour);
       }
     }
 
@@ -185,9 +185,9 @@ public class GamePiece {
     return newPiece;
   }
 
-  public static GamePiece createLoadingPiece(String piece,int colour, int rotation) {
-    var newPiece = createLoadingPiece(piece, colour);
-    newPiece.rotateLoadingBoards(rotation);
+  public static GamePiece createLetterPiece(String piece, int colour, int rotation) {
+    var newPiece = createLetterPiece(piece, colour);
+    newPiece.rotateLetterBoards(rotation);
     return newPiece;
   }
 
@@ -262,22 +262,22 @@ public class GamePiece {
     blocks = rotated;
   }
 
-  public void rotateLoadingBoards(int rotations) {
+  public void rotateLetterBoards(int rotations) {
     for (int rotated = 0; rotated < rotations; rotated++) {
-      rotateLoadingBoards();
+      rotateLetterBoards();
     }
   }
 
-  public void rotateLoadingBoards() {
+  public void rotateLetterBoards() {
     int[][] result = new int[blocks.length][];
 
-    for(int i = 0; i < blocks.length; i++) {
+    for (int i = 0; i < blocks.length; i++) {
       result[i] = new int[blocks[i].length];
       System.arraycopy(blocks[i], 0, result[i], 0, blocks[i].length);
     }
 
-    for(int x = 0; x < 5; x++) {
-      for(int y = 0; y < 5; y++) {
+    for (int x = 0; x < 5; x++) {
+      for (int y = 0; y < 5; y++) {
         blocks[x][y] = result[5 - y - 1][x];
       }
     }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/game/Grid.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/game/Grid.java
index 133f8973e970894317c3e1e6d446c994849161c8..aa368b77d383bd49a53215bc6a3b5e493bf2a717 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/game/Grid.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/game/Grid.java
@@ -95,6 +95,13 @@ public class Grid {
     }
   }
 
+  /**
+   * Checks whether a piece can be played
+   *
+   * @param gamePiece the piece to be played
+   * @param placeX the x-coordinate of the piece to be placed
+   * @param placeY the y-coordinate of the piece to be placed
+   */
   public boolean canPlayPiece(GamePiece gamePiece, int placeX, int placeY) {
     int[][] blocks = gamePiece.getBlocks();
     placeX = placeX - 1;
@@ -112,6 +119,13 @@ public class Grid {
     return true;
   }
 
+  /**
+   * Places a piece if it is possible
+   *
+   * @param gamePiece the piece to be played
+   * @param placeX the x-coordinate of the piece to be placed
+   * @param placeY the y-coordinate of the piece to be placed
+   */
   public boolean playPiece(GamePiece gamePiece, int placeX, int placeY) {
     if (!this.canPlayPiece(gamePiece, placeX, placeY)) return false;
 
@@ -129,6 +143,9 @@ public class Grid {
     return true;
   }
 
+  /**
+   * Clears the grid
+   */
   public void clear() {
     for (int y = 0; y < this.rows; y++) {
       for (int x = 0; x < this.cols; x++) {
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/game/MultiplayerGame.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/game/MultiplayerGame.java
index 5458649e0449f630aa9c8387d84a672e15d04200..c98de7abd3465c95bfee4238aa43309448f4b6e1 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/game/MultiplayerGame.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/game/MultiplayerGame.java
@@ -4,6 +4,8 @@ import javafx.application.Platform;
 import javafx.util.Pair;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
+import uk.ac.soton.comp1206.component.GameBlock;
+import uk.ac.soton.comp1206.event.BoardUpdatedListener;
 import uk.ac.soton.comp1206.network.Communicator;
 import uk.ac.soton.comp1206.utility.Multimedia;
 
@@ -12,7 +14,10 @@ import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.Random;
 
-public class MultiplayerGame extends Game{
+/**
+ * The multiplayer version of the game
+ */
+public class MultiplayerGame extends Game {
   private static final Logger logger = LogManager.getLogger(MultiplayerGame.class);
   private Communicator communicator;
 
@@ -20,9 +25,13 @@ public class MultiplayerGame extends Game{
   private ArrayDeque<GamePiece> pieces;
   private boolean gameStarted = false;
 
+  private BoardUpdatedListener boardUpdatedListener = null;
+
   /**
-   * Create a new game with the specified rows and columns. Creates a corresponding grid model.
+   * Create a new game with the specified rows, columns and a communicator to communicate with the server.
+   * Creates a corresponding grid model.
    *
+   * @param communicator The communicator which sends and receives messages from the server
    * @param cols number of columns
    * @param rows number of rows
    */
@@ -42,16 +51,21 @@ public class MultiplayerGame extends Game{
     this.multiplier.set(1);
     this.pieces = new ArrayDeque<>();
 
+    //Communicator message receive listener
     this.communicator.addListener(data -> {
       Platform.runLater(() -> receiveCommunication(data));
     });
     this.communicator.send("SCORES");
 
+    //Spawns three pieces initially
     for (int i = 0; i < 3; i++) {
       this.communicator.send("PIECE");
     }
   }
 
+  /**
+   * Receives the message from the server and calls the relevant method to handle the message
+   */
   private void receiveCommunication(String message) {
     String[] components = message.split(" ", 2);
     switch (components[0]) {
@@ -79,13 +93,27 @@ public class MultiplayerGame extends Game{
           gameStarted = true;
         }
       }
+      case "BOARD" -> {
+        String[] boardVals = components[1].split(":", 2);
+        if (!boardVals[0].equals(myName.get())) {
+          if (boardUpdatedListener != null) {
+            boardUpdatedListener.updateBoard(boardVals[0],boardVals[1].split(" "));
+          }
+        }
+      }
     }
   }
 
+  /**
+   * Sends a SCORE message to the server which updates the user's score
+   */
   private void updateScore() {
     this.communicator.send("SCORE " + this.getScore().get());
   }
 
+  /**
+   * Parses the message received from the server and displays it in the chat
+   */
   private void parseMessage(String[] data) {
     if (data.length > 1) {
       chatMessage.set("[" + data[0] + "]:" + data[1]);
@@ -94,6 +122,9 @@ public class MultiplayerGame extends Game{
     }
   }
 
+  /**
+   * Updates the leaderboard with the user's score and position
+   */
   public void updateLeaderboard(String[] score) {
     int i = -1;
     for (Pair<String, Integer> pair : leaderboardList) {
@@ -119,6 +150,9 @@ public class MultiplayerGame extends Game{
     }
   }
 
+  /**
+   * Loads all the current scores and adds it to the leaderboard list
+   */
   private void loadScores(String[] scores) {
     onlineScores.clear();
     for (String score : scores) {
@@ -142,10 +176,32 @@ public class MultiplayerGame extends Game{
     leaderboardList.addAll(this.onlineScores);
   }
 
+  /**
+   * Sends a chat message
+   */
   public void sendChatMessage(String message) {
     this.communicator.send("MSG " + message);
   }
 
+  @Override
+  public void blockClicked(GameBlock gameBlock) {
+    super.blockClicked(gameBlock);
+    this.communicator.send("BOARD" + boardToString());
+  }
+
+  public String boardToString() {
+    StringBuilder board = new StringBuilder();
+    for (int x = 0; x < this.cols; x++) {
+      for (int y = 0; y < this.rows; y++) {
+        board.append(" ").append(this.grid.get(x, y));
+      }
+    }
+    return board.toString();
+  }
+
+  /**
+   * Spawns a piece by sending a PARSE message to the server
+   */
   @Override
   public GamePiece spawnPiece() {
     logger.info("Spawning Piece");
@@ -161,4 +217,7 @@ public class MultiplayerGame extends Game{
     this.updateScore();
   }
 
+  public void setBoardUpdatedListener(BoardUpdatedListener listener) {
+    this.boardUpdatedListener = listener;
+  }
 }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/ChallengeScene.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/ChallengeScene.java
index 360ffc22b206e4dba4b21c5174b92f7274dc9c18..e4e4163b129a9109d06b3cde5e8ed58b14c456e4 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/ChallengeScene.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/ChallengeScene.java
@@ -1,10 +1,9 @@
 package uk.ac.soton.comp1206.scene;
 
 import javafx.application.Platform;
-import javafx.beans.Observable;
 import javafx.beans.property.IntegerProperty;
 import javafx.beans.property.SimpleIntegerProperty;
-import javafx.beans.value.ObservableValue;
+import javafx.geometry.HPos;
 import javafx.geometry.Pos;
 import javafx.scene.input.KeyCode;
 import javafx.scene.input.KeyEvent;
@@ -47,7 +46,7 @@ public class ChallengeScene extends BaseScene {
   protected HBox header;
   protected VBox gameInfo;
 
-  private IntegerProperty hiscore = new SimpleIntegerProperty(0);
+  private final IntegerProperty hiscore = new SimpleIntegerProperty(0);
 
   /**
    * Create a new Single Player challenge scene
@@ -70,6 +69,7 @@ public class ChallengeScene extends BaseScene {
 
     this.hiscore.set(getHighScore());
 
+    //Sets the listeners for the game
     this.game.setNextPieceListener(this::nextPiece);
     this.game.setLineClearedListener(this::lineCleared);
     this.game.setGameLoopListener(this::gameTimer);
@@ -85,8 +85,12 @@ public class ChallengeScene extends BaseScene {
     });
 
     this.game.start();
+    this.board.unhover();
   }
 
+  /**
+   * Updates the high score shown in game if a user beats it
+   */
   private void updateHiScore() {
     if (this.hiscore.get() < this.game.getScore().get()) {
       logger.info("Updating Highscore");
@@ -94,8 +98,13 @@ public class ChallengeScene extends BaseScene {
     }
   }
 
-  private void keyHandler(KeyEvent e) {
-    this.board.setHover(this.board.getBlock(keyBoardPosX, keyBoardPosY), false);
+  /**
+   * Handles a key pressed event to add keyboard support for the game
+   *
+   * @param e the key which is pressed
+   */
+  protected void keyHandler(KeyEvent e) {
+    this.board.setHover(this.game.getCurrentPiece(), this.board.getBlock(keyBoardPosX, keyBoardPosY), false);
     if (e.getCode().equals(KeyCode.ESCAPE)) {
       endGame();
       this.gameWindow.startMenu();
@@ -104,9 +113,9 @@ public class ChallengeScene extends BaseScene {
     } else if (e.getCode().equals(KeyCode.SPACE) || e.getCode().equals(KeyCode.R)) {
       this.swapPiece();
     } else if (e.getCode().equals(KeyCode.E) || e.getCode().equals(KeyCode.C) || e.getCode().equals(KeyCode.CLOSE_BRACKET)) {
-      this.rotateBlock(1);
+      this.rotateBlock(this.board.getBlock(keyBoardPosX, keyBoardPosY), 1);
     } else if (e.getCode().equals(KeyCode.Q) || e.getCode().equals(KeyCode.Z) || e.getCode().equals(KeyCode.OPEN_BRACKET)) {
-      this.rotateBlock(3);
+      this.rotateBlock(this.board.getBlock(keyBoardPosX, keyBoardPosY), 3);
     } else if (e.getCode().equals(KeyCode.UP) || e.getCode().equals(KeyCode.W)) {
       if (keyBoardPosY > 0) keyBoardPosY--;
     } else if (e.getCode().equals(KeyCode.DOWN) || e.getCode().equals(KeyCode.S)) {
@@ -115,13 +124,8 @@ public class ChallengeScene extends BaseScene {
       if (keyBoardPosX > 0) keyBoardPosX--;
     } else if (e.getCode().equals(KeyCode.RIGHT) || e.getCode().equals(KeyCode.D)) {
       if (keyBoardPosX < this.game.getCols() - 1) keyBoardPosX++;
-    } else if (e.getCode().equals(KeyCode.SHIFT)) {
-      endGame();
-      Platform.runLater(() -> {
-        this.gameWindow.showScores(this.game);
-      });
     }
-    this.board.setHover(this.board.getBlock(keyBoardPosX, keyBoardPosY), true);
+    this.board.setHover(this.game.getCurrentPiece(), this.board.getBlock(keyBoardPosX, keyBoardPosY), true);
   }
 
   /**
@@ -148,15 +152,16 @@ public class ChallengeScene extends BaseScene {
     HBox header = buildHeader();
     mainPane.setTop(header);
 
+    //Builds the boards of the scene and includes the game information
     HBox boards = buildBoards();
     mainPane.setCenter(boards);
 
+    //Instantiates a new game loop timer
     timer = new GameLoopTimer(this.gameWindow.getWidth());
     mainPane.setBottom(timer);
   }
 
   public HBox buildHeader() {
-    //Header of Challenge Scene
     header = new HBox();
 
     //VBox to hold the Score title and value
@@ -198,12 +203,15 @@ public class ChallengeScene extends BaseScene {
     HBox boards = new HBox();
 
     this.board = new GameBoard(this.game.getGrid(), gameWindow.getWidth() / 2, gameWindow.getWidth() / 2);
-    //Handle block on gameboard grid being clicked
+
+    //Handle block on gameboard grid being clicked or hovered
     this.board.setOnBlockClick(this::blockClicked);
     this.board.setOnRightClick(this::rotateBlock);
+    this.board.setOnHover(this::hoverPiece);
 
     boards.getChildren().add(this.board);
 
+    //VBox to hold all game information such as high score, user level etc.
     gameInfo = new VBox();
 
     Text hiScoreTitle = new Text("High Score");
@@ -215,19 +223,37 @@ public class ChallengeScene extends BaseScene {
     hiScoreVal.getStyleClass().add("hiscore");
     gameInfo.getChildren().add(hiScoreVal);
 
+    GridPane levelAndMult = new GridPane();
+    levelAndMult.setAlignment(Pos.CENTER);
+    levelAndMult.setHgap(10);
+    gameInfo.getChildren().add(levelAndMult);
+
     Text levelTitle = new Text("Level");
     levelTitle.getStyleClass().add("heading");
-    gameInfo.getChildren().add(levelTitle);
+    levelAndMult.add(levelTitle, 0, 0);
 
     Text levelVal = new Text();
     levelVal.textProperty().bind(this.game.getLevel().asString());
     levelVal.getStyleClass().add("level");
-    gameInfo.getChildren().add(levelVal);
+    levelAndMult.add(levelVal, 0, 1);
+
+    Text multTitle = new Text("Multiplier");
+    multTitle.getStyleClass().add("heading");
+    levelAndMult.add(multTitle, 1, 0);
+
+    Text multValue = new Text();
+    multValue.textProperty().bind(this.game.getMultiplier().asString());
+    multValue.getStyleClass().add("level");
+    levelAndMult.add(multValue, 1, 1);
+
+    GridPane.setHalignment(multValue, HPos.CENTER);
+    GridPane.setHalignment(levelVal, HPos.CENTER);
 
     Text incomingTitle = new Text("Incoming");
     incomingTitle.getStyleClass().add("heading");
     gameInfo.getChildren().add(incomingTitle);
 
+    //Piece boards to display the current and next piece
     this.currentPieceBoard = new PieceBoard(gameWindow.getWidth() / 6, gameWindow.getWidth() / 6);
     this.currentPieceBoard.setOnClick(this::rotateBlock);
     this.currentPieceBoard.drawCentre();
@@ -249,6 +275,11 @@ public class ChallengeScene extends BaseScene {
     return boards;
   }
 
+  /**
+   * Runs the game loop timer animation
+   *
+   * @param delay how long the timer runs for
+   */
   protected void gameTimer(int delay) {
     logger.info("Running game loop animation");
     timer.setupFrames(delay);
@@ -259,12 +290,30 @@ public class ChallengeScene extends BaseScene {
     swapPiece();
   }
 
+  /**
+   * Swaps the current and next piece so that it is displayed in the correct board
+   */
   protected void swapPiece() {
     logger.info("Swapping current and next piece");
+    this.board.unhover();
     Multimedia.playSound("rotate.wav");
     this.currentPieceBoard.displayPiece(this.game.getNextPiece());
     this.nextPieceBoard.displayPiece(this.game.getCurrentPiece());
     this.game.swapPiece();
+    this.board.setHover(this.game.getCurrentPiece(), this.board.getBlock(keyBoardPosX, keyBoardPosY), true);
+  }
+
+  /**
+   * Shows the current piece hovering on the grid
+   *
+   * @param block hovers the piece with this block as the centre
+   * @param isHovering boolean which determines whether to hover or unhover a piece
+   */
+  protected void hoverPiece(GameBlock block, boolean isHovering) {
+    this.board.setHover(this.game.getCurrentPiece(), this.board.getBlock(keyBoardPosX, keyBoardPosY), false);
+    this.keyBoardPosX = block.getX();
+    this.keyBoardPosY = block.getY();
+    this.board.setHover(this.game.getCurrentPiece(), block, isHovering);
   }
 
   /**
@@ -278,21 +327,32 @@ public class ChallengeScene extends BaseScene {
     game.blockClicked(gameBlock);
   }
 
-  protected void rotateBlock(int rotations) {
+  /**
+   * Rotates a piece
+   *
+   * @param block rotates the piece about the block clicked
+   * @param rotations number of rotations
+   */
+  protected void rotateBlock(GameBlock block, int rotations) {
+    this.hoverPiece(block, false);
     logger.info("Rotating block");
     Multimedia.playSound("rotate.wav");
     this.game.rotatePiece(rotations);
+    this.hoverPiece(block, true);
     this.currentPieceBoard.displayPiece(this.game.getCurrentPiece());
   }
 
   protected void rotateBlock(GameBlock gameBlock) {
-    rotateBlock(1);
-  }
-
-  protected void rotateBlock() {
-    rotateBlock(1);
+    this.hoverPiece(gameBlock, false);
+    rotateBlock(gameBlock, 1);
+    this.hoverPiece(gameBlock, true);
   }
 
+  /**
+   * Runs the line cleared animation
+   *
+   * @param blocksToRemove Set which holds all the blocks to remove
+   */
   protected void lineCleared(HashSet<GameBlockCoordinate> blocksToRemove) {
     if (blocksToRemove.size() == 0) return;
     Multimedia.playSound("clear.wav");
@@ -301,6 +361,11 @@ public class ChallengeScene extends BaseScene {
     }
   }
 
+  /**
+   * Gets the current local high score
+   *
+   * @return high score
+   */
   private int getHighScore() {
     ArrayList<Pair<String, Integer>> localScores = ScoresScene.loadScores();
     return localScores.get(0).getValue();
@@ -316,8 +381,13 @@ public class ChallengeScene extends BaseScene {
     game = new ChallengeGame(5, 5);
   }
 
+  /**
+   * Method to handle when a new piece is spawned
+   */
   protected void nextPiece(GamePiece nextPiece) {
     logger.info("Next piece to place: " + nextPiece);
+    this.board.unhover();
+    this.board.setHover(nextPiece, this.board.getBlock(keyBoardPosX, keyBoardPosY), true);
     this.currentPieceBoard.displayPiece(nextPiece);
     this.nextPieceBoard.displayPiece(this.game.getNextPiece());
   }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/InstructionScene.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/InstructionScene.java
index 98e620f41a97fd1940c41fb4faa86c6b01a93562..56757513543dd380d815d97d6c2627d4a2a6c8b0 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/InstructionScene.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/InstructionScene.java
@@ -16,20 +16,19 @@ import javafx.scene.text.TextAlignment;
 import javafx.scene.text.TextFlow;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import uk.ac.soton.comp1206.component.GameBlock;
 import uk.ac.soton.comp1206.component.PieceBoard;
-import uk.ac.soton.comp1206.game.Game;
 import uk.ac.soton.comp1206.game.GamePiece;
 import uk.ac.soton.comp1206.ui.GamePane;
 import uk.ac.soton.comp1206.ui.GameWindow;
 import uk.ac.soton.comp1206.utility.Multimedia;
 
-public class InstructionScene extends BaseScene{
+public class InstructionScene extends BaseScene {
   private static final Logger logger = LogManager.getLogger(InstructionScene.class);
 
   private int pieceNumber = 0;
 
   private PieceBoard pieceBoard;
+
   /**
    * Create a new scene, passing in the GameWindow the scene will be displayed in
    *
@@ -41,11 +40,17 @@ public class InstructionScene extends BaseScene{
     logger.info("Creating Instructions Scene");
   }
 
+  /**
+   * Initialise the instructions screen
+   */
   @Override
   public void initialise() {
     this.scene.setOnKeyPressed(this::escapeToMenu);
   }
 
+  /**
+   * Build the instructions screen layout
+   */
   @Override
   public void build() {
     logger.info("Building " + this.getClass().getName());
@@ -91,12 +96,19 @@ public class InstructionScene extends BaseScene{
     mainPane.setCenter(widgets);
   }
 
+  /**
+   * Creates a HBox which dynamically shows each Game piece
+   * Includes right and left arrows which can be used to cycle through the pieces
+   *
+   * @return pieceBoardLayout Horizontal layout box
+   */
   private HBox buildPieceBoards() {
     HBox pieceBoardLayout = new HBox();
 
-    Canvas prevArrow = new Canvas(this.gameWindow.getWidth()/18, this.gameWindow.getHeight()/18);
+    Canvas prevArrow = new Canvas(this.gameWindow.getWidth() / 18, this.gameWindow.getHeight() / 18);
     prevArrow.getGraphicsContext2D().setFill(Color.WHITE);
-    prevArrow.getGraphicsContext2D().fillPolygon(new double[]{prevArrow.getWidth()/2, prevArrow.getWidth(), prevArrow.getWidth()}, new double[]{prevArrow.getHeight()/2, 0, prevArrow.getHeight()}, 3);
+    prevArrow.getGraphicsContext2D().fillPolygon(new double[]{prevArrow.getWidth() / 2, prevArrow.getWidth(), prevArrow.getWidth()}, new double[]{prevArrow.getHeight() / 2, 0, prevArrow.getHeight()}, 3);
+    //Sets it to display the previous piece if left arrow is clicked
     prevArrow.setOnMouseClicked(this::displayPrevPiece);
     pieceBoardLayout.getChildren().add(prevArrow);
 
@@ -105,9 +117,10 @@ public class InstructionScene extends BaseScene{
     pieceBoard.displayPiece(piece);
     pieceBoardLayout.getChildren().add(pieceBoard);
 
-    Canvas nextArrow = new Canvas(this.gameWindow.getWidth()/18, this.gameWindow.getHeight()/18);
+    Canvas nextArrow = new Canvas(this.gameWindow.getWidth() / 18, this.gameWindow.getHeight() / 18);
     nextArrow.getGraphicsContext2D().setFill(Color.WHITE);
-    nextArrow.getGraphicsContext2D().fillPolygon(new double[]{0, nextArrow.getWidth()/2, 0}, new double[] {0, nextArrow.getHeight()/2, nextArrow.getHeight()}, 3);
+    nextArrow.getGraphicsContext2D().fillPolygon(new double[]{0, nextArrow.getWidth() / 2, 0}, new double[]{0, nextArrow.getHeight() / 2, nextArrow.getHeight()}, 3);
+    //Sets it to display the next piece if right arrow is clicked
     nextArrow.setOnMouseClicked(this::displayNextPiece);
     pieceBoardLayout.getChildren().add(nextArrow);
 
@@ -115,9 +128,11 @@ public class InstructionScene extends BaseScene{
     pieceBoardLayout.setSpacing(20);
 
     return pieceBoardLayout;
-
   }
 
+  /**
+   * Displays the next piece in the cycle, loops around if all pieces are shown
+   */
   private void displayNextPiece(MouseEvent event) {
     Multimedia.playSound("rotate.wav");
     if (pieceNumber != 14) {
@@ -130,6 +145,9 @@ public class InstructionScene extends BaseScene{
     pieceBoard.displayPiece(piece);
   }
 
+  /**
+   * Displays the previous piece in the cycle, loops around if at the start
+   */
   private void displayPrevPiece(MouseEvent event) {
     Multimedia.playSound("rotate.wav");
     if (pieceNumber != 0) {
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/LoadingScene.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/LoadingScene.java
index 0a82b16a433db0068b73244b5341f92bdee2c16c..1277bf9cfe69ffa656a40084f491ee74ddf79f49 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/LoadingScene.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/LoadingScene.java
@@ -2,7 +2,6 @@ package uk.ac.soton.comp1206.scene;
 
 import javafx.animation.ScaleTransition;
 import javafx.application.Platform;
-import javafx.event.ActionEvent;
 import javafx.geometry.Pos;
 import javafx.scene.layout.BorderPane;
 import javafx.scene.layout.HBox;
@@ -11,7 +10,7 @@ import javafx.scene.layout.VBox;
 import javafx.util.Duration;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import uk.ac.soton.comp1206.component.LoadingBoard;
+import uk.ac.soton.comp1206.component.LetterBoard;
 import uk.ac.soton.comp1206.game.GamePiece;
 import uk.ac.soton.comp1206.ui.GamePane;
 import uk.ac.soton.comp1206.ui.GameWindow;
@@ -21,19 +20,20 @@ import java.util.ArrayList;
 import java.util.Timer;
 import java.util.TimerTask;
 
-public class LoadingScene extends BaseScene{
+/**
+ * The initial loading screen of the game. Plays an animation which displays the ECS Games logo.
+ */
+public class LoadingScene extends BaseScene {
   private static final Logger logger = LogManager.getLogger(LoadingScene.class);
 
-  private Timer timer;
   private Timer pieceTimer;
   private int pieceNum = 0;
   private VBox titleBox;
-  private ArrayList<LoadingBoard> boards = new ArrayList<>();
-  private int[] rotations = {2,2,3,3,2,3,3,4};
-  private int[] colours = {8,8,8,10,10,10,10,10};
+  private final ArrayList<LetterBoard> boards = new ArrayList<>();
+  private final int[] rotations = {2, 2, 3, 3, 2, 3, 3, 4};
 
   /**
-   * Create a new scene, passing in the GameWindow the scene will be displayed in
+   * Create a new Loading screen scene, passing in the GameWindow the scene will be displayed in
    *
    * @param gameWindow the game window
    */
@@ -41,6 +41,9 @@ public class LoadingScene extends BaseScene{
     super(gameWindow);
   }
 
+  /**
+   * Initialise the loading screen
+   */
   @Override
   public void initialise() {
     pieceTimer = new Timer();
@@ -58,6 +61,9 @@ public class LoadingScene extends BaseScene{
     pieceTimer.scheduleAtFixedRate(pieceTask, 0, 850);
   }
 
+  /**
+   * Build the loading screen layout, includes a VBox which holds grids which represent each letter in the ECS Games logo
+   */
   @Override
   public void build() {
     logger.info("Building " + this.getClass().getName());
@@ -73,6 +79,7 @@ public class LoadingScene extends BaseScene{
     BorderPane mainPane = new BorderPane();
     loadingPane.getChildren().add(mainPane);
 
+    //Vertical Layout box holds the grids used to show the letters of the ECS Games logo
     titleBox = new VBox();
     titleBox.setAlignment(Pos.CENTER);
     titleBox.setSpacing(20);
@@ -82,9 +89,10 @@ public class LoadingScene extends BaseScene{
     ecs.setAlignment(Pos.CENTER);
     ecs.setSpacing(5);
 
+    //For loop used to add 3 grids on the top
     for (int i = 0; i < 3; i++) {
-      LoadingBoard grid = new LoadingBoard(gameWindow.getWidth() / 12, gameWindow.getWidth() / 12);
-      ecs .getChildren().add(grid);
+      LetterBoard grid = new LetterBoard(gameWindow.getWidth() / 12, gameWindow.getWidth() / 12);
+      ecs.getChildren().add(grid);
       boards.add(grid);
     }
 
@@ -92,8 +100,9 @@ public class LoadingScene extends BaseScene{
     games.setAlignment(Pos.CENTER);
     games.setSpacing(5);
 
+    //Second for loop used to add 5 grids on the bottom
     for (int i = 0; i < 5; i++) {
-      LoadingBoard grid = new LoadingBoard(gameWindow.getWidth() / 12, gameWindow.getWidth() / 12);
+      LetterBoard grid = new LetterBoard(gameWindow.getWidth() / 12, gameWindow.getWidth() / 12);
       games.getChildren().add(grid);
       boards.add(grid);
     }
@@ -102,21 +111,30 @@ public class LoadingScene extends BaseScene{
     titleBox.getChildren().add(games);
   }
 
+  /**
+   * Method which is used to place a letter piece in the grids of the loading screen
+   *
+   * @param rotations The number of rotations on the piece
+   */
   public void placePiece(int rotations) throws InterruptedException {
-    String[] letters= {"E","C","S","G","A","M","E","S"};
-    GamePiece piece = GamePiece.createLoadingPiece(letters[pieceNum], colours[pieceNum], rotations);
+    String[] letters = {"E", "C", "S", "G", "A", "M", "E", "S"};
+    int[] colours = {8, 8, 8, 10, 10, 10, 10, 10};
+    //Creates a new letter piece with a given colour and number of rotations
+    GamePiece piece = GamePiece.createLetterPiece(letters[pieceNum], colours[pieceNum], rotations);
     boards.get(pieceNum).displayPiece(piece);
 
+    //Dynamically animates the letter rotating using a for loop
     for (int i = 0; i < 4 - rotations; i++) {
       Thread.sleep(200);
       Multimedia.playSound("rotate.wav");
-      piece.rotateLoadingBoards(1);
+      piece.rotateLetterBoards(1);
       boards.get(pieceNum).displayPiece(piece);
     }
 
     Multimedia.playSound("place.wav");
-
+    //pieceNum is a counter variable which counts how many letters have been placed so far
     pieceNum++;
+    //Cancels the repeating timer when all letters have been shown
     if (pieceNum == 8) {
       pieceTimer.cancel();
       pieceTimer.purge();
@@ -124,17 +142,24 @@ public class LoadingScene extends BaseScene{
     }
   }
 
+  /**
+   * Plays the starting intro sound and scales the ECS Games logo to fit the screen
+   */
   public void startSound() {
     Multimedia.playSound("intro.mp3");
-    ScaleTransition st = new ScaleTransition(Duration.millis(6000),titleBox);
+    //Scale transition to enlarge the logo whilst the sound is playing
+    ScaleTransition st = new ScaleTransition(Duration.millis(6000), titleBox);
     st.setToX(1.5);
     st.setToY(1.5);
 
     st.play();
-    st.setOnFinished(e -> {this.toMenu();});
+    //Goes to the main menu when the animation is finished
+    st.setOnFinished(e -> this.toMenu());
   }
 
-
+  /**
+   * Goes to the main menu
+   */
   public void toMenu() {
     Platform.runLater(this.gameWindow::startMenu);
   }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/LobbyScene.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/LobbyScene.java
index b9859579cbe1bf714ae641ff0de5a7175ae19cb9..30647ca25f4bc925293378ed806972becdc4a5e2 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/LobbyScene.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/LobbyScene.java
@@ -1,15 +1,12 @@
 package uk.ac.soton.comp1206.scene;
 
 import javafx.animation.FadeTransition;
-import javafx.animation.KeyFrame;
-import javafx.animation.KeyValue;
 import javafx.application.Platform;
+import javafx.beans.property.SimpleIntegerProperty;
 import javafx.beans.property.SimpleStringProperty;
-import javafx.geometry.Insets;
 import javafx.geometry.Pos;
 import javafx.scene.control.*;
 import javafx.scene.input.KeyCode;
-import javafx.scene.input.MouseEvent;
 import javafx.scene.layout.*;
 import javafx.scene.paint.Color;
 import javafx.scene.text.Text;
@@ -22,13 +19,18 @@ import uk.ac.soton.comp1206.ui.GamePane;
 import uk.ac.soton.comp1206.ui.GameWindow;
 import uk.ac.soton.comp1206.utility.Multimedia;
 
+import java.util.ArrayList;
 import java.util.Timer;
 import java.util.TimerTask;
 
-public class LobbyScene extends BaseScene{
+
+/**
+ * The lobby scene holds the UI for the multiplayer lobby where players can join or create multiplayer games
+ */
+public class LobbyScene extends BaseScene {
   private static final Logger logger = LogManager.getLogger(LobbyScene.class);
 
-  private Communicator communicator;
+  private final Communicator communicator;
   private Timer timer;
 
   private VBox currentGames;
@@ -39,10 +41,13 @@ public class LobbyScene extends BaseScene{
   private Label infoBox;
 
   private boolean isInChannel = false;
-  private SimpleStringProperty myName = new SimpleStringProperty("");
+  private final SimpleStringProperty myName = new SimpleStringProperty("");
+  private final ArrayList<Text> currentChannels = new ArrayList<>();
+  private String myChannel;
+  private ArrayList<String> players = new ArrayList<>();
 
   /**
-   * Create a new scene, passing in the GameWindow the scene will be displayed in
+   * Create a new lobby scene, passing in the GameWindow the scene will be displayed in
    *
    * @param gameWindow the game window
    */
@@ -53,16 +58,18 @@ public class LobbyScene extends BaseScene{
     logger.info("Creating lobby scene");
   }
 
+  /**
+   * Initialises the lobby
+   */
   @Override
   public void initialise() {
     this.scene.setOnKeyPressed(e -> {
       if (e.getCode().equals(KeyCode.ESCAPE)) backToMenu();
     });
 
-    this.communicator.addListener(data -> {
-      Platform.runLater(() -> receiveCommunication(data));
-    });
+    this.communicator.addListener(data -> Platform.runLater(() -> receiveCommunication(data)));
 
+    //Timer which checks for new multiplayer channels every 2 seconds
     timer = new Timer();
     TimerTask task = new TimerTask() {
       @Override
@@ -73,6 +80,9 @@ public class LobbyScene extends BaseScene{
     timer.scheduleAtFixedRate(task, 0, 2000);
   }
 
+  /**
+   * Method which handles any messages received from the server
+   */
   public void receiveCommunication(String message) {
     String[] components = message.split(" ", 2);
     switch (components[0]) {
@@ -89,6 +99,7 @@ public class LobbyScene extends BaseScene{
         }
         break;
       case "JOIN":
+        myChannel = components[1];
         setupChat();
         isInChannel = true;
         break;
@@ -103,16 +114,16 @@ public class LobbyScene extends BaseScene{
       case "HOST": {
         Button start = new Button("Start");
         buttons.getChildren().add(0, start);
-        start.setOnAction(e -> {
-          startGame();
-        });
+        start.setOnAction(e -> startGame());
         break;
       }
       case "USERS": {
         playerBox.getChildren().clear();
+        players.clear();
         Multimedia.playSound("message.wav");
         String[] names = components[1].split("\n");
         for (String name : names) {
+          players.add(name);
           Text playerName = new Text(name);
           if (name.equals(myName.get())) {
             playerName.getStyleClass().add("myname");
@@ -142,22 +153,28 @@ public class LobbyScene extends BaseScene{
           timer.cancel();
           timer.purge();
         }
-        this.gameWindow.startMultiplayerGame(this.myName.get());
+        this.players.remove(myName.get());
+        this.gameWindow.startMultiplayerGame(this.myName.get(), this.players.toArray(new String[players.size()]));
       }
       break;
       case "ERROR": {
-        if (components[1].equals("Channel already exists")) {
-          infoBox.setText("Error: There is already a game with that channel name!");
-          infoBox.getStyleClass().add("instructions");
-          infoBox.setTextFill(Color.RED);
-        } else if (components[1].equals("That name is already in use")) {
-          infoBox.setText("Error: That name is already in use!");
-          infoBox.getStyleClass().add("instructions");
-          infoBox.setTextFill(Color.RED);
-        } else if (components[1].equals("You are already in a channel")) {
-          infoBox.setText("Error: You are already in a channel!");
-          infoBox.getStyleClass().add("instructions");
-          infoBox.setTextFill(Color.RED);
+        Multimedia.playSound("fail.wav");
+        switch (components[1]) {
+          case "Channel already exists" -> {
+            infoBox.setText("Error: There is already a game with that channel name!");
+            infoBox.getStyleClass().add("instructions");
+            infoBox.setTextFill(Color.RED);
+          }
+          case "That name is already in use" -> {
+            infoBox.setText("Error: That name is already in use!");
+            infoBox.getStyleClass().add("instructions");
+            infoBox.setTextFill(Color.RED);
+          }
+          case "You are already in a channel" -> {
+            infoBox.setText("Error: You are already in a channel!");
+            infoBox.getStyleClass().add("instructions");
+            infoBox.setTextFill(Color.RED);
+          }
         }
 
         FadeTransition ft = new FadeTransition(Duration.millis(5000), infoBox);
@@ -170,35 +187,75 @@ public class LobbyScene extends BaseScene{
     }
   }
 
+  /**
+   * Sends a START message to start the game if the user is the host
+   */
   private void startGame() {
     this.communicator.send("START");
   }
 
+  /**
+   * Requests for all current channels by sending a LIST message to the server
+   */
   private void requestCurrentChannels() {
     this.communicator.send("LIST");
   }
 
+  /**
+   * Sends a request to create a channel
+   */
   private void sendCreateRequest(String channelName) {
     this.communicator.send("CREATE " + channelName);
   }
 
+  /**
+   * Method to leave a channel
+   */
   private void leaveChannel() {
     logger.info("Leaving channel");
     isInChannel = false;
+    myChannel = "";
     this.communicator.send("PART");
+    for (Text channel : currentChannels) {
+      channel.getStyleClass().remove("selected");
+    }
   }
 
+  /**
+   * Method to join a channel
+   */
   private void joinChannel(String channelName) {
     if (!isInChannel) {
       logger.info("Joining channel: {}", channelName);
       this.communicator.send("JOIN " + channelName);
+      for (Text channel : currentChannels) {
+        if (channel.getText().equals(channelName)) {
+          channel.getStyleClass().add("selected");
+        }
+      }
+    } else {
+      Multimedia.playSound("fail.wav");
+      infoBox.setText("Error: You are already in a channel!");
+      infoBox.getStyleClass().add("instructions");
+      infoBox.setTextFill(Color.RED);
+
+      FadeTransition ft = new FadeTransition(Duration.millis(5000), infoBox);
+      ft.setFromValue(1);
+      ft.setToValue(0);
+      ft.play();
     }
   }
 
+  /**
+   * Sends a chat message to the server with the MSG command
+   */
   private void sendMessage(String message) {
     this.communicator.send("MSG " + message);
   }
 
+  /**
+   * Parses any chat messages received and adds it to the chat
+   */
   private void parseMessage(String[] data) {
     Multimedia.playSound("message.wav");
     Text message = new Text();
@@ -211,11 +268,17 @@ public class LobbyScene extends BaseScene{
     messages.getChildren().add(message);
   }
 
+  /**
+   * Changes the user's nickname with the NICK command
+   */
   private void changeNickName(String name) {
     logger.info("Changing nickname to {}", name);
     this.communicator.send("NICK " + name);
   }
 
+  /**
+   * Creates the UI for when the user wants to create a channel
+   */
   private void startCreateOptions() {
     if (!isInChannel) {
       createGame.getChildren().clear();
@@ -237,21 +300,30 @@ public class LobbyScene extends BaseScene{
       infoBox.setWrapText(true);
       createGame.getChildren().add(infoBox);
 
+      //If the user presses enter after typing the channel name, it sends a CREATE request
       channelName.setOnKeyPressed(e -> {
         if (e.getCode().equals(KeyCode.ENTER)) {
           sendCreateRequest(channelName.getText());
         }
       });
 
-      submit.setOnAction(e -> {
-        sendCreateRequest(channelName.getText());
-      });
+      //If the user clicks submit after typing the channel name, it sends a CREATE request
+      submit.setOnAction(e -> sendCreateRequest(channelName.getText()));
     }
   }
 
+  /**
+   * Sets up the chat UI for when a user joins a channel
+   */
   private void setupChat() {
     createGame.getChildren().clear();
 
+    for (Text channel : currentChannels) {
+      if (channel.getText().equals(myChannel)) {
+        channel.getStyleClass().add("selected");
+      }
+    }
+
     playerBox = new HBox();
     playerBox.setSpacing(5);
     playerBox.getStyleClass().add("playerBox");
@@ -265,7 +337,7 @@ public class LobbyScene extends BaseScene{
     Text nickInstructions = new Text("Use /nick [NewName] to change username");
     welcome.getStyleClass().add("instructions");
     nickInstructions.getStyleClass().add("instructions");
-    instructions.getChildren().addAll(welcome,nickInstructions);
+    instructions.getChildren().addAll(welcome, nickInstructions);
 
     ScrollPane chatBox = new ScrollPane();
     chatBox.getStyleClass().add("scroller");
@@ -305,9 +377,7 @@ public class LobbyScene extends BaseScene{
 
     Button leave = new Button("Leave");
 
-    leave.setOnAction(e -> {
-      this.leaveChannel();
-    });
+    leave.setOnAction(e -> this.leaveChannel());
 
     buttons.getChildren().add(leave);
     buttons.setAlignment(Pos.CENTER);
@@ -315,6 +385,9 @@ public class LobbyScene extends BaseScene{
     createGame.getChildren().add(buttons);
   }
 
+  /**
+   * Builds the main lobby scene UI
+   */
   @Override
   public void build() {
     logger.info("Building " + this.getClass().getName());
@@ -360,6 +433,7 @@ public class LobbyScene extends BaseScene{
     hostGameTitle.setOnMouseClicked(e -> this.startCreateOptions());
     createGameVBox.getChildren().add(hostGameTitle);
 
+    //VBox to hold all the current channels
     currentGames = new VBox();
     currentGames.setAlignment(Pos.CENTER);
     currentGames.setSpacing(10);
@@ -368,6 +442,7 @@ public class LobbyScene extends BaseScene{
     currentGames.setMinHeight(500);
     currentGameVBox.getChildren().add(currentGames);
 
+    //VBox to hold the UI where a user can create a channel or type in game chat
     createGame = new VBox();
     createGame.getStyleClass().add("gameBox");
     createGame.setMinWidth(350);
@@ -382,17 +457,24 @@ public class LobbyScene extends BaseScene{
     mainPane.setCenter(widgets);
   }
 
+
+  /**
+   * Shows all current games when a CHANNELS message is received
+   */
   public void showCurrentGames(String[] channels) {
     logger.info("Current number of available games: {}", channels.length);
 
+    currentChannels.clear();
     currentGames.getChildren().clear();
 
     for (String channel : channels) {
       Text channelName = new Text(channel);
       channelName.getStyleClass().add("channelItem");
-      channelName.setOnMouseClicked(e -> {
-        this.joinChannel(channelName.getText());
-      });
+      if (channel.equals(myChannel)) {
+        channelName.getStyleClass().add("selected");
+      }
+      currentChannels.add(channelName);
+      channelName.setOnMouseClicked(e -> this.joinChannel(channelName.getText()));
       currentGames.getChildren().add(channelName);
     }
   }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/MenuScene.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/MenuScene.java
index a0ea97303eb39c952015487a11ff671d04e27ad8..673bd3a4ed7ab0680f3e41ea44888651281a060b 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/MenuScene.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/MenuScene.java
@@ -1,25 +1,21 @@
 package uk.ac.soton.comp1206.scene;
 
-import javafx.event.EventHandler;
+import javafx.animation.*;
 import javafx.geometry.Pos;
-import javafx.scene.control.Button;
-import javafx.scene.image.ImageView;
 import javafx.scene.input.KeyCode;
 import javafx.scene.input.MouseEvent;
 import javafx.scene.layout.*;
-import javafx.scene.media.MediaPlayer;
 import javafx.scene.text.Text;
-import javafx.util.Pair;
+import javafx.util.Duration;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import uk.ac.soton.comp1206.App;
-import uk.ac.soton.comp1206.component.LoadingBoard;
+import uk.ac.soton.comp1206.component.LetterBoard;
 import uk.ac.soton.comp1206.game.GamePiece;
 import uk.ac.soton.comp1206.ui.GamePane;
 import uk.ac.soton.comp1206.ui.GameWindow;
 import uk.ac.soton.comp1206.utility.Multimedia;
 
-
 /**
  * The main menu of the game. Provides a gateway to the rest of the game.
  */
@@ -27,6 +23,8 @@ public class MenuScene extends BaseScene {
 
   private static final Logger logger = LogManager.getLogger(MenuScene.class);
 
+  private HBox title;
+
   /**
    * Create a new menu scene
    *
@@ -57,8 +55,8 @@ public class MenuScene extends BaseScene {
 
     VBox menuWidgets = new VBox();
 
-    //Awful title
-    HBox title = getGridTitle();
+    //Title is a Horizontal layout box which holds 7 grids to represent each letter of the 'Tetrecs' logo
+    title = getGridTitle();
     menuWidgets.getChildren().add(title);
 
     VBox menuButtons = new VBox();
@@ -96,7 +94,6 @@ public class MenuScene extends BaseScene {
     menuWidgets.setSpacing(150);
 
     mainPane.setCenter(menuWidgets);
-
   }
 
   /**
@@ -104,50 +101,104 @@ public class MenuScene extends BaseScene {
    */
   @Override
   public void initialise() {
-    Multimedia.playBackgroundMusic("menuMusic.wav", true);
+    //Plays background music on loop
+    Multimedia.playBackgroundMusic("menu.mp3", true);
+
+    //Runs an animation on the title logo
+    runAnimation();
+
+    //Shuts down the App if the Escape key is pressed
     this.scene.setOnKeyPressed(e -> {
       if (e.getCode().equals(KeyCode.ESCAPE)) shutDown();
     });
   }
 
   /**
-   * Handle when the Start Game button is pressed
-   *
+   * Creates the main logo by creating 7 grids to represent each letter of the Tetrecs logo
    */
-  private void startGame(MouseEvent event) {
-    Multimedia.stopSound();
-    gameWindow.startChallenge();
-  }
-
   private HBox getGridTitle() {
     HBox grids = new HBox();
     grids.setSpacing(5);
     grids.setAlignment(Pos.CENTER);
-    String[] letters = {"T","E","T","R","E","C","S"};
-    int[] colours = {2,3,4,5,10,13,15};
+    String[] letters = {"T", "E", "T", "R", "E", "C", "S"};
+    int[] colours = {2, 3, 4, 5, 10, 13, 15};
     for (int i = 0; i < 7; i++) {
-      LoadingBoard lb = new LoadingBoard(gameWindow.getWidth() / 8, gameWindow.getWidth() / 8);
-      lb.displayPiece(GamePiece.createLoadingPiece(letters[i], colours[i]));
+      LetterBoard lb = new LetterBoard(gameWindow.getWidth() / 12, gameWindow.getWidth() / 12);
+      lb.displayPiece(GamePiece.createLetterPiece(letters[i], colours[i]));
       grids.getChildren().add(lb);
     }
 
     return grids;
   }
 
+  /**
+   * Runs an animation on the main logo with rotations and scale transitions
+   */
+  private void runAnimation() {
+    ScaleTransition st = new ScaleTransition(new Duration(2500), title);
+    st.setToX(1.5);
+    st.setToY(1.5);
+    st.play();
+
+    RotateTransition rt = new RotateTransition(new Duration(2000),title);
+    rt.setFromAngle(0);
+    rt.setToAngle(-7.5);
+    st.setOnFinished(e -> rt.play());
+
+    RotateTransition rt2 = new RotateTransition(new Duration(2000),title);
+    rt2.setFromAngle(-7.5);
+    rt2.setToAngle(7.5);
+    rt.setOnFinished(e -> rt2.play());
+
+    RotateTransition rt3 = new RotateTransition(new Duration(2000),title);
+    rt3.setFromAngle(7.5);
+    rt3.setToAngle(0);
+    rt2.setOnFinished(e -> rt3.play());
+
+    ScaleTransition st2 = new ScaleTransition(new Duration(2500),title);
+    st2.setToX(1);
+    st2.setToY(1);
+    rt3.setOnFinished(e -> st2.play());
+
+    st2.setOnFinished(e -> st.play());
+
+  }
+
+  /**
+   * Handle when the Start Game button is pressed
+   */
+  private void startGame(MouseEvent event) {
+    Multimedia.stopSound();
+    gameWindow.startChallenge();
+  }
+
+  /**
+   * Handle when Multiplayer button is pressed
+   */
   private void startLobby(MouseEvent event) {
     gameWindow.startLobby();
   }
 
+  /**
+   * Handle when the Instructions button is pressed
+   */
   private void showInstructions(MouseEvent event) {
     gameWindow.displayInstructions();
   }
 
+  /**
+   * Handle when the Options button is pressed
+   */
   private void showOptions(MouseEvent event) {
     gameWindow.showOptions();
   }
 
+  /**
+   * Handle when Exit is pressed
+   */
   private void shutDown() {
     App.getInstance().shutdown();
   }
 
+
 }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/MultiplayerScene.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/MultiplayerScene.java
index 95c2a92d02db3b6a54c897d4eab2219d3d338b0a..fc3e846017294b79920980fc7b20c58639f1aeea 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/MultiplayerScene.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/MultiplayerScene.java
@@ -4,26 +4,36 @@ import javafx.application.Platform;
 import javafx.beans.property.SimpleListProperty;
 import javafx.beans.property.SimpleStringProperty;
 import javafx.geometry.Pos;
+import javafx.scene.canvas.Canvas;
 import javafx.scene.control.TextField;
 import javafx.scene.input.KeyCode;
 import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
 import javafx.scene.layout.HBox;
 import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
 import javafx.scene.text.Text;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
+import uk.ac.soton.comp1206.component.GameBlock;
 import uk.ac.soton.comp1206.component.GameBoard;
-import uk.ac.soton.comp1206.component.PieceBoard;
+import uk.ac.soton.comp1206.component.LetterBoard;
+import uk.ac.soton.comp1206.game.Grid;
 import uk.ac.soton.comp1206.game.MultiplayerGame;
 import uk.ac.soton.comp1206.network.Communicator;
 import uk.ac.soton.comp1206.ui.GameWindow;
 import uk.ac.soton.comp1206.ui.Leaderboard;
 import uk.ac.soton.comp1206.utility.Multimedia;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 
-public class MultiplayerScene extends ChallengeScene{
+/**
+ * The multiplayer scene holds the UI for the multiplayer game
+ */
+public class MultiplayerScene extends ChallengeScene {
   private static final Logger logger = LogManager.getLogger(MultiplayerScene.class);
 
   private boolean chatMode = false;
@@ -32,17 +42,26 @@ public class MultiplayerScene extends ChallengeScene{
   private final Communicator communicator;
   private SimpleStringProperty myName = new SimpleStringProperty("");
   private Leaderboard leaderboard;
+  private String[] players;
+  private ArrayList<VBox> playerBoards = new ArrayList<>();
+  private ArrayList<GameBoard> playerGrids = new ArrayList<>();
+  private HBox boardDisplay;
+  private int boardNumber = 0;
 
   /**
-   * Create a new Single Player challenge scene
+   * Create a new multiplayer challenge scene
    *
    * @param gameWindow the Game Window
    */
-  public MultiplayerScene(GameWindow gameWindow, String name) {
+  public MultiplayerScene(GameWindow gameWindow, String name, String[] players) {
     super(gameWindow);
     logger.info("Starting Multiplayer Scene");
 
     this.myName.set(name);
+    this.players = players;
+    for (String player : players) {
+      System.out.println(player);
+    }
     this.communicator = gameWindow.getCommunicator();
   }
 
@@ -55,6 +74,8 @@ public class MultiplayerScene extends ChallengeScene{
     this.game.setNextPieceListener(this::nextPiece);
     this.game.setLineClearedListener(this::lineCleared);
     this.game.setGameLoopListener(this::gameTimer);
+    this.game.setBoardUpdatedListener(this::updatePlayerBoard);
+    //Sets the username based on the username entered in the lobby
     this.game.setMyName(this.myName.get());
 
     this.scene.setOnKeyPressed(this::keyHandler);
@@ -71,15 +92,42 @@ public class MultiplayerScene extends ChallengeScene{
     });
 
     this.game.start();
+    this.board.unhover();
+  }
+
+  private void updatePlayerBoard(String name, String[] values) {
+    logger.info("Updating the board of : {}", name);
+    System.out.println(Arrays.toString(values));
+    int index = -1;
+    for(int i = 0; i < players.length; i++) {
+      if(players[i].equals(name)) {
+        index = i;
+        break;
+      }
+    }
+
+    if (index != -1) {
+      GameBoard board = playerGrids.get(index);
+      int counter = 0;
+      for (int x = 0; x < board.getCols(); x++) {
+        for (int y = 0; y < board.getRows(); y++) {
+          board.getGrid().set(x,y, Integer.parseInt(values[counter]));
+          counter++;
+        }
+      }
+    }
   }
 
   @Override
   public void setupGame() {
     logger.info("Starting a new multiplayer game");
 
-    game = new MultiplayerGame(this.communicator,5, 5);
+    game = new MultiplayerGame(this.communicator, 5, 5);
   }
 
+  /**
+   * Handles communcation received from the server
+   */
   private void receiveCommunication(String message) {
     String[] components = message.split(" ");
     switch (components[0]) {
@@ -108,6 +156,42 @@ public class MultiplayerScene extends ChallengeScene{
     leaderboard.getScores().bind(new SimpleListProperty<>(this.game.getLeaderboardList()));
     gameInfo.getChildren().add(0, leaderboard);
 
+    for (int i = 0; i < this.players.length; i++) {
+      LetterBoard playerBoard = new LetterBoard(gameWindow.getWidth() / 8, gameWindow.getWidth() / 8);
+      playerGrids.add(playerBoard);
+
+      Text playerName = new Text(players[i]);
+      playerName.getStyleClass().add("leaderboard");
+      playerName.setFill(GameBlock.COLOURS[i+1]);
+
+      VBox player = new VBox();
+      player.setAlignment(Pos.CENTER);
+      player.setSpacing(5);
+      player.getChildren().addAll(playerBoard, playerName);
+
+      playerBoards.add(player);
+    }
+
+    boardDisplay = new HBox();
+    boardDisplay.setAlignment(Pos.CENTER);
+    boardDisplay.setSpacing(10);
+
+    Canvas prevArrow = new Canvas(this.gameWindow.getWidth() / 20, this.gameWindow.getHeight() / 20);
+    prevArrow.getGraphicsContext2D().setFill(Color.WHITE);
+    prevArrow.getGraphicsContext2D().fillPolygon(new double[]{prevArrow.getWidth() / 2, prevArrow.getWidth(), prevArrow.getWidth()}, new double[]{prevArrow.getHeight() / 2, 0, prevArrow.getHeight()}, 3);
+    prevArrow.setOnMouseClicked(this::displayPrevBoard);
+    boardDisplay.getChildren().add(prevArrow);
+
+    boardDisplay.getChildren().add(playerBoards.get(0));
+
+    Canvas nextArrow = new Canvas(this.gameWindow.getWidth() / 20, this.gameWindow.getHeight() / 20);
+    nextArrow.getGraphicsContext2D().setFill(Color.WHITE);
+    nextArrow.getGraphicsContext2D().fillPolygon(new double[]{0, nextArrow.getWidth() / 2, 0}, new double[]{0, nextArrow.getHeight() / 2, nextArrow.getHeight()}, 3);
+    nextArrow.setOnMouseClicked(this::displayNextBoard);
+    boardDisplay.getChildren().add(nextArrow);
+
+    gameInfo.getChildren().add(boardDisplay);
+
     VBox chatAndTimer = new VBox();
 
     VBox chatMessages = new VBox();
@@ -118,6 +202,7 @@ public class MultiplayerScene extends ChallengeScene{
     chatMessages.getChildren().add(chatMessage);
     chatAndTimer.getChildren().add(chatMessages);
 
+    //Adds a chat text field to allow users to message during the game
     chatInput = new TextField();
     chatInput.getStyleClass().add("TextField");
     chatInput.setVisible(false);
@@ -131,8 +216,37 @@ public class MultiplayerScene extends ChallengeScene{
   }
 
 
-  private void keyHandler(KeyEvent e) {
-    this.board.setHover(this.board.getBlock(keyBoardPosX, keyBoardPosY), false);
+  public void displayPrevBoard(MouseEvent e) {
+    if (playerBoards.size() > 1) {
+      if (boardNumber != 0) {
+        boardNumber--;
+      } else {
+        boardNumber = this.players.length - 1;
+      }
+
+      boardDisplay.getChildren().remove(1);
+      boardDisplay.getChildren().add(1, playerBoards.get(boardNumber));
+    }
+  }
+
+  public void displayNextBoard(MouseEvent e) {
+    if (playerBoards.size() > 1) {
+      if (boardNumber != this.players.length - 1) {
+        boardNumber++;
+      } else {
+        boardNumber = 0;
+      }
+
+      boardDisplay.getChildren().remove(1);
+      boardDisplay.getChildren().add(1, playerBoards.get(boardNumber));
+    }
+  }
+
+
+  /**
+   * Handles key pressed and checks whether it was pressed in the chat field or in game
+   */
+  protected void keyHandler(KeyEvent e) {
     if (e.getCode().equals(KeyCode.T)) {
       chatMode = true;
       chatInput.setVisible(true);
@@ -145,32 +259,7 @@ public class MultiplayerScene extends ChallengeScene{
       chatMode = false;
       chatInput.setVisible(false);
     } else if (!chatMode) {
-      if (e.getCode().equals(KeyCode.ESCAPE)) {
-        endGame();
-        this.gameWindow.startMenu();
-      } else if (e.getCode().equals(KeyCode.ENTER) || e.getCode().equals(KeyCode.X)) {
-        this.blockClicked(this.board.getBlock(keyBoardPosX, keyBoardPosY));
-      } else if (e.getCode().equals(KeyCode.SPACE) || e.getCode().equals(KeyCode.R)) {
-        this.swapPiece();
-      } else if (e.getCode().equals(KeyCode.E) || e.getCode().equals(KeyCode.C) || e.getCode().equals(KeyCode.CLOSE_BRACKET)) {
-        this.rotateBlock(1);
-      } else if (e.getCode().equals(KeyCode.Q) || e.getCode().equals(KeyCode.Z) || e.getCode().equals(KeyCode.OPEN_BRACKET)) {
-        this.rotateBlock(3);
-      } else if (e.getCode().equals(KeyCode.UP) || e.getCode().equals(KeyCode.W)) {
-        if (keyBoardPosY > 0) keyBoardPosY--;
-      } else if (e.getCode().equals(KeyCode.DOWN) || e.getCode().equals(KeyCode.S)) {
-        if (keyBoardPosY < this.game.getRows() - 1) keyBoardPosY++;
-      } else if (e.getCode().equals(KeyCode.LEFT) || e.getCode().equals(KeyCode.A)) {
-        if (keyBoardPosX > 0) keyBoardPosX--;
-      } else if (e.getCode().equals(KeyCode.RIGHT) || e.getCode().equals(KeyCode.D)) {
-        if (keyBoardPosX < this.game.getCols() - 1) keyBoardPosX++;
-      } else if (e.getCode().equals(KeyCode.SHIFT)) {
-        endGame();
-        Platform.runLater(() -> {
-          this.gameWindow.showScores(this.game);
-        });
-      }
-      this.board.setHover(this.board.getBlock(keyBoardPosX, keyBoardPosY), true);
+      super.keyHandler(e);
     }
   }
 
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/OptionsScene.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/OptionsScene.java
index 00326c2c55b52e30cff3ae5421c35ec5db9d23ea..fcd2c7980eaad721867245ddf39ad3e0b2587a15 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/OptionsScene.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/OptionsScene.java
@@ -2,7 +2,6 @@ package uk.ac.soton.comp1206.scene;
 
 import javafx.beans.property.DoubleProperty;
 import javafx.geometry.Pos;
-import javafx.scene.control.Label;
 import javafx.scene.control.Slider;
 import javafx.scene.input.KeyCode;
 import javafx.scene.layout.BorderPane;
@@ -16,12 +15,13 @@ import uk.ac.soton.comp1206.ui.GamePane;
 import uk.ac.soton.comp1206.ui.GameWindow;
 import uk.ac.soton.comp1206.utility.Multimedia;
 
-public class OptionsScene extends BaseScene{
+public class OptionsScene extends BaseScene {
   private static final Logger logger = LogManager.getLogger(OptionsScene.class);
 
-  private static Slider musicVolumeSlider = new Slider(0,1,0.5);
+  //Instantiates two sliders to changes the volume of music and sound effects
+  private static final Slider musicVolumeSlider = new Slider(0, 1, 0.5);
+  private static final Slider soundVolumeSlider = new Slider(0, 1, 0.5);
 
-  private static Slider soundVolumeSlider = new Slider(0,1,0.5);
   /**
    * Create a new scene, passing in the GameWindow the scene will be displayed in
    *
@@ -31,6 +31,9 @@ public class OptionsScene extends BaseScene{
     super(gameWindow);
   }
 
+  /**
+   * Initialise the options scene
+   */
   @Override
   public void initialise() {
     this.scene.setOnKeyPressed(e -> {
@@ -40,6 +43,9 @@ public class OptionsScene extends BaseScene{
     });
   }
 
+  /**
+   * Builds the options screen layout
+   */
   @Override
   public void build() {
     logger.info("Building " + this.getClass().getName());
@@ -61,7 +67,7 @@ public class OptionsScene extends BaseScene{
     mainPane.setTop(widgets);
 
     Text optionsTitle = new Text("Game Options");
-    optionsTitle .getStyleClass().add("title");
+    optionsTitle.getStyleClass().add("title");
     widgets.getChildren().add(optionsTitle);
 
     HBox options = new HBox();
@@ -106,10 +112,16 @@ public class OptionsScene extends BaseScene{
     soundOptions.getChildren().add(soundVolumeSlider);
   }
 
+  /**
+   * Method to return the value property of the music volume slider
+   */
   public static DoubleProperty getMusicLevel() {
     return musicVolumeSlider.valueProperty();
   }
 
+  /**
+   * Method to return the value property of the sound volume slider
+   */
   public static DoubleProperty getSoundLevel() {
     return soundVolumeSlider.valueProperty();
   }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/ScoresScene.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/ScoresScene.java
index 333c8ebfe55ac69a26d63ce0ad6fe71cfe32c867..7df61150ebbdc10fa495c694b1223a0f7c459611 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/ScoresScene.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/ScoresScene.java
@@ -28,7 +28,11 @@ import uk.ac.soton.comp1206.utility.Multimedia;
 import java.io.*;
 import java.util.*;
 
-public class ScoresScene extends BaseScene{
+
+/**
+ * The scene which displays the local and online highscores
+ */
+public class ScoresScene extends BaseScene {
   private static final Logger logger = LogManager.getLogger(ScoresScene.class);
 
   private final Game game;
@@ -54,6 +58,7 @@ public class ScoresScene extends BaseScene{
    * Create a new scene, passing in the GameWindow the scene will be displayed in
    *
    * @param gameWindow the game window
+   * @param game       The game which the scores will be taken from
    */
   public ScoresScene(GameWindow gameWindow, Game game) {
     super(gameWindow);
@@ -76,6 +81,9 @@ public class ScoresScene extends BaseScene{
     loadOnlineScores();
   }
 
+  /**
+   * Builds the UI for the scores scene
+   */
   @Override
   public void build() {
     logger.info("Building " + this.getClass().getName());
@@ -132,6 +140,9 @@ public class ScoresScene extends BaseScene{
     mainPane.setCenter(widgets);
   }
 
+  /**
+   * Checks whether the user's score is a local or online high score
+   */
   public void checkHiScore() {
     logger.info("Checking for High score");
     isLocalHiScore = false;
@@ -163,6 +174,7 @@ public class ScoresScene extends BaseScene{
 
     }
 
+    //If it is a high score, the user will be asked to enter their username which is then added to the scores.txt file and the online leaderboard
     if (isLocalHiScore || isOnlineHiScore) {
       logger.info("User has got a high score");
 
@@ -224,8 +236,11 @@ public class ScoresScene extends BaseScene{
     }
   }
 
+  /**
+   * Adds the user's score to either or both of the local and online score lists
+   */
   public void parseHiScore(int score, String name) {
-    if (this.isLocalHiScore){
+    if (this.isLocalHiScore) {
       logger.info("User has a local high score");
       this.localList.setName(name);
       this.localScores.add(new Pair<>(name, score));
@@ -267,6 +282,9 @@ public class ScoresScene extends BaseScene{
     }
   }
 
+  /**
+   * Handles communication received
+   */
   public void receiveCommunication(String message) {
     logger.info("Received online scores");
     String[] components = message.split(" ");
@@ -284,6 +302,9 @@ public class ScoresScene extends BaseScene{
     }
   }
 
+  /**
+   * Loads the online scores received from the server
+   */
   public void parseOnlineScores(String scores) {
     logger.info("Loading online scores");
     onlineScores = new ArrayList<>();
@@ -315,25 +336,31 @@ public class ScoresScene extends BaseScene{
     this.communicator.send("HISCORES");
   }
 
+  /**
+   * Sends the new high score to the server with the HISCORE command
+   */
   public void writeOnlineScore(Pair<String, Integer> pair) {
     if (pair != null) {
       this.communicator.send("HISCORE " + pair.getKey() + ":" + pair.getValue());
     }
   }
 
+  /**
+   * Loads the local high scores from a text file
+   */
   public static ArrayList<Pair<String, Integer>> loadScores() {
     logger.info("Loading scores from file");
     ArrayList<Pair<String, Integer>> localScores = new ArrayList<>();
-    try{
-      File f = new File("localscores.txt");
+    try {
+      File f = new File("scores.txt");
       if (!f.exists()) {
         writeDefaultScores();
       }
-      BufferedReader br = new BufferedReader(new FileReader("localscores.txt"));
+      BufferedReader br = new BufferedReader(new FileReader("scores.txt"));
 
       String line = br.readLine();
       int lineCounter = 0;
-      while(line != null) {
+      while (line != null) {
         lineCounter++;
         if (lineCounter <= 10) {
           String[] values = line.split(":");
@@ -345,7 +372,7 @@ public class ScoresScene extends BaseScene{
       }
       br.close();
 
-    } catch(IOException e) {
+    } catch (IOException e) {
       logger.info("Error reading file: " + e.getMessage());
     }
 
@@ -365,12 +392,15 @@ public class ScoresScene extends BaseScene{
     return localScores;
   }
 
+  /**
+   * Writes default scores to a text file if it does not exist
+   */
   public static void writeDefaultScores() {
     try {
       logger.info("Writing default scores to file");
-      BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("localscores.txt")));
-      for (int i = 10; i > 0; i --) {
-        bw.write("test" + i + ":" + (1000*i));
+      BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("scores.txt")));
+      for (int i = 10; i > 0; i--) {
+        bw.write("test" + i + ":" + (1000 * i));
         bw.newLine();
       }
       bw.close();
@@ -379,11 +409,14 @@ public class ScoresScene extends BaseScene{
     }
   }
 
+  /**
+   * Writes any new high scores to the local text file
+   */
   public static void writeScores(List<Pair<String, Integer>> nameScores) {
     logger.info("Writing scores to text file");
 
     try {
-      BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("localscores.txt")));
+      BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("scores.txt")));
 
       for (Pair<String, Integer> nameScore : nameScores) {
         bw.write(nameScore.getKey() + ":" + nameScore.getValue());
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/ui/GameWindow.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/ui/GameWindow.java
index 18541f1a31f5ff1c974717d1042f28f27c385d0d..d9058c9beee9e69d5702b747c7e7f083c6fb4886 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/ui/GameWindow.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/ui/GameWindow.java
@@ -13,6 +13,8 @@ import uk.ac.soton.comp1206.game.Game;
 import uk.ac.soton.comp1206.network.Communicator;
 import uk.ac.soton.comp1206.scene.*;
 
+import java.util.ArrayList;
+
 /**
  * The GameWindow is the single window for the game where everything takes place. To move between screens in the game,
  * we simply change the scene.
@@ -75,9 +77,13 @@ public class GameWindow {
     Font.loadFont(getClass().getResourceAsStream("/style/Orbitron-ExtraBold.ttf"), 32);
   }
 
+  /**
+   * Display the single player challenge
+   */
   public void startLoadingScene() {
     loadScene(new LoadingScene(this));
   }
+
   /**
    * Display the main menu
    */
@@ -92,24 +98,42 @@ public class GameWindow {
     loadScene(new ChallengeScene(this));
   }
 
+  /**
+   * Display the multiplayer lobby
+   */
   public void startLobby() {
     loadScene(new LobbyScene(this));
   }
 
+  /**
+   * Display the game options
+   */
   public void showOptions() {
     loadScene(new OptionsScene(this));
   }
 
+  /**
+   * Display the game instructions
+   */
   public void displayInstructions() {
     loadScene(new InstructionScene(this));
   }
 
+  /**
+   * Display the highscore leaderboards
+   * @param game The current instance of the game being played
+   */
   public void showScores(Game game) {
     loadScene(new ScoresScene(this, game));
   }
 
-  public void startMultiplayerGame(String name) {
-    loadScene(new MultiplayerScene(this, name));
+  /**
+   * Display the multiplayer game
+   * @param name The name of the user
+   * @param players
+   */
+  public void startMultiplayerGame(String name, String[] players) {
+    loadScene(new MultiplayerScene(this, name, players));
   }
 
   /**
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/ui/Leaderboard.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/ui/Leaderboard.java
index 59a43f1339be4cc7dad73c3582da0579ab67f644..46e3d9d3ac163a871de5f4184a52749a7b9a8d5a 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/ui/Leaderboard.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/ui/Leaderboard.java
@@ -4,13 +4,17 @@ import javafx.scene.text.Text;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
-
+/**
+ * Leaderboard which is displayed during the multiplayer game
+ */
 public class Leaderboard extends ScoresList {
   private static final Logger logger = LogManager.getLogger(Leaderboard.class);
 
   public Leaderboard(String listName) {
     super(listName);
     setVisible(true);
+    getStyleClass().remove("scorelist");
+    getStyleClass().add("leaderboard");
   }
 
   @Override
@@ -19,6 +23,9 @@ public class Leaderboard extends ScoresList {
     reveal();
   }
 
+  /**
+   * Adds any dead players to the dead players list who are then crossed out in the leaderboard
+   */
   public void setDead(String player) {
     logger.info("Setting {} as dead", player);
     for (Text nameScore : nameScores) {
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/ui/ScoresList.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/ui/ScoresList.java
index 847e02b8ac85aea5928a19857961cef1eb41b96a..a579e97c24da90bed342b34d18c3468464ff6456 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/ui/ScoresList.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/ui/ScoresList.java
@@ -17,7 +17,9 @@ import uk.ac.soton.comp1206.component.GameBlock;
 
 import java.util.ArrayList;
 
-
+/**
+ * Custom VBox component which dislays the list of high scores and animates the reveal
+ */
 public class ScoresList extends VBox {
   private static final Logger logger = LogManager.getLogger(ScoresList.class);
 
@@ -41,6 +43,7 @@ public class ScoresList extends VBox {
     title.getStyleClass().add("heading");
     getChildren().add(title);
 
+    //Listener added to the score list to allow list changes when the high scores are updated in the Scores scene
     this.scores.addListener((ListChangeListener<? super Pair<String, Integer>>) e -> updateList());
   }
 
@@ -76,6 +79,9 @@ public class ScoresList extends VBox {
 
   }
 
+  /**
+   * Animates the reveal of the highscores
+   */
   public void reveal() {
     logger.info("Playing reveal animations");
 
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/utility/Multimedia.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/utility/Multimedia.java
index e7d93bd3fc0be724f3daeeb14860c32c0f882344..6b0733dbf336b7f1258abd030b6a08f195be94f8 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/utility/Multimedia.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/utility/Multimedia.java
@@ -14,11 +14,18 @@ public class Multimedia {
   private static MediaPlayer mediaPlayer;
   private static MediaPlayer backgroundPlayer;
 
+  /**
+   * Plays the background music specified and loops the music if required
+   *
+   * @param music  Name of the music to play
+   * @param toLoop Boolean which specifies whether to loop the music or not
+   */
   public static void playBackgroundMusic(String music, boolean toLoop) {
     String toPlay = Multimedia.class.getResource("/music/" + music).toExternalForm();
     try {
       Media play = new Media(toPlay);
       backgroundPlayer = new MediaPlayer(play);
+      //Volume property is bound to the volume slider in the Options Scene
       backgroundPlayer.volumeProperty().bind(OptionsScene.getMusicLevel());
       if (toLoop) {
         backgroundPlayer.setOnEndOfMedia(() -> backgroundPlayer.seek(Duration.ZERO));
@@ -31,12 +38,18 @@ public class Multimedia {
     }
   }
 
+  /**
+   * Plays the sound effect specified
+   *
+   * @param sound Name of the sound to play
+   */
   public static void playSound(String sound) {
     String toPlay = Multimedia.class.getResource("/sounds/" + sound).toExternalForm();
 
     try {
       Media play = new Media(toPlay);
       mediaPlayer = new MediaPlayer(play);
+      //Volume property is bound to the volume slider in the Options Scene
       mediaPlayer.volumeProperty().bind(OptionsScene.getSoundLevel());
       mediaPlayer.play();
       logger.info("Playing sound clip " + sound);
@@ -46,6 +59,9 @@ public class Multimedia {
     }
   }
 
+  /**
+   * Stops all currently playing sounds and music
+   */
   public static void stopSound() {
     logger.info("Stopping all current audio tracks");
     if (mediaPlayer != null) {
diff --git a/tetrecs/src/main/resources/music/menu.mp3 b/tetrecs/src/main/resources/music/menu.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..0724b65ee300790b53ed7f4c79a800e934343feb
Binary files /dev/null and b/tetrecs/src/main/resources/music/menu.mp3 differ
diff --git a/tetrecs/src/main/resources/music/menuMusic.wav b/tetrecs/src/main/resources/music/menuMusic.wav
deleted file mode 100644
index 2647529951c66f4f4ae01acd99863950421dbf0c..0000000000000000000000000000000000000000
Binary files a/tetrecs/src/main/resources/music/menuMusic.wav and /dev/null differ
diff --git a/tetrecs/src/main/resources/style/game.css b/tetrecs/src/main/resources/style/game.css
index 7eaa86d49f739d47afa78bf19dc24049935f01cc..cdc04b4c4fd6698e95913606defa32daa8213a30 100644
--- a/tetrecs/src/main/resources/style/game.css
+++ b/tetrecs/src/main/resources/style/game.css
@@ -31,6 +31,7 @@
 }
 
 .menuItem:hover {
+    -fx-font-size: 40px;
     -fx-fill: yellow;
 }
 
@@ -167,12 +168,19 @@
     -fx-border-color: black;
     -fx-stroke: black;
 }
+
+.channelItem:hover {
+    -fx-fill: yellow;
+    -fx-font-size: 19px;
+}
+
 .channelItem.selected {
     -fx-fill: yellow;
 }
 
 .leaderboard {
     -fx-font-size: 16px;
+    -fx-font-family: 'Orbitron';
 }
 
 .gameBox {
diff --git a/tetrecs/target/classes/style/game.css b/tetrecs/target/classes/style/game.css
index 7eaa86d49f739d47afa78bf19dc24049935f01cc..cdc04b4c4fd6698e95913606defa32daa8213a30 100644
--- a/tetrecs/target/classes/style/game.css
+++ b/tetrecs/target/classes/style/game.css
@@ -31,6 +31,7 @@
 }
 
 .menuItem:hover {
+    -fx-font-size: 40px;
     -fx-fill: yellow;
 }
 
@@ -167,12 +168,19 @@
     -fx-border-color: black;
     -fx-stroke: black;
 }
+
+.channelItem:hover {
+    -fx-fill: yellow;
+    -fx-font-size: 19px;
+}
+
 .channelItem.selected {
     -fx-fill: yellow;
 }
 
 .leaderboard {
     -fx-font-size: 16px;
+    -fx-font-family: 'Orbitron';
 }
 
 .gameBox {
diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/App.class b/tetrecs/target/classes/uk/ac/soton/comp1206/App.class
index 12974a99eeb4c3a50e2b5650cf110fc7ece1930d..98f4ae41e0fafb5288f74acf9b966e8ffa34091c 100644
Binary files a/tetrecs/target/classes/uk/ac/soton/comp1206/App.class and b/tetrecs/target/classes/uk/ac/soton/comp1206/App.class differ
diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/Launcher.class b/tetrecs/target/classes/uk/ac/soton/comp1206/Launcher.class
index 08ed8e567f0f1a1eff2b0e281e15023c0acef18f..19de7470ce7a8b4c7c790d2701db7c24c212af38 100644
Binary files a/tetrecs/target/classes/uk/ac/soton/comp1206/Launcher.class and b/tetrecs/target/classes/uk/ac/soton/comp1206/Launcher.class differ
diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/component/GameBlock.class b/tetrecs/target/classes/uk/ac/soton/comp1206/component/GameBlock.class
index 5771b6ac8d29f0f260915e1c06460801f1c85e94..1afded4985df6fd0253eb7f48398768f79e44ec0 100644
Binary files a/tetrecs/target/classes/uk/ac/soton/comp1206/component/GameBlock.class and b/tetrecs/target/classes/uk/ac/soton/comp1206/component/GameBlock.class differ
diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/component/GameBoard.class b/tetrecs/target/classes/uk/ac/soton/comp1206/component/GameBoard.class
index d5094e13923c7a4fdb86af94e0052d0ce1b781f4..325cfc903bfec7a76d91ce58bc5f9c47ee9c9e79 100644
Binary files a/tetrecs/target/classes/uk/ac/soton/comp1206/component/GameBoard.class and b/tetrecs/target/classes/uk/ac/soton/comp1206/component/GameBoard.class differ
diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/game/Game.class b/tetrecs/target/classes/uk/ac/soton/comp1206/game/Game.class
index f0d85b6d2071a4fce55b16b5054c42edf2566ea3..49f28932822c89436d630a2b5e1af553554df8a2 100644
Binary files a/tetrecs/target/classes/uk/ac/soton/comp1206/game/Game.class and b/tetrecs/target/classes/uk/ac/soton/comp1206/game/Game.class differ
diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/game/GamePiece.class b/tetrecs/target/classes/uk/ac/soton/comp1206/game/GamePiece.class
index d26528c24acac20afdd51a29bf9c9d9407242059..aab24c40d0aec23893c553e54c2626906f975f47 100644
Binary files a/tetrecs/target/classes/uk/ac/soton/comp1206/game/GamePiece.class and b/tetrecs/target/classes/uk/ac/soton/comp1206/game/GamePiece.class differ
diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/game/Grid.class b/tetrecs/target/classes/uk/ac/soton/comp1206/game/Grid.class
index dda7f01ba1ac9ba52ef54d6cb3a478b7f95a46ae..2afe0bd3f309d1027929e6c255402b2acbbaf29f 100644
Binary files a/tetrecs/target/classes/uk/ac/soton/comp1206/game/Grid.class and b/tetrecs/target/classes/uk/ac/soton/comp1206/game/Grid.class differ
diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/scene/ChallengeScene.class b/tetrecs/target/classes/uk/ac/soton/comp1206/scene/ChallengeScene.class
index ad0c9db41e584f034dae888bb8ee27054e6fcf6f..f2a7d845976c792e5c2329a5f0576b1b3aa6d75b 100644
Binary files a/tetrecs/target/classes/uk/ac/soton/comp1206/scene/ChallengeScene.class and b/tetrecs/target/classes/uk/ac/soton/comp1206/scene/ChallengeScene.class differ
diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/scene/MenuScene.class b/tetrecs/target/classes/uk/ac/soton/comp1206/scene/MenuScene.class
index 7453b0dfc02dd676f8cbeffd489f15aef967de33..df70c59d88bf5315c30e69cbb29c8066baf0e86c 100644
Binary files a/tetrecs/target/classes/uk/ac/soton/comp1206/scene/MenuScene.class and b/tetrecs/target/classes/uk/ac/soton/comp1206/scene/MenuScene.class differ
diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/ui/GameWindow.class b/tetrecs/target/classes/uk/ac/soton/comp1206/ui/GameWindow.class
index 8521ce32017ef17e94b77b506033a31d869ed4c6..604a75a158347706aa1a858c0accaa53fa9b594b 100644
Binary files a/tetrecs/target/classes/uk/ac/soton/comp1206/ui/GameWindow.class and b/tetrecs/target/classes/uk/ac/soton/comp1206/ui/GameWindow.class differ