M5 Master ResQ: BYOD Public Game Framework Lokaler Multiplayer für die Warteschlange am Messestand der Jugendfeuerwehr.

Team

  • Luca Hobiger
  • Lukas Kaik
  • Felix Schindler
  • Yan-Lennart Schwanbeck
  • Christian Wolter
  • Lucas Zaworski

Supervision

  • Martin Steinicke
  • Alexander Kramer

Das Framework

ResQ nimmt einem Spiel alles ab, was nichts mit dem Spiel zu tun hat.

flowchart TB
    %% Visual Theme & Styles
    classDef tvScreen fill:#1e293b,stroke:#00f2fe,stroke-width:2px,color:#ffffff,rx:6px,ry:6px;
    classDef mobileController fill:#1e293b,stroke:#ff7a00,stroke-width:2px,color:#ffffff,rx:6px,ry:6px;
    classDef backendServer fill:#1e293b,stroke:#0066ff,stroke-width:2px,color:#ffffff,rx:6px,ry:6px;
    classDef dataState fill:#1e293b,stroke:#00e676,stroke-width:2px,color:#ffffff,rx:6px,ry:6px;

    %% Subgraph Styling (Transparent)
    style CLIENTS fill:none,stroke:#475569,stroke-width:1.5px,color:#3e2d4a,rx:8px;
    style SERVER fill:none,stroke:#475569,stroke-width:1.5px,color:#3e2d4a,rx:8px;
    style DATA fill:none,stroke:#475569,stroke-width:1.5px,color:#3e2d4a,rx:8px;

    %% Nodes & Subgraphs
    subgraph CLIENTS ["FRONTEND CLIENTS"]
        direction TB
        MainScreen["Main Screen (TV / Host)
• Zeigt das Spiel & Bestenliste
• Zeigt Raum-Code & QR-Code"] DeviceScreen["Smartphone (Controller)
• Virtueller Joystick & Buttons
• Sendet Bewegung & Aktionen"] end subgraph SERVER ["BACKEND ENGINE"] GameRoom["Game Room & Logik
• Generiert 4-stelligen Raum-Code
• Verarbeitet Spieler-Eingaben
• Berechnet Spielregeln & Kollisionen"] end subgraph DATA ["STATE MANAGEMENT"] GameState["BaseRoomState (Shared Data)
• Spieler-Positionen & Punkte
• Restzeit & Spielphase"] end %% Data Flow Connections DeviceScreen ==>|1. Steuerung senden| GameRoom MainScreen ==>|2. Host-Verbindung| GameRoom GameRoom -->|3. Zustand aktualisieren| GameState GameState -. "4. Live-Sync auf TV" .-> MainScreen %% Class Assignments class MainScreen tvScreen; class DeviceScreen mobileController; class GameRoom backendServer; class GameState dataState; %% Link Styling linkStyle 0 stroke:#ff7a00,stroke-width:2px; linkStyle 1 stroke:#00f2fe,stroke-width:2px; linkStyle 2 stroke:#0066ff,stroke-width:2px; linkStyle 3 stroke:#00e676,stroke-width:2px,stroke-dasharray: 4 4;

Was das Framework übernimmt

Session & Verbindung

  • QR-Code und automatische Verbindung
  • Session-Management, Session-IDs
  • Drop-In und Drop-Out, auch bei Inaktivität

Spieler-Handling

  • Namenszuweisung
  • Farbzuweisung
  • Verwaltung der Spieleranzahl

Spielablauf

  • Endlosloop mit Auswahl der Spiele
  • Phasen-Handling: Connecting, Spiel läuft, Ergebnisse, Disconnecting
  • Timer
  • Scoring
  • Leaderboard

Darstellung

  • MainScreen für den großen Bildschirm
  • Device Screen für die Handys
  • Frontend-UI-Gerüst und Routing

Das Netzwerk

flowchart TB
    %% Visuelle Themes & Styles
    classDef tvScreen fill:#1e293b,stroke:#00f2fe,stroke-width:2px,color:#ffffff,rx:6px,ry:6px;
    classDef mobileController fill:#1e293b,stroke:#ff7a00,stroke-width:2px,color:#ffffff,rx:6px,ry:6px;
    classDef networkNode fill:#1e293b,stroke:#ffc107,stroke-width:2px,color:#ffffff,rx:6px,ry:6px;
    classDef serverProcess fill:#1e293b,stroke:#0066ff,stroke-width:2px,color:#ffffff,rx:6px,ry:6px;

    %% Subgraph Styling (Transparent)
    style CLIENTS fill:none,stroke:#475569,stroke-width:1.5px,color:#3e2d4a,rx:8px;
    style ROUTER fill:none,stroke:#475569,stroke-width:1.5px,color:#3e2d4a,rx:8px;
    style SERVER fill:none,stroke:#475569,stroke-width:1.5px,color:#3e2d4a,rx:8px;

    %% Nodes & Subgraphs
    subgraph CLIENTS ["LOCAL CLIENTS (WLAN)"]
        direction LR
        TV["Main Screen (TV / PC)
• IP im WLAN "] Phone["Smartphone Controller
• IP im WLAN"] end subgraph ROUTER ["NETWORK INFRASTRUCTURE"] WLAN["WLAN Access Point
• Vermittelt Datenpakete im Netzwerk
• Gateway-Funktion"] end subgraph SERVER ["GAME SERVER"] direction TB HTTP["Express HTTP Server
• Web-App ausliefern
• Login & Passwort-Prüfung
• Raum-Lookup (4-stelliger Code)"] WS["Colyseus WebSocket Server
• Dauerhafte bidirektionale Verbindung
• Live-Steuerung (Joystick)
• Synchronisation des Spielstands"] end %% Netzwerk-Verbindungen (HTTP Phase) TV ==>|1a. HTTP: Webseite laden| WLAN Phone ==>|1b. HTTP: Controller-Seite laden| WLAN WLAN ==>|"1c. HTTP Anfragen"| HTTP %% Netzwerk-Verbindungen (WebSocket Phase) TV -. "2a. WebSocket: Host-Verbindung" .-> WLAN Phone -. "2b. WebSocket: Spieler-Verbindung" .-> WLAN WLAN -. "2c. WebSocket Traffic" .-> WS %% Class Assignments class TV tvScreen; class Phone mobileController; class WLAN networkNode; class HTTP,WS serverProcess; %% Link Styling linkStyle 0 stroke:#94a3b8,stroke-width:2px; linkStyle 1 stroke:#94a3b8,stroke-width:2px; linkStyle 2 stroke:#94a3b8,stroke-width:2px; linkStyle 3 stroke:#00f2fe,stroke-width:2px,stroke-dasharray: 4 4; linkStyle 4 stroke:#ff7a00,stroke-width:2px,stroke-dasharray: 4 4; linkStyle 5 stroke:#0066ff,stroke-width:2px,stroke-dasharray: 4 4;

Was ein Spielmodul liefert

Drei Dateien. Mehr braucht es nicht, um ein neues Spiel in ResQ einzuhängen.

1. manifest.ts (Frontend-Manifest & UI-Registrierung):

Deklariert den Anzeigenamen des Spiels sowie die React-Komponenten für den Hauptbildschirm (MainScreen) und die Controller-Ansicht (DeviceScreen), worüber die automatisierte Discovery und Routen-Einbindung im Frontend erfolgt.

2. room.ts (Backend-Serverlogik):

Beinhaltet die serverseitige Zustandsverwaltung (Colyseus Schema), die Physik- und Spiellogik-Updates sowie das Event-Handling durch Ableitung von BaseGameRoom.

3. config.ts (Shared Config & Typen):

Stellt spielspezifische Parameter (z. B. Spawntimer, Geschwindigkeiten, Punkte) und Datenstrukturen bereit, die sowohl vom Backend als auch vom Frontend gemeinsam genutzt werden.

Und natürlich noch Assets, falls hier ein spezielleres Spiel gebaut wird.

flowchart TB
    %% Visuelle Themes & Styles
    classDef manifestNode fill:#1e293b,stroke:#00f2fe,stroke-width:2px,color:#ffffff,rx:6px,ry:6px;
    classDef roomNode fill:#1e293b,stroke:#0066ff,stroke-width:2px,color:#ffffff,rx:6px,ry:6px;
    classDef configNode fill:#1e293b,stroke:#ff7a00,stroke-width:2px,color:#ffffff,rx:6px,ry:6px;
    classDef assetsNode fill:#1e293b,stroke:#ffc107,stroke-width:2px,color:#ffffff,rx:6px,ry:6px;

    %% Subgraph Styling (Transparent)
    style MODULE fill:none,stroke:#475569,stroke-width:1.5px,color:#3e2d4a,rx:8px;
    style FRONTEND fill:none,stroke:#334155,stroke-width:1px,color:#64748b,rx:6px;
    style BACKEND fill:none,stroke:#334155,stroke-width:1px,color:#64748b,rx:6px;
    style SHARED fill:none,stroke:#334155,stroke-width:1px,color:#64748b,rx:6px;
    style OPTIONAL fill:none,stroke:#334155,stroke-width:1px,color:#64748b,rx:6px;

    %% Nodes & Subgraphs
    subgraph MODULE ["SPIELMODUL ARCHITEKTUR"]
        direction TB

        subgraph SHARED ["3. Shared (shared/src/games/id/)"]
            Config["config.ts & types.ts
• Spielparameter (Timer, Speed, Punkte)
• Datenstrukturen & TypeScript-Typen"] end subgraph FRONTEND ["1. Frontend (frontend/src/pages/games/id/)"] Manifest["manifest.ts
• Anzeigename des Spiels
• MainScreen (TV / Host UI)
• DeviceScreen (Smartphone Controller)
• Registrierung & Auto-Discovery"] end subgraph BACKEND ["2. Backend (backend/src/games/id/)"] Room["room.ts
• Erweitert BaseGameRoom
• Colyseus State Schema
• Physik-, Spiellogik- & Tick-Updates
• Event-Handling"] end subgraph OPTIONAL ["4. Assets (Optional)"] Assets["Sprites & Sounds (src/assets/)
• Bilder, Grafiken & Audio-Dateien"] end end %% Abhängigkeiten & Datenfluss Config -. "Typen & Konfiguration" .-> Manifest Config -. "Typen & Konfiguration" .-> Room Assets -. "Visuelle & Audio-Einbindung" .-> Manifest %% Class Assignments class Manifest manifestNode; class Room roomNode; class Config configNode; class Assets assetsNode; %% Link Styling linkStyle 0 stroke:#ff7a00,stroke-width:2px,stroke-dasharray: 4 4; linkStyle 1 stroke:#ff7a00,stroke-width:2px,stroke-dasharray: 4 4; linkStyle 2 stroke:#ffc107,stroke-width:2px,stroke-dasharray: 4 4;

Belege

Nach der Umstellung sind drei weitere Spiele entstanden – Lösch-Quiz, Feuerwehr-Memory und Schlauchstaffel. Alle drei wurden KI-gestützt umgesetzt: Wir haben die Framework-Konventionen in einer AGENTS.md dokumentiert, sodass ein Coding-Agent neue Spielmodule regelkonform erzeugen kann. Dass das funktioniert, ist selbst ein Beleg für die Klarheit der Schnittstelle: Was eine Maschine aus der Doku bauen kann, kann auch ein fremdes Team bauen.