77 lines
3.7 KiB
Markdown
77 lines
3.7 KiB
Markdown
# 12 — Prototyp: ratatui-Durchstich
|
|
|
|
Type: prototype
|
|
Status: resolved
|
|
Blocked by: 11
|
|
|
|
## Question
|
|
|
|
Trägt das Screen-Modell aus 11, bevor sieben Bildschirme darauf gebaut werden?
|
|
|
|
Der Umbau von `print_box` auf ratatui berührt jedes bestehende Modul (`items.rs`, `player.rs`,
|
|
`armor.rs`, `weapon.rs` und deren `print_values`). Vorher ein billiger Durchstich:
|
|
|
|
- Hauptmenü und Dungeon-Grid, mehr nicht. Ein Popup darüber, um das Stacking zu prüfen.
|
|
- Das Grid als eigenes Widget mit direktem Buffer-Zugriff — die Stelle, an der es kein fertiges
|
|
Widget gibt und die Empfehlung sich beweisen muss.
|
|
- Bewegung über `KeyEventKind`-gefilterte Eingabe, damit der Windows-Fallstrick real getestet ist
|
|
statt nur belegt.
|
|
- Prüfen, ob `game/` beim Bauen ratatui-frei bleibt oder ob es sofort leckt.
|
|
|
|
Bewusst nicht im Prototyp: Kampf, Inventar, Shop, Speichern, Mods.
|
|
|
|
Ergebnis: lauffähiger Durchstich plus Urteil, ob das Modell trägt oder Ticket 11 nachgebessert wird.
|
|
|
|
## Answer
|
|
|
|
**Urteil: Das Modell trägt.** Ticket 11 wird an genau einer Stelle nachgebessert, und die hatte nichts
|
|
mit dem Screen-Stack zu tun.
|
|
|
|
Der Prototyp liegt als Primärquelle auf dem Branch **`prototyp/12-ratatui-durchstich`**
|
|
(`examples/durchstich.rs`, 342 Zeilen, `cargo run --example durchstich`). Er bleibt dort und kommt
|
|
nicht nach `main` — Wegwerfcode, der eine Frage beantwortet hat.
|
|
|
|
### Die fünf Zusagen
|
|
|
|
| Zusage | Befund |
|
|
|---|---|
|
|
| `mod game` bleibt ratatui-frei | **hält.** Null Treffer, und zwar ohne dass irgendwer aufpassen musste — die Trennung ergibt sich, wenn `Command` und Spiellogik zusammenliegen |
|
|
| Dungeon-Grid als eigenes `impl Widget` | **trägt.** `buf[(x, y)].set_symbol(…)` ist der ganze Trick; kein fertiges Widget wurde vermisst |
|
|
| `Vec<Screen>` für Screens *und* Popups | **trägt.** Overlay-Flag entscheidet Rendern *und* Auto-Schließen, wie in 11 abgeleitet |
|
|
| `Response` statt Stack-Mutation im Screen | **trägt.** Kein Borrow-Konflikt, weil der Screen den Stack nie sieht |
|
|
| `KeyEventKind::Press`-Filter | **gemessen statt geglaubt** — siehe unten |
|
|
|
|
Popup über Grid, `x` dann `j`: Der Zug zählt hoch und das Popup schließt sich in derselben Iteration.
|
|
Die Regel „ein `Response::Command` schließt alle Overlays" ist damit real und kostet die eine Zeile,
|
|
die in 11 dafür veranschlagt war.
|
|
|
|
### Der Windows-Fallstrick ist jetzt eine Zahl
|
|
|
|
Der Bericht aus 06 führte ihn als Faktum, aber ungemessen. Der Prototyp zählt Tasten-Events
|
|
ungefiltert **und** gefiltert mit. Ergebnis unter Windows 11:
|
|
|
|
```
|
|
Tasten 14 → Press 7 → Züge 7
|
|
```
|
|
|
|
Jeder Tastendruck erzeugt zwei `Event::Key` (Press und Release). **Ohne den Filter würde jeder Schritt
|
|
zwei Züge kosten** — und weil ein Zug befristete Modifikatoren tickt, wäre das kein kosmetischer
|
|
Fehler, sondern doppelte Spielzeit. Der Filter arbeitet, `Press` und `Züge` laufen synchron.
|
|
|
|
### Zwei Befunde, beide nach Ticket 11 zurückgetragen
|
|
|
|
**Gegen eine Wand zu laufen kostete einen Zug.** Aufgefallen beim Spielen, nicht beim Nachdenken: Der
|
|
Zugzähler lief hoch, obwohl sich nichts bewegte — ein Gift-Debuff hätte getickt, weil jemand
|
|
danebengetippt hat. Die Regel und `Outcome { TurnPassed, Rejected(&str) }` stehen jetzt in
|
|
[Ticket 11](11-ui-geruest-screen-modell.md).
|
|
|
|
**`Command` muss `Clone` sein**, sonst kommt das Kommando nicht aus `Confirm { on_yes }` heraus, ohne
|
|
den Screen zu zerstören — im Prototyp brauchte das ein `std::mem::replace`.
|
|
|
|
### Was der Prototyp nicht beantwortet
|
|
|
|
Kampf, Inventar, Shop, Speichern, Mods — bewusst ausgelassen. Ebenso ungetestet: die
|
|
`Registries`-neben-`Game`-Entscheidung aus 07, weil der Durchstich gar keine Registries lädt. Der
|
|
Borrow-Konflikt, den sie vermeiden soll, tritt erst auf, wenn `Game::execute` beides gleichzeitig
|
|
braucht — das prüft erst die Implementierung.
|