Entscheidungen
Log der Projektentscheidungen, neueste oben.
| Datum | Entscheidung | Begründung |
|---|---|---|
| 2026-10-26 | SemVer + CHANGELOG.md, 0.0.x = Testversionen, 0.1.0 = erstes Release; CI-Sicherheitsjob mit gitleaks (ganze History) und osv-scanner (pubspec.lock, package-lock.json), wöchentlich auch ohne Commit; Dependabot für pub, npm, Actions, Docker; tool/doctor.sh prüft die Umgebung | Lieferkette und Repo-Hygiene laut SECURITY_DESIGN/TOOLING |
| 2026-10-26 | Ende-zu-Ende-Verschlüsselung umgesetzt (packages/secure_channel): Noise NKpsk2 mit Schlüssel+Geheimnis aus dem QR-Fragment, Noise NN mit Prüfbild und Bestätigung durch den Gastgeber für Raumsuche/manuellen Beitritt; Primitive aus cryptography (dint.dev, Apache-2.0), HMAC-BLAKE2s nach RFC 2104 selbst gebaut (Paket meldet falsche BLAKE2s-Blocklänge), geprüft mit den offiziellen Noise-Testvektoren; Padding auf feste Größenstufen | Umsetzung von SECURITY_DESIGN.md; das Relay und Mithörer im WLAN sehen nur gleich große Chiffretexte |
| 2026-10-26 | Host-Absturzsicherung: GameHost liefert nach jeder Änderung einen Schnappschuss (Spielstand + Sitzungen, JSON); die App schreibt ihn atomar in ihren privaten Support-Ordner (room.json), bietet nach einem Neustart „Raum wiederherstellen“ an (höchstens 12 h alt) und löscht ihn beim Schließen des Raums. Spieler versuchen 3 Minuten lang, sich neu zu verbinden | Ein Absturz des Host-Geräts beendet die Runde nicht mehr; die Datei enthält alle Rollen und Tokens und verlässt deshalb nie das Gerät |
| 2026-10-26 | Website-Docs für Spieler: Anleitung in 8 Kapiteln (de/en) unter /docs/, die Planungsdokumente unter /docs/dev/ („Für Entwickler“), alte Adressen leiten um. Startbild aus Pappebenen: Himmel, Mond, Wolken, Berge mit Burg, Hügel und Wiese als eigene Pappstücke mit eigener Parallaxe | Spieler finden schnell, was sie brauchen; der Hintergrund trägt die Pappbühne mit statt einer flachen Fläche |
| 2026-10-26 | Beitritt ohne Technik: Räume im WLAN per mDNS/Bonjour (bonsoir, MIT, gepflegt; wakelock_plus dafür auf 1.8.0 gehalten), QR-Code als zweiter Weg, IP/Port/Codes nur unter „Verbindungsdetails“; Tischkreis aus der eigenen Perspektive, Gastgeber tauscht Plätze; Netzwerk-Hilfe in Alltagssprache | „It just works“ auch für Leute ohne Technikwissen |
| 2026-10-25 | Personas: die 11 Pappfiguren sind wählbare Personas (Aussehen), unabhängig von der geheim verteilten Rolle; eindeutig, solange welche frei sind. Persona-Namen bewusst anders als Rollennamen (z. B. „Laternenträgerin“, „Grauwolf“) | Wunsch des Eigentümers; jeder erkennt sich und die anderen am Tisch, ohne dass das Aussehen etwas über die Rolle sagt |
| 2026-10-25 | Schäfchen-Wertung öffentlich am Morgen, Herdengröße vom Spiel: game_core legt pro Spieler und Nacht die Herde fest (3–30, aus einem Startwert der Partie per FNV-Hash, reproduzierbar und serialisierbar, ohne Uhr/Random im Zustand); die Zahlen der Nacht sieht morgens jeder, die Summe ergibt den „Besten Träumer“ | Mehr Spielmechanik: Hinweis zum Kombinieren, aber dank unterschiedlicher Herden kein Beweis gegen Werwölfe |
| 2026-10-25 | Erzähler: Ansagen werden in der App aus dem Phasenwechsel der Sicht abgeleitet (nur öffentliche Informationen), auf allen Geräten als Text, auf dem Host-Gerät zusätzlich per Sprachausgabe (flutter_tts, MIT, gepflegt), stummschaltbar. Mac/iOS nutzen dafür zusätzlich CocoaPods | Ersetzt den menschlichen Spielleiter; eine Stimme aus einer Quelle am Tisch |
| 2026-10-25 | Figuren in der App (WebP, zusammen < 1 MB) und Beitrittsseite whowolf.de/join (erklärt den Beitritt, zeigt die Codes aus dem Link, nichts verlässt den Browser, noindex, nicht in der Sitemap) | QR-Codes mit der normalen Kamera gescannt landen sinnvoll; die App sieht aus wie Whowolf |
| 2026-10-25 | Figuren ohne Stäbe: alle Pappfiguren und Papp-Handys stehen frei (Stäbe aus den Quellbildern entfernt), alle Figuren schauen standardmäßig nach rechts (Jäger gespiegelt); auf der Startseite wandert der große Schriftzug beim Scrollen in den Header | Die Stäbe störten und brachten gestalterisch kaum etwas; einheitliche Blickrichtung für das Wenden |
| 2026-10-25 | Relay-Server und Docker Compose schon in der Testversion: server/ (reines Dart, dart:io) leitet nur weiter; Host hält eine ausgehende Verbindung (/host), Spieler verbinden sich mit /join/<online-code> (8 Zeichen, ~40 Bit). Image aus server/Dockerfile (AOT-kompiliert, scratch, ohne Root, ~16 MB), docker compose up -d im Repo-Root, Healthcheck über das Binary. Ohne Ende-zu-Ende-Verschlüsselung kann das Relay die Nachrichten lesen; deshalb nur eigener Server bzw. Testbetrieb, bis Noise da ist. Offizielle Adresse per --dart-define=RELAY_SERVER, sonst eigener Server in den App-Einstellungen | Wunsch des Eigentümers: Server von Anfang an mit drin; die Host-Logik bleibt unverändert, das Relay ist nur ein weiterer Transport |
| 2026-10-25 | QR-Beitritt: Host zeigt https://whowolf.de/join?room=…&lan=ip:port&relay=…&srv=wss://…; die App scannt (mobile_scanner, iOS/Android/macOS), prüft streng (Host, Pfad, nur bekannte Parameter, private IPv4, ws/wss-Origin) und fragt vor dem Verbinden nach. Verbindung zuerst direkt im WLAN, sonst über das Relay. Geheimnisse kommen später ins Fragment | Ein Link für alle Fälle, wie in ARCHITECTURE geplant |
| 2026-10-25 | Rejoin nach App-Neustart: Sitzungstoken + Verbindungsdaten im sicheren Speicher (flutter_secure_storage: Keychain/Keystore/libsecret), „Zurück ins Spiel“ auf dem Startbildschirm; nach 30 erfolglosen Versuchen gibt die App auf. Der Host speichert den Spielstand noch nicht (Absturz des Hosts beendet die Runde) | Spieler kommen nach Sperren, Absturz oder Neustart mit genau ihrem Stand zurück |
| 2026-10-25 | Minimal spielbare Version vor dem vollständigen M2: Regeln (game_core), Protokoll (protocol), Host (game_host, reines Dart, Transport-Schnittstelle, Speicher-Transport für Tests, LAN-WebSocket in lan.dart) und App-Bildschirme stehen, noch ohne Ende-zu-Ende-Verschlüsselung. Nur als Testversion im eigenen WLAN; vor einem offiziellen Release kommt der Noise-Handshake als Schicht um Connection | Schnell echte Testrunden am Tisch; die Architektur bleibt die geplante, es fehlen nur Schichten |
| 2026-10-25 | Spielstart ab 3 Spielern (Testrunden), Empfehlung ab 5; Rollenvorschlag: 1 Werwolf unter 5 Spielern, sonst ⌊n/4⌋, Seherin ab 4 Spielern | Mit wenigen Geräten testen können, ohne die Regeln für echte Runden zu verbiegen |
| 2026-10-25 | Eine Nachtnachricht für alle Rollen (night mit Ziel); der Host entscheidet anhand der Rolle, ob es Jagd, Blick der Seherin oder Tarnaufgabe ist. Tarnaufgabe in der Testversion: „Wem traust du am wenigsten?“ (Schäfchen zählen folgt) | Netzwerkverkehr und Bildschirm verraten die Rolle nicht |
| 2026-10-25 | Fehler als RuleViolation-Exception mit typisiertem Grund (Violation), PlayerId als Extension Type über String; abgelehnte Aktionen ändern den Zustand nie | Einfache, reine API apply(state, action); Gründe lassen sich direkt ans Protokoll durchreichen |
| 2026-10-25 | Host-Grenzen: Hello innerhalb 5 s, max. 40 Verbindungen, 20 Nachrichten/s, 3 kaputte Nachrichten, Client-Nachrichten max. 1 KiB, strenges Parsen; LAN-Socket nimmt nur private/Loopback-Adressen an; Sitzungstoken 128 Bit aus Random.secure() | Umsetzung von SECURITY_DESIGN.md für die erste Version |
| 2026-10-25 | wakelock_plus (Flutter Community, BSD-3, aktiv gepflegt) hält das Gerät während des Spiels wach; intl (Dart-Team) für die generierten Übersetzungen | Ein gesperrtes Host-Handy beendet das Spiel für alle |
| 2026-10-25 | Startseite als Puppenspiel-Geschichte: Bühne auf dem Spieltisch (gemalter Nachthintergrund, Kulissen, Filz-Tischkante), die beim Scrollen stehen bleibt; in fünf Szenen werden Pappfiguren und zwei moderne Papp-Handys (Dynamic Island / randlos) an Stäben hereingehalten; Handys zeigen echte App-Screens (Rolle, Nacht, Schäfchenzählen, Abstimmung) | Setting der Spielschachtel-Version ohne Schachtel, mit Mondbühnen-Ambiente und einer kleinen Geschichte |
| 2026-10-25 | Startseite wieder Mondbühne: Nachtszene mit Pappfiguren und einem Handy als Pappfigur, das die App zeigt (Rolle, Nacht, Abstimmung); Sterne, Wolken, Glühwürmchen und wippende Figuren für mehr Leben; Spielschachtel und Filz entfernt | Wunsch des Eigentümers: Karton-Look gefiel nicht, Mondbühnen-Ambiente soll tragen |
| 2026-10-25 | Automatische Sprachwahl: Erster Besuch von außen mit nicht-deutscher Browsersprache wird auf die englische Seite geleitet; interne Navigation und Crawler nicht | Nicht-deutschsprachige Besucher landen direkt auf Englisch, ohne Speicherung |
| 2026-10-25 | Cookie-Hinweis eingeführt (ersetzt „Kein Cookie-Banner nötig“): reiner Infohinweis, speichert nur die Bestätigung im localStorage (technisch notwendig) | Wunsch des Eigentümers nach einem sichtbaren Hinweis |
| 2026-10-25 | Website-Redesign „Die Spielschachtel“: Startbild als Spielschachtel auf grünem Spieltisch-Filz, die Schachtel als echtes CSS-3D-Objekt mit texturierten Seiten, das sich beim Scrollen hebt und dreht; Überschriften in Ancizar Serif; restliche Seite als Regelheft-Tafeln und Nachtbrett auf Filz. Entstanden mit impeccable (Richtung gewählt, Entwurf freigegeben, Startbild vermessen nachgebaut; die 3D-Schachtel weicht auf Wunsch vom flachen Entwurf ab) | Eigenständiger Auftritt eines Spiels zum Auspacken statt Indie-Standard; wirkt wertig und verspielt zugleich |
| 2026-10-25 | Kein Cookie-Banner nötig: Die Website speichert nichts auf dem Gerät (keine Cookies, kein localStorage, keine Dritt-Inhalte); der Bestwert beim Schäfchenzählen gilt nur für den Besuch | Banner wäre rechtlich überflüssig und stört |
| 2026-10-25 | Linux-Pre-Releases als .deb (tool/package_deb.sh, Installation nach /opt/whowolf, Starter und Icon) statt tar.gz | Wunsch des Eigentümers; einfache Installation unter Debian/Ubuntu |
| 2026-10-25 | Walking Skeleton zuerst: minimale Flutter-App + Pre-Release-Pipeline (v0.0.X) vor den Spielregeln; Mindestversionen iOS 15 und macOS 12 (Vorgabe der aktuellen Xcode-Version); Android-Pre-Releases bis zum eigenen Keystore mit Debug-Schlüssel signiert, macOS unsigniert bis Developer-ID-Secrets da sind, iOS nur Compile-Check bis TestFlight-Secrets da sind | Signierung, Builds und Downloads früh auf allen Plattformen erproben statt kurz vor dem Release |
| 2026-10-25 | iPhone und Mac zuerst: Entwicklung und Tests auf iOS/macOS; Android im Emulator auf dem Mac, Windows und Linux über CI-Builds (Linux-Test in einer VM); iOS-Testversionen über TestFlight von Anfang an | Eigentümer testet mit iPhone und Mac und hat kein Android-Gerät |
| 2026-10-25 | Website mehrsprachig per Konfiguration: jede Sprache eine Datei in website/src/i18n/locales/ (typgeprüft gegen Deutsch), lokalisierte URL-Slugs, alle Seiten aus einer Route; hreflang, Sprachumschalter und Sitemap leiten sich daraus ab | Neue Sprachen ohne Umbau hinzufügen |
| 2026-10-25 | Website im Theaterzettel-Look: Papierstruktur (CSS-Rauschen) über der ganzen Seite, Wechsel von Programmheft-Papier und Nachtkarton mit gerissenen Kanten, Schäfchen-Zählen als spielbares Element, nur Scroll-Parallaxe (keine Maus-Parallaxe) | Alles wirkt wie auf dasselbe Papier gedruckt, KI-Bilder und CSS aus einem Guss |
| 2026-10-25 | Spur-Radius r = max(1, ⌊Spielerzahl / 5⌋) (5–9 → 1, 10–14 → 2, 15–20 → 3), symmetrisch, Ziel-Handy gleichverteilt im Fenster | Fenster deckt in jeder Gruppengröße ein Drittel bis die Hälfte des Tisches ab; Regel bleibt in einem Satz erklärbar |
| 2026-10-25 | Tarnaufgabe „Schäfchen zählen“ für Rollen ohne Nachtaktion: Schafe hüpfen über eine Wiese, weiße antippen (+1 Traumpunkt), schwarze nicht (−3); Traumpunkte als Spaß-Wertung am Ende | Alle tippen nachts ähnlich viel, niemand fällt auf; die Wartezeit wird zum Mini-Spiel |
| 2026-10-25 | Impressum nicht im Repo: Der offizielle Build (nurkert/whowolf) liest es zur Build-Zeit von https://nurkert.de/impressum (Whitelist-Sanitizer, Build bricht ab, wenn es fehlt); Forks setzen die Repo-Variable IMPRINT_URL oder zeigen einen Hinweis. Wöchentlicher Rebuild übernimmt Änderungen | Persönliche Daten nur an einer Stelle pflegen, nicht im öffentlichen Repo; Forks übernehmen nicht versehentlich ein fremdes Impressum |
| 2026-10-25 | Website ausgebaut: Szene ohne Bühnenrahmen, Logo-Schriftzug, CI-Schrift Lilita One, Docs-Wiki automatisch aus docs/, Download-Seite automatisch aus GitHub-Releases (zur Build-Zeit, Rebuild bei jedem Release), Datenschutz und Impressum | Einheitlicher Auftritt; Doku und Downloads bleiben ohne Handarbeit aktuell; Besucher kontaktieren keine Dritten |
| 2026-10-25 | Website mit Astro 7 (statisch, website/), Bilder per astro:assets als AVIF/WebP, Schriften selbst gehostet, Deploy per GitHub Actions auf Pages (whowolf.de). CSP: Skripte nur 'self', Styles zusätzlich 'unsafe-inline' (Positionsangaben der Bühnenelemente) | Kein JS-Framework nötig, sehr schnell; die Seite hat keine fremden Inhalte, daher ist die Style-Ausnahme vertretbar. npm-Pakete nur in Versionen, die älter als zwei Wochen sind |
| 2026-10-25 | Assets als Sammelbögen generieren (mehrere Elemente pro Bild, transparenter Hintergrund) und mit tool/assets/slice_sheet.py ausschneiden | Spart Bildgenerierungs-Kontingent und hält Stil und Licht über alle Elemente konsistent |
| 2026-10-25 | Stil „Mondbühne“ für App, Website und alles Weitere: Puppentheater bei Mondlicht, flache Pappfiguren mit Kartonrand an Stäben auf gestaffelten Ebenen (2,5D), Cartoon der 2000er, edel ausgeleuchtet. Assets per Codex-Bildgenerierung, Prompts versioniert (siehe DESIGN.md) | Eigenständig und wiedererkennbar; passt technisch ideal zu Parallaxe und Puppen-Animation; laute Illustration + leise Oberfläche wirkt wertig |
| 2026-10-25 | Offizieller Server auf dem VPS des Eigentümers unter einer Subdomain von whowolf.de (Arbeitsname game.whowolf.de), betrieben mit genau dem Container aus dem Repo | Kein Sonderweg: offizieller Server = Self-Host, Self-Hosting bleibt dadurch erprobt |
| 2026-10-25 | Secure by Design (Bedrohungsmodell in SECURITY_DESIGN.md): Ende-zu-Ende-Verschlüsselung per Noise-Handshake mit Schlüssel + Raumgeheimnis aus dem QR-Code, Identität nur aus der Sitzung, gleicher Nachrichtentakt in geheimen Phasen, abgesicherte Lieferkette und nachprüfbare Releases | Realistischster Angreifer ist der schummelnde Mitspieler im selben WLAN; TLS scheidet aus, weil Browser selbst signierte Zertifikate ablehnen und das Relay später nur Chiffretext sehen soll |
| 2026-10-25 | Tooling „It just works“ (TOOLING.md): ein Befehl pro Aufgabe, tool/check.sh = CI, gepinnte Flutter-Version, verständliche Fehlermeldungen | Lokal und CI verhalten sich identisch; kein Wissen nur im Kopf |
| 2026-10-25 | Domain whowolf.de, App-ID de.whowolf.app, QR-Link https://whowolf.de/join?room=…&lan=… | Domain gesichert; App-ID passend zur Domain (umgekehrt); ein Link-Format, das heute die App und später Browser/Server verstehen |
| 2026-10-25 | MVP zuerst: lokal im WLAN, Rollen Dorfbewohner/Werwolf/Seherin, QR-Beitritt in der App, Tischkreis, Wolfsspur v1; veröffentlicht als GitHub-Release + Website. Server, Browser-Beitritt und Stores erst danach; Server ganz zum Schluss, aber von Anfang an mitgedacht (siehe ROADMAP „Von Anfang an mitdenken“) | Schnellster Weg zu echten Testrunden und einem Release; Wolfsspur ist das Alleinstellungsmerkmal und muss früh am Tisch getestet werden |
| 2026-10-25 | Wolfsspur ersetzt „Knurren nur auf Werwolf-Handys“: Spur kommt auf dem Werwolf-Handy oder beim Sitznachbarn. Öffentliche Regel „Spur bei X → Werwolf auf X oder daneben“. Sitzordnung nötig. Spursystem allgemein für alle Nachtaktionen (z. B. Eulenspur der Seherin). Details in NIGHT_SOUNDS.md | Dorfbewohner bekommen private Hinweise und wollen laut spielen, Werwölfe können sich durch Stummschalten nicht ganz schützen; wer die Spur hört, ist selbst verdächtig, also Diskussion statt Auflösung |
| 2026-10-25 | Positionierung über die Kombination, nicht „erste App mit eigenem Handy“ (siehe MARKET.md); keine Werbung, kein Abo, kein Konto | Marktanalyse: Die Nische ist besetzt, aber nur von kleinen Apps mit Lücken. Realistisches Ziel 10K–100K Downloads über einige Jahre |
| 2026-10-25 | Idee aufgenommen: verräterische Wolfsgeräusche + Morgen-Gähnen auf jedem Handy (optionaler Modus, bewusste Ausnahme von der Anti-Tell-Regel) | Neue, physische Deduktionsebene am Tisch, die es so nur mit „jeder hat sein Handy“ gibt |
| 2026-10-25 | Tag-Bildschirm zeigt nur, wer lebt (und ob man selbst lebt), dann dimmen | Handys weg, Gesichter lesen ist der Kern des Spiels |
| 2026-10-25 | Erzähler optional: App erzählt (Standard) oder Mensch erzählt, App zählt | Manche Gruppen lieben einen menschlichen Erzähler |
| 2026-10-25 | Nacht-Soundscape auf allen Geräten, teils mit echten Hinweisen; Geräusche nie direkt an Rolle/Aktion des Besitzers gekoppelt | Atmosphäre „von überall“, neue Spielebene, ohne Tells |
| 2026-10-25 | Rejoin mit vollem Status und Beitritt während der Partie; Spielleiter ist ein normaler Spieler; Server als Spielleiter später möglich | Ausfälle dürfen kein Spiel kaputt machen; Host-Logik bleibt deshalb Flutter-frei |
| 2026-10-25 | Spiel läuft immer beim Host, Server ist nur Relay (ersetzt „Server ist autoritativ“). Gemischtes Spiel: Spieler im WLAN direkt am Host, Spieler von außen über den Server. QR-Code des Spielleiters führt auf die Server-Webseite (im Browser mitspielen oder App installieren). Offizieller Server voreingestellt, eigener in den Einstellungen, keine Abfrage im Onboarding | Eine einzige Spiellogik für lokal, gemischt und online. Server bleibt dumm, billig und leicht selbst zu hosten, keine Spieldaten auf dem Server. Host verbindet sich ausgehend, daher keine Probleme mit Routern/NAT |
| 2026-10-25 | Start: nur Flutter-App, lokal im gleichen WLAN, ohne Server. Ein Gerät ist Host und spielt intern die Rolle des autoritativen Servers, die anderen verbinden sich per WebSocket im LAN. So plattformübergreifend wie möglich (Android, iOS, macOS, Windows, Linux; Web nur als beitretender Client, siehe ARCHITECTURE). | Schnellster Weg zu einer spielbaren Runde am Tisch, keine Hosting-Kosten. Die Architektur bleibt so geschnitten, dass später ein echter Server ohne Umbau dazukommt: Host-Logik und Transport sind getrennt, das Protokoll ist dasselbe. |
| 2026-10-25 | Name Whowolf | Wortspiel „Who? Wolf“, international verständlich und überall gleich aussprechbar; Websuche fand kein Spiel/keine App dieses Namens, Registerprüfung steht noch aus |
| 2026-10-25 | Doku/Wiki im Repo (website/), nicht im GitHub-Wiki | Versioniert, Teil von Pull Requests, im App-Style gestaltbar |
| 2026-10-25 | Kein Schummeln, Clients sehen nur ihre eigenen Infos | |
| 2026-10-25 | Server in Dart, Regeln in gemeinsamem Paket game_core | Regeln nur einmal schreiben, von App und Server gemeinsam genutzt |
| 2026-10-25 | Self-Hosting per Docker + offizieller Server | Open-Source-Gedanke, jeder kann eigenen Server betreiben |
| 2026-10-25 | Flutter als primäre App, inkl. Flutter Web | Eine Codebasis für alle Plattformen, Beitritt im Browser ohne Installation |
| 2026-10-25 | Monorepo nurkert/whowolf (öffentlich) | App, Server, Website und Doku an einem Ort |
| 2026-10-25 | Lizenz Apache 2.0 | Store-kompatibel, permissiv, mit Patentlizenz |
| 2026-10-25 | Konzept: vor Ort zusammen, jeder mit eigenem Gerät, App als Erzähler | Kein Spielleiter nötig, keine Tells, Regeln automatisch |
