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.
93 lines
3.8 KiB
Markdown
93 lines
3.8 KiB
Markdown
# Konventionen
|
|
|
|
Sprache, IDs, Package-Struktur, Naming.
|
|
|
|
## Sprache
|
|
|
|
- **Code:** Englisch — Klassen, Methoden, Felder, Enums, Package-Namen, Javadoc.
|
|
- **YAML:** Englisch — Keys, IDs, alle Texte (descriptions, dialogue, readText, etc.).
|
|
- **Doku-Prose** (`docs/*.md`): Deutsch — Diskussion mit dem Entwickler, keine Spec für Korrektoren.
|
|
|
|
## IDs
|
|
|
|
Slugs, keine UUIDs. Begründung in [item-model.md](item-model.md) und [yaml-schemas.md](yaml-schemas.md).
|
|
|
|
| Regel | Beispiel | Gegenbeispiel |
|
|
|---|---|---|
|
|
| nur kleinbuchstaben | `kitchen`, `letter` | `Kitchen`, `LETTER` |
|
|
| ASCII, keine Umlaute | `cellar`, `kueche` schlecht | `keller` gut, `küche` schlecht |
|
|
| Mehrwortig: snake_case | `oil_lamp`, `old_man` | `oilLamp`, `old-man`, `oil lamp` |
|
|
| keine führende Ziffer | `key1` | `1key` |
|
|
| nur `[a-z0-9_]` | `key2` | `key#2`, `key@2` |
|
|
|
|
Regex zur Validierung im `WorldValidator`:
|
|
|
|
```
|
|
^[a-z][a-z0-9_]*$
|
|
```
|
|
|
|
Geltungsbereich: id ist eindeutig **innerhalb seiner Entitätsart**. Ein Item und ein NPC dürfen `lamp` heißen (nicht empfohlen, aber technisch erlaubt).
|
|
|
|
## Package-Struktur
|
|
|
|
```
|
|
thb.jeanluc.adventure
|
|
├── App, AppGui <- Entry Points (Konsole / Swing)
|
|
├── model
|
|
│ ├── Direction, Room, Player, Npc
|
|
│ ├── Quest, QuestStage, Ending, Combination, Condition, Effect, …
|
|
│ └── item <- eigener Subpackage wegen Hierarchie
|
|
│ ├── Item (abstract)
|
|
│ ├── ReadableItem
|
|
│ ├── SwitchableItem
|
|
│ └── PlainItem
|
|
├── 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. 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
|
|
|
|
Java-Standard:
|
|
- Klassen: `UpperCamelCase`
|
|
- Methoden, Felder, Parameter: `lowerCamelCase`
|
|
- Konstanten: `UPPER_SNAKE_CASE`
|
|
- Packages: `lowercase`, ohne Underscores wenn möglich
|
|
|
|
YAML:
|
|
- Keys: `lowerCamelCase` (`startRoom`, `readText`, `initialState`) — passt zu Jackson-Default-Mapping auf Java-Felder
|
|
- IDs: siehe oben
|
|
|
|
## Javadoc
|
|
|
|
Pflicht laut Aufgabenstellung **an Klassen, Methoden, und Instanzvariablen**. Auch bei Lombok-Feldern wenn sie `@Getter`-exposed sind.
|
|
|
|
Keep it sachlich — was tut die Klasse/Methode, nicht wie. Keine Geschichten erzählen.
|
|
|
|
## Tests
|
|
|
|
- Unit-Tests pro Domain-Klasse: `RoomTest`, `PlayerTest`, `ItemTest` etc.
|
|
- Integration-Tests für Loader: `WorldLoaderTest` mit `src/test/resources/world/`-Fixtures
|
|
- Naming: `methodName_condition_expectedResult` — z.B. `addExit_withNewDirection_storesNeighbour`
|
|
|
|
## Lombok-Cheatsheet
|
|
|
|
| Annotation | Wozu |
|
|
|---|---|
|
|
| `@Getter` | Getter für alle Felder |
|
|
| `@RequiredArgsConstructor` | Konstruktor nur für finals ohne Initializer |
|
|
| `@SuperBuilder` | Builder über Vererbung (statt `@Builder`) |
|
|
| `@Slf4j` | `log`-Field für SLF4J |
|
|
| `@ToString` | Nur wenn aussagekräftig — sonst weglassen |
|
|
|
|
**Vermeiden:** `@Data` (zu viel auf einmal, generiert `equals/hashCode` was bei Room/Player unerwünscht ist).
|