Files
rustkeep/.scratch/rustkeep-1.0/issues/12-prototyp-ratatui-durchstich.md

3.7 KiB

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.

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.