docs: m1-befunde in tickets 03, 04 und 11 zurueckgetragen, verification-abschnitt in der map

This commit is contained in:
2026-08-12 15:42:33 +02:00
parent b39491916f
commit 3714bad313
4 changed files with 56 additions and 6 deletions

View File

@@ -125,6 +125,16 @@ in die Welt gelegt.
Überschreiben zwei Mods dasselbe, entscheidet die Ladereihenfolge — der letzte gewinnt. `overrides` Überschreiben zwei Mods dasselbe, entscheidet die Ladereihenfolge — der letzte gewinnt. `overrides`
ist ein Feld an *jedem* Registry-Eintrag, nicht nur an Gegenständen. ist ein Feld an *jedem* Registry-Eintrag, nicht nur an Gegenständen.
**Befund aus M1: die Referenzseite war offen.** Oben steht, was mit der eigenen `id` passiert — nicht,
was mit **Verweisen** passiert (`slot = "core:hand"`, `category = "core:race"`). Die wörtliche Fassung
ist umgesetzt: Nur `id` wird präfixiert, Verweise stehen voll qualifiziert. Das ist asymmetrisch, und
ein Modder wird darüber stolpern — er schreibt `id = "schwert"` und zwei Zeilen darunter
`slot = "core:hand"`.
Die Alternative wäre, dieselbe Regel auf jedes ID-förmige Feld anzuwenden: **kein Doppelpunkt heißt
eigener Namensraum.** Das ist bequemer und macht mod-interne Verweise kürzer, verlangt aber, dass der
Lader weiß, welche Felder IDs sind. Offen — zu entscheiden, bevor der erste Fremdmod existiert.
### Drei Phasen ### Drei Phasen
1. **Manifeste** — alle Ordner beider Pfade scannen, `manifest.toml` lesen, Reihenfolge aus 1. **Manifeste** — alle Ordner beider Pfade scannen, `manifest.toml` lesen, Reihenfolge aus

View File

