From 8ad5da82c1aa6db77ca438372d07247d52ed2b78 Mon Sep 17 00:00:00 2001 From: MDietermann Date: Tue, 11 Aug 2026 15:13:49 +0200 Subject: [PATCH] docs: wayfinder-map fuer rustkeep 1.0 anlegen --- .../issues/01-effekt-vokabular.md | 21 ++++++ .../rustkeep-1.0/issues/02-typ-registry.md | 21 ++++++ .../issues/03-mod-ladepipeline.md | 20 ++++++ .../rustkeep-1.0/issues/04-fehlerstrategie.md | 23 +++++++ .../issues/05-research-script-engine.md | 21 ++++++ .../issues/06-research-ratatui-architektur.md | 24 +++++++ .../rustkeep-1.0/issues/07-game-state-baum.md | 21 ++++++ .../issues/08-event-trigger-system.md | 23 +++++++ .../rustkeep-1.0/issues/09-save-schema.md | 23 +++++++ .../issues/10-raum-prefab-format.md | 22 ++++++ .scratch/rustkeep-1.0/map.md | 67 +++++++++++++++++++ 11 files changed, 286 insertions(+) create mode 100644 .scratch/rustkeep-1.0/issues/01-effekt-vokabular.md create mode 100644 .scratch/rustkeep-1.0/issues/02-typ-registry.md create mode 100644 .scratch/rustkeep-1.0/issues/03-mod-ladepipeline.md create mode 100644 .scratch/rustkeep-1.0/issues/04-fehlerstrategie.md create mode 100644 .scratch/rustkeep-1.0/issues/05-research-script-engine.md create mode 100644 .scratch/rustkeep-1.0/issues/06-research-ratatui-architektur.md create mode 100644 .scratch/rustkeep-1.0/issues/07-game-state-baum.md create mode 100644 .scratch/rustkeep-1.0/issues/08-event-trigger-system.md create mode 100644 .scratch/rustkeep-1.0/issues/09-save-schema.md create mode 100644 .scratch/rustkeep-1.0/issues/10-raum-prefab-format.md create mode 100644 .scratch/rustkeep-1.0/map.md diff --git a/.scratch/rustkeep-1.0/issues/01-effekt-vokabular.md b/.scratch/rustkeep-1.0/issues/01-effekt-vokabular.md new file mode 100644 index 0000000..42b1b97 --- /dev/null +++ b/.scratch/rustkeep-1.0/issues/01-effekt-vokabular.md @@ -0,0 +1,21 @@ +# 01 — Effekt-Vokabular + +Type: grilling +Status: open +Blocked by: — + +## Question + +Was kann ein Effekt ausdrücken, und wie sieht er in TOML aus? + +Das Effekt-Vokabular ist die Mod-API: ein Modder kann exakt das bauen, was hier definiert wird. +Zu klären: + +- Welche Wirkungen gibt es? Stat-Modifikator (flach, prozentual), Sofortschaden/Heilung, + Ressourcenverbrauch, Statuseffekt anwenden/entfernen, Event auslösen. +- Zeitlichkeit: permanent (Rasse), solange ausgerüstet (Item), N Runden (Statuseffekt), einmalig (Trank). +- Wie werden Effekte gestapelt und in welcher Reihenfolge verrechnet? Erst flach, dann prozentual? +- Wie referenziert ein Effekt sein Ziel — Träger, Gegner, alle Gegner? +- Wie sieht die TOML-Repräsentation aus, und bleibt sie lesbar genug für Modder ohne Doku? + +Ergebnis: eine Liste der Effekt-Varianten mit TOML-Beispiel je Variante. diff --git a/.scratch/rustkeep-1.0/issues/02-typ-registry.md b/.scratch/rustkeep-1.0/issues/02-typ-registry.md new file mode 100644 index 0000000..768bef4 --- /dev/null +++ b/.scratch/rustkeep-1.0/issues/02-typ-registry.md @@ -0,0 +1,21 @@ +# 02 — Typ-Registry statt Enums + +Type: grilling +Status: open +Blocked by: 01 + +## Question + +Wie werden Item-Typen, Rassen und Klassen zu Daten statt zu Rust-Enums? + +`enum ItemType` kann ein Modder nicht erweitern — es muss eine Registry aus String-IDs werden. +Zu klären: + +- Was deklariert ein Typ? Ausrüstungsslot, welche Felder Pflicht sind, welche Effekte er tragen darf. +- Gibt es Slots als eigene Registry (`core:helmet`), oder ist der Slot ein fester Aufzählungswert? +- Wie prüft das Spiel beim Laden, dass ein Item einen existierenden Typ nennt — und was passiert, wenn nicht? +- Wie unterscheiden sich Rasse und Klasse strukturell, oder sind beide dasselbe: eine benannte Effektliste + plus Metadaten? +- 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. diff --git a/.scratch/rustkeep-1.0/issues/03-mod-ladepipeline.md b/.scratch/rustkeep-1.0/issues/03-mod-ladepipeline.md new file mode 100644 index 0000000..f84250e --- /dev/null +++ b/.scratch/rustkeep-1.0/issues/03-mod-ladepipeline.md @@ -0,0 +1,20 @@ +# 03 — Mod-Ladepipeline und Manifest + +Type: grilling +Status: open +Blocked by: 02 + +## Question + +Wie findet, ordnet und lädt das Spiel Mods — inklusive sich selbst? + +Das Kernspiel ist `core:` und damit selbst ein Mod. Zu klären: + +- Ordnerstruktur: Wo liegt `core`, wo liegen fremde Mods, was ist relativ zur Binary vs. zum Benutzerprofil? +- Manifest: Welche Felder? ID-Namespace, Anzeigename, Version, Abhängigkeiten, Ladepriorität. +- Ladereihenfolge: aus Abhängigkeiten berechnet oder vom Spieler festgelegt? Wie werden Zyklen behandelt? +- Überschreiben: Wie sagt Mod B, dass er `core:iron_sword` ersetzt statt ergänzt? Ganz oder feldweise? +- In welchen Phasen läuft das Laden — erst alle Typen, dann alle Instanzen? Was passiert bei Vorwärtsreferenzen? +- Wird beim Start alles geladen, oder gibt es ein Nachladen zur Laufzeit? + +Ergebnis: Ordnerlayout, Manifest-Schema und die Phasen der Ladepipeline. diff --git a/.scratch/rustkeep-1.0/issues/04-fehlerstrategie.md b/.scratch/rustkeep-1.0/issues/04-fehlerstrategie.md new file mode 100644 index 0000000..00dc639 --- /dev/null +++ b/.scratch/rustkeep-1.0/issues/04-fehlerstrategie.md @@ -0,0 +1,23 @@ +# 04 — Fehlerstrategie für kaputte Mods + +Type: grilling +Status: open +Blocked by: 03 + +## Question + +Was passiert, wenn ein Mod kaputt ist — und wie sieht das im Rust-Code aus? + +Explizites Rust-Lernticket. Heute macht `items.rs::parse()` ein `panic!` mit Backtrace; bei Mod-Support +ist fehlerhaftes TOML der Normalfall, nicht der Ausnahmefall. Zu klären: + +- Welche Fehlerklassen gibt es? TOML-Syntax kaputt, Pflichtfeld fehlt, unbekannte Typ-ID, + Abhängigkeit nicht installiert, ID-Kollision ohne Override-Absicht. +- Welche davon sind hart (Start abbrechen) und welche weich (Mod überspringen, Rest laden, warnen)? +- Wie erreicht die Meldung den Spieler — vor dem TUI-Start auf stderr, oder als Bildschirm im TUI? + Braucht es ein Mod-Log? +- Rust-seitig: eigener Fehlertyp mit `thiserror`, oder `anyhow` mit Kontext, oder handgeschriebenes + `enum LoadError`? Wo endet die `Result`-Kette? +- Wie kommt die Herkunft in die Meldung — Datei, Zeile, Mod-ID? + +Ergebnis: Fehlerklassifikation, Reaktion je Klasse, und die gewählte Rust-Fehlerbehandlung mit Begründung. diff --git a/.scratch/rustkeep-1.0/issues/05-research-script-engine.md b/.scratch/rustkeep-1.0/issues/05-research-script-engine.md new file mode 100644 index 0000000..84f2bdd --- /dev/null +++ b/.scratch/rustkeep-1.0/issues/05-research-script-engine.md @@ -0,0 +1,21 @@ +# 05 — Research: Script-Engine für Mod-Stufe (c) + +Type: research +Status: open +Blocked by: — + +## Question + +Welche Script-Engine trägt modderseitiges Verhalten in rustkeep — Rhai, Lua via `mlua`, oder WASM? + +Fakten sammeln, keine Entscheidung treffen. Zu klären: + +- Einbindung: Braucht es eine C-Toolchain unter Windows? Wie groß ist der Build-Overhead? +- Typ-Brücke: Wie schmerzhaft ist es, Rust-Structs (Stats, Item, Game-State) für Scripts zugänglich zu machen? +- Sandbox: Kann ein bösartiges Mod-Script Dateien lesen oder Prozesse starten? Was lässt sich abschalten? +- Fehlerbehandlung: Bekommt man brauchbare Fehlermeldungen mit Zeilennummer aus dem Script zurück? +- Hot-Reload: Lassen sich Scripts zur Laufzeit neu laden? +- Zielgruppe: Wie viele Hobby-Modder kennen die Sprache schon? Lua hat Vorsprung, Rhai ist Rust-nativ. +- Reifegrad: Wartungsstand, Release-Frequenz, Größe des Ökosystems, Beispiele aus echten Spielen. + +Ergebnis: Vergleichstabelle plus Empfehlung mit Begründung; die Entscheidung fällt der Mensch später. diff --git a/.scratch/rustkeep-1.0/issues/06-research-ratatui-architektur.md b/.scratch/rustkeep-1.0/issues/06-research-ratatui-architektur.md new file mode 100644 index 0000000..9c50c95 --- /dev/null +++ b/.scratch/rustkeep-1.0/issues/06-research-ratatui-architektur.md @@ -0,0 +1,24 @@ +# 06 — Research: ratatui-App-Architektur + +Type: research +Status: open +Blocked by: — + +## Question + +Wie strukturiert man eine ratatui-Anwendung mit mehreren Bildschirmen sauber? + +rustkeep braucht Grid-Ansicht, Kampfbildschirm, Inventar, Shop, Questlog, Charakterbogen, Hauptmenü. +Fakten sammeln. Zu klären: + +- Welches App-Muster ist etabliert — Elm-artig (Message/Update/View), Screen-Stack, State-Machine? + Was empfiehlt ratatui selbst, was machen echte Projekte? +- Wie werden Bildschirme gestapelt, wenn ein Popup über dem Kampf liegt? +- Wie trennt man Spiellogik von Rendering, damit der Kern ohne Terminal testbar bleibt? +- Event-Loop: Wie läuft Eingabe gegen Rendering, braucht ein rundenbasiertes Spiel überhaupt einen Tick? +- Welche Widgets bringt ratatui mit (Liste, Tabelle, Gauge, Popup), und was muss man selbst bauen — + insbesondere ein Dungeon-Grid? +- Terminal-Aufräumen bei Panic, damit kein kaputtes Terminal zurückbleibt. +- Stand der Versionen: aktuelle ratatui- und crossterm-Version, bekannte Fallstricke unter Windows. + +Ergebnis: empfohlenes App-Muster mit Skizze der Modulstruktur, plus Quellenliste. diff --git a/.scratch/rustkeep-1.0/issues/07-game-state-baum.md b/.scratch/rustkeep-1.0/issues/07-game-state-baum.md new file mode 100644 index 0000000..b8915f1 --- /dev/null +++ b/.scratch/rustkeep-1.0/issues/07-game-state-baum.md @@ -0,0 +1,21 @@ +# 07 — Game-State-Baum + +Type: grilling +Status: open +Blocked by: 01, 02 + +## Question + +Wie sieht der Weltzustand als Rust-Datenstruktur aus? + +Entschieden ist: ein `Game`-Ownership-Baum mit Verweisen über IDs oder Indizes, kein ECS. Zu klären: + +- Was besitzt was? Wo leben Held, aktuelle Etage, Räume, Gegner, Bodenloot, Questfortschritt? +- Trennung von unveränderlichen Definitionen (aus Mods geladen) und veränderlichem Laufzeitzustand: + zwei getrennte Strukturen, oder eine mit Verweisen in den Katalog? +- Referenzform: `String`-ID überall, oder beim Laden zu `usize`-Index auflösen? Was kostet das beim Speichern? +- Wo werden aktive Statuseffekte gehalten — am Träger oder in einer zentralen Liste? +- Welche Operation kämpft absehbar mit dem Borrow-Checker (Gegner greift Held an, während beide im selben + `Game` hängen), und wie wird das aufgelöst? + +Ergebnis: Skizze der Structs mit Besitzverhältnissen und Referenzform. diff --git a/.scratch/rustkeep-1.0/issues/08-event-trigger-system.md b/.scratch/rustkeep-1.0/issues/08-event-trigger-system.md new file mode 100644 index 0000000..93973dc --- /dev/null +++ b/.scratch/rustkeep-1.0/issues/08-event-trigger-system.md @@ -0,0 +1,23 @@ +# 08 — Event- und Trigger-System + +Type: grilling +Status: open +Blocked by: 07 + +## Question + +Welche Ereignisse meldet das Spiel, und wie hängen Quests und Effekte daran? + +Quests sind Bedingung plus Belohnung als Daten; Script-Mods hängen sich später an dieselben Events. +Zu klären: + +- Welche Events gibt es, und welche Daten trägt jedes? `enemy_killed`, `item_picked_up`, `floor_entered`, + `npc_talked`, `turn_started`, `damage_taken`, `player_died`. +- Wie werden Events benannt und für Modder erweiterbar gemacht — feste Liste oder auch namespaced IDs? +- Bedingungen: reines Zählen (töte 5 Ratten) oder auch Zustandsabfragen (habe 100 Gold, Level ≥ 3)? + Braucht es Verknüpfung mit UND/ODER? +- Wie wird ein Questfortschritt gespeichert und wie überlebt er das Deaktivieren des Quest-Mods? +- Reihenfolge und Rekursion: Was passiert, wenn eine Belohnung selbst ein Event auslöst? +- Ist das synchrone Aufrufe (Handler direkt ausführen) oder eine Warteschlange? + +Ergebnis: Eventliste mit Nutzlast, Bedingungs-Grammatik, TOML-Beispiel für eine Quest. diff --git a/.scratch/rustkeep-1.0/issues/09-save-schema.md b/.scratch/rustkeep-1.0/issues/09-save-schema.md new file mode 100644 index 0000000..401e96e --- /dev/null +++ b/.scratch/rustkeep-1.0/issues/09-save-schema.md @@ -0,0 +1,23 @@ +# 09 — Save-Schema + +Type: grilling +Status: open +Blocked by: 07 + +## Question + +Was steht in einem Speicherstand, und wie überlebt er geänderte Mods? + +Entschieden ist: TOML, Mod-Liste im Header, fehlender Mod bedeutet Warnung und Verwerfen statt Abbruch. +Zu klären: + +- Was genau wird gespeichert? Held mit Stats und Effekten, Inventar, Ausrüstung, aktuelle Etage, + Etagen-Layout (oder Seed?), erkundete Räume, Gegnerzustand, Questfortschritt, Gold. +- Etage: gesamtes Layout speichern oder nur den Generator-Seed? Seed ist kompakt, bricht aber, sobald + der Generator oder ein Prefab-Mod sich ändert. +- Versionierung: Was steht im Header — Spielversion, Save-Schema-Version, Liste aus Mod-ID und Version? +- Migration: Was passiert bei älterem Schema? Migrieren, ablehnen, oder Best-Effort-Laden? +- Verwerfen im Detail: Wenn ein Item fehlt, wird der Slot leer — was, wenn die *Klasse* des Helden fehlt? +- Wie viele Speicherstände, Autosave, und speichert man mitten im Kampf? + +Ergebnis: Save-Schema als kommentiertes TOML-Beispiel plus Regeln für fehlende Mods. diff --git a/.scratch/rustkeep-1.0/issues/10-raum-prefab-format.md b/.scratch/rustkeep-1.0/issues/10-raum-prefab-format.md new file mode 100644 index 0000000..aeb3ad1 --- /dev/null +++ b/.scratch/rustkeep-1.0/issues/10-raum-prefab-format.md @@ -0,0 +1,22 @@ +# 10 — Raum-Prefab-Format + +Type: grilling +Status: open +Blocked by: 03 + +## Question + +Wie sieht ein Raum-Prefab in TOML aus, und wie fügt der Generator daraus eine Etage zusammen? + +Entschieden ist der Hybrid: Modder bauen Prefabs, der Generator setzt prozedural zusammen. Zu klären: + +- Prefab-Inhalt: Grid als ASCII-Block oder als Koordinatenliste? Wie werden Ausgänge markiert? + Wie Spawn-Punkte für Gegner, Loot, NPCs, Treppen? +- Wie flexibel ist die Größe — feste Raster oder beliebige Rechtecke, Rotation und Spiegelung erlaubt? +- Verbindungsregeln: Wie weiß der Generator, welche Prefabs aneinanderpassen? Tags an den Ausgängen? +- Steuerung durch Daten: Welche Prefabs auf welcher Etage, mit welcher Gewichtung? Pflichträume + (Eingang, Treppe, Boss) versus optionale? +- Garantien: Wie wird sichergestellt, dass die Treppe erreichbar ist? +- Wie greift ein Mod ein — nur neue Prefabs hinzufügen, oder auch Generator-Parameter ändern? + +Ergebnis: Prefab-Schema mit Beispiel plus die Regeln, nach denen der Generator zusammensetzt. diff --git a/.scratch/rustkeep-1.0/map.md b/.scratch/rustkeep-1.0/map.md new file mode 100644 index 0000000..378a46c --- /dev/null +++ b/.scratch/rustkeep-1.0/map.md @@ -0,0 +1,67 @@ +# Map: rustkeep 1.0 + +Gitea-Spiegel: [Issue #1](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/1). +Diese Datei ist die kanonische Quelle — bei Abweichung gilt `.scratch/`. + +Gitea hat keine nativen Parent-Child- oder Blocking-Beziehungen, deshalb steht beides +dort als Konvention im Body. Zuordnung Ticket → Gitea-Issue: + +| Ticket | Gitea | Ticket | Gitea | +|---|---|---|---| +| 01 Effekt-Vokabular | [#2](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/2) | 06 Research ratatui | [#7](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/7) | +| 02 Typ-Registry | [#3](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/3) | 07 Game-State-Baum | [#8](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/8) | +| 03 Mod-Ladepipeline | [#4](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/4) | 08 Event-System | [#9](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/9) | +| 04 Fehlerstrategie | [#5](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/5) | 09 Save-Schema | [#10](https://gitlab.hive-brain.de/MDietermann/rustkeep/issues/10) | +| 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) | + +## Destination + +Alle Architektur- und Design-Entscheidungen für rustkeep 1.0 sind getroffen — nicht gebaut, entschieden. +1.0 heißt: 5 Etagen mit Boss, Solo-Held mit Rasse und Klasse, Grid-Erkundung mit Menü-Kampf, +Inventar und Ausrüstung, Quests, NPCs, Handel, Speichern/Laden, Mod-Support auf drei Stufen. + +## Notes + +Domain: Rust-Terminal-Roguelike, moddbar. Repo: `MDietermann/rustkeep`. + +Jede Session konsultiert: `ponytail` (dauerhaft aktiv), `/grilling` und `/domain-modeling` für +Grilling-Tickets, `/research` für Research-Tickets, `/prototype` für Prototype-Tickets. + +Feststehende Rahmenentscheidungen aus der Charter-Session: + +| Thema | Entscheidung | +|---|---| +| Motivation | Rust lernen **und** Spiel bauen — Lern-Entscheidungen bekommen eigene Tickets, wo sie echte Architekturfragen sind | +| Kernschleife | Grid-Bewegung zum Erkunden, Kampf im Menü (Dungeon Master / Etrian Odyssey) | +| Held | Solo, kein Party-System | +| Rendering | ratatui + crossterm; `print_box` fliegt raus, sobald ratatui steht | +| Etagen | Hybrid — Raum-Prefabs in TOML, prozedural zusammengesetzt | +| Daten | Alles TOML, zur Laufzeit geladen. `include_str!` und `enum ItemType` fallen | +| Mod-IDs | Namespaced (`core:iron_sword`), Ladereihenfolge aus Mod-Manifest. Das Kernspiel ist selbst ein Mod | +| Mod-Stufen | Daten → Typen → Scripting, in dieser Reihenfolge. Scripting setzt auf der Typ-Registry auf | +| Effekte | Ein generisches Effekt-System mit Wirkung auf Stats. Rasse, Klasse, Items, Statuseffekte, Quest-Belohnungen und später Scripts nutzen dasselbe Vokabular — dieses Vokabular *ist* die Mod-API | +| Quests | Bedingung + Belohnung als Daten, generisches Event-/Trigger-System | +| Weltzustand | `Game`-Ownership-Baum, Verweise über IDs/Indizes. Kein ECS | +| Fehler | `Result` statt `panic!` — kaputte Mod-TOMLs sind der Normalfall, nicht der Ausnahmefall | +| Save | TOML, Mod-Liste im Header, fehlender Mod = Warnung und Verwerfen, kein harter Abbruch | + +## Decisions so far + + + +## Not yet specified + +- **Kampfmechanik im Detail** — Initiative, Aktionen pro Runde, Trefferformel, Krit, Flucht. Wartet auf das Effekt-Vokabular (01), weil Angriffe und Fähigkeiten Effekte sind. +- **Loot-Tabellen** — wie Drops definiert und gewichtet werden, wie `luck` einwirkt. Wartet auf die Typ-Registry (02). +- **XP-Kurve und Progression** — was Level-ups geben, wie Rasse/Klasse mitskalieren. Wartet auf 01. +- **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 auf die ratatui-Architektur (06). +- **Mod-Verteilung** — wie Spieler an Mods kommen und ob es eine Versionsprüfung gibt. Wartet auf das Manifest-Format (03). + +## Out of scope + +- **Story-Modul** — kommt später als eigenes Modul, linear statt prozedural, ebenfalls moddbar. Eigene Map, wenn 1.0 steht. +- **Party-System** — bewusst gegen Solo entschieden; ein Wechsel wäre ein Umbau der Kampfarchitektur, keine Erweiterung. +- **Multiplayer** +- **Grafik jenseits des Terminals**