# CLAUDE.md — AfterHours (Boutique Simulator) Diese Datei ist die Arbeitsanweisung für Claude Code in diesem Repo. Lies sie vollständig, bevor du Code änderst. --- ## 1. Projekt in einem Satz Koop-Ladensimulator (2–4 Spieler) für PC: Die Spieler betreiben gemeinsam eine diskrete Erwachsenen-Boutique — Ware bestellen, einräumen, bepreisen, Kunden beraten, kassieren, Laden ausbauen. **Codename:** AfterHours **Zielplattform:** Windows (Steam), später Linux/Proton **Zielrating:** Mature, NICHT Adult-Only. Siehe §7 — das ist eine harte Constraint. --- ## 2. Tech-Stack | Bereich | Entscheidung | |--------------|-----------------------------------------------| | Engine | Unity 6 LTS (6000.0.x) | | Sprache | C# (.NET Standard 2.1) | | Netcode | Unity Netcode for GameObjects (NGO) 2.x | | Transport | Unity Transport + Steam Relay (Facepunch) | | KI-Pathing | Unity NavMesh (NavMeshAgent, nur serverseitig)| | Tests | Unity Test Framework (NUnit), EditMode | | Daten | ScriptableObjects (`Assets/Data/...`) | **Warum NGO und nicht FishNet:** erstklassige Doku, First-Party-Support, reicht für 4 Spieler + ~30 NPCs vollkommen aus. Nicht ohne Rücksprache wechseln. --- ## 3. Die wichtigste Regel: Server-Authority > **Der Host simuliert. Clients fragen und zeigen an.** Alles, was Geld, Inventar, Warenbestand oder Kundenlogik betrifft, läuft **ausschließlich** auf dem Host. Clients senden Absichten via `ServerRpc`, der Server validiert und schreibt in `NetworkVariable`s. **Konkret:** - ✅ `[Rpc(SendTo.Server)]` → validieren → `NetworkVariable` setzen - ❌ Niemals Geld/Bestand clientseitig verändern und "hoffen" - ❌ Niemals einem Client-Wert vertrauen, ohne ihn zu prüfen (Beispiel: Client sagt "ich scanne Produkt X" → Server prüft, ob der Client dieses Produkt tatsächlich in der Hand hält) - Kunden-NPCs: Bewegung + Entscheidungen nur auf dem Server. Clients bekommen nur Transform-Sync und Zustandsflags. Jede Methode, die Zustand ändert, wird mit `if (!IsServer) return;` abgesichert — auch wenn sie "eigentlich" nur serverseitig aufgerufen wird. --- ## 4. Ordnerstruktur ``` Assets/Scripts/ ├── Core/ GameClock, ShopEconomy, GameBootstrap — Kern-Loop & Zustand ├── Data/ ScriptableObjects: ProductDefinition, ProductCatalog, Enums ├── Economy/ PricingService, SupplierService, PurchaseOrder ├── Shop/ Shelf, ShelfSlot, CashRegister, StorageCrate ├── Customers/ CustomerAgent, CustomerBrain (FSM), ComfortModel, Spawner ├── Interaction/ IInteractable, PlayerInteractor, Carryable ├── Networking/ NetworkBootstrap, PlayerAvatar, PlayerHands └── Tests/EditMode/ NUnit-Tests für reine Logik ``` **Namespaces spiegeln Ordner:** `AfterHours.Economy`, `AfterHours.Customers`, … --- ## 5. Code-Konventionen - Klassen/Methoden `PascalCase`, Felder `_camelCase` mit Unterstrich, Konstanten `PascalCase`. - `[SerializeField] private` statt `public` für Inspector-Felder. - **Reine Logik gehört in statische, engine-freie Klassen** (`PricingService`, `ComfortModel`). Nur die sind testbar — MonoBehaviours sind es nicht. Wenn du eine Formel schreibst und sie in einem `MonoBehaviour` landet: rausziehen. - Produkte werden im Netzwerk **nie als Referenz**, sondern als `ProductId` (int) übertragen. Auflösung über `ProductCatalog`. - Keine `FindObjectOfType` im Frame-Loop. Referenzen im `Awake` cachen. - Kein `async void` außer in Event-Handlern. --- ## 6. Tests ```bash # Unity CLI (Pfad ggf. anpassen) Unity -runTests -batchmode -projectPath . -testPlatform EditMode ``` Neue Logik in `Economy/` oder `Customers/` **braucht** einen EditMode-Test. Netzwerk- und Szenenlogik wird nicht getestet — dort zählt manuelles Host+Client-Testing (siehe `docs/ARCHITECTURE.md`). --- ## 7. Content-Constraint (nicht verhandelbar) Das Spiel darf **nicht** in Steams "Adult Only"-Kategorie landen, weil das Sichtbarkeit, Regionen und Zahlungsdienstleister massiv einschränkt. **Deshalb gilt:** - Produkte werden als **stilisierte Verpackungen / Icons** dargestellt, nie explizit modelliert. - Kein sexuell explizites Bildmaterial, keine Nacktheit, keine sexuellen Akte. - Humor ist trocken und situativ (Verlegenheit, Beratungspannen, Stoßzeiten-Chaos) — nicht anzüglich. - Ton der Kundendialoge: höflich, vage, alltäglich. Die Komik entsteht aus dem, was *nicht* gesagt wird. Wenn ein Feature-Vorschlag dagegen verstößt: melde es, statt es umzusetzen. --- ## 8. Aktueller Stand Gerüst steht. Implementiert sind Datenmodell, Preis-/Komfort-Formeln, Regal-/Kassen-Grundgerüst und der Netzwerk-Bootstrap. Es existieren **noch keine Unity-Szenen, Prefabs oder Assets** — die musst du bzw. der Nutzer im Editor anlegen. Offene Punkte in Prioritätsreihenfolge: siehe `docs/ROADMAP.md`. `// TODO:`-Marker im Code zeigen die konkreten Lücken. --- ## 9. Arbeitsweise mit mir - Bevor du eine neue Datei anlegst: prüfe, ob die Logik in eine bestehende gehört. Das Projekt soll klein und lesbar bleiben. - Ändere nie mehrere Systeme in einem Rutsch. Ein System, ein Commit. - Wenn eine Anforderung mit §3 (Server-Authority) oder §7 (Content) kollidiert: nachfragen, nicht raten. - Commit-Messages: `feat(economy): ...`, `fix(customers): ...`, `docs: ...`