docs: correct stale documentation and drop planning artifacts

The docs had drifted from the code and described things that never existed.

- architecture.md documented a QuitCommand class (quit/exit are aliases on
  MenuCommand) and a GameIO interface of read()/write(String); the real one is
  readLine() plus print(StyledText) with presentation hooks. Both corrected,
  along with the package diagram and the game-loop sketch.
- conventions.md listed a package tree missing save, menu, io.text and
  command.impl. Updated, including why MapLayout lives in game.
- data-structures.md claimed LinkedList was deliberately avoided (Pathfinder
  uses one for O(1) addFirst during path reconstruction), named the wrong queue
  for the Swing bridge, and listed an input history that was never built.
- Removed enhancement-ideas.md and implementation-status.md: a backlog and a
  phase tracker, neither of which documents the delivered project.

Also stop tracking the built jars. They still ship in the submission, but a
22 MB binary that changes on every build does not belong in git history.
This commit is contained in:
2026-07-14 12:40:09 +02:00
parent 526e3d4ee7
commit c205d1f49b
10 changed files with 92 additions and 424 deletions

View File

@@ -33,19 +33,22 @@ flowchart LR
model --> item
item --> item_files["Item (abstract)<br/>ReadableItem<br/>SwitchableItem<br/>PlainItem"]
loader --> loader_files["WorldLoader<br/>ReferenceResolver<br/>WorldValidator"]
loader --> loader_files["WorldLoader<br/>ReferenceResolver<br/>WorldValidator<br/>*Factory"]
loader --> dto
dto --> dto_files["RoomDto, ItemDto,<br/>NpcDto, GameDto"]
dto --> dto_files["RoomDto, ItemDto,<br/>NpcDto, GameDto,<br/>QuestDto, EndingDto, …"]
command --> cmd_core["Command (Interface)<br/>CommandRegistry<br/>CommandParser"]
command --> impl
impl --> impl_files["GoCommand, TakeCommand,<br/>DropCommand, UseCommand,<br/>InventoryCommand, LookCommand,<br/>TalkCommand, GiveCommand,<br/>HelpCommand, QuitCommand"]
impl --> impl_files["GoCommand, TakeCommand,<br/>DropCommand, UseCommand,<br/>ReadCommand, ExamineCommand,<br/>InventoryCommand, LookCommand,<br/>TalkCommand, GiveCommand,<br/>MapCommand, QuestsCommand,<br/>SaveCommand, MenuCommand,<br/>HelpCommand"]
game --> game_files["Game (Loop)<br/>GameContext"]
game --> game_files["Game (Loop)<br/>GameContext/Session/State<br/>QuestEngine, EndingEngine,<br/>EscortEngine, Light,<br/>Pathfinder, MapLayout"]
io --> io_files["GameIO (Interface)<br/>ConsoleIO<br/>SwingIO"]
io --> io_files["GameIO (Interface)<br/>ConsoleIO<br/>SwingIO<br/>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<String> options) { }
default void shutdown() { }
}
```
Damit ist der Game-Loop **identisch** für beide Modi. `SwingIO` blockiert intern mit einer `BlockingQueue<String>`, 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<String>`, die vom JTextField-ActionListener gefüllt wird.