diff --git a/.gitignore b/.gitignore
index e327c84..4952917 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,3 @@ Thumbs.db
# Nextcloud sync
.sync-exclude.lst
-
-# Build artifacts (kept on disk for the submission ZIP, not in git)
-release/*.jar
diff --git a/Semesterprojekt/.gitignore b/Semesterprojekt/.gitignore
index 7b46e53..7b5e9a1 100644
--- a/Semesterprojekt/.gitignore
+++ b/Semesterprojekt/.gitignore
@@ -45,3 +45,6 @@ saves/
# src/main/resources/music/ is tracked and bundled. Anchored so it
# ignores the top-level source folder but not the resources path.
/music/
+
+# Built jars (kept on disk for the submission ZIP, not tracked)
+release/*.jar
diff --git a/Semesterprojekt/docs/README.md b/Semesterprojekt/docs/README.md
index 5112969..0d7d32f 100644
--- a/Semesterprojekt/docs/README.md
+++ b/Semesterprojekt/docs/README.md
@@ -1,33 +1,36 @@
# Semesterprojekt – Textadventure
-Design- und Architekturdokumentation. Dient als Spec während der Implementierung.
+Design- und Architekturdokumentation. Bedienung und Build stehen im
+[Haupt-README](../README.md).
## Inhalt
| Datei | Inhalt |
|---|---|
| [architecture.md](architecture.md) | Package-Struktur, Schichten, DTO-vs-Domain-Trennung |
-| [conventions.md](conventions.md) | Sprache, ID-Format, Naming, Lombok-Cheatsheet |
| [data-structures.md](data-structures.md) | Alle gewählten Collection-Typen mit Begründung |
+| [conventions.md](conventions.md) | Sprache, ID-Format, Naming, Lombok-Cheatsheet |
| [item-model.md](item-model.md) | Item-Hierarchie (abstract + 3 Subtypen), Lombok-Inheritance |
-| [yaml-schemas.md](yaml-schemas.md) | Schemas für `items.yaml`, `rooms.yaml`, `npcs.yaml`, `game.yaml` |
-| [loading-flow.md](loading-flow.md) | Lade-Reihenfolge, Referenz-Auflösung, Validierung |
| [commands.md](commands.md) | Befehlsparser, Command-Pattern, Befehlsliste |
| [npcs.md](npcs.md) | NPC-Modell, Talk- und Give-Interaktion |
-| [implementation-status.md](implementation-status.md) | Aktueller Stand, Phasen-Checkliste, festgelegte Entscheidungen |
+| [yaml-schemas.md](yaml-schemas.md) | Schemas der YAML-Dateien unter `resources/world/` |
+| [loading-flow.md](loading-flow.md) | Lade-Reihenfolge, Referenz-Auflösung, Validierung |
+| [music.md](music.md) | Hintergrundmusik in der GUI (Bonus) |
## Pflicht vs. Optional (laut Aufgabenstellung)
-- **Pflicht:** ≥4 Räume mit Navigation, ≥3 Gegenstände mit Inventar
-- **Optional/Bonus:** NPCs, Swing-GUI
+- **Pflicht:** ≥ 4 Räume mit Navigation, ≥ 3 Gegenstände mit Inventar —
+ erfüllt mit 14 Räumen und 19 Gegenständen.
+- **Optional/Bonus:** NPCs (3) und Swing-GUI — beides umgesetzt.
-Beide optionalen Teile sind hier eingeplant.
+Welche Klasse welche Anforderung umsetzt, steht als Tabelle im
+[Haupt-README](../README.md).
## Technologie-Stack
-- Java 25
-- Jackson (YAML) für Daten-Loading
-- Lombok für Boilerplate-Reduktion
+- Java 21 (LTS)
+- Jackson (YAML) für das Laden der Spielwelt
+- Lombok zur Reduktion von Boilerplate
- JUnit 5 + AssertJ + Mockito für Tests
-- Logback + SLF4J für Logging
-- Swing für GUI (Bonus)
+- SLF4J + Logback für Logging
+- Swing für die GUI (Bonus)
diff --git a/Semesterprojekt/docs/architecture.md b/Semesterprojekt/docs/architecture.md
index 7485f51..9dcda4f 100644
--- a/Semesterprojekt/docs/architecture.md
+++ b/Semesterprojekt/docs/architecture.md
@@ -33,19 +33,22 @@ flowchart LR
model --> item
item --> item_files["Item (abstract)
ReadableItem
SwitchableItem
PlainItem"]
- loader --> loader_files["WorldLoader
ReferenceResolver
WorldValidator"]
+ loader --> loader_files["WorldLoader
ReferenceResolver
WorldValidator
*Factory"]
loader --> dto
- dto --> dto_files["RoomDto, ItemDto,
NpcDto, GameDto"]
+ dto --> dto_files["RoomDto, ItemDto,
NpcDto, GameDto,
QuestDto, EndingDto, …"]
command --> cmd_core["Command (Interface)
CommandRegistry
CommandParser"]
command --> impl
- impl --> impl_files["GoCommand, TakeCommand,
DropCommand, UseCommand,
InventoryCommand, LookCommand,
TalkCommand, GiveCommand,
HelpCommand, QuitCommand"]
+ impl --> impl_files["GoCommand, TakeCommand,
DropCommand, UseCommand,
ReadCommand, ExamineCommand,
InventoryCommand, LookCommand,
TalkCommand, GiveCommand,
MapCommand, QuestsCommand,
SaveCommand, MenuCommand,
HelpCommand"]
- game --> game_files["Game (Loop)
GameContext"]
+ game --> game_files["Game (Loop)
GameContext/Session/State
QuestEngine, EndingEngine,
EscortEngine, Light,
Pathfinder, MapLayout"]
- io --> io_files["GameIO (Interface)
ConsoleIO
SwingIO"]
+ io --> io_files["GameIO (Interface)
ConsoleIO
SwingIO
io.text (Styled Output)"]
```
+> **Hinweis:** Es gibt **keine** `QuitCommand`-Klasse. `quit`/`exit`/`beenden` sind Aliase,
+> die in `App` auf `MenuCommand` registriert werden (siehe `App.play`).
+
## DTO vs. Domain-Trennung
**Kernprinzip:** YAML wird in Records deserialisiert (DTOs), erst danach werden String-IDs zu Objekt-Referenzen aufgelöst.
@@ -67,15 +70,15 @@ flowchart LR
## Game-Loop (vereinfacht)
```java
-while (!game.isOver()) {
- String input = io.read();
+while (running) {
+ String input = io.readLine();
+ if (input == null) break; // EOF
ParsedCommand parsed = parser.parse(input);
- Command cmd = registry.get(parsed.verb());
- if (cmd == null) {
- io.write("Unbekannter Befehl.");
- } else {
- cmd.execute(context, parsed.args());
- }
+ registry.find(parsed.verb()).ifPresentOrElse(
+ cmd -> cmd.execute(ctx, parsed.args()),
+ () -> io.write("I don't understand '" + parsed.verb() + "'."));
+ publishHud(); // Engines ticken, HUD/Map/Quests updaten
+ maybeEnd(); // Ending-Bedingungen prüfen
}
```
@@ -85,9 +88,25 @@ Konsole und GUI teilen sich `GameIO`:
```java
public interface GameIO {
- String read(); // blockierende Leseoperation
- void write(String text);
+ String readLine(); // blockierende Leseoperation
+ void print(StyledText text); // einzige Ausgabe-Primitive
+
+ // Convenience + Presentation-Hooks als default-Methoden:
+ default void write(String text) { … } // Kurzform für ungestylten Text
+ default void showRoom(RoomView v) { … }
+ default void setHud(Hud hud) { … }
+ default void setMap(MapView map) { … }
+ default void setQuests(QuestView quests) { … }
+ default void setMusic(String track) { … }
+ default int choose(String title, List options) { … }
+ default void shutdown() { … }
}
```
-Damit ist der Game-Loop **identisch** für beide Modi. `SwingIO` blockiert intern mit einer `BlockingQueue`, die vom JTextField-ActionListener gefüllt wird.
+Ausgabe läuft **immer** über `print(StyledText)` — eine Liste von `Span`s mit `Style`.
+`ConsoleIO` rendert sie als ANSI-Farben (oder ASCII, je nach Settings), `SwingIO` als
+`StyledDocument` im `JTextPane`. Die `default`-Methoden geben der GUI Extra-Hooks
+(Karte, Quest-Panel, Musik), die die Konsole schlicht ignoriert oder als Text ausgibt.
+
+Damit ist der Game-Loop **identisch** für beide Modi. `SwingIO` blockiert intern mit einer
+`LinkedBlockingQueue`, die vom JTextField-ActionListener gefüllt wird.
diff --git a/Semesterprojekt/docs/conventions.md b/Semesterprojekt/docs/conventions.md
index 573f296..c5611c8 100644
--- a/Semesterprojekt/docs/conventions.md
+++ b/Semesterprojekt/docs/conventions.md
@@ -32,24 +32,28 @@ Geltungsbereich: id ist eindeutig **innerhalb seiner Entitätsart**. Ein Item un
```
thb.jeanluc.adventure
+├── App, AppGui <- Entry Points (Konsole / Swing)
├── model
-│ ├── Direction
-│ ├── Room
-│ ├── Player
-│ ├── Npc
+│ ├── Direction, Room, Player, Npc
+│ ├── Quest, QuestStage, Ending, Combination, Condition, Effect, …
│ └── item <- eigener Subpackage wegen Hierarchie
│ ├── Item (abstract)
│ ├── ReadableItem
│ ├── SwitchableItem
│ └── PlainItem
-├── io
-├── command
-├── game
-└── loader
- └── dto
+├── io <- ConsoleIO, SwingIO, GameIO, Music*, MapPanel, QuestPanel
+│ └── text <- StyledText, Style, Span, Hud, *View (15 Klassen)
+├── command <- Command, CommandParser, CommandRegistry, ParsedCommand
+│ └── impl <- die 15 konkreten Kommandos
+├── game <- Game-Loop, Engines (Quest, Ending, Escort), Light,
+│ Pathfinder, MapLayout, GameState/Session/Context
+├── loader
+│ └── dto <- die YAML-Records
+├── save <- SaveService, SaveCodec, SaveData, Settings*
+└── menu <- MainMenu, SettingsMenu, MenuAction
```
-**Wann ein Subpackage:** wenn eine Klassenfamilie ≥ 3 Klassen umfasst und eine eigene Abstraktion bildet (`item`, evtl. später `command.impl`). Sonst flach lassen.
+**Wann ein Subpackage:** wenn eine Klassenfamilie ≥ 3 Klassen umfasst und eine eigene Abstraktion bildet. Erfüllt von `item` (4), `command.impl` (15), `io.text` (15), `loader.dto` (16), `save` (7), `menu` (3). Sonst flach lassen — `MapLayout` liegt deshalb in `game` neben `Pathfinder` und **nicht** in einem eigenen `map`-Package (eine Klasse reicht nicht).
## Naming
diff --git a/Semesterprojekt/docs/data-structures.md b/Semesterprojekt/docs/data-structures.md
index 3cff7dc..f41629d 100644
--- a/Semesterprojekt/docs/data-structures.md
+++ b/Semesterprojekt/docs/data-structures.md
@@ -15,13 +15,16 @@ Bewusste Wahl jeder Collection — der Dozent bewertet das laut Aufgabenstellung
| Spieler-Inventar | `LinkedHashMap` | O(1) |
| Befehlsregistry | `HashMap` | O(1) |
| NPC-Reaktionen | `HashMap` | O(1) |
-| Eingabehistorie (optional) | `ArrayDeque` | O(1) Front/Back |
+| Besuchte Räume (für die Karte) | `LinkedHashSet` | O(1) + Besuchsreihenfolge |
+| BFS-Queue (Pathfinder, MapLayout) | `ArrayDeque` | O(1) FIFO |
+| BFS-Pfadrekonstruktion | `LinkedList` | O(1) `addFirst` |
+| GUI-Eingabebrücke (EDT → Worker) | `LinkedBlockingQueue` | blockierend, unbegrenzt |
## Begründungen im Detail
### `EnumMap` für Raum-Ausgänge
-- **Direction** ist Enum (`NORTH`, `SOUTH`, `EAST`, `WEST`, evtl. `UP`, `DOWN`)
+- **Direction** ist Enum (`NORTH`, `SOUTH`, `EAST`, `WEST`)
- `EnumMap` ist array-backed, kein Hashing nötig → schneller und kompakter als `HashMap`
- Iteration in Enum-Deklarationsreihenfolge (stabil)
@@ -49,11 +52,19 @@ Entscheidung "keine Stapel" (1 Item pro id) macht das Map-basierte Modell sauber
- Entspricht dem expliziten Tipp aus der Aufgabenstellung
- Vermeidet wachsendes `switch`-Statement
-### `ArrayDeque` für Historie (optional)
+### `ArrayDeque` als BFS-Queue
-- Falls Up-Arrow in der GUI gewünscht oder Befehlsverlauf
-- `ArrayDeque` ist `LinkedList` praktisch immer überlegen (bessere Cache-Lokalität, weniger Overhead)
-- Beidseitige O(1)-Operationen
+- `Pathfinder` (Auto-Travel `go to `) und `MapLayout` (Karten-Layout) sind beides
+ Breitensuchen → brauchen eine **FIFO-Queue**
+- `ArrayDeque` ist die Standardwahl dafür: O(1) an beiden Enden, keine Node-Allokation
+ wie bei `LinkedList`, bessere Cache-Lokalität
+
+### `LinkedList` für die Pfadrekonstruktion
+
+Die eine Stelle, an der `LinkedList` die richtige Wahl ist (`Pathfinder`):
+Nach der BFS läuft man über `cameFrom` **rückwärts** vom Ziel zum Start und will den
+Pfad in Vorwärtsreihenfolge. `addFirst()` ist bei `LinkedList` O(1) — bei `ArrayList`
+wäre `add(0, x)` O(n), weil alles verschoben werden müsste.
## Bewusst NICHT gewählt
@@ -62,7 +73,7 @@ Entscheidung "keine Stapel" (1 Item pro id) macht das Map-basierte Modell sauber
| `ArrayList- ` für Inventar | O(n)-Lookup, Duplikat-Handling nötig |
| `HashMap` für Inventar | Anzeige-Reihenfolge instabil |
| `TreeMap` irgendwo | Keine sortierte Iteration nötig, O(log n) ohne Nutzen |
-| `LinkedList` | `ArrayDeque` ist fast immer besser |
+| `LinkedList` als Queue | dafür ist `ArrayDeque` besser (s.o.) — als `addFirst`-Liste in der Pfadrekonstruktion aber sehr wohl genutzt |
| `Vector` / `Hashtable` | Legacy, synchronisiert (nicht gebraucht), langsamer |
| `Map` für Exits in Domain | Direction sollte Enum sein, nicht String |
@@ -70,4 +81,9 @@ Entscheidung "keine Stapel" (1 Item pro id) macht das Map-basierte Modell sauber
Single-threaded: Game-Loop liest, dispatcht, schreibt — keine parallelen Mutationen.
-**Ausnahme:** Bei Swing-GUI läuft Input über den Event-Dispatch-Thread, der Game-Loop in einem Worker-Thread. Hier kommt `BlockingQueue` (`ArrayBlockingQueue` reicht) als Brücke ins Spiel — siehe [architecture.md](architecture.md).
+**Ausnahme:** Bei Swing-GUI läuft Input über den Event-Dispatch-Thread, der Game-Loop in
+einem Worker-Thread. Als Brücke dient eine `LinkedBlockingQueue` (`SwingIO`):
+Der `JTextField`-ActionListener (EDT) legt die Zeile ab, der Worker blockiert in
+`take()`. Unbegrenzt statt `ArrayBlockingQueue`, weil es keine sinnvolle Obergrenze für
+getippte Zeilen gibt und ein volles `offer()` Eingaben verlieren würde — siehe
+[architecture.md](architecture.md).
diff --git a/Semesterprojekt/docs/enhancement-ideas.md b/Semesterprojekt/docs/enhancement-ideas.md
deleted file mode 100644
index bdb1f85..0000000
--- a/Semesterprojekt/docs/enhancement-ideas.md
+++ /dev/null
@@ -1,239 +0,0 @@
-# Enhancement-Ideen (Backlog)
-
-> Roh-Sammlung von Ausbau-Ideen über die Abgabe hinaus. Lebendes Dokument –
-> noch kein Design, noch keine Festlegung. Wird in Teilprojekte zerlegt und
-> nacheinander über den Brainstorming → Spec → Plan → Implementierung-Zyklus
-> verfeinert.
-
-Stand: 2026-05-31. Ausgangslage: Pflichtumfang ("bare minimum") erfüllt,
-alle Phasen 1–7 grün. Ziel: deutlich mehr Tiefe und Politur.
-
-## Leitziele
-
-- **Reichere Ausgabe** statt nacktem Konsolentext – sowohl Konsole als auch GUI.
-- **GUI soll noch mehr bieten** als die Konsole (mehr Raum für visuelle Mittel).
-- **~60 Minuten Spielzeit** anpeilen. Viel mehr Inhalt, viel mehr zu tun.
-- Bestehendes **NPC-System zu einem tieferen Quest-System** ausbauen.
-
-## Themenblöcke
-
-### 1. Reichere Präsentation / Ausgabe-Schicht ✅ umgesetzt (Branch `feature/presentation-layer`)
-
-> Umgesetzt: semantisches Modell (`io.text`), `ConsoleIO` (ANSI + Box-Drawing,
-> Color/Glyph-Modi), `SwingIO` (4 Regionen, `JTextPane`, gebündelter Font,
-> HiDPI-Skalierung + Zoom `Strg +/-/0`), HUD pro Zug, Welcome-Banner. 79 Tests grün.
-> Spec/Plan unter `docs/superpowers/`. Karte/Menü/Save/Musik weiterhin offen.
-
-
-- Weg vom reinen `write(String)`: formatierte Ausgabe (Überschriften, Trenner,
- Hervorhebungen für Items/NPCs/Richtungen).
-- **Konsole**: ANSI-Farben, Box-Drawing-Zeichen für Rahmen, evtl. ASCII-Art /
- Banner für Räume oder Spielstart.
-- **GUI (Swing)**: mehr als ein `JTextArea` – Farben, Stile, evtl. Panels,
- Statusanzeige, Bilder/Icons.
-
-**Festgelegt (Zielbild Konsole):** Stufe **B als Baseline** (Boxed Heading,
-gelabelte Sektionen, persistente HUD-Zeile: Ort · Gold · Zug · Licht), **ASCII-Art
-nur für große Momente** (Spielstart, Finale, Schlüsselräume). Semantische
-Farb-Rollen: Items / NPCs / Exits / Heading / Gefahr.
-
-**Designprinzipien:**
-- **Nicht überladen / Progressive Disclosure** – Raumeintritt zeigt nur das
- Wesentliche (Ort, kurze Beschreibung, Auffälliges); Details auf Abruf
- (`examine`, `look`).
-- **Info auf Regionen verteilen statt Text stapeln** – die **Karte ersetzt die
- „Exits:"-Zeile**. GUI: persistentes Map-Panel macht die Exit-Zeile überflüssig.
- Konsole: kompakte Mini-Map (bei `map` bzw. knapp beim Raumeintritt).
-
-### 2. Nerd Fonts / Glyphen – das Installationsproblem
-
-- Nerd-Font-Glyphen (Icons) sehen gut aus, müssen aber auf dem System des
- Spielers installiert sein, sonst Tofu-Kästchen.
-- Offene Frage: gute Lösung finden, damit es überall funktioniert.
-- Erste Gedanken:
- - **GUI**: Font ließe sich *mitliefern* (`.ttf` in Resources, via
- `Font.createFont` laden) → Installationsproblem entfällt für die GUI.
- - **Konsole**: Font nicht kontrollierbar → gestufte Fallbacks
- (reines ASCII → Unicode-Box-Drawing → Nerd-Glyphen) statt harter Annahme.
-
-### 3. Karte / Map ✅ umgesetzt (Branch `feature/map`)
-
-> Umgesetzt: `MapLayout` (BFS-Gitter-Layout + Fog of War), `MapView`-Modell,
-> GUI-`MapPanel` (Graphics2D, ersetzt die Exit-Liste), Konsolen-ASCII via
-> `AsciiMap` + `map`-Befehl, Besuchte-Räume-Tracking auf `Player`, Map-Push pro Zug.
-> Item/NPC-Marker und Türen-Styling offen (Quest-Teilprojekt). Spec/Plan unter
-> `docs/superpowers/`.
-
-
-- Übersichtskarte der Räume – in **beiden** Modi.
-- Konsole: ASCII-Map. GUI: gezeichnete Map (Grid/Graph).
-- Offene Fragen: nur bereits besuchte Räume zeigen? aktuelle Position markieren?
- fester Grundriss oder dynamisch aus den Exits berechnet?
-
-### 4. Gameplay-Ausbau (Inhalt)
-
-- Deutlich mehr Räume, Items, NPCs.
-- Mehr zu *tun*: Rätsel, Mechaniken, Abhängigkeiten zwischen Objekten.
-- Zielgröße: ~60 Min. Spielzeit (laut Annahme machbar, da überwiegend Text).
-
-### 5. Quest-System (NPC-Ausbau)
-
-> ✅ Fundament umgesetzt (Branch `feature/quest-foundation`): World-Flags +
-> Condition/Effect-Engine, verschlossene Exits, zustandsabhängige Beschreibungen,
-> bedingte Dialoge, Reaktionen mit requires/effects, Schalter-Effekte. Demo:
-> Generator schaltet Strom → Keller-Tür öffnet + Raum wird beleuchtet.
->
-> ✅ #3.2 umgesetzt (Branch `feature/quests`): condition-driven Quests
-> (Quest/QuestStage), QuestEngine mit Auto-Advance + Ansagen, START_QUEST-Effekt,
-> Konsolen-Befehl `quests` und GUI-Quest-Box unter der Karte. Demo-Quest
-> `restore_power`.
->
-> ✅ #3.3 umgesetzt (Branch `feature/endings`): priorisierte, condition-driven
-> Enden (`endings.yaml`) + End-Screen mit Summary (Züge, Quests X/Y, Rang).
-> Demo: Sieg-Ende (`manor_secured`) und Flucht-Ende (Front Door → `fled`).
-> **Damit ist das Quest-System (#3) komplett.** Offen: Licht/Dunkelheit &
-> Item-Kombination sowie #4 Content-Ausbau.
-
-
-- Aktuelles NPC-System: Begrüßung + Geschenk-Reaktion (Item → Item).
-- Ausbau Richtung: mehrstufige Quests, Bedingungen, NPC-"Memory" (Zustand),
- Quest-Log, evtl. Win-Condition daran gekoppelt.
-
-**GUI-Layout (festgelegt):** Quest-Log als **dauerhaft sichtbare Box unterhalb der
-Karte** im rechten Seitenbereich (Map oben, Quests darunter). Gehört zu Quest-
-Teilprojekt #2 (Quest-Log); das Fundament #1 reserviert/plant den Slot.
-
-### 5b. Spielkern: zentraler Bogen + Mechanik-Spine
-
-**Leitidee (bestätigt):** Bewusst *kondensiert* – wenige Mechaniken, die sich
-vielfach kombinieren, statt vieler Einzel-Gimmicks. Ein 60-Min-Spiel soll
-*designt* wirken, nicht gestreckt.
-
-**Hauptziel:** *Den Strom wieder anschalten* (`power_on`). Der Weg dahin ist eine
-**Quest-Kette, die den Spieler Raum für Raum führt** (Raum X freischalten → führt
-zu Raum Y → … → Generator/Sicherungskasten). Das Hauptziel selbst ist das Ende
-des Bogens; einzelne Teilziele schalten je den nächsten Bereich frei.
-
-**Mechanik-Spine (5 Bausteine, die sich kombinieren):**
-
-1. **World-Flags / Zustand** – Rückgrat (`power_on`, `cellar_drained`,
- `ghost_banished`). Beschreibungen, Exits und NPC-Reaktionen lesen/schreiben sie.
-2. **Verschlossene Exits & Schalter** – Türen brauchen Schlüssel *oder* Flag;
- Hebel/Ventile setzen Flags und öffnen Bereiche.
-3. **Licht & Dunkelheit** – dunkle Räume brauchen eine brennende Lichtquelle,
- sonst keine Sicht auf Exits/Items (Atmosphäre, einfach umzusetzen).
- > ✅ Umgesetzt (Branch `feature/light-darkness`): `Room.dark` + `Item.light`,
- > `Light`-Helper, Gating in go/look/take/examine (Modell B: kein Eintritt ohne
- > Licht), HUD-Licht verdrahtet. Demo: dunkler Dungeon braucht die brennende
- > Lampe für den Generator.
-4. **Item-Kombination** – z.B. `match + candle → lit candle`. Achtung: v1.0 hat
- bewusst argloses `use X` ohne Targets gewählt → Command-Grammatik muss erweitert
- werden (jetzt erlaubt, da über MVP hinaus).
- > ✅ umgesetzt (Branch `feature/use-x-on-y`): `use X on Y` als datengetriebene
- > Rezepte (`combinations.yaml`: requires/consume/produce/effects/response/failText),
- > Operanden aus Inventar oder Raum, reihenfolge-unabhängiger Paar-Key. Kein
- > Parser-Eingriff (`on`/`with`/`to` sind bereits Filler). Selbst-Kombination
- > (a==b) wird beim Laden abgelehnt. Demo: `matches` + `torch` → `lit_torch`
- > (dauerhafte Lichtquelle).
-5. **Quest-Ketten + mehrere Enden** – Teilziele referenzieren Flags; Kette
- abschließen = Win; *welche* Flags gesetzt sind, entscheidet das Ende.
-
-**Beispiel-Puzzle (zeigt das Stapeln):** *Strom wiederherstellen* – Sicherung im
-gefluteten Keller; erst Ventil → `cellar_drained`; Sicherung einsetzen → Schalter
-→ `power_on` → oberes Stockwerk/Tür öffnet sich. Ein Puzzle, drei Mechaniken,
-schaltet einen ganzen Flügel frei.
-
-*Weitere Puzzle-Ideen im Backlog (optional, nach Bedarf):* Zahlenschloss mit
-Code aus Lore, Caesar-Chiffre-Brief (`decode`), Geist bannen (Reliquien-Fetch),
-Melodie-/Sequenz-Rätsel, dunkler Gang. Resource-Meter (Sanity/Öl) **offen** –
-vorerst puzzle-fokussiert ohne Survival-Druck.
-
-### 6. Hauptmenü & Settings
-
-> ✅ umgesetzt (Branch `feature/main-menu-save-load`). Hauptmenü-Shell oberhalb
-> des Game-Loops (Neues Spiel / Laden / Einstellungen / Beenden) über neue
-> `GameIO.choose`-Primitive (Konsole: nummeriertes Menü; GUI: Buttons).
-> **Minimale Settings**: nur Farb-Modus + Glyphen-Modus (ASCII/Unicode), live
-> umschaltbar, in `saves/settings.json` persistiert. Musik-/Typewriter-Toggles
-> weiter zurückgestellt (Features existieren noch nicht).
-
-- **Hauptmenü** vor der Spielschleife: *Neues Spiel*, *Spiel laden*, *Einstellungen*, *Beenden*.
-- **Spielstände-Liste**: gespeicherte Spiele mit Metadaten (Name, Raum, Zugzahl,
- Zeitstempel) anzeigen und hineinladen.
-- **Settings-Untermenü**: z.B. Farben an/aus, Typewriter-Tempo, Musik-Lautstärke
- an/aus, ASCII vs. Unicode.
-- Sollte in beiden Modi funktionieren: Konsole = nummeriertes Textmenü, GUI =
- Buttons/Liste. Architektur: Menü-Schicht *oberhalb* des Game-Loops.
-
-### 7. Speichern / Laden
-
-> ✅ umgesetzt (Branch `feature/main-menu-save-load`). JSON-Spielstand als
-> Delta über die frisch aus YAML geladene Welt (`SaveData`/`SaveCodec`/
-> `SaveService`, atomare Writes). **Ein aktiver Slot**: manuelles `save`,
-> Autosave (Quest-Completion + alle 10 Züge) und `quit`/`menu` (speichern +
-> zurück ins Menü) schreiben denselben Slot; Laden nur über das Menü.
-> `saves/` ist gitignored.
-
-- Spielstand serialisieren (Player-Zustand, Inventar, World-Flags, besuchte Räume,
- Quest-Fortschritt) – Format z.B. YAML/JSON.
-- Mehrere Speicherstände, benennbar; Anbindung an die Spielstände-Liste im Menü.
-
-### 8. Musik (GUI)
-
-> ✅ umgesetzt (Branch `feature/music`): OGG Vorbis (vorbisspi/jorbis), pro Raum
-> via `music:`-Feld in `rooms.yaml`, externer gitignored `music/`-Ordner (nicht im
-> JAR). Idempotenter Track-Wechsel mit ~400 ms Fades; Räume ohne `music` blenden zu
-> Stille; gleicher Track läuft nahtlos weiter. Music-Stufe Off/Low/Med/High in den
-> Settings (Default Medium), persistiert. Konsole stumm. Testbarer `MusicController`
-> über isoliertes `OggMusicBackend`; fehlende Datei → still, kein Absturz. Siehe
-> `docs/music.md`.
-
-- Hintergrundmusik **nur in der GUI**.
-- **Pro Raum definierbar via YAML**: in `rooms.yaml` ein optionales Feld
- (z.B. `music: `), Dateien in *einem* Ordner.
-- **Dateigröße** ist ein Thema → Lösungsrichtung:
- - Audiodateien **nicht** in JAR/Repo bündeln, sondern externer `music/`-Ordner;
- Audio ggf. via `.gitignore` ausschließen + dokumentieren, wo Dateien hinkommen.
- - **Komprimierte Formate** (OGG/MP3) statt WAV, **gestreamt** statt komplett geladen.
- - Bibliothek erlaubt → kleinen Audio-Decoder einbinden (Java `javax.sound` kann
- OGG/MP3 nicht nativ).
- - Loop pro Track, sanfter Wechsel beim Raumwechsel, graceful fallback bei
- fehlender Datei, Lautstärke aus den Settings.
- - Architektur: `MusicPlayer`-Komponente hinter Interface; Konsole = No-Op.
-
-## Festgelegte Erweiterungs-Entscheidungen
-
-> ✅ **Pathfinding** umgesetzt (Branch `feature/pathfinding-go-to`): `go to `
-> per BFS über besuchte Räume (Locks + Licht beachtet), via `GoCommand`
-> (Richtung vs. Raumziel). Konsole still + Zusammenfassung (Start/Mitte/Ziel),
-> GUI-Minikarte animiert pro Schritt (`GameIO.travelStep`, ~300 ms).
-> **Trie-Autocomplete** weiterhin für eine spätere Runde zurückgestellt.
-
-> ✅ **Tutorial** umgesetzt (Branch `feature/tutorial`): interaktiver Walkthrough
-> beim Neuen Spiel (look→examine→take→inventory→use→go→go to), verb-/alias-basierte
-> Abschluss-Erkennung (Bewegungs-Schritte verlangen echten Raumwechsel),
-> Abschluss-Tipps, jederzeit per `skip` abbrechbar. Datengetrieben (`tutorial.yaml`,
-> `TutorialLoader`), als `TutorialGuide` in den Game-Loop eingehängt; nur bei Neuem
-> Spiel, nicht beim Laden.
-
-| Entscheidung | Wert |
-|---|---|
-| Eigene `uebung`-Datenstrukturen verwenden? | **Nein** – Standard-Collections (vom Prof bestätigt) |
-| Algorithmen-Showcase | weiterhin willkommen, aber mit Standard-Datenstrukturen (z.B. BFS `go to `, Trie-Autocomplete) |
-| Bibliotheken erlaubt? | **Ja** (Pflichtteil war bewusst ohne; Erweiterung darf welche nutzen) |
-| Hauptmenü | ja: Neues Spiel / Laden / Settings / Beenden |
-| Speichern/Laden | ja, mehrere benannte Spielstände |
-| Musik | ja, **nur GUI**, pro Raum via YAML, externer Ordner, komprimiert + gestreamt |
-
-## Offene Designfragen (zu klären)
-
-- Wie weit darf die `GameIO`-Abstraktion aufgebohrt werden, ohne dass Konsole
- und GUI auseinanderlaufen? (Gemeinsamer Loop ist ein Kernwert der Architektur.)
-- Bleibt alles datengetrieben (YAML), auch Quests und Map-Layout?
-- Reihenfolge / Abhängigkeiten der Teilprojekte.
-
----
-
-*Notiz: Datengetriebenheit (YAML), getrennte DTO/Domain-Schicht und ein für
-beide Frontends identischer Game-Loop sind etablierte Architekturwerte – neue
-Features sollten sie respektieren, nicht umgehen.*
diff --git a/Semesterprojekt/docs/implementation-status.md b/Semesterprojekt/docs/implementation-status.md
deleted file mode 100644
index 8d1102d..0000000
--- a/Semesterprojekt/docs/implementation-status.md
+++ /dev/null
@@ -1,135 +0,0 @@
-# Implementierungsstand & Reihenfolge
-
-Stand: alle Phasen 1–7 implementiert, 67 Tests grün, End-to-End-Smoke-Test des Walking-Skeletons + YAML-Load erfolgreich.
-
-## Phasen-Überblick
-
-```mermaid
-flowchart TD
- P1["Phase 1
Domain-Fundament"]
- P2["Phase 2
Command-Schicht"]
- P3["Phase 3
Walking Skeleton
(Konsole + handgebaute Welt)"]
- P4["Phase 4
YAML-Loading + Validator"]
- P5["Phase 5
Restliche Commands"]
- P6["Phase 6
NPCs end-to-end"]
- P7["Phase 7
Swing-GUI (Bonus)"]
-
- P1 --> P2 --> P3 --> P4 --> P5 --> P6 --> P7
-```
-
-## Checkliste Phase 1: Domain
-
-- [x] `Direction` (`model.Direction`)
-- [x] `Room` (`model.Room`)
-- [x] `Item` abstract (`model.item.Item`) mit `abstract use(GameContext)`
-- [x] `Npc` (`model.Npc`) inklusive `shell()`-Factory und `putReaction()`
-- [x] `NpcReaction` (`model.NpcReaction`)
-- [x] `GameIO` interface (`io.GameIO`)
-- [x] `Player` (`model.Player`)
-- [x] `World` (`model.World`)
-- [x] `GameContext` (`game.GameContext`)
-- [x] `ReadableItem` (`model.item.ReadableItem`)
-- [x] `SwitchableItem` (`model.item.SwitchableItem`)
-- [x] `PlainItem` (`model.item.PlainItem`)
-
-## Checkliste Phase 2: Commands
-
-- [x] `Command` interface (`command.Command`)
-- [x] `ParsedCommand` (record)
-- [x] `CommandRegistry` (`command.CommandRegistry`)
-- [x] `CommandParser` (`command.CommandParser`) mit Filler-Words
-- [x] `LookCommand`
-- [x] `GoCommand`
-- [x] `InventoryCommand`
-
-## Checkliste Phase 3: Walking Skeleton
-
-- [x] `ConsoleIO`
-- [x] `Game` (Loop)
-- [x] `App.main` (lädt sofort über YAML; der Walking-Skeleton-Zustand mit hartkodierter Welt wurde übersprungen, weil YAML-Load und Loop schon zusammen funktionieren)
-- [x] Probelauf: `look`, `go north`, `inventory` (siehe `GameTest`, `LookCommandTest`)
-
-## Checkliste Phase 4: YAML-Loading
-
-- [x] DTOs: `GameDto`, `ItemDto`, `RoomDto`, `NpcDto`, `ReactionDto`
-- [x] Test-Fixtures unter `src/test/resources/world/`
-- [x] `WorldLoader` (Happy-Path)
-- [x] `ReferenceResolver`
-- [x] `WorldValidator` (eine Validierungsregel pro Test)
-- [x] Echte Welt-YAMLs unter `src/main/resources/world/`
-- [x] `App.main` läuft direkt gegen YAML-Load
-
-## Checkliste Phase 5: Restliche Commands
-
-- [x] `TakeCommand`
-- [x] `DropCommand`
-- [x] `UseCommand`
-- [x] `ReadCommand`
-- [x] `ExamineCommand`
-- [x] `HelpCommand`
-- [x] `QuitCommand`
-
-## Checkliste Phase 6: NPCs
-
-- [x] `Npc` voll ausgebaut (greeting, reactions)
-- [x] `NpcReaction`
-- [x] `TalkCommand`
-- [x] `GiveCommand`
-- [x] NPCs in `WorldLoader` integriert
-- [x] End-to-End-Test: Lampe geben → Schlüssel bekommen (`TalkGiveCommandTest`)
-
-## Checkliste Phase 7: Swing-GUI
-
-- [x] `SwingIO` mit `LinkedBlockingQueue`-Brücke
-- [x] `AppGui.main`
-- [x] Game-Loop in Worker-Thread
-
-## Build & Run
-
-```sh
-mvn test # 67 Tests
-mvn -DskipTests exec:java -Dexec.mainClass=thb.jeanluc.adventure.App # Konsole
-mvn -DskipTests exec:java -Dexec.mainClass=thb.jeanluc.adventure.AppGui # Swing
-```
-
-## Festgelegte Designentscheidungen
-
-Nicht mehr offen, nicht nochmal diskutieren:
-
-| Entscheidung | Wert |
-|---|---|
-| Item-Hierarchie | abstract Item + ReadableItem/SwitchableItem/PlainItem |
-| Item-Package | `model.item` (Subpackage) |
-| Switchable-State-Typ | `boolean` (kein Enum) |
-| Switchable-Felder | nur `state` (Builder mappt YAML `initialState`); kein separates `initialState`-Feld am Domain-Objekt |
-| use-Targets | argless `use X`, kein `use X on Y` |
-| Item kennt Standort | nein, „dumme" Items |
-| Hidden Items | nein |
-| State→Raum-Beschreibung | nein im MVP |
-| Room.description | `final`, immutable |
-| Room.describe() | nicht auf Room, im LookCommand |
-| Room.equals/hashCode | nicht überschreiben, Identity |
-| Room-NPCs-Feld | von Anfang an drin |
-| Bidirektionale Exits | manuell, kein Auto-Spiegeln |
-| GameContext-Inhalt | minimal: World + Player + GameIO |
-| IDs | lowercase snake_case slugs, kein UUID |
-| ID-Regex | `^[a-z][a-z0-9_]*$` |
-| YAML-Aufteilung | `game.yaml`, `items.yaml`, `rooms.yaml`, `npcs.yaml` |
-| DTO ↔ Domain | getrennt, Resolver-Phase löst String-IDs zu Referenzen auf |
-| Item-Type-Discriminator | YAML-Feld `type: plain|readable|switchable`, in `ItemFactory` als switch |
-| Codebase-Sprache | Englisch (Identifier, YAML, User-Strings) |
-| Doku-Sprache | Deutsch (Prose), Englisch (Code-Beispiele) |
-| Diagramme | Mermaid |
-| Lombok-Inheritance | `@SuperBuilder` |
-| `@Data` | vermeiden, einzelne Annotations bevorzugen |
-| Quit-Wiring | `QuitCommand.bind(Game)` nach Registry-Aufbau |
-| Help-Quelle | `HelpCommand` zieht aus `CommandRegistry.distinctCommands()` |
-| GameIO-Methodennamen | `readLine()` / `write(String)` (Java-üblich, konsistent) |
-| Lombok-Version | 1.18.42 (1.18.36 ist nicht Java-26-kompatibel) |
-
-## Offen / nicht im MVP
-
-- **Win-Condition**: Spiel endet nur per `quit`. Optionale Erweiterung: Bedingung in `game.yaml` (`winRoom`, `requiredItem`).
-- **Bedingte NPC-Reaktionen**, NPC-Memory, Quests — bewusst ausgelassen (siehe `npcs.md`).
-- **Item-Aliases** (z.B. `lamp` ↔ `oil_lamp`) — YAGNI bis konkreter Bedarf.
-- **Eingabehistorie** in der GUI — `ArrayDeque` ist vorgesehen, nicht umgesetzt.
diff --git a/Semesterprojekt/release/HauntedManor-Console.jar b/Semesterprojekt/release/HauntedManor-Console.jar
deleted file mode 100644
index b51b4db..0000000
Binary files a/Semesterprojekt/release/HauntedManor-Console.jar and /dev/null differ
diff --git a/Semesterprojekt/release/HauntedManor-GUI.jar b/Semesterprojekt/release/HauntedManor-GUI.jar
deleted file mode 100644
index 42470cb..0000000
Binary files a/Semesterprojekt/release/HauntedManor-GUI.jar and /dev/null differ