feat(progression): Erfahrung, Aufstieg und Punkteverteilung

Toeten gibt Erfahrung (exp_reward stand seit M3 ungelesen an jedem
Gegner), give_exp als zwoelfte Aktion fuer spaetere Quests. Aufstieg in
einer Schleife am Zugende, ein Punkt je Stufe, keine Obergrenze.

Verteilt wird im Charakterbogen — kein zwoelfter Screen. AssignPoints
nimmt alle Punkte auf einmal und kostet damit einen Zug.

luck wirkt jetzt: eine Chance auf einen Zusatzzug auf jeder Beutetabelle.

Drei Befunde:
- strength und constitution las niemand, zwei der fuenf verteilbaren
  Grundwerte waren Fallen. Zwei balance-Knoepfe rechnen sie beim
  Verteilen um.
- Rng::chance(0.0) verbrauchte eine Zahl und verschob den Zufallsstrom.
- Cheat::ClearRoom ging am Todesweg vorbei.
This commit is contained in:
2026-08-12 21:15:25 +02:00
parent b072e5ade3
commit b19492bb51
12 changed files with 421 additions and 45 deletions

View File

@@ -146,3 +146,34 @@ Blocker gewesen.
Die Beute-Skalierung darf **nicht gegen fünf feste Etagen fest verdrahtet** werden — der Endlosmodus
kommt später, und eine Skalierung, die nur bis Etage 5 denkt, wäre dann ein Umbau statt einer
Erweiterung.
### Befunde aus M5
**Zwei der fünf verteilbaren Grundwerte waren Fallen.** Das Ticket verteilt Punkte auf `strength`,
`dexterity`, `constitution`, `charisma` und `luck` — und begründet sauber, warum abgeleitete Größen
ausgeschlossen bleiben. Nur las `strength` und `constitution` bis M5 **niemand**: `damage` und
`max_health` sind eigene Attribute ohne Herleitung, `dexterity` steckt in Flucht und Initiative,
`charisma` seit M4 im Preis, `luck` jetzt in der Beute. Ein Punkt in Stärke hätte nichts getan.
Entschieden: `damage_per_strength` und `health_per_constitution` als `[balance]`-Knöpfe, angewandt
**beim Verteilen** und nicht beim Auslesen. Damit hebt ein Punkt in Konstitution den *Grundwert*
`max_health` — genau das, was der Satz „`max_health` steigt erst, wenn `constitution` tatsächlich
erhöht wird, also beim Verteilen" ohnehin voraussetzt. In `Game::attribute` gehört die Umrechnung
nicht: Dort wäre sie ein Sonderfall im generischen Pfad, dieselbe Begründung, mit der M4 die
Charisma-Formel in die Preisfunktion gelegt hat.
**Von den „zwei Stellen" ist nur eine echt.** Das Ticket nennt Aufstieg *und* `AssignPoints` als
Stellen, an denen der Lebensstand einem `max_health`-Zuwachs folgt. Im Code ist die erste beweisbar ein
No-op: Der Aufstieg hebt `base.level` und `unspent_points`, sonst nichts, und `per_level` hat dasselbe
Ticket ersatzlos gestrichen. Die vorsorgliche Vorher/Nachher-Klammer im Aufstieg ist raus — sie
suggerierte eine Regel, die es nicht gibt.
**`Rng::chance(0.0)` verbrauchte eine Zahl.** Aufgefallen, weil die Glücksregel aus Ticket 16 auch beim
Erzeugen einer Etage greift (Händlerregal, `luck = 0`) und damit den ganzen Zufallsstrom verschob — ein
bestehender Kampftest schlug fehl, weil sein Angriff plötzlich danebenging. `chance` kürzt jetzt bei
0 und 1 ab. Ohne das erzeugte derselbe Seed je nach Glück des Helden eine andere Etage, und die Zusage
aus Ticket 14 („Seed im Save ⇒ Nachladen würfelt nicht neu") wäre stillschweigend gebrochen gewesen.
**`Cheat::ClearRoom` ging am Todesweg vorbei.** Die Werkbank setzte den Lebensstand auf null und ließ
das Aufräumen am Zugende erledigen — ohne `check_death`, also ohne Todes-Trigger und ohne Erfahrung.
Genau der Fehler, gegen den ihr eigener Kommentar argumentierte. Sie ruft jetzt `check_death`.