diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/PathsSingleton.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/PathsSingleton.java
index 1c98afb3100fed235f8265f4132a6f4918cab934..9946f5eb6901098847ad10f86195f520b032559c 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/PathsSingleton.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/PathsSingleton.java
@@ -3,6 +3,7 @@ package edu.ntnu.idatt2001.group_30.paths;
 import edu.ntnu.idatt2001.group_30.paths.model.Player;
 import edu.ntnu.idatt2001.group_30.paths.model.Story;
 import edu.ntnu.idatt2001.group_30.paths.model.goals.*;
+import java.io.File;
 import java.util.List;
 import java.util.Objects;
 import java.util.stream.Collectors;
@@ -20,6 +21,7 @@ public enum PathsSingleton {
     INSTANCE;
 
     private Story story;
+    private File storyFile;
     private Player player = new Player("Default", 100, 100, 100);
     private boolean passageMoving = false;
     private HealthGoal healthGoal;
@@ -44,18 +46,52 @@ public enum PathsSingleton {
         this.story = story;
     }
 
+    /**
+     * This method retrieves the file to the story.
+     * @return  The file of the story, given as a File object.
+     */
+    public File getStoryFile() {
+        return storyFile;
+    }
+
+    /**
+     * This method changes the file of the story.
+     * @param storyFile New file, given as a File object.
+     */
+    public void setStoryFile(File storyFile) {
+        this.storyFile = storyFile;
+    }
+
+    /**
+     * This method retrieves the player.
+     * @return  Current player of game, given as a Player object.
+     */
     public Player getPlayer() {
         return player;
     }
 
+    /**
+     * This method sets the player to a new player.
+     * @param player    New player, given as a Player object.
+     */
     public void setPlayer(Player player) {
         this.player = player;
     }
 
+    /**
+     * This method allows a goal to be changed, given the goal type.
+     * @param newGoal   New goal, given as a Goal implemented Object
+     */
     public void changeGoal(Goal<?> newGoal) {
         setGoal(GoalType.getGoalType(newGoal.getClass().getSimpleName()), newGoal);
     }
 
+    /**
+     * This method sets a given goal to a new goal by the goal type.
+     * @param goalType  Type of goal, given as a GoalType enum.
+     * @param goal      New goal, given as a Goal object.
+     * @param <T>       The type of Goal.
+     */
     public <T> void setGoal(GoalType goalType, Goal<?> goal) {
         switch (goalType) {
             case HEALTH_GOAL -> healthGoal = (HealthGoal) goal;
@@ -66,22 +102,44 @@ public enum PathsSingleton {
         }
     }
 
+    /**
+     * This method retrieves the health goal.
+     * @return  Health goal, given as a HealthGoal object.
+     */
     public HealthGoal getHealthGoal() {
         return healthGoal;
     }
 
+    /**
+     * This method retrieves the score goal.
+     * @return  Score goal, given as a ScoreGoal object.
+     */
     public ScoreGoal getScoreGoal() {
         return scoreGoal;
     }
 
+    /**
+     * This method retrieves the inventory goal.
+     * @return  Inventory goal, given as a InventoryGoal object.
+     */
     public InventoryGoal getInventoryGoal() {
         return inventoryGoal;
     }
 
+    /**
+     * This method retrieves the gold goal.
+     * @return  Gold goal, given as a GoldGoal object.
+     */
     public GoldGoal getGoldGoal() {
         return goldGoal;
     }
 
+    /**
+     * This method gets a goal variable given the GoalType.
+     * @param goalType  Type of goal, given as a GoalType enum.
+     * @return          The goal variable.
+     * @param <T>       Type of goal.
+     */
     public <T> Goal<?> getGoal(GoalType goalType) {
         return switch (goalType) {
             case HEALTH_GOAL -> healthGoal;
@@ -91,10 +149,18 @@ public enum PathsSingleton {
         };
     }
 
+    /**
+     * This method retrieves the character load out image.
+     * @return  Image of the character created, given as an ImageView object.
+     */
     public ImageView getCharacterImageView() {
         return characterImageView;
     }
 
+    /**
+     * This method sets the character load out.
+     * @param characterImageView    New character image, given as an ImageView object.
+     */
     public void setCharacterImageView(ImageView characterImageView) {
         this.characterImageView = characterImageView;
     }
@@ -103,8 +169,8 @@ public enum PathsSingleton {
      * Returns a list of all the non-null goals.
      * @return A list of all the non-null goals, given as a List of Goal objects.
      */
-    public List<Goal> getGoals() {
-        List<Goal> goals = Stream
+    public List<Goal<?>> getGoals() {
+        List<Goal<?>> goals = Stream
             .of(healthGoal, scoreGoal, goldGoal)
             .filter(Objects::nonNull)
             .collect(Collectors.toList());
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/Controller.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/Controller.java
index 4a62d0acd5453a9fbbda8ba8aa3494761a393c77..7ea189bd035cc0f2fbf24cb3cc0f00c9598b8957 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/Controller.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/Controller.java
@@ -21,6 +21,10 @@ public class Controller {
     protected final StageManager STAGE_MANAGER = StageManager.getInstance();
     protected final Map<Class<? extends View<?>>, Runnable> availableViews = new HashMap<>();
 
+    /**
+     * Creates a new Controller with the given view classes.
+     * @param viewClasses The view classes that this controller is responsible for.
+     */
     @SafeVarargs
     public Controller(Class<? extends View<?>>... viewClasses) {
         for (Class<? extends View<?>> viewClass : viewClasses) {
@@ -53,10 +57,17 @@ public class Controller {
         return actionEvent -> STAGE_MANAGER.goBackTo(viewClass);
     }
 
+    /**
+     * This method is used to get the root stage of the application.
+     * @return The root stage of the application, which is the stage that is used to display the views.
+     */
     public Stage getRootStage() {
         return STAGE_MANAGER.getStage();
     }
 
+    /**
+     * This method is used to go to the home view.
+     */
     public void goToHome() {
         STAGE_MANAGER.setCurrentView(ViewFactory.createView(HomeView.class));
     }
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/CreatePlayerController.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/CreatePlayerController.java
index 01c52afc3b17a81c271d52b77ff23a99784b43b8..e197403d78fe5133cf606840d8e82b49f0d910b2 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/CreatePlayerController.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/CreatePlayerController.java
@@ -1,10 +1,18 @@
 package edu.ntnu.idatt2001.group_30.paths.controller;
 
-import edu.ntnu.idatt2001.group_30.paths.view.views.NewGameView;
+import edu.ntnu.idatt2001.group_30.paths.view.views.LoadGameView;
 
+/**
+ * The class CreatePlayerController is responsible for managing the CreatePlayerView.
+ *
+ * @author Trym Hamer Gudvangen
+ */
 public class CreatePlayerController extends Controller {
 
+    /**
+     * Creates a new CreatePlayerController.
+     */
     public CreatePlayerController() {
-        super(NewGameView.class);
+        super(LoadGameView.class);
     }
 }
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/HelpController.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/HelpController.java
index 71d54a3c1d9e2db538ed3100a82b83a00b10278d..e2019fdca619ac953be249ef30894d5c21a025f1 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/HelpController.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/HelpController.java
@@ -9,6 +9,9 @@ import edu.ntnu.idatt2001.group_30.paths.view.views.HomeView;
  */
 public class HelpController extends Controller {
 
+    /**
+     * Creates a new HelpController.
+     */
     public HelpController() {
         super(HomeView.class);
     }
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/HomeController.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/HomeController.java
index d3090acb250e365cfea8c71a85cb03b675af5d05..6753105984aed797a257c8a781bf4a4921878ba7 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/HomeController.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/HomeController.java
@@ -2,7 +2,7 @@ package edu.ntnu.idatt2001.group_30.paths.controller;
 
 import edu.ntnu.idatt2001.group_30.paths.view.views.CreatePlayerView;
 import edu.ntnu.idatt2001.group_30.paths.view.views.HelpView;
-import edu.ntnu.idatt2001.group_30.paths.view.views.NewGameView;
+import edu.ntnu.idatt2001.group_30.paths.view.views.LoadGameView;
 import edu.ntnu.idatt2001.group_30.paths.view.views.PlaythroughView;
 
 /**
@@ -16,7 +16,7 @@ public class HomeController extends Controller {
      * Creates a new HomeController.
      */
     public HomeController() {
-        super(HelpView.class, NewGameView.class, CreatePlayerView.class, PlaythroughView.class);
+        super(HelpView.class, LoadGameView.class, CreatePlayerView.class, PlaythroughView.class);
     }
 
     /**
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/NewGameController.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/NewGameController.java
index fdd7934a5d125d1057255744eb36d2131cf4521b..7df50729abee2e0e5a6c06f3e6cb6ae0be566104 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/NewGameController.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/NewGameController.java
@@ -3,20 +3,34 @@ package edu.ntnu.idatt2001.group_30.paths.controller;
 import static edu.ntnu.idatt2001.group_30.paths.PathsSingleton.INSTANCE;
 
 import edu.ntnu.idatt2001.group_30.paths.model.filehandling.StoryFileReader;
+import edu.ntnu.idatt2001.group_30.paths.view.views.NewStoryView;
 import edu.ntnu.idatt2001.group_30.paths.view.views.PlaythroughView;
 import java.io.File;
 import java.io.IOException;
 
+/**
+ * This class is used to control the NewGameView.
+ *
+ * @author Trym Hamer Gudvangen
+ */
 public class NewGameController extends Controller {
 
+    /**
+     * Creates a new NewGameController.
+     */
     public NewGameController() {
-        super(PlaythroughView.class);
+        super(PlaythroughView.class, NewStoryView.class);
     }
 
+    /**
+     * Sets the story to the storyFile.
+     * @param storyFile The story to set, as a File.
+     */
     public void setStory(File storyFile) {
         StoryFileReader storyFileReader = new StoryFileReader();
         try {
             INSTANCE.setStory(storyFileReader.parse(storyFile));
+            INSTANCE.setStoryFile(storyFile);
         } catch (IOException | InstantiationException ex) {
             throw new RuntimeException(ex);
         }
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/NewStoryController.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/NewStoryController.java
new file mode 100644
index 0000000000000000000000000000000000000000..6a646143eafc077e06fdb225f1a0047a4ac98e63
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/NewStoryController.java
@@ -0,0 +1,63 @@
+package edu.ntnu.idatt2001.group_30.paths.controller;
+
+import static edu.ntnu.idatt2001.group_30.paths.PathsSingleton.INSTANCE;
+
+import edu.ntnu.idatt2001.group_30.paths.model.Passage;
+import edu.ntnu.idatt2001.group_30.paths.model.Story;
+import edu.ntnu.idatt2001.group_30.paths.model.filehandling.StoryFileWriter;
+import edu.ntnu.idatt2001.group_30.paths.view.views.NewStoryView;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.List;
+import javafx.stage.FileChooser;
+
+/**
+ * This class is used to control the NewStoryView.
+ *
+ * @author Trym Hamer Gudvangen
+ */
+public class NewStoryController extends Controller {
+
+    /**
+     * Creates a new NewStoryController.
+     */
+    public NewStoryController() {
+        super(NewStoryView.class);
+    }
+
+    /**
+     * Adds a story to the PathsSingleton.
+     * @param title        The title of the story, as a String.
+     * @param passages     The passages of the story, as a List of Passages.
+     * @throws IOException If the story could not be saved to file system.
+     */
+    public void addStory(String title, List<Passage> passages) throws IOException {
+        Story story = new Story(title, passages.isEmpty() ? null : passages.get(0));
+        passages.forEach(story::addPassage);
+        INSTANCE.setStory(story);
+
+        saveStory(story);
+    }
+
+    /**
+     * This method saves the story to the file system.
+     * @param story         The story to save, as a Story.
+     * @throws IOException  If the story could not be saved to file system.
+     */
+    public void saveStory(Story story) throws IOException {
+        FileChooser fileChooser = new FileChooser();
+        fileChooser.setInitialDirectory(new File("./src/main/resources/story-files"));
+        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Paths files", "*.paths"));
+        File selectedFile = fileChooser.showSaveDialog(null);
+
+        if (selectedFile != null) {
+            StoryFileWriter storyFileWriter = new StoryFileWriter();
+            storyFileWriter.create(story, selectedFile);
+        } else {
+            throw new FileNotFoundException("File was not saved to file system");
+        }
+
+        INSTANCE.setStoryFile(selectedFile);
+    }
+}
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/PlaytroughController.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/PlaythroughController.java
similarity index 97%
rename from src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/PlaytroughController.java
rename to src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/PlaythroughController.java
index 7a1f987e4e74536604e92ae687aeff4c57fbf4da..9cf00291bb89c8bbc3ebef9ef562c91f4f8af6ec 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/PlaytroughController.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/controller/PlaythroughController.java
@@ -20,7 +20,7 @@ import javafx.scene.image.ImageView;
  *
  * @author Nicolai H. Brand.
  */
-public class PlaytroughController extends Controller {
+public class PlaythroughController extends Controller {
 
     private Playthrough playthrough;
 
@@ -30,7 +30,7 @@ public class PlaytroughController extends Controller {
     private final StringProperty passageContent = new SimpleStringProperty();
     private final ObservableList<Link> links = FXCollections.observableList(new ArrayList<>());
     private final ObservableList<String> inventory = FXCollections.observableList(new ArrayList<>());
-    private final ObservableMap<Goal, Boolean> goals = FXCollections.observableMap(new HashMap<>());
+    private final ObservableMap<Goal<?>, Boolean> goals = FXCollections.observableMap(new HashMap<>());
     private final StringProperty health = new SimpleStringProperty();
     private final StringProperty score = new SimpleStringProperty();
     private final StringProperty gold = new SimpleStringProperty();
@@ -40,7 +40,7 @@ public class PlaytroughController extends Controller {
      * Creates a new instance of the controller.
      * It initializes the controller and starts a new game.
      */
-    public PlaytroughController() {
+    public PlaythroughController() {
         super(HomeView.class, HelpView.class);
         startNewPlaythrough();
     }
@@ -178,7 +178,7 @@ public class PlaytroughController extends Controller {
      * Returns the goals of the game as an observable map.
      * @return the goals of the game.
      */
-    public ObservableMap<Goal, Boolean> getGoals() {
+    public ObservableMap<Goal<?>, Boolean> getGoals() {
         return goals;
     }
 
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/Game.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/Game.java
index 287a0131c96daa0f057331ac88f3a9fb7d484b40..f1399d8c02934cadba13d12ba55b69ad7d3d60ac 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/Game.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/Game.java
@@ -9,7 +9,7 @@ import java.util.List;
  *
  * @author Nicolai H. Brand, Trym Hamer Gudvangen
  */
-public record Game(Player player, Story story, List<Goal> goals) {
+public record Game(Player player, Story story, List<Goal<?>> goals) {
     /**
      * This method constructs a Game object with the given parameters.
      *
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/Story.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/Story.java
index a22f45d073c6aaab575aec1aa0cef99fc28c95d5..183490579c36ad8c7277f8433eb551b23503ff76 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/Story.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/Story.java
@@ -13,7 +13,7 @@ import java.util.Objects;
  */
 public class Story {
 
-    private final String title;
+    private String title;
     private final Map<Link, Passage> passages;
     private final Passage openingPassage;
 
@@ -25,13 +25,7 @@ public class Story {
      * @throws IllegalArgumentException     This exception is thrown if title or openingPassage is invalid
      */
     public Story(String title, Passage openingPassage) throws IllegalArgumentException {
-        //if (title.isBlank() || !title.matches("[a-zA-Z]")) {
-        //    throw new IllegalArgumentException("Title cannot be blank, empty, or contain special characters.");
-        //}
-        if (title.isBlank()) throw new IllegalArgumentException(
-            "Title cannot be blank, empty, or contain special characters."
-        );
-        this.title = title;
+        setTitle(title);
         if (openingPassage == null) throw new IllegalArgumentException("Opening passage cannot be null");
         this.openingPassage = openingPassage;
         this.passages = new HashMap<>();
@@ -107,6 +101,17 @@ public class Story {
         return title;
     }
 
+    /**
+     * This method sets the title of the story.
+     * @param title The new title of the story, given as a {@code String}.
+     */
+    public void setTitle(String title) {
+        if (title == null || title.isBlank()) throw new IllegalArgumentException(
+            "Title cannot be blank, empty, or contain special characters."
+        );
+        this.title = title;
+    }
+
     /**
      * This method retrieves all the passages of a story.
      * @return All the passages of the Story as a {@code Collection<Passages>}.
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/ActionType.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/ActionType.java
index 0d4afa902a3c42ae0edf0a85488b120b48402398..bedbaf92da351ab21f79d3ce6534fa9f4840b6b5 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/ActionType.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/ActionType.java
@@ -6,8 +6,18 @@ package edu.ntnu.idatt2001.group_30.paths.model.actions;
  * @author Trym Hamer Gudvangen
  */
 public enum ActionType {
-    GOLD_ACTION,
-    HEALTH_ACTION,
-    INVENTORY_ACTION,
-    SCORE_ACTION,
+    GOLD_ACTION("Gold Action"),
+    HEALTH_ACTION("Health Action"),
+    INVENTORY_ACTION("Inventory Action"),
+    SCORE_ACTION("Score Action");
+
+    private final String displayName;
+
+    ActionType(String displayName) {
+        this.displayName = displayName;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
 }
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/GoldAction.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/GoldAction.java
index 1101d8c660bbc86d1207c26adcc070c35d6a35af..f479b4826f43348845ddf5d583ff51b87cd76763 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/GoldAction.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/GoldAction.java
@@ -18,7 +18,6 @@ public class GoldAction implements Action<Integer> {
      */
     public GoldAction(int gold) {
         this.gold = gold;
-        //TODO: Add exception?
     }
 
     /**
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/HealthAction.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/HealthAction.java
index bf588fe6767b34ffe4dc4f26c41238032ef579b5..55a4afd0def466b0947c3ba49f16881a21dbbdfa 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/HealthAction.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/HealthAction.java
@@ -18,7 +18,6 @@ public class HealthAction implements Action<Integer> {
      */
     public HealthAction(int health) {
         this.health = health;
-        //TODO: Add exception?
     }
 
     /**
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/InventoryAction.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/InventoryAction.java
index a8b5939b85a62fb5fce85ab0ad6a1ed7827b177f..040768f0cd0e2e59ba83e4564cd45fed6c6f6901 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/InventoryAction.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/InventoryAction.java
@@ -18,7 +18,6 @@ public class InventoryAction implements Action<String> {
      */
     public InventoryAction(String item) {
         this.item = item;
-        //TODO: Add exception?
     }
 
     /**
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/ScoreAction.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/ScoreAction.java
index bf20494e9decc5c7910fe1d5842d0f0b8f3dd4c9..9c09207642e0b830dd1a90578c38a7aff1e2bd21 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/ScoreAction.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/actions/ScoreAction.java
@@ -18,7 +18,6 @@ public class ScoreAction implements Action<Integer> {
      */
     public ScoreAction(int points) {
         this.points = points;
-        //TODO: Add exception?
     }
 
     /**
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/filehandling/StoryFileWriter.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/filehandling/StoryFileWriter.java
index 40256fd7981c102e3eb8f9d8a2a9b6a1f83ce154..3bbc14c868a9f8c3726d4dee9678b828722892f6 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/filehandling/StoryFileWriter.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/filehandling/StoryFileWriter.java
@@ -20,7 +20,24 @@ import java.util.*;
 public class StoryFileWriter {
 
     /**
-     * Creates a new story file with the given name and writes the story to it.
+     * This method takes a story and writes its contents to a .paths file. The story information is transcribed
+     * in the given format:
+     * <pre>
+     *  Story title
+     *
+     *  ::Opening Passage Title
+     *  Opening Passage Content
+     *  [Link Text](Link Reference)
+     *
+     *  ::Another Passage Title
+     *  Passage Content
+     *  [Link Text](Link Reference)
+     *  {@code <Action Type>}\Action Value/
+     *  [Link Text](Link Reference)
+     *
+     *  ...
+     *  </pre>
+     *
      * @param story    The story to be written to the file.
      * @param fileName The name of the file to be created.
      * @throws IOException if an I/O error occurs with the writer, or if the file already exists.
@@ -30,6 +47,37 @@ public class StoryFileWriter {
         Objects.requireNonNull(fileName, "File name cannot be null");
 
         File file = FileHandler.createFile(fileName);
+
+        create(story, file);
+    }
+
+    /**
+     * This method takes a story and writes its contents to a .paths file. The story information is transcribed
+     * in the given format:
+     * <pre>
+     *  Story title
+     *
+     *  ::Opening Passage Title
+     *  Opening Passage Content
+     *  [Link Text](Link Reference)
+     *
+     *  ::Another Passage Title
+     *  Passage Content
+     *  [Link Text](Link Reference)
+     *  {@code <Action Type>}\Action Value/
+     *  [Link Text](Link Reference)
+     *
+     *  ...
+     *  </pre>
+     *
+     * @param story         The story to be written to the file.
+     * @param file          The file the story is going to be written to.
+     * @throws IOException  if an I/O error occurs with the writer, or if the file already exists.
+     */
+    public void create(Story story, File file) throws IOException {
+        Objects.requireNonNull(story, "Story cannot be null");
+        Objects.requireNonNull(file, "File cannot be null");
+
         if (FileHandler.fileExists(file)) throw new FileAlreadyExistsException(
             "You cannot overwrite a pre-existing story file"
         );
@@ -38,6 +86,8 @@ public class StoryFileWriter {
         writeStory(story, file);
     }
 
+    //TODO: add test for story files...
+
     /**
      * Writes the story to the given file.
      * @param story The story to be written to the file.
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/goals/GoalFactory.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/goals/GoalFactory.java
index d18f5aca79e7d6cc095031c106cc2aa6757bc99e..92cd32b22b19d5de62826f245e7b56bce350ef0d 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/goals/GoalFactory.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/goals/GoalFactory.java
@@ -1,12 +1,23 @@
 package edu.ntnu.idatt2001.group_30.paths.model.goals;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
 
+/**
+ * This class is a factory for creating Goal objects.
+ *
+ * @author Trym Hamer Gudvangen
+ */
 public class GoalFactory {
 
+    /**
+     * This method creates a Goal object based on the given goal type and goal value.
+     * @param goalType                      The type of goal, given as a GoalType object.
+     * @param goalValue                     The value of the goal, given as an Object.
+     * @return                              A Goal object.
+     * @throws IllegalArgumentException     If the goal type or value is invalid.
+     */
     public static Goal<?> getGoal(GoalType goalType, Object goalValue) throws IllegalArgumentException {
         switch (goalType) {
             case GOLD_GOAL, HEALTH_GOAL, SCORE_GOAL -> {
@@ -37,6 +48,13 @@ public class GoalFactory {
         throw new IllegalArgumentException("Invalid goal type or value");
     }
 
+    /**
+     * This method creates a Goal object based on the given goal type and goal value.
+     * @param goalType                      The type of goal, given as a String.
+     * @param goalValue                     The value of the goal, given as an Object.
+     * @return                              A Goal object.
+     * @throws IllegalArgumentException     If the goal type or value is invalid.
+     */
     public static Goal<?> getGoal(String goalType, Object goalValue) throws IllegalArgumentException {
         return getGoal(GoalType.getGoalType(goalType), goalValue);
     }
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/goals/GoalType.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/goals/GoalType.java
index b164bc07972740fa0a901c84fde99c1f568a7fb9..0d369287e785abccae76c20a16577372f6afc9c8 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/goals/GoalType.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/goals/GoalType.java
@@ -3,6 +3,11 @@ package edu.ntnu.idatt2001.group_30.paths.model.goals;
 import java.util.HashMap;
 import java.util.Map;
 
+/**
+ * This enum represents the different types of goals.
+ *
+ * @author Trym Hamer Gudvangen
+ */
 public enum GoalType {
     GOLD_GOAL("GoldGoal"),
     HEALTH_GOAL("HealthGoal"),
@@ -18,14 +23,27 @@ public enum GoalType {
         }
     }
 
+    /**
+     * This constructor creates a GoalType object based on the given string value.
+     * @param stringVal   The string value of the GoalType object.
+     */
     GoalType(String stringVal) {
         this.stringVal = stringVal;
     }
 
+    /**
+     * This method retrieves the GoalType object based on the given string value.
+     * @param goalType The string value of the GoalType object.
+     * @return         The GoalType object.
+     */
     public static GoalType getGoalType(String goalType) {
         return stringToEnum.get(goalType);
     }
 
+    /**
+     * This method retrieves the string value of the GoalType object.
+     * @return  The string value of the GoalType object.
+     */
     public String getStringVal() {
         return stringVal;
     }
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/goals/GoldGoal.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/goals/GoldGoal.java
index 2f51d2165a9119654d5222d1ffaf3726e37f5abf..79ebf1121f6a17db6510b49bf46567444614298f 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/goals/GoldGoal.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/goals/GoldGoal.java
@@ -18,7 +18,6 @@ public class GoldGoal implements Goal<Integer> {
      */
     public GoldGoal(int minimumGold) {
         this.minimumGold = minimumGold;
-        //TODO: Add exception?
     }
 
     /**
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/goals/ScoreGoal.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/goals/ScoreGoal.java
index def6210020b1873a56698fab33ed53fde778fb77..a0d688e1a83839e47d140a9cf9fdeba326abb315 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/goals/ScoreGoal.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/goals/ScoreGoal.java
@@ -18,7 +18,6 @@ public class ScoreGoal implements Goal<Integer> {
      */
     public ScoreGoal(int minimumPoints) {
         this.minimumPoints = minimumPoints;
-        //TODO: Add exception?
     }
 
     /**
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/utils/TextValidation.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/utils/TextValidation.java
index 57610f010601a59de1a2a514bc3cc0e1fbad11e3..edfd723757903064ad2f91e31b1a8a0799b8ec70 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/utils/TextValidation.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/model/utils/TextValidation.java
@@ -3,12 +3,26 @@ package edu.ntnu.idatt2001.group_30.paths.model.utils;
 import javafx.scene.control.TextFormatter;
 import javafx.util.converter.IntegerStringConverter;
 
+/**
+ * This class represents a text validation.
+ *
+ * @author Trym Hamer Gudvangen
+ */
 public class TextValidation {
 
+    /**
+     * This method creates a text formatter for integers.
+     * @return A text formatter for integers.
+     */
     public static TextFormatter<Integer> createIntegerTextFormatter() {
         return createIntegerTextFormatter(100);
     }
 
+    /**
+     * This method creates a text formatter for integers.
+     * @param startValue   The start value of the text formatter, given as an integer.
+     * @return             A text formatter for integers.
+     */
     public static TextFormatter<Integer> createIntegerTextFormatter(int startValue) {
         return new TextFormatter<>(
             new IntegerStringConverter(),
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/App.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/App.java
index 8f18add2be461aff2bd711a220fe267c2aa003a8..6f149869142bbc25642d016dd475b994cc9083d1 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/App.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/App.java
@@ -32,7 +32,7 @@ public class App extends Application {
     @Override
     public void start(Stage stage) {
         stage.initStyle(StageStyle.UTILITY);
-        stage.setAlwaysOnTop(true);
+        stage.setAlwaysOnTop(false);
         stage.setTitle("Paths");
         /* initialize STAGE_MANAGER */
         STAGE_MANAGER = StageManager.init(stage);
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/PassageNode.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/PassageNode.java
deleted file mode 100644
index 05882d9d03a540638019bd0441e305cae01fca50..0000000000000000000000000000000000000000
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/PassageNode.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package edu.ntnu.idatt2001.group_30.paths.view;
-
-import edu.ntnu.idatt2001.group_30.paths.PathsSingleton;
-import edu.ntnu.idatt2001.group_30.paths.model.Passage;
-import java.util.ArrayList;
-import java.util.List;
-import javafx.geometry.Point2D;
-import javafx.scene.Cursor;
-import javafx.scene.layout.Pane;
-import javafx.scene.paint.Color;
-import javafx.scene.paint.Paint;
-import javafx.scene.shape.Line;
-import javafx.scene.shape.Rectangle;
-import javafx.scene.text.Text;
-
-/*
-    TODO:
-      - add ability to edit.
-      - add links (double click to draw? click again on another passage to add link?)
-      - problems: reconstructing the layout of shapes (need to store positions)
- */
-
-public class PassageNode extends Pane {
-
-    private final Passage passage;
-    private final Rectangle rectangle;
-    private final Text text;
-    private Point2D passageInitOffset;
-
-    private final List<Line> links = new ArrayList<>(); //TODO: may need to actually make a linkNode class...
-
-    public PassageNode(Passage passage) {
-        this(100, 100, 100, 100, passage);
-    }
-
-    public PassageNode(double v, double v1, Passage passage) {
-        this(v, v1, 100, 100, passage);
-    }
-
-    public PassageNode(double v, double v1, Paint paint, Passage passage) {
-        this(v, v1, 100, 100, passage);
-        this.rectangle.setFill(paint);
-    }
-
-    public PassageNode(double v, double v1, double v2, double v3, Passage passage) {
-        this.passage = passage;
-        this.rectangle = new Rectangle(0, 0, v2, v3);
-        this.rectangle.setFill(Color.WHITE);
-        this.rectangle.setStyle("-fx-border-color: black;");
-        this.text = new Text(passage.toString());
-        this.text.setFill(Color.BLACK);
-
-        addPassageEventListener();
-
-        getChildren().addAll(this.rectangle, this.text);
-        this.setLayoutX(v);
-        this.setLayoutY(v1);
-        this.setPrefSize(v2, v3);
-        //        this.setTranslateX(v);
-        //        this.setTranslateY(v1);
-
-    }
-
-    private void addPassageEventListener() {
-        this.setOnMousePressed(mouseEvent -> {
-                this.setCursor(Cursor.HAND);
-                this.passageInitOffset =
-                    new Point2D(mouseEvent.getX(), mouseEvent.getY())
-                        .subtract(this.getTranslateX(), this.getTranslateY());
-            });
-
-        this.setOnMouseDragged(event -> {
-                this.setCursor(Cursor.MOVE);
-                PathsSingleton.INSTANCE.setPassageMoving(true);
-
-                double newX = event.getX() - this.passageInitOffset.getX();
-                double newY = event.getY() - this.passageInitOffset.getY();
-
-                this.setTranslateX(newX);
-                this.setTranslateY(newY);
-                //            this.getChildren().forEach(child -> child.setTranslateX(event.getX() - this.getWidth()/2));
-                //            this.setX(event.getX() - this.getWidth()/2);
-                //            this.setY(event.getY() - this.getHeight()/2);
-                //TODO: adjust link as well
-            });
-
-        this.setOnMouseReleased(mouseDragEvent -> {
-                PathsSingleton.INSTANCE.setPassageMoving(false);
-            });
-    }
-}
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/StoryCreation.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/StoryCreation.java
deleted file mode 100644
index 51e4144d1365f0f98d7fe03fb07262bcd9a14365..0000000000000000000000000000000000000000
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/StoryCreation.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package edu.ntnu.idatt2001.group_30.paths.view;
-
-import edu.ntnu.idatt2001.group_30.paths.PathsSingleton;
-import edu.ntnu.idatt2001.group_30.paths.model.Passage;
-import javafx.application.Application;
-import javafx.collections.FXCollections;
-import javafx.collections.ObservableList;
-import javafx.geometry.Point2D;
-import javafx.scene.Cursor;
-import javafx.scene.Scene;
-import javafx.scene.control.Button;
-import javafx.scene.control.ScrollPane;
-import javafx.scene.layout.AnchorPane;
-import javafx.scene.layout.Pane;
-import javafx.scene.layout.VBox;
-import javafx.scene.shape.Line;
-import javafx.stage.Stage;
-
-public class StoryCreation extends Application {
-
-    public static final int DEFAULT_WIDTH = 1000;
-    public static final int DEFAULT_HEIGHT = 1000;
-    private static Stage stage;
-    private Point2D contentPaneInitOffset;
-    private final ObservableList<PassageNode> passages = FXCollections.observableArrayList();
-
-    /**
-     * The entry point of the application.
-     * @param args The command line arguments.
-     */
-    public static void main(String[] args) {
-        launch();
-    }
-
-    /**
-     * The start method is called by the JavaFX runtime after the init method has returned.
-     * @param stage The primary stage for this application, onto which the application scene can be set.
-     */
-    @Override
-    public void start(Stage stage) {
-        StoryCreation.stage = stage;
-        StoryCreation.stage.setTitle("Paths");
-        AnchorPane anchorPane = new AnchorPane();
-
-        ScrollPane scrollPane = new ScrollPane();
-        scrollPane.setPrefSize(1000, 1000);
-
-        Pane contentPane = new Pane();
-        contentPane.setStyle("-fx-border-color: black;");
-        scrollPane.setContent(contentPane);
-
-        PassageNode passage1 = new PassageNode(50, 50, 100, 50, new Passage("Passage title", "Content"));
-        PassageNode passage2 = new PassageNode(200, 200, 100, 50, new Passage("Passage title2", "Content2"));
-
-        passages.addAll(passage1, passage2);
-        //TODO: make class for GUI passage, containing place for GUI link...
-        Line link1 = new Line(100, 75, 200, 225);
-
-        contentPane.getChildren().addAll(passage1, passage2, link1);
-
-        addContentPaneEventListeners(contentPane);
-
-        scrollPane.setOnZoom(event -> {
-            double zoomFactor = event.getTotalZoomFactor();
-            contentPane.setScaleX(contentPane.getScaleX() * zoomFactor);
-            contentPane.setScaleY(contentPane.getScaleY() * zoomFactor);
-        });
-
-        Button addPassage = new Button("Add Passage");
-        VBox menu = new VBox(addPassage);
-        menu.setTranslateX(300);
-        menu.setTranslateY(300);
-
-        anchorPane.getChildren().addAll(scrollPane, menu);
-
-        addPassage
-            .onActionProperty()
-            .set(actionEvent -> {
-                PassageNode newPassage = new PassageNode(
-                    200 + 100 * passages.size(),
-                    200,
-                    100,
-                    50,
-                    new Passage("Passage title", "Content2")
-                );
-                passages.add(newPassage);
-                contentPane.getChildren().add(newPassage);
-            });
-
-        Scene scene = new Scene(anchorPane, DEFAULT_WIDTH, DEFAULT_HEIGHT);
-        StoryCreation.stage.setScene(scene);
-        StoryCreation.stage.show();
-    }
-
-    private void addContentPaneEventListeners(Pane contentPane) {
-        contentPane.setOnMousePressed(mouseEvent -> {
-            contentPane.setCursor(Cursor.HAND);
-            contentPaneInitOffset =
-                new Point2D(mouseEvent.getX(), mouseEvent.getY())
-                    .subtract(contentPane.getTranslateX(), contentPane.getTranslateY());
-        });
-
-        contentPane.setOnMouseReleased(mouseEvent -> {
-            contentPane.setCursor(Cursor.DEFAULT);
-        });
-
-        contentPane.setOnMouseDragged(mouseEvent -> {
-            if (!PathsSingleton.INSTANCE.isPassageMoving()) {
-                contentPane.setCursor(Cursor.HAND);
-
-                double newX = mouseEvent.getX() - contentPaneInitOffset.getX();
-                double newY = mouseEvent.getY() - contentPaneInitOffset.getY();
-                contentPane.setTranslateX(newX);
-                contentPane.setTranslateY(newY);
-            }
-        });
-
-        contentPane.setOnMouseClicked(mouseEvent -> {
-            PassageNode newPassage = new PassageNode(
-                mouseEvent.getX(),
-                mouseEvent.getY(),
-                100,
-                50,
-                new Passage("Passage title", "Content2")
-            );
-            passages.add(newPassage);
-            contentPane.getChildren().add(newPassage);
-        });
-    }
-}
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/CreatePlayer.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/CreatePlayer.java
index bc00aca590e12118c59f808f3e0e7bac31c6598f..004702c843a858ab8e3fa8116170b0569e8ce169 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/CreatePlayer.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/CreatePlayer.java
@@ -18,6 +18,9 @@ public class CreatePlayer extends GridPane {
     private final TextField goldField;
     private final ComboBox<String> goalBox;
 
+    /**
+     * Constructor for the CreatePlayer component.
+     */
     public CreatePlayer() {
         setHgap(10);
         setVgap(5);
@@ -38,18 +41,34 @@ public class CreatePlayer extends GridPane {
         add(goalBox, 1, 3);
     }
 
+    /**
+     * Method for getting the name of the player.
+     * @return  The name of the player, as a String.
+     */
     public String getName() {
         return nameField.getText();
     }
 
+    /**
+     * Method for getting the health of the player.
+     * @return  The health of the player, as an int.
+     */
     public int getHealth() {
         return Integer.parseInt(healthField.getText());
     }
 
+    /**
+     * Method for getting the gold of the player.
+     * @return  The gold of the player, as an int.
+     */
     public int getGold() {
         return Integer.parseInt(goldField.getText());
     }
 
+    /**
+     * Method for getting the goal of the player.
+     * @return  The goal of the player, as a String.
+     */
     public String getGoal() {
         return goalBox.getValue();
     }
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/ImageCarousel.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/ImageCarousel.java
index 7858c3660988b7b2c5fc96b46d8ce4d473f7e1fe..a95573f21a490516385765e79f952d6f1154b2f9 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/ImageCarousel.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/ImageCarousel.java
@@ -9,6 +9,11 @@ import javafx.scene.image.Image;
 import javafx.scene.image.ImageView;
 import javafx.scene.layout.HBox;
 
+/**
+ * This class represents a component for displaying a carousel of images.
+ *
+ * @author Trym Hamer Gudvangen
+ */
 public class ImageCarousel {
 
     private final LinkedList<Image> images = new LinkedList<>();
@@ -18,6 +23,10 @@ public class ImageCarousel {
     private final int WIDTH = 150;
     private final int HEIGHT = 150;
 
+    /**
+     * Constructor for the ImageCarousel component.
+     * @param imageNames    A list of image names, as Strings.
+     */
     public ImageCarousel(List<String> imageNames) {
         if (imageNames == null || imageNames.isEmpty()) {
             throw new IllegalArgumentException("Image URI list must not be empty.");
@@ -39,6 +48,10 @@ public class ImageCarousel {
         this.currentImage.setImage(images.getFirst());
     }
 
+    /**
+     * Method for getting the carousel component.
+     * @return  The carousel component, as an HBox.
+     */
     public HBox getCarousel() {
         Button leftButton = new Button("<");
         leftButton.setOnAction(e -> previous());
@@ -51,20 +64,34 @@ public class ImageCarousel {
         return carousel;
     }
 
+    /**
+     * Method for getting the next image.
+     */
     public void next() {
         currentIndex = (currentIndex + 1) % size;
         currentImage.setImage(images.get(currentIndex));
     }
 
+    /**
+     * Method for getting the previous image.
+     */
     public void previous() {
         currentIndex = (currentIndex - 1 + size) % size;
         currentImage.setImage(images.get(currentIndex));
     }
 
+    /**
+     * Method for getting the size of the list of images.
+     * @return  The size of the list of images, as an int.
+     */
     public int size() {
         return size;
     }
 
+    /**
+     * Method for getting the current image.
+     * @return  The current image, as an ImageView.
+     */
     public ImageView getCurrentImage() {
         return currentImage;
     }
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/StoryDisplay.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/StoryDisplay.java
similarity index 99%
rename from src/main/java/edu/ntnu/idatt2001/group_30/paths/view/StoryDisplay.java
rename to src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/StoryDisplay.java
index 9b4b4457463b28bbe96f725157a070bf01ae04a6..0ef5e184defa013b60cb6b9db158008c44b60088 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/StoryDisplay.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/StoryDisplay.java
@@ -1,4 +1,4 @@
-package edu.ntnu.idatt2001.group_30.paths.view;
+package edu.ntnu.idatt2001.group_30.paths.view.components;
 
 import edu.ntnu.idatt2001.group_30.paths.model.Story;
 import edu.ntnu.idatt2001.group_30.paths.model.filehandling.FileHandler;
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/common/DefaultInputField.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/common/DefaultInputField.java
new file mode 100644
index 0000000000000000000000000000000000000000..a030a4bd51bd011df7e4c4f6ed4768859013e228
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/common/DefaultInputField.java
@@ -0,0 +1,26 @@
+package edu.ntnu.idatt2001.group_30.paths.view.components.common;
+
+import javafx.scene.control.TextField;
+import javafx.scene.layout.HBox;
+import javafx.scene.text.Text;
+
+/**
+ * This class contains methods to create different input fields with default layouts.
+ *
+ * @author Trym Hamer Gudvangen
+ */
+public class DefaultInputField {
+
+    /**
+     * This method creates a text input field with a given label and prompt.
+     * @param label     The label of the input field, given as a String.
+     * @param prompt    The prompt of the input field, given as a String.
+     * @return          An HBox containing the label and the input field.
+     */
+    public static HBox inputWithLabelAndPrompt(String label, String prompt) {
+        Text labelText = new Text(label);
+        TextField textField = new TextField();
+        textField.setPromptText(prompt);
+        return new HBox(labelText, textField);
+    }
+}
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/AbstractPopUp.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/AbstractPopUp.java
new file mode 100644
index 0000000000000000000000000000000000000000..35fa07f2d7b7444bbcb12bba3eb96c8004d17b1e
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/AbstractPopUp.java
@@ -0,0 +1,32 @@
+package edu.ntnu.idatt2001.group_30.paths.view.components.pop_up;
+
+/**
+ * This class provides a template for creating pop-ups.
+ *
+ * @author Trym Hamer Gudvangen
+ */
+public abstract class AbstractPopUp {
+
+    /**
+     * This method initializes the pop-up by setting up the UI components and the behavior.
+     */
+    protected void initialize() {
+        setupUiComponents();
+        setupBehavior();
+    }
+
+    /**
+     * This method sets up the UI components of the pop-up.
+     */
+    protected abstract void setupUiComponents();
+
+    /**
+     * This method sets up the behavior of the pop-up.
+     */
+    protected abstract void setupBehavior();
+
+    /**
+     * This method creates the pop-up.
+     */
+    protected abstract void createPopUp();
+}
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/GoalsPopUp.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/GoalsPopUp.java
index c60ab50127f111cadef1dc0aef67c6bafd9dd6c7..71e19b86a45896a37c987674488faaadb51b28ef 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/GoalsPopUp.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/GoalsPopUp.java
@@ -16,14 +16,39 @@ import javafx.scene.image.ImageView;
 import javafx.scene.layout.HBox;
 import javafx.scene.layout.VBox;
 
-public class GoalsPopUp {
+/**
+ * This class contains a pop-up for creating and editing goals.
+ *
+ * @author Trym Hamer Gudvangen
+ */
+public class GoalsPopUp extends AbstractPopUp {
 
     private TextField healthField;
     private TextField goldField;
     private TextField scoreField;
     private Button saveButton;
-
+    private Button addButton;
+    private Button deleteButton;
+    private TextField inventoryField;
+    private ObservableList<String> items;
+    private TableView<String> inventoryTable;
+    private VBox content;
+    private ScrollPane scrollPane;
+    private PopUp<ScrollPane, ?> popUp;
+
+    /**
+     * This constructor creates a new GoalsPopUp.
+     */
     public GoalsPopUp() {
+        initialize();
+        createPopUp();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void setupUiComponents() {
         healthField = new TextField();
         healthField.setTextFormatter(
             TextValidation.createIntegerTextFormatter(
@@ -50,10 +75,10 @@ public class GoalsPopUp {
 
         saveButton = new Button("Save");
 
-        TextField inventoryField = new TextField();
+        inventoryField = new TextField();
         inventoryField.setPromptText("Add inventory item");
 
-        Button addButton = new Button();
+        addButton = new Button();
         URL imageUrl = getClass().getResource("/images/plus.png");
         if (imageUrl != null) {
             ImageView addIcon = new ImageView(new Image(imageUrl.toString()));
@@ -64,18 +89,18 @@ public class GoalsPopUp {
             System.err.println("Something is wrong with the trash image resource link");
         }
 
-        ObservableList<String> items = FXCollections.observableArrayList();
+        items = FXCollections.observableArrayList();
         if (INSTANCE.getInventoryGoal() != null) {
             items.addAll(INSTANCE.getInventoryGoal().getGoalValue());
         }
-        TableView<String> inventoryTable = new TableView<>(items);
+        inventoryTable = new TableView<>(items);
         TableColumn<String, String> itemColumn = new TableColumn<>("Items");
         itemColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue()));
         inventoryTable.getColumns().add(itemColumn);
         itemColumn.prefWidthProperty().bind(inventoryTable.widthProperty());
         inventoryTable.setMaxHeight(200);
 
-        Button deleteButton = new Button();
+        deleteButton = new Button();
         imageUrl = getClass().getResource("/images/trash.png");
         if (imageUrl != null) {
             ImageView trashIcon = new ImageView(new Image(imageUrl.toString()));
@@ -86,6 +111,33 @@ public class GoalsPopUp {
             System.err.println("Something is wrong with the trash image resource link");
         }
 
+        content =
+            new VBox(
+                new Label("Health:"),
+                healthField,
+                new Label("Gold:"),
+                goldField,
+                new Label("Score:"),
+                scoreField,
+                new Label("Inventory"),
+                new HBox(inventoryField, addButton),
+                inventoryTable,
+                deleteButton,
+                saveButton
+            );
+
+        content.setAlignment(Pos.CENTER);
+        content.setSpacing(20);
+
+        scrollPane = new ScrollPane(content);
+        scrollPane.setFitToWidth(true);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void setupBehavior() {
         addButton.setOnAction(e -> {
             if (!inventoryField.getText().isBlank()) {
                 items.add(inventoryField.getText());
@@ -100,33 +152,6 @@ public class GoalsPopUp {
             }
         });
 
-        VBox content = new VBox(
-            new Label("Health:"),
-            healthField,
-            new Label("Gold:"),
-            goldField,
-            new Label("Score:"),
-            scoreField,
-            new Label("Inventory"),
-            new HBox(inventoryField, addButton),
-            inventoryTable,
-            deleteButton,
-            saveButton
-        );
-
-        content.setAlignment(Pos.CENTER);
-        content.setSpacing(20);
-
-        ScrollPane scrollPane = new ScrollPane(content);
-        scrollPane.setFitToWidth(true);
-
-        PopUp<ScrollPane, ?> popUp = PopUp
-            .<ScrollPane>create()
-            .withTitle("Add goals to your player")
-            .withoutCloseButton()
-            .withContent(scrollPane)
-            .withDialogSize(400, 500);
-
         saveButton.setOnAction(e -> {
             if (healthField.getText().isBlank() || goldField.getText().isBlank()) {
                 AlertDialog.showWarning("The different fields cannot be blank.");
@@ -139,6 +164,21 @@ public class GoalsPopUp {
                 popUp.close();
             }
         });
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void createPopUp() {
+        popUp =
+            PopUp
+                .<ScrollPane>create()
+                .withTitle("Add goals to your player")
+                .withoutCloseButton()
+                .withContent(scrollPane)
+                .withDialogSize(400, 750);
+
         popUp.showAndWait();
     }
 }
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/LinkPopUp.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/LinkPopUp.java
new file mode 100644
index 0000000000000000000000000000000000000000..54bd0ee6d0f05d650d73ff237281e3cbbda0e58d
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/LinkPopUp.java
@@ -0,0 +1,213 @@
+package edu.ntnu.idatt2001.group_30.paths.view.components.pop_up;
+
+import edu.ntnu.idatt2001.group_30.paths.model.Link;
+import edu.ntnu.idatt2001.group_30.paths.model.Passage;
+import edu.ntnu.idatt2001.group_30.paths.model.actions.Action;
+import edu.ntnu.idatt2001.group_30.paths.model.actions.ActionFactory;
+import edu.ntnu.idatt2001.group_30.paths.model.actions.ActionType;
+import edu.ntnu.idatt2001.group_30.paths.model.utils.TextValidation;
+import edu.ntnu.idatt2001.group_30.paths.view.components.table.ActionTable;
+import edu.ntnu.idatt2001.group_30.paths.view.components.table.TableDisplay;
+import java.util.HashMap;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.geometry.Pos;
+import javafx.scene.control.*;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+
+/**
+ * This class is a pop-up for creating a new link or editing an existing one.
+ *
+ * @author Trym Hamer Gudvangen
+ */
+public class LinkPopUp extends AbstractPopUp {
+
+    private TextField textField;
+    private TextField actionTextField;
+    private Button saveButton;
+    private Button addActionButton;
+    private Button removeActionButton;
+    private ComboBox<String> reference;
+    private ComboBox<ActionType> actionComboBox;
+    private ActionTable<Action<?>> actionTable;
+    private VBox content;
+    private final ObservableList<Passage> passages;
+    private ObservableList<Action<?>> actions;
+    private HashMap<String, Passage> passageHashMap;
+    private Link link;
+    private PopUp<VBox, ?> popUp;
+
+    /**
+     * This constructor allows a new link to be created.
+     * @param passages Other passages in the story, given as an ObservableList of passages.
+     */
+    public LinkPopUp(ObservableList<Passage> passages) {
+        this.actions = FXCollections.observableArrayList();
+        this.passages = passages;
+        this.passageHashMap = new HashMap<>();
+        passages.forEach(passage -> passageHashMap.put(passage.getTitle(), passage));
+
+        initialize();
+        createPopUp();
+    }
+
+    /**
+     * This constructor allows a pre-existing link to be edited.
+     * @param passages Other passages in the story, given as an ObservableList of passages.
+     * @param link     The link to be edited, given as a Link object.
+     */
+    public LinkPopUp(ObservableList<Passage> passages, Link link) {
+        this.link = link;
+        this.actions = FXCollections.observableArrayList(link.getActions());
+        this.passages = passages;
+        this.passageHashMap = new HashMap<>();
+        passages.forEach(passage -> passageHashMap.put(passage.getTitle(), passage));
+
+        initialize();
+        loadLink();
+        createPopUp();
+    }
+
+    /**
+     * This method loads the link to be edited into the pop-up.
+     */
+    @Override
+    protected void setupUiComponents() {
+        textField = new TextField();
+        textField.setPromptText("Enter the text of the link");
+
+        reference = new ComboBox<>(FXCollections.observableArrayList(passageHashMap.keySet()));
+        reference.setPromptText("Select reference passage of the link");
+
+        saveButton = new Button("Save");
+
+        ObservableList<ActionType> actionTypes = FXCollections.observableArrayList(ActionType.values());
+
+        actionComboBox = new ComboBox<>(actionTypes);
+        actionComboBox.setPromptText("Select an action");
+
+        actionTextField = new TextField();
+
+        removeActionButton = new Button("Remove Action");
+        removeActionButton.setDisable(true);
+
+        addActionButton = new Button("Add Action");
+
+        HBox actionHbox = new HBox(actionComboBox, actionTextField, addActionButton);
+        actionHbox.setAlignment(Pos.CENTER);
+
+        actionTable =
+            new ActionTable<>(
+                new TableDisplay.Builder<Action<?>>()
+                    .addColumnWithComplexValue("Type", action -> action.getClass().getSimpleName())
+                    .addColumnWithComplexValue("Value", action -> action.getActionValue().toString())
+            );
+
+        actionTable.setItems(actions);
+
+        actionTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
+
+        content =
+            new VBox(
+                new Label("Link Text:"),
+                textField,
+                new Label("Link Reference:"),
+                reference,
+                new Label("Actions:"),
+                actionHbox,
+                actionTable,
+                removeActionButton,
+                saveButton
+            );
+
+        content.setAlignment(Pos.CENTER);
+        content.setSpacing(20);
+    }
+
+    /**
+     * This method sets up the behavior of the Ui components.
+     */
+    @Override
+    protected void setupBehavior() {
+        removeActionButton.setOnAction(event -> actions.remove(actionTable.getSelectionModel().getSelectedItem()));
+
+        actionTable
+            .getSelectionModel()
+            .selectedItemProperty()
+            .addListener((obs, oldSelection, newSelection) -> {
+                removeActionButton.setDisable(newSelection == null);
+            });
+
+        addActionButton.setOnAction(e -> {
+            if (actionComboBox.getValue() != null) {
+                actions.add(ActionFactory.getAction(actionComboBox.getValue(), actionTextField.getText()));
+                actionComboBox.setValue(null);
+            }
+        });
+
+        saveButton.setOnAction(e -> {
+            if (textField.getText().isBlank() || reference.getValue() == null) {
+                AlertDialog.showWarning("The text or reference cannot be blank.");
+            } else {
+                link = new Link(textField.getText(), passageHashMap.get(reference.getValue()).getTitle());
+                actions.forEach(action -> link.addAction(action));
+                popUp.close();
+            }
+        });
+
+        actionComboBox.setCellFactory(listView ->
+            new ListCell<>() {
+                @Override
+                protected void updateItem(ActionType actionType, boolean empty) {
+                    super.updateItem(actionType, empty);
+                    if (empty || actionType == null) {
+                        setText(null);
+                    } else {
+                        setText(actionType.getDisplayName());
+                        switch (actionType) {
+                            case SCORE_ACTION, GOLD_ACTION, HEALTH_ACTION -> actionTextField.setTextFormatter(
+                                TextValidation.createIntegerTextFormatter()
+                            );
+                            case INVENTORY_ACTION -> actionTextField.setTextFormatter(null);
+                        }
+                    }
+                }
+            }
+        );
+
+        actionComboBox.setButtonCell(actionComboBox.getCellFactory().call(null));
+    }
+
+    /**
+     * This method creates the pop-up.
+     */
+    @Override
+    protected void createPopUp() {
+        popUp =
+            PopUp
+                .<VBox>create()
+                .withTitle("Create a Link")
+                .withoutCloseButton()
+                .withContent(content)
+                .withDialogSize(400, 500);
+
+        popUp.showAndWait();
+    }
+
+    /**
+     * This method loads the link to be edited into the pop-up.
+     */
+    private void loadLink() {
+        textField.setText(this.link.getText());
+        reference.setValue(this.link.getReference());
+    }
+
+    /**
+     * This method retrieves the link created in the pop-up.
+     * @return  Link created in pop-up, given as a Link object.
+     */
+    public Link getLink() {
+        return link;
+    }
+}
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/PassagePopUp.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/PassagePopUp.java
new file mode 100644
index 0000000000000000000000000000000000000000..3b25186dcc066391c7d7de2ac6678e971d28efbe
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/PassagePopUp.java
@@ -0,0 +1,187 @@
+package edu.ntnu.idatt2001.group_30.paths.view.components.pop_up;
+
+import edu.ntnu.idatt2001.group_30.paths.model.Link;
+import edu.ntnu.idatt2001.group_30.paths.model.Passage;
+import edu.ntnu.idatt2001.group_30.paths.view.components.table.LinkTable;
+import edu.ntnu.idatt2001.group_30.paths.view.components.table.TableDisplay;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.geometry.Pos;
+import javafx.scene.control.*;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+
+/**
+ *  This class contains a pop-up for creating a new passage.
+ *
+ * @author Trym Hamer Gudvangen
+ */
+public class PassagePopUp extends AbstractPopUp {
+
+    private TextField titleField;
+    private TextArea contentArea;
+    private Button saveButton;
+    private Button removeLinkButton;
+    private Button addLinkButton;
+    private Button editLinkButton;
+    private VBox content;
+    private LinkTable<Link> linkTable;
+    private final ObservableList<Passage> passages;
+    private final ObservableList<Link> links;
+    private Passage passage;
+    private PopUp<VBox, ?> popUp;
+
+    /**
+     * This constructor allows a new passage to be created.
+     * @param passages Other passages in the story, given as an ObservableList of passages.
+     */
+    public PassagePopUp(ObservableList<Passage> passages) {
+        this.passages = passages;
+        this.links = FXCollections.observableArrayList();
+        initialize();
+        createPopUp();
+    }
+
+    /**
+     * This constructor allows a pre-existing passage to be edited.
+     * @param passages  Other passages in the story, given as an ObservableList of passages.
+     * @param passage   Passage to edit, given as a Passage object.
+     */
+    public PassagePopUp(ObservableList<Passage> passages, Passage passage) {
+        this.passages = passages;
+        this.passage = passage;
+        this.links = FXCollections.observableArrayList(passage.getLinks());
+        initialize();
+        loadPassage(passage);
+        createPopUp();
+    }
+
+    /**
+     * This method sets up the UI components for the pop-up.
+     */
+    @Override
+    protected void setupUiComponents() {
+        titleField = new TextField();
+        titleField.setPromptText("Enter the title of the passage");
+
+        contentArea = new TextArea();
+        contentArea.setPromptText("Enter the content of the passage");
+        contentArea.setMinHeight(150);
+
+        saveButton = new Button("Save");
+
+        linkTable =
+            new LinkTable<>(
+                new TableDisplay.Builder<Link>().addColumn("Link Title", "text").addColumn("Reference", "reference")
+            );
+
+        linkTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
+        linkTable.setItems(links);
+
+        editLinkButton = new Button("Edit Link");
+        editLinkButton.setDisable(true);
+
+        removeLinkButton = new Button("Remove Link");
+        removeLinkButton.setDisable(true);
+
+        addLinkButton = new Button("Add Link");
+        if (passages.isEmpty()) addLinkButton.setDisable(true);
+
+        HBox linkTableButtonHBox = new HBox(editLinkButton, addLinkButton, removeLinkButton);
+        linkTableButtonHBox.setAlignment(Pos.CENTER);
+
+        content =
+            new VBox(
+                new Label("Passage Title:"),
+                titleField,
+                new Label("Passage Content:"),
+                contentArea,
+                new Label("Links:"),
+                linkTable,
+                linkTableButtonHBox,
+                saveButton
+            );
+
+        content.setAlignment(Pos.CENTER);
+        content.setSpacing(20);
+    }
+
+    /**
+     * This method sets up the behavior for the pop-up.
+     */
+    @Override
+    protected void setupBehavior() {
+        editLinkButton.setOnAction(e -> {
+            Link newLink = new LinkPopUp(this.passages, linkTable.getSelectionModel().getSelectedItem()).getLink();
+            if (newLink != null) {
+                this.links.remove(linkTable.getSelectionModel().getSelectedItem());
+                this.links.add(newLink);
+            }
+        });
+
+        removeLinkButton.setOnAction(e -> links.remove(linkTable.getSelectionModel().getSelectedItem()));
+        linkTable
+            .getSelectionModel()
+            .selectedItemProperty()
+            .addListener((obs, oldSelection, newSelection) -> {
+                removeLinkButton.setDisable(newSelection == null);
+                editLinkButton.setDisable(newSelection == null);
+            });
+
+        addLinkButton.setOnAction(e -> {
+            Link newLink = new LinkPopUp(this.passages).getLink();
+            if (newLink != null) {
+                this.links.add(newLink);
+            }
+        });
+
+        saveButton.setOnAction(e -> {
+            if (titleField.getText().isBlank() || contentArea.getText().isBlank()) {
+                AlertDialog.showWarning("The title or content cannot be blank.");
+            } else if (
+                this.passages.stream()
+                    .anyMatch(passage1 -> passage1.getTitle().equals(titleField.getText()) && passage != passage1)
+            ) {
+                AlertDialog.showWarning("A passage with the title " + titleField.getText() + " already exists.");
+            } else {
+                this.passage = new Passage(titleField.getText(), contentArea.getText());
+
+                this.links.forEach(link -> this.passage.addLink(link));
+                popUp.close();
+            }
+        });
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void createPopUp() {
+        popUp =
+            PopUp
+                .<VBox>create()
+                .withTitle("Create a Passage")
+                .withoutCloseButton()
+                .withContent(content)
+                .withDialogSize(400, 750);
+
+        popUp.showAndWait();
+    }
+
+    /**
+     * This method loads a passage into the pop-up.
+     * @param passage   Passage to load, given as a Passage object.
+     */
+    private void loadPassage(Passage passage) {
+        titleField.setText(passage.getTitle());
+        contentArea.setText(passage.getContent());
+    }
+
+    /**
+     * This method retrieves the passages created from the pop-up.
+     * @return  Passages created, given as a List of Passage objects.
+     */
+    public Passage getPassage() {
+        return passage;
+    }
+}
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/PopUp.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/PopUp.java
index 7b38f065463c9e8b0261fcbe23728c39c34cfd7d..9fff0bfd999acf0d5a905339dcb4daf1a60c1473 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/PopUp.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/PopUp.java
@@ -3,15 +3,28 @@ package edu.ntnu.idatt2001.group_30.paths.view.components.pop_up;
 import javafx.scene.control.*;
 import javafx.scene.layout.Region;
 
+/**
+ * This class provides a template for creating pop-ups.
+ * @param <T>       The type of the content of the pop-up.
+ * @param <SELF>    The type of the pop-up.
+ */
 public class PopUp<T extends Region, SELF extends PopUp<T, SELF>> extends Dialog<Void> {
 
     private final DialogPane dialogPane;
 
+    /**
+     * This constructor sets up the dialog pane.
+     */
     protected PopUp() {
         dialogPane = new DialogPane();
         setDialogPane(dialogPane);
     }
 
+    /**
+     * This method creates a pop-up.
+     * @return      The pop-up.
+     * @param <T>   The type of the content of the pop-up.
+     */
     public static <T extends Region> PopUp<T, ?> create() {
         return new PopUp<>();
     }
@@ -21,16 +34,30 @@ public class PopUp<T extends Region, SELF extends PopUp<T, SELF>> extends Dialog
         return self();
     }
 
+    /**
+     * This method returns the dialog pane.
+     * @param content   The content of the dialog pane.
+     * @return          The dialog pane.
+     */
     public SELF withContent(T content) {
         dialogPane.setContent(content);
         return self();
     }
 
+    /**
+     * This method returns the dialog pane.
+     * @param buttonType    The button type of the dialog pane.
+     * @return              The dialog pane.
+     */
     public SELF withButton(ButtonType buttonType) {
         dialogPane.getButtonTypes().add(buttonType);
         return self();
     }
 
+    /**
+     * This method returns the dialog pane.
+     * @return    The dialog pane.
+     */
     public SELF withoutCloseButton() {
         // Add a close button type to the dialog
         ButtonType closeButtonType = new ButtonType("Close", ButtonBar.ButtonData.CANCEL_CLOSE);
@@ -44,12 +71,22 @@ public class PopUp<T extends Region, SELF extends PopUp<T, SELF>> extends Dialog
         return self();
     }
 
+    /**
+     * This method returns the dialog pane.
+     * @param width     The width of the dialog pane.
+     * @param height    The height of the dialog pane.
+     * @return          The dialog pane.
+     */
     public SELF withDialogSize(double width, double height) {
         getDialogPane().setMinSize(width, height);
         getDialogPane().setMaxSize(width, height);
         return self();
     }
 
+    /**
+     * This method returns the dialog pane.
+     * @return  The dialog pane.
+     */
     @SuppressWarnings("unchecked")
     protected SELF self() {
         return (SELF) this;
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/StatsPopUp.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/StatsPopUp.java
index dca6f643b11a972f75cfd7d50f2d45b1042cd9ab..5e6ba2692d8d81b5937c13fac36729ab07d5ff52 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/StatsPopUp.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/pop_up/StatsPopUp.java
@@ -9,13 +9,48 @@ import javafx.scene.control.Label;
 import javafx.scene.control.TextField;
 import javafx.scene.layout.VBox;
 
-public class StatsPopUp {
+/**
+ * This class contains a pop-up for adding stats to the player.
+ *
+ * @author Trym Hamer Gudvangen
+ */
+public class StatsPopUp extends AbstractPopUp {
 
     private TextField healthField;
     private TextField goldField;
     private Button saveButton;
+    private VBox content;
+    private PopUp<VBox, ?> popUp;
 
+    /**
+     * This constructor creates a new StatsPopUp.
+     */
     public StatsPopUp() {
+        initialize();
+        createPopUp();
+    }
+
+    /**
+     * This method retrieves the health value from the pop-up.
+     * @return  The health value, as an int.
+     */
+    public int getHealth() {
+        return Integer.parseInt(healthField.getText());
+    }
+
+    /**
+     * This method retrieves the gold value from the pop-up.
+     * @return  The gold value, as an int.
+     */
+    public int getGold() {
+        return Integer.parseInt(goldField.getText());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void setupUiComponents() {
         healthField = new TextField();
         healthField.setTextFormatter(TextValidation.createIntegerTextFormatter(INSTANCE.getPlayer().getHealth()));
 
@@ -27,17 +62,16 @@ public class StatsPopUp {
 
         saveButton = new Button("Save");
 
-        VBox content = new VBox(new Label("Health:"), healthField, new Label("Gold:"), goldField, saveButton);
+        content = new VBox(new Label("Health:"), healthField, new Label("Gold:"), goldField, saveButton);
         content.setAlignment(Pos.CENTER);
         content.setSpacing(20);
+    }
 
-        PopUp<VBox, ?> popUp = PopUp
-            .<VBox>create()
-            .withTitle("Add stats to your player")
-            .withoutCloseButton()
-            .withContent(content)
-            .withDialogSize(400, 300);
-
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void setupBehavior() {
         saveButton.setOnAction(e -> {
             if (healthField.getText().isBlank() || goldField.getText().isBlank()) {
                 AlertDialog.showWarning("The different fields cannot be blank.");
@@ -47,14 +81,21 @@ public class StatsPopUp {
                 popUp.close();
             }
         });
-        popUp.showAndWait();
     }
 
-    public int getHealth() {
-        return Integer.parseInt(healthField.getText());
-    }
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void createPopUp() {
+        popUp =
+            PopUp
+                .<VBox>create()
+                .withTitle("Add stats to your player")
+                .withoutCloseButton()
+                .withContent(content)
+                .withDialogSize(400, 300);
 
-    public int getGold() {
-        return Integer.parseInt(goldField.getText());
+        popUp.showAndWait();
     }
 }
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/ActionTable.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/ActionTable.java
new file mode 100644
index 0000000000000000000000000000000000000000..31719edef73503f62471e6fc6e08fd5d9a481baf
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/ActionTable.java
@@ -0,0 +1,19 @@
+package edu.ntnu.idatt2001.group_30.paths.view.components.table;
+
+/**
+ * This class contains the table display implementation for the action object.
+ * @param <Action>  Type of table, which is for Action.
+ *
+ * @author Trym Hamer Gudvangen
+ */
+public class ActionTable<Action> extends TableDisplay<Action> {
+
+    /**
+     * This is a constructor which is used to construct a table for different actions.
+     *
+     * @param tableBuilder The builder used to construct a table, represented using an tableBuilder object.
+     */
+    public ActionTable(Builder<Action> tableBuilder) {
+        super(tableBuilder);
+    }
+}
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/GoalTable.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/GoalTable.java
index be5916a7410212bd28a4740820b490e3e6b4d080..c9646a11b7d1f7fff6ec658b8d90751dc145d50a 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/GoalTable.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/GoalTable.java
@@ -1,5 +1,11 @@
 package edu.ntnu.idatt2001.group_30.paths.view.components.table;
 
+/**
+ * This class contains the specific table display implementation for the Goal classes.
+ * @param <Goal> Type of table, which is Goal.
+ *
+ * @author Trym Hamer Gudvangen
+ */
 public class GoalTable<Goal> extends TableDisplay<Goal> {
 
     /**
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/LinkTable.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/LinkTable.java
new file mode 100644
index 0000000000000000000000000000000000000000..4a4dbaccc42362bc0bc7ced9c876aad4e75b3acf
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/LinkTable.java
@@ -0,0 +1,17 @@
+package edu.ntnu.idatt2001.group_30.paths.view.components.table;
+
+/**
+ * This class concerns itself with the aspects intrinsic to a link table.
+ * @param <Link> The type of the table, represented using a Link object.
+ */
+public class LinkTable<Link> extends TableDisplay<Link> {
+
+    /**
+     * This is a constructor which is used to construct a table for different links.
+     *
+     * @param tableBuilder The builder used to construct a table, represented using an tableBuilder object.
+     */
+    public LinkTable(Builder<Link> tableBuilder) {
+        super(tableBuilder);
+    }
+}
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/PassageTable.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/PassageTable.java
new file mode 100644
index 0000000000000000000000000000000000000000..50ade57fad82d379fe538d430571577c291e8947
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/PassageTable.java
@@ -0,0 +1,17 @@
+package edu.ntnu.idatt2001.group_30.paths.view.components.table;
+
+/**
+ * This class concerns itself with the aspects intrinsic to a passage table.
+ * @param <Passage> The type of the table, represented using a Passage object.
+ */
+public class PassageTable<Passage> extends TableDisplay<Passage> {
+
+    /**
+     * This is a constructor which is used to construct a table for different passages.
+     *
+     * @param tableBuilder The builder used to construct a table, represented using an tableBuilder object.
+     */
+    public PassageTable(Builder<Passage> tableBuilder) {
+        super(tableBuilder);
+    }
+}
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/StatsTable.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/StatsTable.java
index a0fec2282aa03daa29e5e0eeb6a1aab3ade3f70f..e639b45d7b44b74cc947efa52a7400eacce32c61 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/StatsTable.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/StatsTable.java
@@ -1,5 +1,9 @@
 package edu.ntnu.idatt2001.group_30.paths.view.components.table;
 
+/**
+ * This class concerns itself with the aspects intrinsic to a stats table.
+ * @param <Player>  The type of the table, represented using a Player object.
+ */
 public class StatsTable<Player> extends TableDisplay<Player> {
 
     /**
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/TableDisplay.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/TableDisplay.java
index bd8a5d874cd8be3f42093127b6725ee0d6c9b8c1..ad2f18c18b60760a46df91631850afe3113dccde 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/TableDisplay.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/components/table/TableDisplay.java
@@ -1,5 +1,7 @@
 package edu.ntnu.idatt2001.group_30.paths.view.components.table;
 
+import java.util.function.Function;
+import javafx.beans.property.SimpleStringProperty;
 import javafx.collections.FXCollections;
 import javafx.collections.ObservableList;
 import javafx.scene.control.TableColumn;
@@ -47,6 +49,23 @@ public class TableDisplay<T> extends TableView<T> {
             return this;
         }
 
+        /**
+         * This method attaches a desired column {@link TableDisplayColumn#TableDisplayColumn(String, String)} to the
+         * tableview that is complex.
+         * @param infoHeader            The name of the column, represented using a String.
+         * @param complexValueFunction  The attribute the information will be extracted from, represented as a String.
+         * @return                      The builder itself is returned, represented as a Builder object.
+         */
+        public Builder<T> addColumnWithComplexValue(String infoHeader, Function<T, String> complexValueFunction) {
+            TableColumn<T, String> column = new TableColumn<>(infoHeader);
+            column.setCellValueFactory(cellData ->
+                new SimpleStringProperty(complexValueFunction.apply(cellData.getValue()))
+            );
+            column.setStyle("-fx-alignment: CENTER");
+            this.tableColumns.add(column);
+            return this;
+        }
+
         /**
          * This method actually constructs the table by creating an TableDisplay object.
          * @return The table view, represented using an TableDisplay object.
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/CreatePlayerView.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/CreatePlayerView.java
index b7eb60f988d387c435faa4081d2f3c6ae4aa3d2d..30947754877071704ec83cfa210b0d0ff006d75e 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/CreatePlayerView.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/CreatePlayerView.java
@@ -19,18 +19,26 @@ import javafx.scene.control.Button;
 import javafx.scene.control.TextField;
 import javafx.scene.image.*;
 import javafx.scene.layout.BorderPane;
-import javafx.scene.layout.HBox;
 import javafx.scene.layout.VBox;
 import javafx.scene.text.Font;
 import javafx.scene.text.FontWeight;
 import javafx.scene.text.Text;
 
+/**
+ * The view for creating a player. This view therefore contains the character layout implementation and pop-ups
+ * for goals and stats.
+ *
+ * @author Trym Hamer Gudvangen
+ */
 public class CreatePlayerView extends View<BorderPane> {
 
     private final CreatePlayerController createPlayerController;
     private TextField nameField;
     private Button continueButton, returnButton;
 
+    /**
+     * Creates the view for creating a player.
+     */
     public CreatePlayerView() {
         super(BorderPane.class);
         createPlayerController = new CreatePlayerController();
@@ -73,9 +81,9 @@ public class CreatePlayerView extends View<BorderPane> {
         VBox leftVBox = new VBox(statsButton, goalsButton);
         leftVBox.setSpacing(20);
         leftVBox.setPadding(new Insets(300, 20, 0, 20));
-        HBox leftHBox = new HBox(leftVBox);
-        leftHBox.setAlignment(Pos.CENTER_LEFT);
-        getParentPane().setLeft(leftHBox);
+        leftVBox.setAlignment(Pos.CENTER);
+        getParentPane().setLeft(leftVBox);
+        getParentPane().getLeft().setTranslateY(-200);
 
         statsButton.setOnAction(e -> new StatsPopUp());
 
@@ -112,13 +120,13 @@ public class CreatePlayerView extends View<BorderPane> {
         nameField.setMinWidth(200);
 
         continueButton = new Button("Continue");
-        returnButton = new Button("Return");
-        HBox viewButtons = new HBox(returnButton, continueButton);
-        returnButton.setAlignment(Pos.CENTER_LEFT);
-        continueButton.setAlignment(Pos.CENTER_RIGHT);
-        viewButtons.setSpacing(200);
+        returnButton = new Button("Back");
 
-        VBox bottomBox = new VBox(nameField, viewButtons);
+        getParentPane().setBottom(returnButton);
+        getParentPane().getBottom().setTranslateY(-50);
+        getParentPane().getBottom().setTranslateX(10);
+
+        VBox bottomBox = new VBox(nameField, continueButton);
         bottomBox.setSpacing(20);
         bottomBox.setAlignment(Pos.CENTER);
         bottomBox.setPadding(new Insets(0, 0, 0, 0));
@@ -159,7 +167,7 @@ public class CreatePlayerView extends View<BorderPane> {
                 ImageView characterImageView = new ImageView(characterImage);
                 INSTANCE.setCharacterImageView(characterImageView);
 
-                createPlayerController.goTo(NewGameView.class).handle(event);
+                createPlayerController.goTo(LoadGameView.class).handle(event);
             } catch (Exception e) {
                 AlertDialog.showWarning(e.getMessage());
             }
@@ -167,6 +175,12 @@ public class CreatePlayerView extends View<BorderPane> {
         returnButton.setOnAction(e -> StageManager.getInstance().goBack());
     }
 
+    /**
+     * Copies the image onto the writable image.
+     * @param image     the image to copy
+     * @param writer    the pixel writer
+     * @param yOffset   the y offset
+     */
     private void copyImageOnto(Image image, PixelWriter writer, int yOffset) {
         PixelReader reader = image.getPixelReader();
         for (int y = 0; y < image.getHeight(); y++) {
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/HelpView.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/HelpView.java
index 715e930126add6ef7e7fc5dcaa394da14d1c6c0c..d4df12b733ef8de4db37e94681b0556c644d8bbb 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/HelpView.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/HelpView.java
@@ -22,6 +22,9 @@ public class HelpView extends View<VBox> {
 
     private final HelpController controller = new HelpController();
 
+    /**
+     * Creates the help page.
+     */
     public HelpView() {
         super(VBox.class);
         VBox parent = getParentPane();
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/NewGameView.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/LoadGameView.java
similarity index 62%
rename from src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/NewGameView.java
rename to src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/LoadGameView.java
index e4a5469cff642c6e9e718b708df66e7649df3c17..a4c2f3ba84ab8c86488377534a1f5b08cfdf3948 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/NewGameView.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/LoadGameView.java
@@ -4,7 +4,7 @@ import static edu.ntnu.idatt2001.group_30.paths.PathsSingleton.INSTANCE;
 
 import edu.ntnu.idatt2001.group_30.paths.controller.NewGameController;
 import edu.ntnu.idatt2001.group_30.paths.controller.StageManager;
-import edu.ntnu.idatt2001.group_30.paths.view.StoryDisplay;
+import edu.ntnu.idatt2001.group_30.paths.view.components.StoryDisplay;
 import edu.ntnu.idatt2001.group_30.paths.view.components.common.DefaultButton;
 import edu.ntnu.idatt2001.group_30.paths.view.components.pop_up.AlertDialog;
 import java.io.File;
@@ -25,19 +25,22 @@ import javafx.stage.FileChooser;
  *
  * @author Trym Hamer Gudvangen
  */
-public class NewGameView extends View<BorderPane> {
+public class LoadGameView extends View<BorderPane> {
 
     private final NewGameController newGameController;
 
     private BorderPane titlePane;
     private VBox buttonVBox;
     private Button startButton;
+    private Button loadButton;
+    private Button newButton;
+    private HBox buttonBox;
 
     /**
      * The constructor of the View class.
      * It creates a new instance of the Pane that the View wraps.
      */
-    public NewGameView() {
+    public LoadGameView() {
         super(BorderPane.class);
         newGameController = new NewGameController();
 
@@ -45,31 +48,46 @@ public class NewGameView extends View<BorderPane> {
 
         VBox mainContainer = createMainContainerVBox(titlePane);
 
+        if (INSTANCE.getStory() != null) {
+            try {
+                addStoryPane();
+            } catch (IOException e) {
+                AlertDialog.showError(e.getMessage());
+            }
+        }
+
         setupParentPane(mainContainer);
     }
 
+    /**
+     * Adds the story pane to the view.
+     * @param titlePane The title pane of the view.
+     * @return          The main container of the view.
+     */
     private VBox createMainContainerVBox(BorderPane titlePane) {
         VBox mainContainer = new VBox();
         mainContainer.getChildren().addAll(titlePane);
-        mainContainer.setAlignment(Pos.CENTER);
-        mainContainer.setSpacing(40);
+        mainContainer.setAlignment(Pos.TOP_CENTER);
+        mainContainer.setSpacing(100);
 
         Button backButton = new Button("Back");
         backButton.setOnAction(e -> StageManager.getInstance().goBack());
+        getParentPane().setBottom(backButton);
 
         startButton = DefaultButton.medium("Start game", newGameController.goTo(PlaythroughView.class));
         startButton.setVisible(false);
 
-        HBox buttonBox = new HBox(10, backButton, startButton);
-        buttonBox.setAlignment(Pos.CENTER);
-
-        VBox containerWithButtons = new VBox(mainContainer, buttonBox);
+        VBox containerWithButtons = new VBox(mainContainer, startButton);
         containerWithButtons.setSpacing(20);
         containerWithButtons.setAlignment(Pos.CENTER);
 
         return containerWithButtons;
     }
 
+    /**
+     * Sets up the parent pane of the view.
+     * @param mainContainer The main container of the view.
+     */
     private void setupParentPane(VBox mainContainer) {
         getParentPane().setCenter(mainContainer);
         getParentPane().setStyle("-fx-background-color: #f5f5f5");
@@ -80,6 +98,10 @@ public class NewGameView extends View<BorderPane> {
         getParentPane().setPadding(new Insets(20));
     }
 
+    /**
+     * Adds the story pane to the view.
+     * @return  The story pane.
+     */
     private BorderPane createTitlePane() {
         BorderPane titlePane = new BorderPane();
         titlePane.setPadding(new Insets(20));
@@ -89,11 +111,12 @@ public class NewGameView extends View<BorderPane> {
         title.setStyle("-fx-font-size: 20px; -fx-font-weight: bold");
         titlePane.setTop(title);
         BorderPane.setAlignment(title, Pos.TOP_CENTER);
+        titlePane.getTop().setTranslateY(-70);
 
-        Button loadButton = new Button("Load");
-        Button newButton = new Button("New");
+        loadButton = new Button("Load");
+        newButton = new Button("New");
 
-        HBox buttonBox = new HBox(10, loadButton, newButton);
+        buttonBox = new HBox(10, loadButton, newButton);
         buttonBox.setAlignment(Pos.CENTER);
         buttonVBox = new VBox(buttonBox);
         buttonVBox.setAlignment(Pos.CENTER);
@@ -110,29 +133,7 @@ public class NewGameView extends View<BorderPane> {
             if (selectedFile != null) {
                 try {
                     newGameController.setStory(selectedFile);
-                    VBox storyVBox = new StoryDisplay.Builder(INSTANCE.getStory())
-                        .addStoryName()
-                        .addFileInfo(selectedFile)
-                        .build();
-                    storyVBox.setAlignment(Pos.CENTER);
-
-                    Button pencilButton = createIconButton("/images/pencil.png", 16, 16);
-                    Button xButton = createIconButton("/images/remove.png", 16, 16);
-
-                    HBox buttonIcons = new HBox(10, pencilButton, xButton);
-                    buttonIcons.setAlignment(Pos.CENTER_LEFT);
-
-                    VBox storyContainer = new VBox(storyVBox, buttonIcons);
-                    storyContainer.setAlignment(Pos.CENTER);
-
-                    xButton.setOnAction(event -> {
-                        titlePane.getChildren().remove(storyContainer);
-                        titlePane.setCenter(buttonBox);
-                        startButton.setVisible(false);
-                    });
-
-                    titlePane.setCenter(storyContainer);
-                    startButton.setVisible(true);
+                    addStoryPane();
                 } catch (RuntimeException runtimeException) {
                     AlertDialog.showError(runtimeException.getMessage());
                 } catch (IOException ex) {
@@ -141,9 +142,19 @@ public class NewGameView extends View<BorderPane> {
             }
         });
 
+        newButton.setOnAction(newGameController.goTo(NewStoryView.class));
+
+        this.titlePane = titlePane;
         return titlePane;
     }
 
+    /**
+     * Creates an icon button.
+     * @param imagePath The path to the image.
+     * @param width     The width of the image.
+     * @param height    The height of the image.
+     * @return          The button.
+     */
     private Button createIconButton(String imagePath, int width, int height) {
         Button button = new Button();
         URL imageUrl = getClass().getResource(imagePath);
@@ -157,4 +168,38 @@ public class NewGameView extends View<BorderPane> {
         }
         return button;
     }
+
+    /**
+     * Adds the story pane to the view.
+     * @throws IOException  If the story pane cannot be added.
+     */
+    private void addStoryPane() throws IOException {
+        VBox storyVBox = new StoryDisplay.Builder(INSTANCE.getStory())
+            .addStoryName()
+            .addFileInfo(INSTANCE.getStoryFile())
+            .build();
+        storyVBox.setAlignment(Pos.CENTER);
+
+        Button pencilButton = createIconButton("/images/pencil.png", 16, 16);
+        Button xButton = createIconButton("/images/remove.png", 16, 16);
+
+        HBox buttonIcons = new HBox(10, pencilButton, xButton);
+        buttonIcons.setAlignment(Pos.CENTER);
+
+        VBox storyContainer = new VBox(storyVBox, buttonIcons);
+        storyContainer.setAlignment(Pos.CENTER);
+
+        pencilButton.setOnAction(newGameController.goTo(NewStoryView.class));
+
+        xButton.setOnAction(event -> {
+            titlePane.getChildren().remove(storyContainer);
+            titlePane.setCenter(buttonBox);
+            startButton.setVisible(false);
+
+            INSTANCE.setStory(null);
+        });
+
+        titlePane.setCenter(storyContainer);
+        startButton.setVisible(true);
+    }
 }
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/NewStoryView.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/NewStoryView.java
new file mode 100644
index 0000000000000000000000000000000000000000..eedaa1d4d4c259148d1d926a775dab26a37dae03
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/NewStoryView.java
@@ -0,0 +1,188 @@
+package edu.ntnu.idatt2001.group_30.paths.view.views;
+
+import static edu.ntnu.idatt2001.group_30.paths.PathsSingleton.INSTANCE;
+
+import edu.ntnu.idatt2001.group_30.paths.controller.NewStoryController;
+import edu.ntnu.idatt2001.group_30.paths.controller.StageManager;
+import edu.ntnu.idatt2001.group_30.paths.model.Link;
+import edu.ntnu.idatt2001.group_30.paths.model.Passage;
+import edu.ntnu.idatt2001.group_30.paths.model.Story;
+import edu.ntnu.idatt2001.group_30.paths.view.components.common.DefaultText;
+import edu.ntnu.idatt2001.group_30.paths.view.components.pop_up.AlertDialog;
+import edu.ntnu.idatt2001.group_30.paths.view.components.pop_up.PassagePopUp;
+import edu.ntnu.idatt2001.group_30.paths.view.components.table.PassageTable;
+import edu.ntnu.idatt2001.group_30.paths.view.components.table.TableDisplay;
+import java.net.URL;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.geometry.Pos;
+import javafx.scene.control.Button;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TextField;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import javafx.scene.text.Text;
+
+/**
+ * This class contains the view for creating/writing a new story. It, therefore, contains the title and passages.
+ * The passages can be changed and the corresponding object variables such as links and actions can also be changed.
+ *
+ * @author Trym Hamer Gudvangen
+ */
+public class NewStoryView extends View<BorderPane> {
+
+    private final NewStoryController newStoryController;
+    private String title = "";
+    private Story story;
+    private final ObservableList<Passage> passages;
+    private final Button removePassageButton;
+    private final Button editPassageButton;
+
+    /**
+     * The constructor to create the NewStoryView.
+     */
+    public NewStoryView() {
+        super(BorderPane.class);
+        newStoryController = new NewStoryController();
+
+        if (INSTANCE.getStory() != null) {
+            story = INSTANCE.getStory();
+        }
+
+        if (story != null) title = story.getTitle();
+
+        passages =
+            story == null
+                ? FXCollections.observableArrayList()
+                : FXCollections.observableArrayList(story.getPassages());
+        Text titleText = DefaultText.big("Create a new/edit a Story");
+
+        Text labelText = new Text("Story Title: ");
+        TextField textField = new TextField(title);
+        textField.setPromptText("Enter story title");
+
+        HBox titleBox = new HBox(labelText, textField);
+        titleBox.setSpacing(20);
+
+        textField.setOnKeyTyped(event -> title = textField.getText());
+
+        titleBox.setAlignment(Pos.CENTER);
+
+        PassageTable<Passage> passageTable = new PassageTable<>(
+            new TableDisplay.Builder<Passage>()
+                .addColumn("Name of Passage", "title")
+                .addColumn("Passage Content", "content")
+                .addColumnWithComplexValue(
+                    "Links",
+                    passage ->
+                        passage == null
+                            ? null
+                            : passage.getLinks().stream().map(Link::getText).collect(Collectors.joining(", "))
+                )
+        );
+
+        passageTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
+        passageTable.setItems(passages);
+        passageTable.setMaxWidth(1000);
+
+        removePassageButton = new Button("Remove Passage");
+        removePassageButton.setDisable(true);
+        removePassageButton.setOnAction(e -> {
+            passages.forEach(passage ->
+                passage
+                    .getLinks()
+                    .removeIf(link ->
+                        Objects.equals(
+                            link.getReference(),
+                            passageTable.getSelectionModel().getSelectedItem().getTitle()
+                        )
+                    )
+            );
+            passages.remove(passageTable.getSelectionModel().getSelectedItem());
+        });
+
+        editPassageButton = new Button("Edit Passage");
+        editPassageButton.setDisable(true);
+        editPassageButton.setOnAction(e -> {
+            Passage selectedPassage = passageTable.getSelectionModel().getSelectedItem();
+            if (selectedPassage != null) {
+                Passage updatedPassage = new PassagePopUp(passages, selectedPassage).getPassage();
+                if (updatedPassage != null && !selectedPassage.equals(updatedPassage)) {
+                    passages.forEach(passage ->
+                        passage
+                            .getLinks()
+                            .replaceAll(link ->
+                                link.getReference().equals(selectedPassage.getTitle())
+                                    ? new Link(link.getText(), updatedPassage.getTitle())
+                                    : link
+                            )
+                    );
+                    passages.remove(selectedPassage);
+                    passages.add(updatedPassage);
+                }
+            }
+        });
+
+        passageTable
+            .getSelectionModel()
+            .selectedItemProperty()
+            .addListener((obs, oldSelection, newSelection) -> {
+                removePassageButton.setDisable(newSelection == null);
+                editPassageButton.setDisable(newSelection == null);
+            });
+
+        Button addPassageButton = new Button();
+        URL imageUrl = getClass().getResource("/images/plus.png");
+        if (imageUrl != null) {
+            ImageView addIcon = new ImageView(new Image(imageUrl.toString()));
+            addIcon.setFitHeight(25);
+            addIcon.setFitWidth(25);
+            addPassageButton.setGraphic(addIcon);
+        } else {
+            System.err.println("Something is wrong with the trash image resource link");
+        }
+
+        VBox editTableButtons = new VBox(addPassageButton, removePassageButton, editPassageButton);
+        editTableButtons.setAlignment(Pos.CENTER);
+        editTableButtons.setSpacing(20);
+
+        addPassageButton.setOnAction(event -> {
+            if (passages.isEmpty()) {
+                AlertDialog.showInformation(
+                    "Every story needs an opening passage.",
+                    "The opening passage" + " will by default be the first passage added."
+                );
+            }
+            PassagePopUp passagePopUp = new PassagePopUp(passages);
+            if (passagePopUp.getPassage() != null) this.passages.addAll(passagePopUp.getPassage());
+        });
+
+        Button saveButton = new Button("Save Story");
+        saveButton.setOnAction(event -> {
+            try {
+                newStoryController.addStory(title, passages);
+                StageManager.getInstance().setCurrentView(new LoadGameView());
+            } catch (Exception ex) {
+                AlertDialog.showWarning(ex.getMessage());
+            }
+        });
+
+        VBox display = new VBox(titleText, titleBox, passageTable, saveButton);
+        display.setAlignment(Pos.CENTER);
+        display.setSpacing(10);
+        display.setPrefWidth(500);
+
+        Button backButton = new Button("Back");
+        backButton.setOnAction(newStoryController.goBack());
+
+        getParentPane().setCenter(display);
+        getParentPane().setBottom(backButton);
+        getParentPane().setRight(editTableButtons);
+        getParentPane().getRight().setTranslateX(-50);
+    }
+}
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/PlaythroughView.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/PlaythroughView.java
index 09598a34a33ca34dd5868ab09a900217e393942d..0f9da678288c54ba019f4258fe16e8c9203c1363 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/PlaythroughView.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/PlaythroughView.java
@@ -1,6 +1,6 @@
 package edu.ntnu.idatt2001.group_30.paths.view.views;
 
-import edu.ntnu.idatt2001.group_30.paths.controller.PlaytroughController;
+import edu.ntnu.idatt2001.group_30.paths.controller.PlaythroughController;
 import edu.ntnu.idatt2001.group_30.paths.model.Link;
 import edu.ntnu.idatt2001.group_30.paths.model.PlaythroughState;
 import edu.ntnu.idatt2001.group_30.paths.model.goals.Goal;
@@ -35,7 +35,7 @@ import javafx.scene.text.Text;
  */
 public class PlaythroughView extends View<VBox> {
 
-    private final PlaytroughController controller;
+    private final PlaythroughController controller;
 
     /**
      * Creates a new instance of the view.
@@ -44,7 +44,7 @@ public class PlaythroughView extends View<VBox> {
      */
     public PlaythroughView() {
         super(VBox.class);
-        controller = new PlaytroughController();
+        controller = new PlaythroughController();
 
         /*
          * The view is divided into three parts:
@@ -54,7 +54,7 @@ public class PlaythroughView extends View<VBox> {
          * |                                    |  player & game  |
          * |                                    |       info      |
          * |                                    | --------------- |
-         * |          play-trough window        |      goals      |
+         * |          play-through window       |      goals      |
          * |                                    | --------------- |
          * |                                    |    inventory    |
          * |                                    |                 |
@@ -317,9 +317,9 @@ public class PlaythroughView extends View<VBox> {
         content.setSpacing(20);
         content.setPadding(new Insets(0, 0, 0, 20));
 
-        ObservableMap<Goal, Boolean> goals = controller.getGoals();
+        ObservableMap<Goal<?>, Boolean> goals = controller.getGoals();
         goals.addListener(
-            (MapChangeListener<Goal, Boolean>) change -> {
+            (MapChangeListener<Goal<?>, Boolean>) change -> {
                 showGoals(goals, content);
             }
         );
@@ -388,7 +388,7 @@ public class PlaythroughView extends View<VBox> {
      * @param goals The goals to show.
      * @param content The pane to show the goals in.
      */
-    private void showGoals(ObservableMap<Goal, Boolean> goals, Pane content) {
+    private void showGoals(ObservableMap<Goal<?>, Boolean> goals, Pane content) {
         content.getChildren().clear();
         goals.forEach((goal, completed) -> {
             HBox goalBox = new HBox();
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/View.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/View.java
index 0ba45db74582e52ac25b7b09f433cb7dc6d7e523..e549e73a5ab571aae955301d855b93469f3804ab 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/View.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/View.java
@@ -7,7 +7,6 @@ import java.util.Objects;
 import javafx.scene.Node;
 import javafx.scene.Scene;
 import javafx.scene.layout.*;
-import javafx.scene.shape.SVGPath;
 
 /**
  * A View is a wrapper for a JavaFX Pane.
@@ -40,7 +39,6 @@ public class View<T extends Pane> {
         } catch (
             InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e
         ) {
-            //TODO: better error handling
             e.printStackTrace();
         }
     }
diff --git a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/ViewFactory.java b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/ViewFactory.java
index ce9cabadbe943f5063446ede9b28fa1894fc4ae0..9674ac5f1536e3f4d80b3f4cfe498d80661cb24b 100644
--- a/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/ViewFactory.java
+++ b/src/main/java/edu/ntnu/idatt2001/group_30/paths/view/views/ViewFactory.java
@@ -2,8 +2,17 @@ package edu.ntnu.idatt2001.group_30.paths.view.views;
 
 import java.lang.reflect.InvocationTargetException;
 
+/**
+ * A factory for creating views.
+ */
 public class ViewFactory {
 
+    /**
+     * Given a class of a view, this method creates an instance of that view.
+     * @param viewClass The class of the view to be created.
+     * @return          An instance of the view.
+     * @param <T>       The type of the view.
+     */
     public static <T extends View<?>> T createView(Class<T> viewClass) {
         try {
             return viewClass.getDeclaredConstructor().newInstance();
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index e7626c24e21cbd777c172d66d1187bf7486cb596..566bcec21c7ba5336dc035ea8de557aadf69cf00 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -6,6 +6,7 @@ module edu.ntnu.idatt2001.group_30.paths {
     exports edu.ntnu.idatt2001.group_30.paths.view;
     exports edu.ntnu.idatt2001.group_30.paths.model;
     exports edu.ntnu.idatt2001.group_30.paths.model.goals;
+    exports edu.ntnu.idatt2001.group_30.paths.model.actions;
     exports edu.ntnu.idatt2001.group_30.paths.view.components;
     exports edu.ntnu.idatt2001.group_30.paths.view.components.common;
     exports edu.ntnu.idatt2001.group_30.paths.view.components.pane;
diff --git a/src/main/resources/stylesheet.css b/src/main/resources/stylesheet.css
index 2d16dd20a814676381d110b5100cdbcad85c47eb..8aeae865e557fef7f334a291f96731308bd7f609 100644
--- a/src/main/resources/stylesheet.css
+++ b/src/main/resources/stylesheet.css
@@ -1,10 +1,36 @@
+* {
+    /*-fx-font-family: Arial;*/
+    -fx-transition: all 0.3s ease-in-out;
+}
+
 .border-pane {
     background-color: #f5f5f5;
 }
 
+.label {
+    -fx-font-size: 14px;
+    -fx-font-weight: bold;
+    -fx-padding: 5px;
+}
+
+.text-field {
+    -fx-padding: 8px;
+    -fx-border-color: #ccc;
+    -fx-border-width: 1px;
+    -fx-border-radius: 5px;
+}
+
+
+.text-field:focused {
+    -fx-border-color: #0077ff;
+}
+
+
+
 #title {
-    -fx-font-size: 20px;
+    -fx-font-size: 22px;
     -fx-font-weight: bold;
+    -fx-color: #2c3e50;
 }
 
 #player-container, #goal-container {
@@ -75,7 +101,6 @@ Button {
     -fx-border-color: #303f9f;
     -fx-border-width: 1px;
     -fx-padding: 10 20;
-    -fx-font-weight: bold;
 }
 
 Button:hover {
diff --git a/src/test/java/edu/ntnu/idatt2001/group_30/paths/model/GameTest.java b/src/test/java/edu/ntnu/idatt2001/group_30/paths/model/GameTest.java
index 7c6cdd07e3a182b89bc5350d3fa10daf6c039b82..093517875e56dcadcc3b7817896dc990b3209219 100644
--- a/src/test/java/edu/ntnu/idatt2001/group_30/paths/model/GameTest.java
+++ b/src/test/java/edu/ntnu/idatt2001/group_30/paths/model/GameTest.java
@@ -22,7 +22,7 @@ public class GameTest {
         Passage attackPassage;
 
         Story story;
-        List<Goal> goals;
+        List<Goal<?>> goals;
 
         @BeforeEach
         void setup() {
diff --git a/src/test/java/edu/ntnu/idatt2001/group_30/paths/model/PlaythroughTest.java b/src/test/java/edu/ntnu/idatt2001/group_30/paths/model/PlaythroughTest.java
index fd49df0b77d10fee055a9072165ac5806dd63a88..d90ddb67c9bdb85ec0620905778dfc576218d61b 100644
--- a/src/test/java/edu/ntnu/idatt2001/group_30/paths/model/PlaythroughTest.java
+++ b/src/test/java/edu/ntnu/idatt2001/group_30/paths/model/PlaythroughTest.java
@@ -18,7 +18,7 @@ class PlaythroughTest {
         openingPassage = new Passage("Opening passage", "This is the opening passage");
         Player player = new Player("Player", 10, 20, 30);
         Story story = new Story("My story", openingPassage);
-        List<Goal> goals = List.of(new GoldGoal(50));
+        List<Goal<?>> goals = List.of(new GoldGoal(50));
         Game game = new Game(player, story, goals);
 
         playthrough = new Playthrough(game);
diff --git a/src/test/java/edu/ntnu/idatt2001/group_30/paths/model/filehandling/StoryFileWriterImplTest.java b/src/test/java/edu/ntnu/idatt2001/group_30/paths/model/filehandling/StoryFileWriterImplTest.java
index d6815495ee00802ed3a0bc64e5d0f9c02c2c5161..0adf5335ce2c7717b5f744bd193f3708e668d228 100644
--- a/src/test/java/edu/ntnu/idatt2001/group_30/paths/model/filehandling/StoryFileWriterImplTest.java
+++ b/src/test/java/edu/ntnu/idatt2001/group_30/paths/model/filehandling/StoryFileWriterImplTest.java
@@ -220,7 +220,7 @@ public class StoryFileWriterImplTest {
             Assertions.assertThrows(
                 NullPointerException.class,
                 () -> {
-                    storyFileWriter.create(story, null);
+                    storyFileWriter.create(story, (String) null);
                 }
             );
         }