diff --git a/.scratch/rustkeep-1.0/issues/02-typ-registry.md b/.scratch/rustkeep-1.0/issues/02-typ-registry.md index 768bef4..f2869db 100644 --- a/.scratch/rustkeep-1.0/issues/02-typ-registry.md +++ b/.scratch/rustkeep-1.0/issues/02-typ-registry.md @@ -1,7 +1,7 @@ # 02 — Typ-Registry statt Enums Type: grilling -Status: open +Status: resolved Blocked by: 01 ## Question @@ -19,3 +19,89 @@ Zu klären: - Was verliert man ohne Enum an Compile-Zeit-Sicherheit, und was fängt das ab (Validierung beim Laden)? Ergebnis: das Registry-Datenmodell plus TOML-Beispiel für einen selbstdefinierten Item-Typ. + +## Answer + +Begriffe im [Glossar](../../../CONTEXT.md). + +### Fünf Registries + +**Gegenstände** · **Slots** · **Charakteroption-Kategorien** · **Charakteroptionen** · **Fähigkeiten**. +Alle moddbar, alle namespaced. + +### Es gibt keinen Item-Typ mehr + +`enum ItemType` verschwindet ersatzlos — er vermischte drei Konzepte: `Helmet` ist ein *Slot*, +`Consumable` ein *Verhalten*, `Currency` eine *Kategorie*. Genau deshalb war er nie erweiterbar. +An seine Stelle treten drei Felder am Gegenstand: `slot` (leer = nicht ausrüstbar), `stackable`, +`consumed_on_use`. + +`ItemWeapon` und `ItemArmor` entfallen ebenfalls. Ein Gegenstand ist einheitlich +`{ id, name, base_price, slot?, stackable, consumed_on_use, modifiers[], actions[], abilities[] }`. +Ein Schwert ist ein Gegenstand mit einem Modifikator auf `damage`, ein Helm einer mit einem +Modifikator auf `resistance`. + +**Tragende Regel:** Braucht ein Gegenstand etwas, das Modifikator, Aktion oder Fähigkeit nicht +ausdrücken können, ist das eine Lücke im Vokabular — sie wird dort geschlossen, nicht hier mit +einem Sonderfeld umgangen. + +### Fähigkeit — der dritte Begriff + +Modifikator rechnet um, Aktion wirkt einmal, **Fähigkeit** ist ein benanntes, wiederholt auslösbares +Angebot an den Spieler, das Aktionen ausführt. Sie erscheint im Kampfmenü, hat Symbol und Kosten, +kann gesperrt sein. Ein Zauberspruch als Gegenstand im Inventar wäre die Alternative gewesen — dann +könnte ein Magier seine Zaubersprüche aber verkaufen oder verlieren. + +Dieses Ticket legt nur fest, dass Fähigkeiten eine eigene Registry sind und von Gegenständen wie +Charakteroptionen referenziert werden. Kosten, Abklingzeit und Verfügbarkeit entscheidet Ticket 14. + +### Deklarationen + +```toml +# slots.toml +[[slots]] +id = "core:head" +name = "Kopf" +order = 10 + +# character_option_categories.toml +[[categories]] +id = "core:race" +name = "Rasse" +order = 10 +pick = 1 + +# races.toml +[[options]] +id = "core:dwarf" +category = "core:race" +name = "Zwerg" +description = "Zäh, misstrauisch, trinkfest." +modifiers = [ { attribute = "constitution", flat = 2 } ] +abilities = ["core:stonesense"] +on_create = [ { action = "give_item", item = "core:pickaxe", count = 1, target = "self" } ] +``` + +Kategorien tragen `pick = N`, damit „wähle zwei Talente" ohne neue Maschine möglich ist. + +**`on_create` ist keine neue Mechanik**, sondern eine Liste gewöhnlicher Aktionen, einmal beim +Charakterbau ausgeführt. Startgold, Startausrüstung und Startbuff sind damit moddbar, ohne dass die +Engine den Begriff „Startausrüstung" kennt. + +### Umbenennung + +`Item.value` → `base_price` (Grundwert des Gegenstands). Attribut `shop_price` → `price_modifier` +(Charaktereigenschaft, über die Charisma wirkt). Zwei Dinge, zwei Namen. + +### Auflagen an andere Tickets + +- **11 UI-Gerüst und Screen-Modell**: Charakterbogen und Charakterbau sind Schleifen über Registries, + keine fest gemauerten Layouts — Modder können Slots *und* Wahlkategorien ergänzen. +- **14 Kampfformeln und Rundenablauf**: muss Fähigkeitskosten, Abklingzeit und Verfügbarkeit + mitentscheiden. Ticketkörper wurde entsprechend erweitert. + +### Folgen für bestehenden Code + +`src/items/weapon.rs` und `src/items/armor.rs` werden gelöscht, `enum ItemType` entfällt, +`weapons.toml` und `armors.toml` verschmelzen zu einer gewöhnlichen Gegenstandsdatei, `items.rs` +schrumpft auf Laden plus Registry. diff --git a/.scratch/rustkeep-1.0/issues/14-kampfformeln-und-rundenablauf.md b/.scratch/rustkeep-1.0/issues/14-kampfformeln-und-rundenablauf.md index 0feb763..2943c4f 100644 --- a/.scratch/rustkeep-1.0/issues/14-kampfformeln-und-rundenablauf.md +++ b/.scratch/rustkeep-1.0/issues/14-kampfformeln-und-rundenablauf.md @@ -20,6 +20,10 @@ Der Attributkatalog aus 01 liefert die Zutaten (`damage`, `hit_chance`, `critica - **Kritische Treffer**: Wie speist `luck` in `critical_chance`? Multipliziert `critical_factor` den Rohschaden oder den geminderten? - **Aktionen pro Zug**: Genau eine, oder gibt es Ausdauer als Budget? Wozu dient `max_stamina` sonst? +- **Fähigkeiten** (nachgetragen aus Ticket 02): Was kostet eine Fähigkeit — Ausdauer, ein eigener + Ressourcenpool, Ladungen? Gibt es Abklingzeiten, und werden sie in Zügen gezählt? Wann ist eine + Fähigkeit gesperrt, und woran sieht der Spieler das? Ticket 02 hat Fähigkeiten als Registry + festgelegt, ihre Kampfsemantik aber ausdrücklich hierher delegiert. - **Flucht**: Möglich, mit welcher Chance, mit welchen Kosten? - **Zufall**: Schadensstreuung ja oder nein, und woher kommt der Zufallsgenerator — braucht es einen Seed im Speicherstand? diff --git a/.scratch/rustkeep-1.0/issues/16-loot-tabellen.md b/.scratch/rustkeep-1.0/issues/16-loot-tabellen.md new file mode 100644 index 0000000..611c96c --- /dev/null +++ b/.scratch/rustkeep-1.0/issues/16-loot-tabellen.md @@ -0,0 +1,27 @@ +# 16 — Loot-Tabellen + +Type: grilling +Status: open +Blocked by: 02 + +## Question + +Wie werden Beutefunde definiert, gewichtet und ausgewürfelt? + +Die Gegenstands-Registry aus 02 steht, `luck` ist ein Attribut aus 01. Offen ist alles dazwischen: + +- **Wo hängt Beute?** Am Gegner, am Raum-Prefab, an der Etage, oder an einer benannten Tabelle, die + mehrere referenzieren können? +- **Wie wird gewichtet?** Gewichte pro Eintrag, Wahrscheinlichkeit in Prozent, oder Seltenheitsstufen + mit fester Verteilung? Dürfen Tabellen andere Tabellen referenzieren? +- **Wie wirkt `luck`?** Auf die Drop-Chance, auf die Seltenheitsstufe, auf die Menge — oder auf + mehreres, und mit welcher Formel? +- **Mengen und Garantien**: Gibt es „genau ein Gegenstand", „null bis drei", garantierte Drops für + Bosse? Kann ein Eintrag mehrfach gezogen werden? +- **Etagenskalierung**: Fallen auf Etage 5 andere Gegenstände als auf Etage 1, und wird das über + getrennte Tabellen ausgedrückt oder über eine Bedingung am Eintrag? +- **Wie greifen Mods ein?** Nur neue Tabellen hinzufügen, oder auch Einträge in fremde Tabellen + einhängen — und wie sieht dieses Einhängen aus, ohne die fremde Datei zu überschreiben? +- **Zufall**: derselbe Generator wie im Kampf (Ticket 14), und gehört sein Zustand in den Speicherstand? + +Ergebnis: Tabellenschema mit TOML-Beispiel, Gewichtungsregel, `luck`-Formel und die Mod-Einhängepunkte. diff --git a/.scratch/rustkeep-1.0/map.md b/.scratch/rustkeep-1.0/map.md index 7287eb2..cf1123b 100644 --- a/.scratch/rustkeep-1.0/map.md +++ b/.scratch/rustkeep-1.0/map.md @@ -15,7 +15,7 @@ dort als Konvention im Body. Zuordnung Ticket → Gitea-Issue: | 05 Research Script-Engine | [#6](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/6) | 10 Raum-Prefab-Format | [#11](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/11) | | 11 UI-Gerüst | [#12](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/12) | 12 Prototyp ratatui | [#13](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/13) | | 13 Script-Engine wählen | [#14](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/14) | 14 Kampfformeln | [#15](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/15) | -| 15 Progression | [#16](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/16) | | | +| 15 Progression | [#16](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/16) | 16 Loot-Tabellen | [#17](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/17) | ## Destination @@ -60,12 +60,13 @@ auch über Ticket 13. - [01 — Effekt-Vokabular](issues/01-effekt-vokabular.md) ([#2](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/2)) — **Zwei Begriffe statt einem**: Modifikator (rechnet ein Attribut um, solange er existiert) und Aktion (ändert Zustand einmalig), getrennte Maschinen und getrennte TOML-Arrays. Fester Attributkatalog ohne Namensraum; `max_health` ist Attribut, der Lebensstand ist Zustand. Sechs Aktionen, `damage` eigenständig wegen der Minderungskette. Stapeln `(Basis + Σ flach) × (1 + Σ prozentual)`. Eine Uhr: der Zug. Sieben feste Schadenstypen, ein Minderungsmechanismus (`resistance`), `armor` nur Kurzschreibweise. Auren wohnen beim Träger. Bedingungsvokabular bewusst an Ticket 08 delegiert. Begriffe im [Glossar](../../CONTEXT.md). +- [02 — Typ-Registry statt Enums](issues/02-typ-registry.md) ([#3](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/3)) — **Es gibt keinen Item-Typ mehr**: `enum ItemType` vermischte Slot, Verhalten und Kategorie und entfällt ersatzlos zugunsten der Felder `slot`, `stackable`, `consumed_on_use`. `ItemWeapon` und `ItemArmor` fallen weg, ein Gegenstand ist einheitlich. **Fähigkeit** kommt als dritter Begriff neben Modifikator und Aktion dazu (Angebot statt Wirkung). Fünf moddbare Registries; Slots und sogar Charakteroption-Kategorien sind Inhalt, mit `pick = N`. Startausrüstung ist `on_create` als gewöhnliche Aktionsliste. `value` → `base_price`, `shop_price` → `price_modifier`. - [05 — Research: Script-Engine](issues/05-research-script-engine.md) ([#6](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/6)) — Empfehlung Rhai wegen Fehlermeldungen mit Zeile und Spalte, billiger Typ-Brücke, AST-Hot-Reload und Build ohne `cc`. Gemessen: mlua liest unter `StdLib::ALL_SAFE` per `io.open` echte Dateien — „safe" heißt dort speichersicher, nicht fähigkeitsbeschränkt. Lua gewinnt bei der Modder-Vertrautheit; WASM scheidet für 1.0 aus. **Kernfolge: reden Scripts nur über das Effekt-Vokabular, ist die Engine-Wahl umkehrbar.** Entscheidung offen in Ticket 13. - [06 — Research: ratatui-App-Architektur](issues/06-research-ratatui-architektur.md) ([#7](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/7)) — Screen-Stack über zentralem `Game`-State statt Elm oder Component-Trait; `game/` bleibt ratatui-frei; Popups per `Clear` auf Sub-`Rect` statt Widget-Stack; blockierendes `event::read()` ohne Tick; Dungeon-Grid ist Eigenbau, es gibt kein Widget dafür; ratatui 0.30.2 mit MSRV 1.88; `KeyEventKind::Press`-Filter unter Windows Pflicht. Voller Bericht in [research/06](research/06-ratatui-architektur.md). ## Not yet specified -- **Loot-Tabellen** — wie Drops definiert und gewichtet werden, wie `luck` einwirkt. Wartet auf die Typ-Registry (02). +- **Balancing** — konkrete Zahlen für Attribute, Schaden, Preise und Erfahrung über fünf Etagen. Wartet auf Kampfformeln (14), Progression (15) und Loot (16); vorher gibt es nichts zu balancieren. - **Boss-Design** — ob Bosse nur Gegner mit besseren Werten sind oder eigene Mechanik brauchen (Phasen, Skripte). Berührt Stufe (c) des Mod-Supports. - **NPC- und Handelsmodell** — Warenbestand, Preisbildung über `charisma`, Dialogdaten. Wartet auf das Event-System (08). - **Inventar-UX** — Slots, Gewicht oder Kapazität, Sortierung, Vergleichsansicht. Wartet jetzt auf das Screen-Modell (11), nicht mehr auf 06. diff --git a/CONTEXT.md b/CONTEXT.md index f173057..df86d49 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -7,7 +7,7 @@ Kanonische Begriffe für rustkeep. Nur Sprache, keine Implementierung. Eine benannte, veränderbare Größe an einem Wesen. Der Katalog ist fest und wird von der Engine vorgegeben — er umfasst die Grundwerte (Stärke, Geschicklichkeit, Konstitution, Charisma, Glück, Leben, Ausdauer, Level) *und* die abgeleiteten Kampfgrößen (Schaden, Rüstung, Trefferchance, -Kritische Chance, Kritischer Faktor, Shop-Preis, Tragfähigkeit). +Kritische Chance, Kritischer Faktor, Preis-Modifikator, Tragfähigkeit). Ein Attribut ist kein Inhalt, den ein Mod anlegt: Ein Modifikator auf ein Attribut, das keine Spiellogik ausliest, hätte keine Wirkung. Der Katalog darf wachsen — aber durch die Engine, @@ -31,6 +31,45 @@ Beispiele: „12 Schaden zufügen", „20 Leben heilen", „50 Gold geben", „G Eine Aktion kann einen befristeten [Modifikator](#modifikator) erzeugen — so hängen die beiden Begriffe zusammen, ohne dasselbe zu sein. +## Fähigkeit + +Ein benanntes, wiederholt auslösbares Angebot an den Spieler, das [Aktionen](#aktion) ausführt. +Sie erscheint im Kampfmenü, trägt Symbol und Kosten und kann gesperrt sein. + +Die dritte und letzte Wirkungsform neben [Modifikator](#modifikator) und [Aktion](#aktion), und die +Unterscheidung ist wesentlich: Eine Aktion ist eine *Wirkung*, eine Fähigkeit ist ein *Angebot*. +Fähigkeiten werden von [Charakteroptionen](#charakteroption) und Gegenständen gewährt, nicht im +Inventar getragen — sonst könnte ein Magier seine Zaubersprüche verkaufen. + +## Gegenstand + +Ein Ding im Spiel, einheitlich strukturiert: Kennung, Name, Grundpreis, optionaler [Slot](#slot), +Stapelbarkeit, Verbrauch beim Benutzen, plus Listen von [Modifikatoren](#modifikator), +[Aktionen](#aktion) und [Fähigkeiten](#fähigkeit). + +Es gibt **keine Item-Typen**. Der frühere `enum ItemType` vermischte drei Konzepte — `Helmet` war ein +Slot, `Consumable` ein Verhalten, `Currency` eine Kategorie. Ein Schwert ist ein Gegenstand mit einem +Modifikator auf `damage`, mehr nicht. + +Braucht ein Gegenstand etwas, das Modifikator, Aktion oder Fähigkeit nicht ausdrücken können, ist das +eine Lücke im Vokabular — sie wird dort geschlossen, nicht mit einem Sonderfeld umgangen. + +## Slot + +Eine benannte Stelle am Charakter, an der genau ein [Gegenstand](#gegenstand) getragen werden kann. +Moddbarer, namespaced Inhalt mit Anzeigename und Sortierreihenfolge (`core:head`, `meinmod:umhang`). +Der Charakterbogen rendert die vorhandenen Slots, statt ein festes Layout zu mauern. + +## Charakteroption + +Eine Wahl beim Charakterbau — eine benannte Liste von [Modifikatoren](#modifikator), +[Fähigkeiten](#fähigkeit) und einmalig ausgeführten [Aktionen](#aktion). Rasse und Klasse sind +Charakteroptionen, keine eigenen Konzepte. + +Optionen liegen in **Kategorien**, und die Kategorien sind selbst moddbarer Inhalt mit einem Feld +`pick = N`. Ein Mod kann so eine dritte Wahl („Gottheit") oder eine Mehrfachwahl („zwei Talente") +ergänzen, ohne dass die Engine davon weiß. + ## Zustand Der veränderliche Istwert eines Wesens — aktuelles Leben, aktuelle Ausdauer, getragene Gegenstände,