@@ -85,6 +85,17 @@ meinmod/items.toml:42: core:iron_sword — unknown field `base_pric`
Die **Mod-ID steht vorne**: Bei zwölf installierten Mods ist sie die einzige Angabe, mit der ein Die **Mod-ID steht vorne**: Bei zwölf installierten Mods ist sie die einzige Angabe, mit der ein
Spieler weiß, wen er anschreiben muss. Spieler weiß, wen er anschreiben muss.
**Befund aus M1:** `Spanned` liefert den Anfang des *Eintrags* — also die `[[items]]`-Zeile —, nicht
die Zeile des schuldigen Feldes. Das deckt sich mit der Zusage oben („liefert dessen Zeilenbereich"),
sieht in der Praxis aber so aus:
```
test/items.toml:6: [1] — invalid type: integer `42`, expected a string
```
Zeile 6 ist der Eintragskopf, das kaputte Feld steht in Zeile 8. Den Feldnamen liefert `message()`,
weshalb die Meldung trotzdem eindeutig ist — die Genauigkeit reicht, solange ein Eintrag kurz bleibt.
`toml::de::Error` liefert `span() -> Option<Range<usize>>` und `message()`, aber keine Zeile — die ist `toml::de::Error` liefert `span() -> Option<Range<usize>>` und `message()`, aber keine Zeile — die ist
`input[..span.start].lines().count()`, eine Zeile Code. Keine Spalte: `message()` nennt das Feld `input[..span.start].lines().count()`, eine Zeile Code. Keine Spalte: `message()` nennt das Feld
bereits im Klartext, die Spalte wäre doppelt gemoppelt und bräuchte eine zweite Rechnung. Ein Eintrag bereits im Klartext, die Spalte wäre doppelt gemoppelt und bräuchte eine zweite Rechnung. Ein Eintrag

View File

@@ -190,6 +190,11 @@ Die ratatui-Freiheit prüft ein `#[test]`, der `src/game/**/*.rs` liest und auf
Zeilen; ein Cargo-Workspace mit `game` als eigener Crate wäre echte Compiler-Durchsetzung und ist die Zeilen; ein Cargo-Workspace mit `game` als eigener Crate wäre echte Compiler-Durchsetzung und ist die
Decke, falls es je ernst wird. Decke, falls es je ernst wird.
**Befund aus M1:** Die wörtliche Fassung trägt nicht. Sie schlägt sofort an — nämlich beim
Doc-Kommentar von `game/mod.rs`, der erklärt, dass die Grenze existiert. Der Test muss
**Kommentarzeilen ausnehmen** und sollte Datei, Zeile und Inhalt nennen statt nur „ist gefallen".
Steht so in `tests/boundaries.rs`.
### Nachtrag an Ticket 01: Darstellung muss moddbar sein ### Nachtrag an Ticket 01: Darstellung muss moddbar sein
01 hat `symbol` als *Schlüssel* definiert, dessen Zuordnung `ui/theme.rs` macht. Darin steckt eine 01 hat `symbol` als *Schlüssel* definiert, dessen Zuordnung `ui/theme.rs` macht. Darin steckt eine

View File

@@ -19,13 +19,15 @@ dort als Konvention im Body. Zuordnung Ticket → Gitea-Issue:
## Destination — **erreicht am 2026-08-12** ## Destination — **erreicht am 2026-08-12**
Alle sechzehn Tickets sind geschlossen. Was jetzt existiert: sechzehn Entscheidungsdokumente, ein Alle sechzehn Tickets sind geschlossen. Damit ist die Entscheidungsphase vorbei und die Umsetzung
Glossar mit den kanonischen Begriffen, und ein 342-Zeilen-Wegwerfprototyp auf dem Branch läuft — Stand siehe „Verification" weiter unten.
`prototyp/12-ratatui-durchstich`. Was **nicht** existiert: das Spiel. Der nächste Schritt ist die
Implementierung, und sie hat mit `src/` (heute `print_box`, `include_str!`, `enum ItemType`) fast Sechs Meilensteine statt neuer Tickets: **M1** vertikaler Durchstich · **M2** Etagengenerierung und
nichts gemein. Prefabs · **M3** Kampf mit Events und Triggern · **M4** Inventar, Ausrüstung, Affixe, Handel ·
**M5** Quests und Save/Laden · **M6** Inhalt für fünf Etagen und Balancing. Die Map hat sich für
*Entscheidungen* gelohnt; dieselbe Zeremonie über Implementierungsaufgaben zu stülpen wäre Prozess um
seiner selbst willen.
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, 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 den Stufen (a) und Inventar und Ausrüstung, Quests, NPCs, Handel, Speichern/Laden, **Mod-Support auf den Stufen (a) und
(b)**. (b)**.
@@ -33,6 +35,28 @@ Inventar und Ausrüstung, Quests, NPCs, Handel, Speichern/Laden, **Mod-Support a
Stufe (c) — Scripting — ist entschieden, aber nicht Teil von 1.0: Engine (Rhai) und Schnittstelle Stufe (c) — Scripting — ist entschieden, aber nicht Teil von 1.0: Engine (Rhai) und Schnittstelle
stehen, gebaut wird sie, wenn ein Modder an eine Lücke im Vokabular stößt (13). stehen, gebaut wird sie, wenn ein Modder an eine Lücke im Vokabular stößt (13).
## Verification — was der Compiler bestätigt hat
Sechzehn Tickets Papier, davon hatte bis M1 nur das Screen-Modell (12) Kontakt zu einem Compiler.
Diese Liste wächst mit jedem Meilenstein und ist der einzige Ort, an dem steht, welche Entscheidung
*gehalten* hat.
**M1 — vertikaler Durchstich** (`feat/m1-durchstich`, 10 Tests)
| Zusage | Aus | Befund |
|---|---|---|
| `Registries` neben `Game`, disjunkte Borrows | 07 | **bestätigt** — `game.execute(cmd, &reg)` und `game.attribute(…, &reg)` nebeneinander. Ticket 12 konnte das nicht prüfen, weil der Durchstich keine Registries lud |
| Zweistufige Deserialisierung, Eintrag als Fehlereinheit | 04 | **bestätigt** — ein kaputtes Feld tötet seinen Eintrag, die Nachbarn überleben |
| `Game::attribute` sammelt aus mehreren Quellen | 07 | **bestätigt** — Basis + Optionen + Ausrüstung, Stapelregel aus 01 stimmt |
| `game/` bleibt ratatui-frei | 11 | **bestätigt** — aber der *Test* dafür musste nachgebessert werden |
| Trigger-Suche, Event-Warteschlange | 08 | **ungeprüft** — es gibt weder Trigger noch Events. M3 |
**Drei Befunde, die nur der Compiler liefern konnte** — alle in die Tickets zurückgetragen:
- **11**: Der Grenztest in seiner wörtlichen Fassung schlägt beim eigenen Doc-Kommentar an. Muss Kommentarzeilen ausnehmen.
- **03**: Die **Referenzseite** war nie entschieden. Präfixiert wird nur `id`; Verweise stehen voll qualifiziert. Asymmetrisch — zu klären, bevor der erste Fremdmod existiert.
- **04**: `Spanned` zeigt auf den Eintragskopf, nicht auf das schuldige Feld. Deckt sich mit der Zusage, ist aber gut zu wissen.
## Notes ## Notes
Domain: Rust-Terminal-Roguelike, moddbar. Repo: `MDietermann/rustkeep`. Domain: Rust-Terminal-Roguelike, moddbar. Repo: `MDietermann/rustkeep`.