# 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).