# DESIGN_NOTES.md

Entscheidungsprotokoll während der Umsetzung, wie im Masterprompt gefordert
("dokumentiere Annahmen in DECISIONS.md"). Dies ist der wichtigste Eintrag.

---

## Korrektur: Ader-Bonus-Mechanik (gefunden durch Simulation, M1)

**Ursprüngliche Spezifikation (Konzept-/PRD-Dokument):** Ein Ader-Bonus
erscheint mit 8 % Chance nach einem erfolgreichen Schlag. Er sollte nur
eingelöst werden, wenn der *nächste* Schlag in Weißglut ausgeführt wird und
überlebt (+0,5× Einsatz Sofortbonus).

**Befund:** Beim Aufbau der Monte-Carlo-Simulation (`sim.js`, Abnahmekriterium
aus PRD §5.4) wurde geprüft, ob der Gesamt-Erwartungswert für die Strategie
"Nur Weißglut" innerhalb der Toleranz um C^n liegt. Er lag deutlich
außerhalb (gemessener Mittelwert 1,0236 vs. erwarteter 0,9901 bei n=3,
Abweichung > 11 Standardfehler). Der Grund: Eine Strategie, die immer
Weißglut wählt, kann *jeden* erschienenen Bonus einlösen, während Glut- oder
Feuer-Strategien ihn nur einlösen könnten, wenn sie gezielt für einen
einzelnen Schlag auf Weißglut wechseln. Die ursprüngliche Ader-Regel machte
Weißglut damit strikt überlegen und widersprach der zentralen
Fairness-Zusage des Spiels: "jede Hitzestufe ist strategisch gleichwertig."

**Korrektur:** Der Ader-Bonus wird jetzt **sofort bei Erscheinen und
unabhängig von der gewählten Hitzestufe** ausgeschüttet (kein Erfordernis
eines Weißglut-Folgeschlags mehr). Die 8-%-Auslösewahrscheinlichkeit selbst
war bereits heat-unabhängig; durch den Wegfall der
Weißglut-Einlösebedingung ist jetzt auch die *Einlösung* heat-unabhängig.

**Verbleibende, bewusst in Kauf genommene und offen dokumentierte
Eigenschaft:** Da der Bonus als fester Betrag in Einsatz-Einheiten (+0,5×)
ausgezahlt wird, während der Basis-Multiplikator je nach Hitzefolge
unterschiedlich stark wächst, trägt der Bonus bei aggressiven Hitzefolgen
(Weißglut) *relativ* etwas weniger zum Gesamtergebnis bei als bei
vorsichtigen (Glut) — bei gleicher Schlagzahl. Diese Restabweichung ist
klein (siehe SIMULATION_REPORT.md, Abschnitt 3b: ca. 4–10 % des Einsatzes je
nach Strategie) und wird **nicht als invariant beworben**. Stattdessen gilt:

> Die Kernaussage "jede Hitzestufe ist strategisch gleichwertig" bezieht
> sich auf den Basis-Schmiedepfad (Multiplikator-Wachstum), der
> **mathematisch exakt bewiesen und simulationsverifiziert** invariant ist.
> Der Ader-Bonus ist ein klar deklarierter, kleiner Zusatzmechanismus mit
> leicht unterschiedlichem Erwartungsbeitrag je nach Spielstil.

Diese Formulierung ersetzt die im ursprünglichen Konzeptdokument zu weit
gefasste Aussage, der *gesamte* Erwartungswert (inklusive Bonus) sei für
jede Strategie exakt identisch. Sie ist die im Verifikator und im UI
kommunizierte, wahrheitsgemäße Fassung.

**Warum nicht stattdessen die Wahrscheinlichkeiten p neu kalibrieren, um
auch den Bonus einzupreisen?** Das wurde geprüft (siehe Kommentar in
`engine.js`): Eine exakte Kompensation ist nur möglich, wenn der Bonus
selbst multiplikativ (proportional zum aktuellen Multiplikator) statt
additiv (fester Betrag) ausgezahlt wird. Das hätte aber bedeutet, die
bereits im Konzept-Playscreen und PRD kommunizierten Bruchwahrscheinlichkeiten
(5 % / 13 % / 29 %) zu verändern — eine größere, sichtbare Änderung an
bereits gezeigten Zahlen. Die gewählte Lösung (heat-unabhängige
Sofortauszahlung + ehrliche Dokumentation der kleinen Restabweichung) hält
alle bereits kommunizierten Kernzahlen stabil und behebt den eigentlichen
Fairness-Fehler (Weißglut-Bevorzugung) vollständig.

---

## Entkopplung von Ingot-Optik und Hitzewahl (nach Asset-Katalog des Nutzers)

Der Nutzer lieferte einen Asset-Katalog mit 10 Glutkern-Stufen (Stufe 1
"Kalt" bis Stufe 10 "Weißglut") und wollte eine Hammer-Animation, die
zwischen diesen Stufen übergeht. Das ersetzt das bisherige System, in dem
die Ingot-Farbe direkt die GEWÄHLTE Hitzestufe (Glut/Feuer/Weißglut)
widerspiegelte.

