7.4 KiB
7.4 KiB
Projektplan: Audiopoker (Bevy + Wasm)
Zielsetzung
Ein barrierefreies Multiplayer-Pokergame für blinde Spieler, das primär über Audio (TTS & SFX) bedient wird. Das Spiel wird via Webbrowser aufgerufen und auf WebAssembly kompiliert.
Technologie-Stack
- Engine: Bevy (Rust)
- Target: WebAssembly (Wasm)
- Networking: WebSockets für die Synchronisation des Spielzustands.
- Audio-Output: Web Speech API (via JS-Bindings) für Text-to-Speech,
bevy_audiofür Soundeffekte. - Input: Tastatur-zentrierte Steuerung (Tab/Space/Enter).
Modul-Struktur
core::logic: Reine Poker-Logik (Deck, Hand-Evaluation, Betting) ohne grafische Abhängigkeiten.core::network: Netzwerkprotokoll und WebSocket-Handhabung für Multiplayer-Synchronisation.audio::tts: Interface zur Web Speech API für dynamisches Sprechen von Spielereignissen.audio::sfx: Sound-Manager für atmosphärische Effekte (Chips, Karten mischen).ui_minimal: Minimalistische Darstellung, optimiert für Barrierefreiheit und geringen Ressourcenverbrauch.
Implementierungsphasen
Phase 1: Fundament & Core Logic (MVP)
- Projektstruktur aufsetzen (
Cargo.toml; Modul-Strukturcore/audiobereinigt und verdrahtet). - Poker Engine: Hand-Rankings (inkl. Wheel-Straight, 7-Karten-Bestbewertung), Deck-Shuffling/Draw und einfache Betting-Logik (Fold/Check/Call/Raise, All-In) implementiert und getestet.
- Audio-Grundlagen:
audio::ttsruft die Web Speech API korrekt an (SpeechSynthesisUtterance); auf nativen Targets Dummy-Ausgabe für Tests. - Bevy-
App-Grundgerüst aufgesetzt:AudiopokerPlugin(src/game_plugin.rs) verdrahtetcore::game/core::logicundaudioüber Bevy-Messages (Announce,PlaySfx) mitStartup/Update-Systemen. API-Stand: Bevy 0.19 (Message/MessageWriter/MessageReader/add_message, seit 0.17 getrennt von Observer-Events). Bitte lokal mitcargo check/cargo runverifizieren, da hier kein zu Bevy 0.19 passender Compiler zur Verfügung stand.
Projektstruktur (seit Phase 2: Cargo-Workspace)
core/(Libaudiopoker_core):logic,game,network- unverändert engine-unabhängig, jetzt von Client und Server genutzt.client/(Binaudiopoker_client): Bevy/Wasm, bisheriger Inhalt vonsrc/.server/(Binaudiopoker_server): neuer nativer WebSocket-Server (Tokio + tokio-tungstenite).
Phase 2: Networking & Multiplayer
- Server-Architektur:
server/src/table.rs(TableActor, Actor-Modell: ein Tokio-Task pro Tisch, kein geteilter Mutex für den Spielzustand) +server/src/lobby.rs(Tisch-Registry, legt Tische on-demand per Namen an).server/src/main.rsnimmt WebSocket-Verbindungen an (tokio-tungstenite) und verbindet sie mit dem passenden Tisch. - Netzwerkprotokoll:
core::network::{ClientMessage, ServerMessage}neu entworfen, sodass der Server dieselben Announce-/PlaySfx-"Häppchen" verschickt, die der lokale Client schon per TTS/SFX verarbeitet (GameManager::take_actionliefert sie direkt). Erhöhungsbeträge werden bewusst serverseitig festgelegt (kein clientseitig frei wählbarer Raise-Betrag). - Multiplayer-Lobby/Tischsuche (einfache Variante): Tischname im
JoinTabledient als Suchbegriff; unbekannte Namen legen automatisch einen neuen Tisch an. Kein Auflisten aller offenen Tische (ListTables) - falls gewünscht, wäre das die nächste Ausbaustufe. - Getestet:
cargo test -p audiopoker_core(10 Tests) und ein Ende-zu-Ende-Smoke-Test mit zwei echten WebSocket-Clients (Python) gegen den laufendenaudiopoker_serverliefen hier erfolgreich durch (kompletter Hand-Durchlauf Pre-Flop bis Showdown, korrekte Sieger-Ermittlung). - Client-Anbindung an den Server:
client/src/network.rsverbindet sich perweb_sys::WebSocketmitaudiopoker_server(Non-Send-Resource, da die JS-Callbacks nichtSendsind).game_plugin.rsspielt jetzt nicht mehr lokal/offline, sondern hält nur noch eine schlankeNetworkGameView(eigene Hole Cards, sichtbare Community Cards, wer am Zug ist) und schickt Aktionen alsClientMessagean den Server;ServerMessages werden zuAnnounce/PlaySfxübersetzt (gleicher Audio-Pfad wie zuvor lokal). Server-Bugfix nebenbei gefixt: Aktionen nachRound::Showdownwurden bisher nicht abgelehnt - jetzt gibt's dafür einenErrorplus ein neuesServerMessage::HandFinished-Signal, mit dem Clients die Eingabe sperren.- Server-/Tisch-/Spielername sind über Browser-URL-Parameter steuerbar (
?server=...&table=...&name=...), damit sich mehrere Browser-Tabs bequem als unterschiedliche Spieler an denselben Tisch hängen lassen. - Wichtiger Verifikationshinweis: Der eigentliche
web_sys::WebSocket-Code (#[cfg(target_arch = "wasm32")]) konnte hier nicht kompiliert werden (kein wasm32-Std verfügbar). Ein nativescargo check -p audiopoker_clientprüft nur dennot(wasm32)-Dummy-Zweig, NICHT den echten WebSocket-Pfad! Bitte zusätzlichcargo check --target wasm32-unknown-unknown -p audiopoker_client(Target ggf. perrustup target add wasm32-unknown-unknowninstallieren) ausführen, um das wirklich zu verifizieren. Der plattformunabhängige Teil (ClientMessage/ServerMessage-Nutzung, Query-Parameter-Parsing) wurde hier isoliert gegen den nativen Dummy-Zweig getestet und funktioniert.
- Server-/Tisch-/Spielername sind über Browser-URL-Parameter steuerbar (
- Tisch-Übersicht/
ListTablesfür echte Tischsuche (aktuell nur "Name kennen und beitreten"). - Neue Hand nach Showdown starten (serverseitig; der Client sperrt nach
HandFinishednur die Eingabe).
Phase 3: Audio Experience & UI
- TTS-Logik verfeinert:
GameManager::take_actionerzeugt kontextuelle Ansagen (Aktion des Spielers, Rundenwechsel inkl. aufgedeckter Community Cards, Showdown-Gewinner mit Hand-Kategorie, "wer ist am Zug"). Karten werden überCard/Suit-Displaysprachfreundlich ausgegeben ("König Herz"). - Soundeffekte eingebunden (Event-Ebene):
PlaySfx-Messages für "shuffle", "chip", "fold", "flip" werden an den entsprechenden Stellen ausgelöst und vonaudio::sfxentgegengenommen. Echte Audiodateien/bevy_audio-Wiedergabe fehlen noch (keine Assets im Projekt) – aktuell Log-Ausgabe als Platzhalter. - Minimalistische, tastaturzentrierte Steuerung:
Tabwählt zwischen Fold/Call-Check/Raise,Leertaste/Enterbestätigt (siehegame_plugin::handle_player_input). Kein grafisches UI nötig, da das Spiel primär auf Audio-Feedback setzt. - Mehrspieler-lokal-Testbarkeit über die Konsole hinaus (aktuell nur 2 fest verdrahtete Spieler; echte Steuerung pro Spieler braucht Networking, siehe Phase 2).
- Neue Hand nach Showdown starten (aktuell stoppt die Eingabe-Verarbeitung nach
Round::Showdown).
Phase 4: Polishing & Testing
- Barrierefreiheits-Audit (Tastatur-Flow ohne Maus).
- Latenztests im Multiplayer.
- WebAssembly Deployment Vorbereitung.
Lokal zu zweit testen (nach Client-Netzwerk-Anbindung)
- Server starten:
cargo run -p audiopoker_server(lauscht standardmäßig aufws://0.0.0.0:9001, überschreibbar über die UmgebungsvariableAUDIOPOKER_ADDR). - Client für Wasm bauen/starten (z. B. über
trunk serveo. ä. - noch nicht Teil dieses Repos, siehe offene Punkte) und zweimal im Browser öffnen:- Tab 1:
?server=ws://127.0.0.1:9001&table=tisch1&name=Anna - Tab 2:
?server=ws://127.0.0.1:9001&table=tisch1&name=Ben
- Tab 1:
- Sobald beide beigetreten sind, startet die Hand automatisch; Steuerung wie gehabt über Tab/Space/Enter.