# Delfin Tippen Ein Lernspiel fürs Zehnfingerschreiben auf einer deutschen QWERTZ-Tastatur, gebaut für eine Sechsjährige, die Delfine mag. Alles auf Deutsch. Technisch ein Geschwister des Musik-Players in `../web` — React 19, TypeScript, Vite, keine Laufzeit-Abhängigkeiten außer React, dieselbe oklch-Glasoptik und dieselbe Nunito — aber **vollständig entkoppelt**: eigenes Vite-Projekt, eigener Dev-Server, kein Backend, kein gemeinsamer Build. Was geteilt werden sollte, wurde kopiert. ## Loslegen ```sh npm install npm run dev # http://localhost:5174 npm run test # vitest über src/lib npx tsc --noEmit # der eigentliche Check npm run build # -> dist/ ``` Es braucht eine echte QWERTZ-Tastatur. Der Fortschritt liegt im `localStorage` (`delfin-tippen:v1`); zum Zurücksetzen den Key löschen. ## Wie es aufgebaut ist Die Logik ist DOM-frei und getestet, die Komponenten sind Layout. Das ist dieselbe Aufteilung wie in `../web` und der Grund, warum sechs Spielmodi dieselbe Mechanik teilen können, ohne sie sechsmal zu implementieren. | Datei | Wofür | |---|---| | `lib/fingers.ts` | Die QWERTZ-Belegung: welcher Finger welche Taste, welche Farbe, welche Grundstellungstaste. | | `lib/curriculum.ts` | 48 Lektionen in 5 Welten. Höchstens zwei neue Tasten pro Lektion, mit Übungslektionen dazwischen. | | `lib/generator.ts` | Was getippt wird — Übungszeilen aus den aktiven Tasten, echte Wörter sobald möglich. | | `lib/engine.ts` | Die Tippmechanik: ein Tastendruck rein, ein neuer Zustand und Ereignisse raus. Pur. | | `lib/grading.ts` | Zeichen pro Minute, Genauigkeit, Sterne, Tier. | | `lib/progress.ts` | Was das Spiel sich merkt, und wann die nächste Lektion aufgeht. | | `hooks/useRun.ts` | Der dünne Adapter zwischen echten Tastendrücken und `engine.ts`. | ## Die Entscheidungen, die das Spiel ausmachen Vier davon sind bewusst anders, als man es zuerst bauen würde. Sie stehen ausführlicher in den Dateikommentaren: **Tempo schaltet nichts frei.** Die nächste Lektion geht bei 93 % Treffern auf — ohne jede Geschwindigkeitsbedingung. Wer langsam und sorgfältig tippt, kommt durch den ganzen Kurs. Tempo bringt nur das Tier. Zusätzlich geht die nächste Lektion nach fünf Versuchen ohnehin auf, damit niemand an einer Taste hängen bleibt. **`punkte = tempo × genauigkeit³`.** Die Lehrbuchformel `netto = brutto − fehler/minute` wird bei einem Anfänger negativ, und ein negatives Ergebnis darf hier nie erscheinen. Multiplikativ kann das nicht passieren: 95 % Genauigkeit behalten 86 % des Tempos, 90 % behalten 73 %. **Eine falsche Taste rückt nicht vor und zählt pro Stelle nur einmal.** Es gibt kein Backspace und keine zerschossene Zeile zum Anstarren, und zehnmal panisch dieselbe falsche Taste ist ein Fehler, nicht zehn. **Es gibt keinen Verloren-Bildschirm.** Eine schwache Runde zeigt weniger Sterne und ein langsameres Tier — nie ein rotes X, nie einen Summer, und die Perlen steigen immer. ## Die sechs Spielmodi Alle sechs laufen über dieselbe Mechanik (`lib/engine.ts`) und landen in derselben Bewertung. Sie unterscheiden sich nur darin, *wie* das Ziel gezeigt wird — deshalb ist ein siebter Modus eine Datei und eine Zeile, keine zweite Spiellogik. | Modus | Was man sieht | Wofür | |---|---|---| | 🤿 Tauchgang | Eine Zeile mit Cursor | Die Kernübung. Sie zählt fürs Freischalten. | | 🫧 Blasenplatzen | Blasen steigen auf, eine pro Buchstabe | Tastenlage, weiche Uhr | | 🦑 Quallenalarm | Sechs Quallen, eine leuchtet | Reine Tastenlage — erst suchen, dann tippen | | 🐟 Fütterungszeit | Fische mit Wörtern schwimmen zum Delfin | Ganze Wörter statt Buchstaben | | 🐬 Delfinrennen | Zwei Bahnen: du gegen deinen Rekord | Tempo, gegen den einzigen fairen Gegner | | 🦪 Perlentaucher | Eine Muschel, ein Wort, eine Perlenkette | Genauigkeit — **ohne jede Uhr** | Beim Delfinrennen ist der Gegner der Geist des eigenen besten Laufs: die Tastenzeiten liegen in `progress.lessons[id].ghost` und werden gegen die Uhr abgespielt. Gegen sich selbst zu rennen ist das einzige Wettkampfformat, das nicht entmutigen kann — der Gegner ist per Definition genau so gut, wie man selbst war. Vor dem ersten Rekord schwimmt eine absichtlich schlagbare Krabbe. ## Das Aquarium Wer eine Welt schafft, bekommt ein Haustier — Clownfisch, Krake, Seepferdchen, Schildkröte, Perlmuschel. Es zieht für immer ein und schwimmt ab dann frei hinter jedem Bildschirm herum; während einer Runde nur blass, damit es nicht mit der Zeile konkurriert. Das Schwimmen ist ein purer, getesteter Schritt in `lib/aquarium.ts`, `components/AquariumTiere.tsx` zeichnet nur. Ein neues Tier: die Zeichnung (auf schwarzem Hintergrund) nach `art/aquarium/` legen, ```sh scripts/aquarium-bild.sh art/aquarium/qualle.png public/aquarium/qualle.webp ``` und in `KREATUREN` eintragen. Das Skript entfernt den Hintergrund als zusammenhängende Fläche statt als Farbe — schwarze Augen und Wimpern bleiben stehen — und rechnet die Kanten aus dem Schwarz heraus, damit kein dunkler Rand bleibt. ## Stand Fertig und spielbar: alle 48 Lektionen, alle sechs Modi, Freischalten, Bewertung, Tierleiter, Aquarium, Sprachausgabe und die Bildschirmtastatur. Noch offen: die Geschichten am Ende jeder Welt, der Eltern-Bildschirm (`?eltern=1`) und eine Welt 6 mit der Zahlenreihe.