**Neue Aufteilung:**
- **Hitzestufe (Glut/Feuer/Weißglut):** weiterhin reine Risiko-Wahl für die
  Spielmathematik (unverändert, siehe Abschnitt oben). Visuell jetzt nur
  noch am Hitze-Regler selbst sichtbar (Rahmenfarbe der drei Segmente).
- **Glutkern-Stufe (1–10):** rein visuell, entspricht der Anzahl
  erfolgreicher Schläge in der laufenden Runde, unabhängig von der
  Hitzewahl. Bei Rundenstart immer Stufe 1 (kalt), wächst mit jedem
  Schlag, sättigt bei Stufe 10 (bleibt dort bei weiteren Schlägen).

Das ist eine bewusste Vereinfachung: eine Zuordnung wie "Weißglut-Schläge
lassen die Stufe schneller steigen als Glut-Schläge" wäre thematisch auch
denkbar gewesen, hätte aber die Kernlogik verkompliziert und war vom
Nutzer nicht explizit gefordert. Die aktuelle 1:1-Zuordnung
(Schlagzahl = Stufe) ist einfach nachvollziehbar und für die Katalog-Assets
direkt nutzbar.

## Korrektur: rgba() in SVG-Präsentationsattributen (gefunden nach Nutzer-Screenshot)

Der Nutzer meldete mit Screenshots, dass Amboss und Ingot-Grafik auf einem
iPhone (Mobile Safari) als kaputte graue Blase mit weißem "X" statt der
eigentlichen Grafik erschienen — sowohl über `file://` als auch über einen
echten lokalen HTTP-Server. Untersuchung ergab zwei Ursachen:

1. **Echter Bug:** Alle 10 Ingot-Stufen-SVGs nutzten `stroke="rgba(r,g,b,a)"`
   als Präsentationsattribut. Die SVG-1.1-Spezifikation für
   Präsentationsattribute (im Unterschied zu CSS-`style`-Eigenschaften)
   kennt kein `rgba()` mit Alphakanal — nur `rgb()`, Hex-Farben oder
   benannte Farben. Manche strikten Parser (u. a. mobiles WebKit) lehnen
   das ab. Behoben durch `stroke="rgb(r,g,b)" stroke-opacity="a"` (beides
   spezifikationskonform), sowohl in den erzeugten Dateien als auch im
   Generator-Skript `generate-ingot-stages.js`.
2. **Vermuteter Cache-Effekt:** Da derselbe Bug identisch über mehrere
   Testrunden mit unterschiedlichen ZIP-Versionen auftrat, liegt nahe, dass
   der Browser zwischenzeitlich eine alte, gecachte Version einzelner
   Assets zeigte. Als dauerhafte Absicherung wurde allen Bild-/Sound-Pfaden
   ein Cache-Busting-Query-Parameter (`?v=v3`) angehängt, zentral über die
   Konstante `ASSET_VERSION` in `app.js` sowie manuell in `index.html` und
   `styles.css`. Bei künftigen Asset-Updates einfach `ASSET_VERSION`
   hochzählen, dann lädt jeder Browser garantiert die neue Version.

**Wichtig für das Anvil-Problem im Speziellen:** `anvil.svg` selbst enthielt
kein `rgba()` — der rgba()-Fund erklärt zweifelsfrei nur die
Ingot-Stufen-Dateien. Für den Amboss bleibt die Cache-Theorie die
plausibelste Erklärung, da die Datei in einem eigenständigen SVG-Rasterizer
(cairosvg) einwandfrei als korrekter Amboss rendert und keine weiteren
Spezifikationsverstöße gefunden wurden.

## Weitere Annahmen

- **Client-seitige "Server"-Simulation:** Für diesen lokal testbaren
  Prototyp läuft die komplette Rundenlogik (inkl. Seed-Erzeugung) im
  Browser selbst, nicht auf einem echten Backend-Server. Das ist eine
  bewusste Vereinfachung gegenüber PRD §7/T-02 ("Server ist autoritativ"),
  um das Spiel ohne Node-Installation oder Hosting direkt aus der ZIP-Datei
  heraus spielbar zu machen. Für einen Produktivbetrieb mit Echtgeld ist
  serverseitige Autorität zwingend (siehe KNOWN_ISSUES.md).
- **Reality-Check-Intervall** ist im Einstellungsmenü auf eine kürzere
  Testdauer (Minuten statt der produktiv vorgesehenen 30–60 Minuten)
  einstellbar, damit die Funktion beim Testen tatsächlich beobachtet werden
  kann, ohne eine Stunde zu warten.
- **Gilden-Esse / echtes Multiplayer** wurde wie im PRD als Nicht-Ziel für
  diesen Prototyp behandelt; der Live-Feed am Bildschirmrand ist eine
  lokale Simulation fiktiver Mitspieler, klar als solche gekennzeichnet.
