docs: ticket 15 (progression) aufloesen, nachtraege an 01 07 11 14, erfahrung ins glossar

This commit is contained in:
2026-08-12 13:45:41 +02:00
parent 380400611e
commit 5faa5d6165
7 changed files with 170 additions and 2 deletions

View File

@@ -138,10 +138,20 @@ eine Aktion, die sie ausführt.
überall verwendbar, wo eine Aktion stehen darf, und braucht keine eigenen Platzierungsregeln. Es gibt überall verwendbar, wo eine Aktion stehen darf, und braucht keine eigenen Platzierungsregeln. Es gibt
Aktionen zurück, die in die Warteschlange aus 08 wandern — der Schreibpfad bleibt also genau einer. Aktionen zurück, die in die Warteschlange aus 08 wandern — der Schreibpfad bleibt also genau einer.
### Nachtrag aus Ticket 15: `give_exp`
`{ action = "give_exp", amount = 50, target = "self" }` als **zehnte Aktion**, für Questbelohnungen.
Erfahrung aus Tötungen läuft dagegen über das Feld `exp_reward` an der `creatures`-Registry — die
Kurzform für einen Todes-Trigger, den sonst jede Gegnerdefinition mitschleppen müsste.
Ticket 15 hat außerdem geprüft, ob ein Modifikator „je Level" skalieren können muss (`per_level`).
**Antwort: nein** — Charakteroptionen geben flache Boni, und was sie dauerhaft relevant hält, sind
Fähigkeiten. Das Vokabular bleibt hier unverändert.
### Der Katalog ### Der Katalog
`damage` · `change_attribute` · `apply_modifier` · `remove_modifier` · `give_item` · `remove_item` · `damage` · `change_attribute` · `apply_modifier` · `remove_modifier` · `give_item` · `remove_item` ·
`start_quest` (08) · `flee` (14) · `run_script` (13) — **neun**. `start_quest` (08) · `flee` (14) · `run_script` (13) · `give_exp` (15) — **zehn**.
### Bewusst nicht entschieden ### Bewusst nicht entschieden

View File

@@ -177,6 +177,15 @@ Zwei neue Felder am `Creature`:
Dazu der RNG-Seed als Feld in `Game`, damit Nachladen nicht neu würfelt. Dazu der RNG-Seed als Feld in `Game`, damit Nachladen nicht neu würfelt.
Ticket 15 beantwortet außerdem die Frage, die 07 offen an es weitergereicht hatte — wo der
EXP-Fortschritt wohnt: **`current_exp` und `unspent_points: u32` gehören an `Game`**, nicht an
`Creature`. `base.level` bleibt am Wesen, weil Gegner echte Level haben und die Etagen-Skalierung sie
liest; Erfahrung und unverteilte Punkte hat dagegen ausschließlich der Held, und ein Feld, das für
99 % der Exemplare bedeutungslos ist, schriebe der Save für jeden Gegner mit.
`base.level` ist dabei die **einzige** Quelle für Punkte; `attribute(wer, "level")` darf durch
Modifikatoren höher ausfallen, ohne welche zu schenken.
Und die Antwort auf die Frage, die 07 offen an 14 gereicht hatte: **Tote Gegner werden am Ende von Und die Antwort auf die Frage, die 07 offen an 14 gereicht hatte: **Tote Gegner werden am Ende von
`Game::execute` entfernt**, nach dem Leerarbeiten der Event-Warteschlange. Innerhalb eines Zuges `Game::execute` entfernt**, nach dem Leerarbeiten der Event-Warteschlange. Innerhalb eines Zuges
bleiben Indizes stabil. bleiben Indizes stabil.

View File

