diff --git a/package-lock.json b/package-lock.json
index f31fe0dd9e292d8ec743b4656061f1b3d48800cb..2f42109d43a5019d739101a7592ffa99555318a0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -909,6 +909,11 @@
         }
       }
     },
+    "svelte-local-storage-store": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/svelte-local-storage-store/-/svelte-local-storage-store-0.1.4.tgz",
+      "integrity": "sha512-XlSJqMdV1UAROsKHYQSKwI9xU0u8En/nQ6ti2flmUhBA0PM+oqXjvCyM2849ONb5JbrpyUO18CwXcSJgxYCR8w=="
+    },
     "svelte-preprocess": {
       "version": "4.6.9",
       "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-4.6.9.tgz",
diff --git a/package.json b/package.json
index 1021f27c0e212f20bacb84a9237fe46d8a785332..2759372b8821aa25137ac06d695f3eb9d79205f3 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
     "typescript": "^4.0.0"
   },
   "dependencies": {
-    "sirv-cli": "^1.0.0"
+    "sirv-cli": "^1.0.0",
+    "svelte-local-storage-store": "^0.1.4"
   }
 }
diff --git a/public/dialogs/ftb.json b/public/dialogs/ftb.json
index 199f61b10f9d61f9e1967948cb57fd7723d2906a..7eb51596bc184505ca893851b2abe28568a92496 100644
--- a/public/dialogs/ftb.json
+++ b/public/dialogs/ftb.json
@@ -1,30 +1,86 @@
 {
+  "title": "Frank Thorsten Breuer – Studienkoordinator",
+  "imageUrl": "./Breuer_Frank_Thorsten.jpg",
   "startDialogName": "start",
   "dialogs": {
     "start": {
-      "title": "Frank Thorsten Breuer – Studienkoordinator",
-      "imageUrl": "./Breuer_Frank_Thorsten.jpg",
-      "text": "Hallo, kann ich etwas für sie tun?",
+      "text": "",
       "options": [
         {
           "text": "Hallo Herr Breuer, ich grüße sie recht herzlich!",
           "linksToDialog": "greetBreuer"
         },
+        {
+          "text": "Geht es ihnen gut? Sie sehen etwas bleich aus.",
+          "linksToDialog": "mayIBringSomething",
+          "forbiddenFacts": ["acceptedFtbMateQuest"]
+        },
+        {
+          "text": "Ich habe ihnen ihre Mate gebracht!",
+          "linksToDialog": "giveMate",
+          "requiredFacts": ["collectedFtbMate"],
+          "forbiddenFacts": ["completedFtbMateQuest"]
+        },
         {
           "text": "Hallo, ich suche den Hörsaal E23",
+          "forbiddenFacts": ["askedFtbForHs"],
           "linksToDialog": "seekHS"
         }
       ]
     },
+    "mayIBringSomething": {
+      "text": "Oh ja!\nIch verdurste fast, könnten sie mir eine Mate bringen?\nIch kann hier leider erstmal nicht weg und das selbst tun, zu viel Arbeit...",
+      "options": [
+        {
+          "text": "Klar, warum nicht.",
+          "linksToDialog": "acceptFtbMateQuest"
+        },
+        {
+          "text": "Danke, kein Interesse",
+          "linksToDialog": "rejectFtbMateQuest"
+        }
+      ]
+    },
+    "giveMate": {
+      "text": "Ah, das tut gut. Vielen Dank, das war jetzt nötig. Sie haben was gut bei mir.",
+      "addFacts": ["completedFtbMateQuest"],
+      "options": [
+        {
+          "text": "Gern geschehen.",
+          "linksToDialog": "start"
+        }
+      ]
+    },
+    "acceptFtbMateQuest": {
+      "text": "Ich danke ihnen. Der Kiosk ist direkt links, wenn sie in den Fachschaftsflur kommen. Das ist der Gang auf rechten Seite von der Eingangstür.",
+      "addFacts": ["acceptedFtbMateQuest"],
+      "options": [
+        {
+          "text": "Ok",
+          "linksToDialog": "start"
+        }
+      ]
+    },
+    "rejectFtbMateQuest": {
+      "text": "Schade. Sollten sie sich noch umentscheiden, melden sie sich gerne bei mir.",
+      "options": [
+        {
+          "text": "Ok",
+          "linksToDialog": "start"
+        }
+      ]
+    },
     "seekHS": {
-      "title": "Frank Thorsten Breuer – Studienkoordinator",
-      "imageUrl": "./Breuer_Frank_Thorsten.jpg",
       "text": "Da müssen sie den Flur wieder zurück gehen und im Foyer nach hinten durchgehen. Den Hörsaal erkennen sie an der großen Doppeltür",
-      "options": []
+      "addFacts": ["askedFtbForHs"],
+      "options": [
+        {
+          "text": "Ah, danke",
+          "linksToDialog": "start"
+        }
+      ]
     },
     "greetBreuer": {
-      "title": "Frank Thorsten Breuer – Studienkoordinator",
-      "imageUrl": "./Breuer_Frank_Thorsten.jpg",
       "text": "Ich grüße sie auch recht herzlich, studieren sie zufälligerweise Informatik?",
       "options": [
         {
@@ -38,29 +94,22 @@
       ]
     },
     "longTimeStudent": {
-      "title": "Frank Thorsten Breuer – Studienkoordinator",
-      "imageUrl": "./Breuer_Frank_Thorsten.jpg",
       "text": "Dann sollten sie mal schnell weiter studieren gehen!",
       "options": []
     },
     "startedToStudy": {
-      "title": "Frank Thorsten Breuer – Studienkoordinator",
-      "imageUrl": "./Breuer_Frank_Thorsten.jpg",
-      "text": "Wunderbar, ich kann deine, verzeihung, ich darf sie doch duzen, oder?\\n\\nAlso ich brauche deine Hilfe. Der Studiengang Informatik muss regelmäßig akkreditiert werden, damit wir ihn weiter anbieten dürfen. Jetzt haben leider die verdammten Studenten von der Fachschaft in den letzten genehnmigten Studienplan das Modul \"Angewandte Chaostheorie\" hineingeschmuggelt. Das ist bei uns leider niemanden aufgefallen, der Akkreditierungskommission vom Bildungsministerium aber schon. Wenn wir nicht bald nachweisen können, dass jemand dieses Modul auch belegt und erfolgreich abgeschlossen hat, wird uns die Akkreditierung entzogen und der Informatik-Studiengang muss eingestellt werden. Ich bitte sie, helfen sie mir!",
+      "text": "Wunderbar, ich kann deine, verzeihung, ich darf sie doch duzen, oder?\nAlso ich brauche deine Hilfe. Der Studiengang Informatik muss regelmäßig akkreditiert werden, damit wir ihn weiter anbieten dürfen. Jetzt haben leider die verdammten Studenten von der Fachschaft in den letzten genehnmigten Studienplan das Modul \"Angewandte Chaostheorie\" hineingeschmuggelt. Das ist bei uns leider niemanden aufgefallen, der Akkreditierungskommission vom Bildungsministerium aber schon. Wenn wir nicht bald nachweisen können, dass jemand dieses Modul auch belegt und erfolgreich abgeschlossen hat, wird uns die Akkreditierung entzogen und der Informatik-Studiengang muss eingestellt werden. Ich bitte sie, helfen sie mir!",
+      "addFacts": ["acceptedMainQuest"],
       "options": [
         { "text": "Ich helfe gerne!", "linksToDialog": "agreeToHelp" },
         { "text": "Was geht mich das denn an?", "linksToDialog": "denyHelp" }
       ]
     },
     "denyHelp": {
-      "title": "Frank Thorsten Breuer – Studienkoordinator",
-      "imageUrl": "./Breuer_Frank_Thorsten.jpg",
       "text": "Schade, ich dachte sie hätten das Zeug dazu. Nun gut, gehen sie studieren, ich finde schon selbst eine Lösung.",
       "options": []
     },
     "agreeToHelp": {
-      "title": "Frank Thorsten Breuer – Studienkoordinator",
-      "imageUrl": "./Breuer_Frank_Thorsten.jpg",
       "text": "Wunderbar, sobald mehr Story geschrieben wurde, erhalten sie hier eine epische Quest um die Fakultät vor Schmach und Schande zu retten.",
       "options": []
     }
diff --git a/public/index.html b/public/index.html
index bdda1cf5fb35225395f6160fd3d432651b8c3926..80aa7cdeb8fcac62033133fdb714642cc7b117c1 100644
--- a/public/index.html
+++ b/public/index.html
@@ -5,7 +5,7 @@
   <meta charset="utf-8" />
   <meta name="viewport" content="width=device-width,initial-scale=1" />
 
-  <title>OH14 Workadventure Story</title>
+  <title>OH14 Work Adventure Story</title>
 
   <link rel="icon" type="image/png" href="./favicon.png" />
   <link rel="stylesheet" href="./global.css" />
diff --git a/src/App.svelte b/src/App.svelte
index 2e0ce067e3eba180d8af4cab902f31fb28ab107e..c8348b1e204b4ba9fe3d2d5f4612aea08cd80b5c 100644
--- a/src/App.svelte
+++ b/src/App.svelte
@@ -1,17 +1,23 @@
 <script lang="ts">
   import DialogSetComponent from "./DialogSetComponent.svelte";
   import { fetchDialogSet } from "./utils";
+  import Debugger from "./Debugger.svelte";
+  import type { Dialog } from "./types";
 
   const dialogSetPromise = fetchDialogSet();
+  let currentDialog: Dialog;
 </script>
 
 <main>
   {#await dialogSetPromise then dialogSet}
-    <DialogSetComponent {...dialogSet} />
-  {:catch error}
+    <DialogSetComponent bind:currentDialog={currentDialog} {...dialogSet} />
+
+    <br>
+    <Debugger dialogSet={dialogSet} bind:currentDialog={currentDialog}/>
+  {:catch _error}
     <h3>Oh no :(</h3>
     <p>
-      We could not load that dialogSet that you specified in the url. Sorry.
+      We could not load that dialogSet that you specified in the url. Sorry. Please go complain to your friendly admin(s).
     </p>
   {/await}
 </main>
diff --git a/src/Debugger.svelte b/src/Debugger.svelte
new file mode 100644
index 0000000000000000000000000000000000000000..4361433f9e0b80ec63eb3f6677238658613329d8
--- /dev/null
+++ b/src/Debugger.svelte
@@ -0,0 +1,60 @@
+<script lang="ts">
+  import { gameFactsStore, addGameFactToFactArray, toggleFactInFactArray } from './gameFacts'
+  import type { Dialog, DialogMap, DialogSet, FactId } from './types';
+  
+  export let currentDialog: Dialog;
+  export let dialogSet: DialogSet;
+  $: dialogNames = Object.keys(dialogSet.dialogs)
+  export let selectedDialogName: string
+
+  function getDialogFacts(dialogMap: DialogMap): FactId[] {
+      const dialogs = [];
+      for (const dmKey of Object.keys(dialogMap)) dialogs.push(dialogMap[dmKey]);
+      return dialogs.map(dialog => [...(dialog.addFacts || []), ...(dialog.removeFacts || [])]).flat()
+  }
+
+  let seenFactIds = new Set<FactId>([...$gameFactsStore, ...getDialogFacts(dialogSet.dialogs)]);
+  $: seenFactIdsArray = Array.from(seenFactIds)
+  let addFactInputValue: string;
+</script>
+
+<div>
+    <h3>Dialog-Debugger</h3>
+    Jump to dialog:
+    <!-- svelte-ignore a11y-no-onchange -->
+    <select bind:value={selectedDialogName} on:change="{() => currentDialog = dialogSet.dialogs[selectedDialogName]}">
+		{#each dialogNames as dialogName}
+			<option value={dialogName} selected={dialogName === selectedDialogName}>
+				{dialogName}
+			</option>
+		{/each}
+	</select>
+    <hr>
+
+    <h3>Quest-Debugger</h3>
+    <b>GameFacts:</b>
+    <ul>
+        {#each seenFactIdsArray as gameFact}
+            <li>
+                <input type="checkbox" checked={$gameFactsStore.includes(gameFact)} on:change={() => gameFactsStore.set(toggleFactInFactArray(gameFact, $gameFactsStore))}>
+                {gameFact}
+            </li>
+        {/each}
+    </ul>
+    Add fact:
+    <input type="text" bind:value={addFactInputValue}>
+    <button style="width: 3rem;" on:click={() => {
+        gameFactsStore.set(addGameFactToFactArray(addFactInputValue, $gameFactsStore));
+        seenFactIds = seenFactIds.add(addFactInputValue);
+        addFactInputValue = '';
+    }}>Add</button>
+
+</div>
+
+<style>
+    div {
+        border: 1px solid;
+        padding: 10px;
+        margin: 5px;
+    }
+</style>
\ No newline at end of file
diff --git a/src/DialogSetComponent.svelte b/src/DialogSetComponent.svelte
index 77a84d3b10feb297e9e381fd1fb105fe6c19c687..bb0977b8e6406476467613a82f93abc51f854fbc 100644
--- a/src/DialogSetComponent.svelte
+++ b/src/DialogSetComponent.svelte
@@ -1,10 +1,12 @@
 <script lang="ts">
   import SingleDialogComponent from "./SingleDialogComponent.svelte";
   import type { DialogMap } from "./types";
+  export let title: string;
+  export let imageUrl: string;
   export let startDialogName: string;
   export let dialogs: DialogMap;
 
-  let currentDialog = dialogs[startDialogName];
+  export let currentDialog = dialogs[startDialogName];
 
   function switchDialog(targetDialog: string) {
     currentDialog = dialogs[targetDialog];
@@ -19,6 +21,6 @@
 </script>
 
 <SingleDialogComponent
-  {...currentDialog}
+  imageUrl={imageUrl} title={title} {...currentDialog} 
   on:switchToDialog={(event) => switchDialog(event.detail)}
 />
diff --git a/src/SingleDialogComponent.svelte b/src/SingleDialogComponent.svelte
index f8970827b5bb0f844325f75beb3e9c98805b947a..7ba0fff3e2509e652a02837c4588d4b6d8eed616 100644
--- a/src/SingleDialogComponent.svelte
+++ b/src/SingleDialogComponent.svelte
@@ -1,13 +1,53 @@
 <script lang="ts">
-  import type { DialogOption } from "./types";
+  import type { DialogOption, FactId } from "./types";
   import { createEventDispatcher } from "svelte";
+  import { gameFactsStore, addGameFactToFactArray } from './gameFacts'
 
   const dispatch = createEventDispatcher();
 
   export let imageUrl: string;
   export let title: string | undefined;
   export let text: string;
-  export let options: DialogOption[];
+  export let options: DialogOption[] = [];
+  $: usableOptions = options.filter(option => isDialogOptionAllowedByGameFacts(option, $gameFactsStore))
+  export let addFacts: FactId[] = [];
+  $: {
+    if (Array.isArray(addFacts)) {
+      const gameFactsAfterAddedFacts = addFacts.reduce((accFacts, factToAdd) => addGameFactToFactArray(factToAdd, accFacts), $gameFactsStore)
+      $gameFactsStore = gameFactsAfterAddedFacts;
+    }
+  }
+  export let removeFacts: FactId[] = [];
+  $: {
+    if (Array.isArray(removeFacts)) {
+      const gameFactsAfterRemovedFacts = removeFacts.reduce((accFacts, factToRemove) => accFacts.filter(f => f !== factToRemove), $gameFactsStore)
+      $gameFactsStore = gameFactsAfterRemovedFacts;
+    }
+  }
+
+  function isDialogOptionAllowedByGameFacts(option: DialogOption, gameFacts: FactId[]): boolean {
+    // Check if all required facts are given
+    if (Array.isArray(option.requiredFacts)) {
+      const isOk = option.requiredFacts.every(requiredFact => gameFacts.includes(requiredFact));
+      if (!isOk) {
+        return false;
+      }
+    }
+
+    // Check if no forbidden facts are given
+    if (Array.isArray(option.forbiddenFacts)) {
+      const isOk = option.forbiddenFacts.every(forbiddenFact => !gameFacts.includes(forbiddenFact));
+      if (!isOk) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  function handleDialogOptionClick(option: DialogOption): void {
+    dispatch("switchToDialog", option.linksToDialog)
+  }
 </script>
 
 {#if typeof title === "string"}
@@ -19,16 +59,16 @@
 <img src={imageUrl} alt="Portrait" />
 
 <div>
-  {#each text.split("\n\n") as para}
+  {#each text.split("\n") as para}
     <p>{para}</p>
   {/each}
 </div>
 <hr />
 <div>
-  {#each options as option}
-    <button on:click={() => dispatch("switchToDialog", option.linksToDialog)}
-      >{option.text}</button
-    >
+  {#each usableOptions as option}
+    <button on:click={() => handleDialogOptionClick(option)}>
+      {option.text}
+    </button>
     <br />
   {/each}
 </div>
diff --git a/src/gameFacts.ts b/src/gameFacts.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c7b271402ec09349209ac79a2fee8cf13ffeb028
--- /dev/null
+++ b/src/gameFacts.ts
@@ -0,0 +1,29 @@
+import { writable } from "svelte-local-storage-store";
+import type { Writable } from "svelte/store";
+import type { FactId } from "./types";
+
+export const gameFactsStore: Writable<FactId[]> = writable("gameFacts", [
+  "debugRequiredFact",
+]);
+
+export function addGameFactToFactArray(
+  gameFact: FactId,
+  factArray: FactId[]
+): FactId[] {
+  if (!factArray.includes(gameFact)) {
+    return [...factArray, gameFact];
+  } else {
+    return factArray;
+  }
+}
+
+export function toggleFactInFactArray(
+  gameFact: FactId,
+  factArray: FactId[]
+): FactId[] {
+  if (!factArray.includes(gameFact)) {
+    return [...factArray, gameFact];
+  } else {
+    return factArray.filter((f) => f !== gameFact);
+  }
+}
diff --git a/src/types.ts b/src/types.ts
index 6c7b222d610787b6c3482917b8c02ba62fac27e4..27d90abba23de3c15c1fe6b96720baa8247b31d1 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -1,4 +1,6 @@
 export interface DialogSet {
+  title?: string;
+  imageUrl: string;
   startDialogName: string;
   dialogs: DialogMap;
 }
@@ -8,13 +10,19 @@ export type DialogMap = {
 };
 
 export interface Dialog {
-  imageUrl: string;
-  title?: string;
-  text: string;
+  title?: string; // Can be used to overwrite title from DialogSet
+  imageUrl?: string; // Can be used to overwrite imageUrl from DialogSet
+  text?: string;
   options: DialogOption[];
+  addFacts?: FactId[];
+  removeFacts?: FactId[];
 }
 
 export interface DialogOption {
   text: string;
   linksToDialog: string;
+  requiredFacts?: FactId[];
+  forbiddenFacts?: FactId[];
 }
+
+export type FactId = String;