@@ -59,6 +59,12 @@ hätte es vergessen.
`Unequip(SlotId)` · `Drop(usize, u32)` · `PickUp(usize)` · `Descend` · `Talk(NpcId)` · `Unequip(SlotId)` · `Drop(usize, u32)` · `PickUp(usize)` · `Descend` · `Talk(NpcId)` ·
`Buy(ItemId, u32)` · `Sell(usize, u32)` · `Wait` `Buy(ItemId, u32)` · `Sell(usize, u32)` · `Wait`
*Nachtrag aus Ticket 15:* **`AssignPoints`** kommt als dreizehnter Command dazu — ein Aufstieg gibt
einen frei verteilbaren Attributpunkt, verteilt wird im `CharacterSheet`. Bewusst **ein** Command mit
allen Punkten auf einmal statt einer je Punkt: Drei Stufen wären sonst drei Züge, in denen ein
Gift-Debuff tickt, während man ein Menü bedient. Dasselbe Muster wie `Buy(item, 10)`, und damit ohne
Ausnahme von der Zugregel.
Weder Angriff noch Flucht sind **eigene Varianten** — beides sind Fähigkeiten: Weder Angriff noch Flucht sind **eigene Varianten** — beides sind Fähigkeiten:
`UseAbility("core:attack", ziel)` und `UseAbility("core:flee", …)`. Ticket 02 hat Fähigkeiten als `UseAbility("core:attack", ziel)` und `UseAbility("core:flee", …)`. Ticket 02 hat Fähigkeiten als
Registry festgelegt, also gehören sie dorthin, und ein Mod kann beide ersetzen: eine Klasse, die Registry festgelegt, also gehören sie dorthin, und ein Mod kann beide ersetzen: eine Klasse, die

View File

@@ -206,6 +206,13 @@ nicht.
Standardwerte liegen in der Engine, nicht in `core`. Dann ist ein Mod, der einen Knopf dreht, eine Standardwerte liegen in der Engine, nicht in `core`. Dann ist ein Mod, der einen Knopf dreht, eine
Zeile lang. Zeile lang.
**Nachtrag aus Ticket 15:** Zwei weitere Knöpfe kommen dazu — `exp_base` und `exp_exponent`, die die
Erfahrungskurve bilden. Eine Tabelle je Level wäre die Alternative gewesen; zwei Zahlen schlagen
fünfzig Zeilen. Dazu bekommt die `creatures`-Registry ein Feld `exp_reward`.
Ausdrücklich **nicht** dazugekommen ist `points_per_level`: Ein Aufstieg gibt genau einen Punkt, das
ist eine Regel und kein Stellknopf.
### Vier Nachträge an geschlossene Tickets ### Vier Nachträge an geschlossene Tickets
| Ticket | Nachtrag | | Ticket | Nachtrag |

View File

@@ -1,7 +1,7 @@
# 15 — Progression und Level-up # 15 — Progression und Level-up
Type: grilling Type: grilling
Status: open Status: resolved
Blocked by: 02 Blocked by: 02
## Question ## Question
@@ -23,3 +23,126 @@ Attributkatalog aus 01 steht. Offen ist, was ein Level überhaupt gibt:
Folgen für die Etagen-Länge. Folgen für die Etagen-Länge.
Ergebnis: Aufstiegsregel, Kurvenform (Daten oder Formel), Erfahrungsquellen und die Obergrenze. Ergebnis: Aufstiegsregel, Kurvenform (Daten oder Formel), Erfahrungsquellen und die Obergrenze.
## Answer
Begriffe im [Glossar](../../../CONTEXT.md). Dieses Ticket entscheidet **Formen und Regeln** — die
konkreten Zahlen bleiben beim Balancing, das ein spielbares Spiel voraussetzt.
### Ein Aufstieg gibt genau einen Punkt
Frei verteilbar auf die **fünf Grundwerte**: `strength` · `dexterity` · `constitution` · `charisma` ·
`luck`. Abgeleitete Größen wie `damage` oder `hit_chance` bleiben ausgeschlossen — Punkte direkt
dorthin zu setzen umginge das ganze Modifikatorsystem aus 01.
**`current_exp` und `unspent_points` leben an `Game`, nicht am `Creature`.** Ticket 07 hatte die
Platzierung ausdrücklich hierher delegiert; `base.level` bleibt am Wesen (Gegner haben echte Level, die
Etagen-Skalierung liest sie), aber Erfahrung und unverteilte Punkte hat ausschließlich der Held. Ein
Feld, das für 99 % der Exemplare bedeutungslos ist, wäre ein Kommentar in Feldform — und der Save
schriebe es für jeden Gegner mit. Beide Werte werden ohnehin nur beim Aufstieg und in `AssignPoints`
angefasst, und beides läuft über `Game`.
Verteilt wird im `CharacterSheet` aus Ticket 11, kein zwölfter Screen. **Kein Umverteilen** — ein
Permadeath-Lauf ist kurz und endet endgültig, eine Respec-Mechanik löst ein Problem, das dabei gar
nicht entsteht.
`AssignPoints` ist **ein** Command mit allen Punkten auf einmal und kostet damit **einen** Zug. Ein
Command je Punkt hieße bei drei Stufen drei Züge, in denen ein Gift-Debuff tickt, während man ein Menü
bedient; eine Ausnahme von der Zugregel wollte Ticket 11 ausdrücklich vermeiden. Dasselbe Muster wie
`Buy(item, 10)`.
### Keine Obergrenze
`Stats::level_up()`s `clamp(1, 50)` fällt ersatzlos. Fünfzig Stufen über fünf Etagen wären
bedeutungslos, und eine harte Grenze wäre der einzige Teil der Progression, der einen späteren
**Endlosmodus** blockierte.
Die Kurve begrenzt sich selbst über steigende Kosten: `exp_base` und `exp_exponent` als zwei Felder in
`[balance]` aus Ticket 14 — zwei Zahlen statt fünfzig Tabellenzeilen. Eine Tabelle ließe einen Modder
Level 13 zum Sprung machen; falls das je gewünscht ist, ist sie der Ausbau.
### Erfahrung aus Tötungen und Quests
`exp_reward` als Feld an der `creatures`-Registry aus 14, plus **`give_exp` als zehnte Aktion** für
Questbelohnungen.
Das sind zwei Wege zum selben Ziel, gerechtfertigt nach demselben Muster, mit dem Ticket 01 `armor` als
Kurzschreibweise für Resistenz zugelassen hat: `exp_reward` ist die Kurzform für einen Todes-Trigger,
den sonst **jede einzelne** Gegnerdefinition mitschleppen müsste — samt einer `is_self`-Prüfung, die es
gar nicht gibt.
**Keine Erfahrung fürs Betreten einer Etage.** Das belohnte das Durchrennen; wer Räume auslässt, soll
schwächer ankommen — das ist die Spannung, von der ein Abstieg lebt.
Geprüft wird am Ende von `Game::execute`, nach dem Leerarbeiten der Warteschlange aus 08 — dann wirkt
eine Questbelohnung noch im selben Zug. Reicht die Erfahrung für mehrere Stufen, wird in einer
**Schleife** aufgestiegen; drei Stufen geben drei Punkte. Eine Stufe pro Ereignis erzeugte sonst die
Frage, wann der Rest nachgeholt wird, plus einen Zustand „aufstiegsbereit", den niemand bestellt hat.
### Die Zuwachs-Regel bleibt eng
Steigt `max_health` durch Progression um 10, steigt der Lebensstand um 10 mit — **aber nur durch
Progression.**
Ticket 01 hat davor ausdrücklich gewarnt: *„Ein Modifikator wirkt auf `max_health`, eine Aktion ändert
den Lebensstand. Die Trennung muss scharf bleiben, sonst heilt ein Ring beim Anlegen."* Eine allgemeine
Regel „max ändert sich → Stand ändert sich mit" bräche das sofort.
Genau **zwei** Stellen erhöhen den Stand um den Zuwachs, beide im Spielkern benannt statt aus einer
allgemeinen Regel gefolgert:
1. der Aufstieg,
2. `AssignPoints` — und das ist die unauffällige: `max_health` steigt erst, wenn `constitution`
tatsächlich erhöht wird, also beim Verteilen und nicht schon beim Aufstieg.
Ausrüstung nie. Der Unterschied ist die Dauerhaftigkeit: Ein Ring kommt und geht, ein Punkt in
Konstitution bleibt.
### Rasse und Klasse bleiben flach
Das beantwortet die Skalierungsfrage aus dem Ticketkörper mit „gar nicht": **`per_level` als Nachtrag
an 01 entfällt ersatzlos.** Charakteroptionen geben einen einmaligen, flachen Bonus.
Dass „Zwerg: +2 Konstitution" auf Level 30 nur noch Rauschen ist, ist gewollt. Was Charakteroptionen
dauerhaft trägt, sind **Fähigkeiten** — die veralten nicht. Ticket 02 hat sie als „Modifikatoren *und*
Fähigkeiten" definiert, und der interessante Teil ist die zweite Hälfte: Ein Magier bleibt ein Magier,
weil er zaubern kann, nicht weil er +2 auf etwas hat.
### `level` darf modifiziert werden
`Creature.base.level` steigt beim Aufstieg und ist die **einzige** Quelle für Punkte.
`attribute(wer, "level")` darf durch Modifikatoren höher ausfallen und wird von Bedingungen („Level ≥
3"), Formeln und Etagen-Skalierung gelesen.
Ein Ring mit `+1 level` macht den Helden also für alles, was Level *liest*, eine Stufe stärker — ohne
einen Punkt zu schenken. Dieselbe Trennung wie zwischen `max_health` und Lebensstand. Modifikatoren auf
`level` zu verbieten wäre die Bevormundung, die Ticket 02 abgeräumt hat, und nähme einem Modder ein
hübsches Item, das keinen Schaden anrichtet.
### Endlosrunner — neu aufgetaucht, bewusst hinter 1.0
In dieser Sitzung kam auf, dass das Fernziel ein **Endlosrunner** ist. Das berührt drei geschlossene
Entscheidungen: die Siegbedingung aus 10, `GameOver { outcome: Won }` aus 14, und die
`floors`-Registry, die einen Eintrag *je Nummer* hat — Etage 500 bräuchte eine Definition.
**1.0 bleibt endlich.** Die endliche Fassung ist vollständig durchentschieden, und ein Endlosmodus ist
additiv: ein Feld `repeat = true` an der letzten Etage plus eine Skalierungsformel. Umgekehrt hieße es,
10 und 16 gegen ein Zielbild zu bauen, das noch niemand gespielt hat.
Die fehlende Level-Obergrenze ist der Teil, der davon **jetzt schon** profitiert — sie wäre der einzige
Blocker gewesen.
### Vier Nachträge an geschlossene Tickets
| Ticket | Nachtrag |
|---|---|
| **01** | `give_exp` als **zehnte** Aktion |
| **07** | `current_exp` und `unspent_points: u32` an **`Game`**, nicht am `Creature` — die Platzierung, die 07 hierher delegiert hatte |
| **11** | `AssignPoints` als **dreizehnter** Command |
| **14** | `exp_base` und `exp_exponent` in `[balance]`, dazu `exp_reward` an der `creatures`-Registry |
### Auflage an Ticket 16
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.

View File

@@ -77,6 +77,7 @@ auch über Ticket 13.
- [12 — Prototyp: ratatui-Durchstich](issues/12-prototyp-ratatui-durchstich.md) ([#13](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/13)) — **Das Modell aus 11 traegt.** Primaerquelle: Branch `prototyp/12-ratatui-durchstich`, `cargo run --example durchstich`. Bestaetigt: `mod game` bleibt ratatui-frei ohne Disziplin, Grid als eigenes `impl Widget` ueber `buf[(x,y)].set_symbol(…)`, `Vec<Screen>` mit Overlay-Flag fuer Rendern *und* Auto-Schliessen, `Response` statt Stack-Mutation (kein Borrow-Aerger). **Der Windows-Fallstrick ist jetzt eine Zahl**: `Tasten 14 → Press 7 → Zuege 7` — ohne Filter kostete jeder Schritt zwei Zuege und damit doppelte Spielzeit. Zwei Korrekturen: 11 sagte „alle Commands kosten einen Zug", richtig ist **alle ausgefuehrten** (`Outcome { TurnPassed, Rejected(&str) }`, Grund reist mit zurueck); und `Command` muss `Clone` sein, damit `Confirm` es herausgeben kann. Ungetestet blieb `Registries` neben `Game` — der Durchstich laedt keine. - [12 — Prototyp: ratatui-Durchstich](issues/12-prototyp-ratatui-durchstich.md) ([#13](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/13)) — **Das Modell aus 11 traegt.** Primaerquelle: Branch `prototyp/12-ratatui-durchstich`, `cargo run --example durchstich`. Bestaetigt: `mod game` bleibt ratatui-frei ohne Disziplin, Grid als eigenes `impl Widget` ueber `buf[(x,y)].set_symbol(…)`, `Vec<Screen>` mit Overlay-Flag fuer Rendern *und* Auto-Schliessen, `Response` statt Stack-Mutation (kein Borrow-Aerger). **Der Windows-Fallstrick ist jetzt eine Zahl**: `Tasten 14 → Press 7 → Zuege 7` — ohne Filter kostete jeder Schritt zwei Zuege und damit doppelte Spielzeit. Zwei Korrekturen: 11 sagte „alle Commands kosten einen Zug", richtig ist **alle ausgefuehrten** (`Outcome { TurnPassed, Rejected(&str) }`, Grund reist mit zurueck); und `Command` muss `Clone` sein, damit `Confirm` es herausgeben kann. Ungetestet blieb `Registries` neben `Game` — der Durchstich laedt keine.
- [13 — Script-Engine wählen](issues/13-script-engine-waehlen.md) ([#14](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/14)) — **Rhai**, aber die Wahl ist dank der Leitplanke aus 05 nur noch eine *Implementierungs*-Entscheidung: Scripts lesen ueber eine Handvoll Funktionen (gespiegelt an der Bedingungsgrammatik aus 08 — sie sehen nichts, was eine Bedingung nicht auch saehe) und schreiben ausschliesslich ueber Aktionen. Begruendung unbequem, aber ehrlich — **fuer ein unveroeffentlichtes Terminal-Roguelike schreibt niemand Mods**, der Lua-Vorsprung zahlt sich erst mit einer Gemeinde aus. Mods gelten als **vertrauenswuerdig** (wie bei Factorio, Minecraft, Skyrim), gehaertet wird gegen Unfaelle: acht Engine-Schalter, gegen die Doku geprueft; `set_max_operations` ausdruecklich **nicht** in `[balance]`, sonst hebt ein Mod sein eigenes Limit auf. `rand()` laeuft durch den Seed aus 14, sonst wuerfelten ausgerechnet Scripts beim Laden neu. `run_script` als neunte Aktion, Scripts als **elfte Registry**. Risiken beobachtet mit benanntem Ausstiegssignal; `smartstring` ist ein INFO-Advisory, kein Ausstiegsgrund. **Stufe (c) wandert hinter 1.0** — eine Script-Engine zu bauen, bevor jemand an eine Vokabular-Luecke gestossen ist, baut die Antwort vor der Frage. - [13 — Script-Engine wählen](issues/13-script-engine-waehlen.md) ([#14](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/14)) — **Rhai**, aber die Wahl ist dank der Leitplanke aus 05 nur noch eine *Implementierungs*-Entscheidung: Scripts lesen ueber eine Handvoll Funktionen (gespiegelt an der Bedingungsgrammatik aus 08 — sie sehen nichts, was eine Bedingung nicht auch saehe) und schreiben ausschliesslich ueber Aktionen. Begruendung unbequem, aber ehrlich — **fuer ein unveroeffentlichtes Terminal-Roguelike schreibt niemand Mods**, der Lua-Vorsprung zahlt sich erst mit einer Gemeinde aus. Mods gelten als **vertrauenswuerdig** (wie bei Factorio, Minecraft, Skyrim), gehaertet wird gegen Unfaelle: acht Engine-Schalter, gegen die Doku geprueft; `set_max_operations` ausdruecklich **nicht** in `[balance]`, sonst hebt ein Mod sein eigenes Limit auf. `rand()` laeuft durch den Seed aus 14, sonst wuerfelten ausgerechnet Scripts beim Laden neu. `run_script` als neunte Aktion, Scripts als **elfte Registry**. Risiken beobachtet mit benanntem Ausstiegssignal; `smartstring` ist ein INFO-Advisory, kein Ausstiegsgrund. **Stufe (c) wandert hinter 1.0** — eine Script-Engine zu bauen, bevor jemand an eine Vokabular-Luecke gestossen ist, baut die Antwort vor der Frage.
- [14 — Kampfformeln und Rundenablauf](issues/14-kampfformeln-und-rundenablauf.md) ([#15](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/15)) — **Ein Zug = Spielerhandlung plus alle Gegnerreaktionen**, sonst tickte ein Debuff bei drei Gegnern viermal. Initiative als `i32` **am Wesen** statt als Reihenfolgeliste (die waere eine zweite Indexsammlung mit demselben Ungueltigkeitsproblem); tote Gegner erst am Ende von `execute`, nach dem Leeren der Warteschlange. Trefferformel und Schadenskette mit drei Klemmbereichen — `0.8` bei Resistenz, weil `1.0` Immunitaet und damit ein Spielabbruch waere. **Die Krit-Reihenfolge-Frage loest sich auf**: multiplikativ ist kommutativ. Eigener xorshift, **Seed im Save** — Nachladen wuerfelt nicht neu. Faehigkeiten kosten Ausdauer, Abklingzeit in Zuegen, gesperrt ⇒ `Rejected` ohne Zug. **Achte Registry: Wesen** — die Luecke lag seit 02 offen; `ai` als geordnete Bedingungsliste. `[balance]` verschmilzt **feldweise**, ausdrueckliche Ausnahme zu 03 (festes Schema). Vier Nachtraege: `scale` und `flee` an 01, drei Felder an 07, zwei Events an 08, `GameOver` an 11. - [14 — Kampfformeln und Rundenablauf](issues/14-kampfformeln-und-rundenablauf.md) ([#15](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/15)) — **Ein Zug = Spielerhandlung plus alle Gegnerreaktionen**, sonst tickte ein Debuff bei drei Gegnern viermal. Initiative als `i32` **am Wesen** statt als Reihenfolgeliste (die waere eine zweite Indexsammlung mit demselben Ungueltigkeitsproblem); tote Gegner erst am Ende von `execute`, nach dem Leeren der Warteschlange. Trefferformel und Schadenskette mit drei Klemmbereichen — `0.8` bei Resistenz, weil `1.0` Immunitaet und damit ein Spielabbruch waere. **Die Krit-Reihenfolge-Frage loest sich auf**: multiplikativ ist kommutativ. Eigener xorshift, **Seed im Save** — Nachladen wuerfelt nicht neu. Faehigkeiten kosten Ausdauer, Abklingzeit in Zuegen, gesperrt ⇒ `Rejected` ohne Zug. **Achte Registry: Wesen** — die Luecke lag seit 02 offen; `ai` als geordnete Bedingungsliste. `[balance]` verschmilzt **feldweise**, ausdrueckliche Ausnahme zu 03 (festes Schema). Vier Nachtraege: `scale` und `flee` an 01, drei Felder an 07, zwei Events an 08, `GameOver` an 11.
- [15 — Progression und Level-up](issues/15-progression-und-levelup.md) ([#16](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/16)) — Ein Aufstieg gibt **genau einen** frei verteilbaren Punkt auf die fuenf Grundwerte; `AssignPoints` ist **ein** Command mit allen Punkten (drei Stufen waeren sonst drei Zuege im Menue). **Keine Obergrenze** — `clamp(1, 50)` faellt, die Kurve begrenzt sich ueber steigende Kosten (`exp_base`, `exp_exponent` in `[balance]`). Erfahrung aus Toetungen (`exp_reward` am Wesen) und Quests (`give_exp`, zehnte Aktion), **nicht** fuers Betreten einer Etage — das belohnte das Durchrennen. **Die Zuwachs-Regel bleibt eng**: nur Aufstieg und `AssignPoints` heben den Lebensstand mit `max_health`, Ausruestung nie — sonst „heilt ein Ring beim Anlegen" (01). Rasse und Klasse bleiben **flach**, `per_level` entfaellt ersatzlos; was sie traegt, sind Faehigkeiten. `level` darf modifiziert werden, aber Punkte haengen an `base.level` — ein `+1 level`-Ring schenkt keinen. Vier Nachtraege: `give_exp` an 01, `current_exp`/`unspent_points` an **`Game`** statt ans Wesen (07 hatte die Platzierung hierher delegiert), `AssignPoints` an 11, zwei Balance-Knoepfe plus `exp_reward` an 14.
## Not yet specified ## Not yet specified
@@ -86,6 +87,8 @@ auch über Ticket 13.
- **Inventar-UX** — Gewicht oder Kapazität (`carry_capacity` ist seit 01 ein Attribut ohne Regel), Sortierung, Vergleichsansicht. 11 hat nur den Screen und die Commands festgelegt, nicht was darin steht. - **Inventar-UX** — Gewicht oder Kapazität (`carry_capacity` ist seit 01 ein Attribut ohne Regel), Sortierung, Vergleichsansicht. 11 hat nur den Screen und die Commands festgelegt, nicht was darin steht.
- **Mod-Verteilung** — durch 03 auf „Ordner ins Profil entpacken" geschrumpft, ohne Versionsprüfung. Offen ist nur noch, ob 1.0 mehr braucht. - **Mod-Verteilung** — durch 03 auf „Ordner ins Profil entpacken" geschrumpft, ohne Versionsprüfung. Offen ist nur noch, ob 1.0 mehr braucht.
- **Endlosmodus** — das erklärte Fernziel (aufgekommen in Ticket 15). 1.0 bleibt endlich; endlos ist **additiv**: ein Feld `repeat = true` an der letzten Etage plus eine Skalierungsformel. Berührt drei getroffene Entscheidungen — die Siegbedingung (10), `GameOver { outcome: Won }` (14) und die `floors`-Registry, die einen Eintrag *je Nummer* hat. Die fehlende Level-Obergrenze aus 15 ist bereits darauf ausgelegt.
## Out of scope ## Out of scope
- **Story-Modul** — kommt später als eigenes Modul, linear statt prozedural, ebenfalls moddbar. Eigene Map, wenn 1.0 steht. - **Story-Modul** — kommt später als eigenes Modul, linear statt prozedural, ebenfalls moddbar. Eigene Map, wenn 1.0 steht.

View File

@@ -187,6 +187,16 @@ Es existiert immer nur **eine** Etage; beim Abstieg wird die vorige verworfen, e
Zurückgehen. Gibt es keine Etage mit der nächsten Nummer, ist der Lauf **gewonnen** — die Zahl der Zurückgehen. Gibt es keine Etage mit der nächsten Nummer, ist der Lauf **gewonnen** — die Zahl der
Etagen steht nirgends im Code. Etagen steht nirgends im Code.
## Erfahrung
Der Fortschrittszähler des Helden. Quellen sind **Tötungen** (Feld `exp_reward` am
[Wesen](#wesen)) und **Quests** (Aktion `give_exp`) — nicht das Betreten einer [Etage](#etage), denn
das belohnte das Durchrennen.
Ein Aufstieg gibt **genau einen** frei verteilbaren Punkt auf einen der fünf Grundwerte. Es gibt
**keine Obergrenze**: Die Kurve begrenzt sich über steigende Kosten. Erfahrung hat nur der Held —
Gegner tragen zwar ein Level, aber keinen Fortschritt.
## Initiative ## Initiative
Ein Zahlenwert am [Wesen](#wesen), einmal beim Betreten eines Kampfes aus `dexterity` plus Wurf Ein Zahlenwert am [Wesen](#wesen), einmal beim Betreten eines Kampfes aus `dexterity` plus Wurf