'use client' /** * Multiplayer Feature Wizard * * Interactive guide for learning about and testing * Breakpilot Drive multiplayer features (Matrix Chat & Jitsi Video) */ import { useState } from 'react' import Link from 'next/link' import AdminLayout from '@/components/admin/AdminLayout' // ======================================== // Types // ======================================== type WizardStep = | 'welcome' | 'game-modes' | 'matrix-chat' | 'jitsi-video' | 'go-services' | 'unity-integration' | 'demo' | 'summary' interface StepInfo { id: WizardStep title: string description: string } // ======================================== // Step Configuration // ======================================== const STEPS: StepInfo[] = [ { id: 'welcome', title: 'Willkommen', description: 'Multiplayer-Uebersicht' }, { id: 'game-modes', title: 'Spielmodi', description: 'Co-Op, Challenge, Klasse' }, { id: 'matrix-chat', title: 'Matrix Chat', description: 'Echtzeit-Kommunikation' }, { id: 'jitsi-video', title: 'Jitsi Video', description: 'Video-Konferenzen' }, { id: 'go-services', title: 'Go Services', description: 'Backend-Integration' }, { id: 'unity-integration', title: 'Unity', description: 'WebGL Bridge' }, { id: 'demo', title: 'Demo', description: 'Live-Test' }, { id: 'summary', title: 'Zusammenfassung', description: 'Naechste Schritte' }, ] // ======================================== // Educational Content // ======================================== const EDUCATION_CONTENT: Record = { 'welcome': { title: 'Multiplayer fuer Breakpilot Drive', content: `Das Multiplayer-System ermoeglicht kooperatives und kompetitives Spielen zwischen Schuelern. Es basiert auf zwei bewaehrten Open-Source-Technologien: - **Matrix Synapse** fuer Echtzeit-Chat - **Jitsi Meet** fuer Video-Kommunikation Diese Integration ermoeglicht verschiedene Spielmodi, von 1v1-Challenges bis hin zu klassenweiten Wettbewerben.`, tips: [ 'Matrix ist ein dezentrales Chat-Protokoll mit End-to-End-Verschluesselung', 'Jitsi ist eine Open-Source-Alternative zu Zoom/Teams', 'Beide Systeme sind DSGVO-konform und selbst-gehostet' ] }, 'game-modes': { title: 'Multiplayer-Spielmodi', content: `Breakpilot Drive unterstuetzt vier verschiedene Multiplayer-Modi: **Solo** - Einzelspieler ohne Netzwerk **Co-Op** - 2-4 Spieler arbeiten zusammen - Gemeinsame Strecke - Team-Chat - Optionales Video **Challenge** - 1v1 Wettbewerb - Gleiche Quiz-Fragen - Live-Punktestand - Video-Chat empfohlen **Klassenrennen** - Alle gegen alle - Lehrer als Moderator - Klassen-Chat - Live-Leaderboard`, tips: [ 'Co-Op ist ideal fuer Lerngruppen und Foerderunterricht', 'Challenges motivieren durch direkten Wettbewerb', 'Klassenrennen eignen sich als Abschluss einer Lerneinheit' ] }, 'matrix-chat': { title: 'Matrix Chat Integration', content: `Matrix wird fuer die Echtzeit-Kommunikation verwendet: **Raum-Typen:** - Team-Raeume (Co-Op, privat) - Challenge-Raeume (1v1, temporaer) - Klassen-Raeume (alle Schueler, Lehrer moderiert) **Features:** - Spieler-Beitritt/Austritt Benachrichtigungen - Score-Updates in Echtzeit - Achievement-Ankuendigungen - End-to-End-Verschluesselung optional **Game Events:** - player_joined, player_left - game_started, game_ended - score_update, quiz_answered - achievement, challenge_won`, tips: [ 'Matrix-Raeume werden automatisch erstellt und archiviert', 'Power Levels kontrollieren wer schreiben darf', 'Custom Events (breakpilot.game.*) fuer Spiellogik' ] }, 'jitsi-video': { title: 'Jitsi Video Integration', content: `Jitsi ermoeglicht Video-Kommunikation waehrend des Spiels: **Konfiguration pro Modus:** - Co-Op: Audio an, Video optional - Challenge: Audio/Video empfohlen - Klassenrennen: Lehrer-Video, Schueler stumm **Sicherheit:** - JWT-basierte Authentifizierung - Lobby fuer Klassenraeume - Kein Recording fuer Minderjaehrige **Unity-Embedding:** - Kompaktes Overlay (320x240px) - Minimale UI (nur Mikro, Kamera, Auflegen) - Automatisches Verbinden bei Spielstart`, tips: [ 'Jitsi-Container erscheint als Overlay im Spiel', 'Audio hat Prioritaet - Video ist optional', 'Lehrer koennen Schueler stummschalten' ] }, 'go-services': { title: 'Backend Go Services', content: `Die Multiplayer-Logik ist in Go implementiert: **Matrix Service** (game_rooms.go) - CreateGameTeamRoom() - Co-Op Raeume - CreateGameChallengeRoom() - 1v1 Raeume - CreateGameClassRaceRoom() - Klassen-Raeume - SendGameEvent() - Event Broadcasting **Jitsi Service** (game_meetings.go) - CreateCoopMeeting() - Team Video - CreateChallengeMeeting() - 1v1 Video - CreateClassRaceMeeting() - Klassen-Video - JWT-Token Generierung **Pfade:** - consent-service/internal/services/matrix/game_rooms.go - consent-service/internal/services/jitsi/game_meetings.go`, tips: [ 'Services erweitern bestehende Matrix/Jitsi Integration', 'Validierung erfolgt vor Raum-Erstellung', 'Cleanup wird automatisch bei Spielende ausgefuehrt' ] }, 'unity-integration': { title: 'Unity WebGL Integration', content: `Die Unity-seitige Integration besteht aus zwei Teilen: **MultiplayerManager.cs** - Singleton fuer Session-Verwaltung - Events fuer UI-Updates - Score/Achievement Broadcasting - Editor-Simulation fuer Entwicklung **MultiplayerPlugin.jslib** - JavaScript Bridge fuer WebGL - WebSocket-Verbindung zu Backend - Jitsi External API Integration - Automatisches Container-Management **Pfade:** - Assets/Scripts/Network/MultiplayerManager.cs - Assets/Plugins/WebGL/MultiplayerPlugin.jslib`, tips: [ 'Im Editor werden Multiplayer-Events simuliert', 'jslib-Funktionen nur im WebGL Build verfuegbar', 'Jitsi-Container wird dynamisch erstellt' ] }, 'demo': { title: 'Live-Demo', content: `Teste die Multiplayer-Komponenten: **Matrix-Verbindung:** - Pruefe ob Matrix Synapse erreichbar ist - Teste Raum-Erstellung - Sende Test-Nachricht **Jitsi-Verbindung:** - Pruefe ob Jitsi Meet erreichbar ist - Teste Meeting-Link Generierung - Pruefe JWT-Validierung **Hinweis:** Fuer vollstaendige Tests muss das Unity WebGL Build laufen und mit dem Backend verbunden sein.`, tips: [ 'Matrix laeuft auf Port 8008', 'Jitsi laeuft auf Port 8443', 'Beide Services muessen in Docker laufen' ] }, 'summary': { title: 'Zusammenfassung & Naechste Schritte', content: `Du hast gelernt: ✓ Vier Multiplayer-Modi (Solo, Co-Op, Challenge, Klasse) ✓ Matrix fuer Chat und Game Events ✓ Jitsi fuer Video-Kommunikation ✓ Go Backend Services ✓ Unity WebGL Integration **Naechste Schritte:** 1. Backend-Services starten (docker-compose up) 2. Unity WebGL Build erstellen 3. Multiplayer im Admin Panel testen 4. Phase 9: Mobile App Delivery`, tips: [ 'Dokumentation in docs/breakpilot-drive/multiplayer.md', 'Tests in consent-service/*_test.go', 'Unity Tests ueber Test Runner' ] }, } // ======================================== // Components // ======================================== function WizardStepper({ steps, currentStep, onStepClick }: { steps: StepInfo[] currentStep: WizardStep onStepClick: (step: WizardStep) => void }) { const currentIndex = steps.findIndex(s => s.id === currentStep) return (
{steps.map((step, index) => { const isActive = step.id === currentStep const isCompleted = index < currentIndex const isClickable = index <= currentIndex + 1 return ( ) })}
) } function EducationCard({ title, content, tips }: { title: string; content: string; tips: string[] }) { return (

{title}

{content.split('\n\n').map((paragraph, i) => (

{paragraph.split('**').map((part, j) => j % 2 === 1 ? {part} : part )}

))}

Tipps:

    {tips.map((tip, i) => (
  • {tip}
  • ))}
) } function GameModeDemo() { const modes = [ { name: 'Solo', icon: '🎮', players: '1', features: ['Einzelspieler', 'Offline moeglich', 'Eigenes Tempo'] }, { name: 'Co-Op', icon: '🤝', players: '2-4', features: ['Team-Chat', 'Gemeinsame Strecke', 'Video optional'] }, { name: 'Challenge', icon: '⚔️', players: '2', features: ['1v1 Wettbewerb', 'Live-Score', 'Video empfohlen'] }, { name: 'Klassenrennen', icon: '🏁', players: '∞', features: ['Alle gegen alle', 'Lehrer-Moderation', 'Leaderboard'] }, ] return (
{modes.map((mode) => (
{mode.icon}

{mode.name}

{mode.players} Spieler

    {mode.features.map((feature, i) => (
  • {feature}
  • ))}
))}
) } function ServiceStatusDemo() { const [matrixStatus, setMatrixStatus] = useState<'idle' | 'checking' | 'online' | 'offline'>('idle') const [jitsiStatus, setJitsiStatus] = useState<'idle' | 'checking' | 'online' | 'offline'>('idle') const checkMatrix = async () => { setMatrixStatus('checking') try { // In production, this would check the actual Matrix server await new Promise(resolve => setTimeout(resolve, 1000)) setMatrixStatus('online') // Mock - assume online } catch { setMatrixStatus('offline') } } const checkJitsi = async () => { setJitsiStatus('checking') try { await new Promise(resolve => setTimeout(resolve, 1000)) setJitsiStatus('online') // Mock } catch { setJitsiStatus('offline') } } return (

Service-Status pruefen:

💬 Matrix Synapse
{matrixStatus === 'online' ? 'Online' : matrixStatus === 'offline' ? 'Offline' : matrixStatus === 'checking' ? 'Pruefe...' : 'Unbekannt'}

Port 8008

📹 Jitsi Meet
{jitsiStatus === 'online' ? 'Online' : jitsiStatus === 'offline' ? 'Offline' : jitsiStatus === 'checking' ? 'Pruefe...' : 'Unbekannt'}

Port 8443

) } function CodePreview({ title, code, language }: { title: string; code: string; language: string }) { return (
{title} {language}
        {code}
      
) } // ======================================== // Main Component // ======================================== export default function MultiplayerWizardPage() { const [currentStep, setCurrentStep] = useState('welcome') const currentStepIndex = STEPS.findIndex(s => s.id === currentStep) const education = EDUCATION_CONTENT[currentStep] const goToNext = () => { const nextIndex = currentStepIndex + 1 if (nextIndex < STEPS.length) { setCurrentStep(STEPS[nextIndex].id) } } const goToPrevious = () => { const prevIndex = currentStepIndex - 1 if (prevIndex >= 0) { setCurrentStep(STEPS[prevIndex].id) } } return ( {/* Back Link */}
Zurueck zum Game Dashboard
{/* Stepper */}
{/* Content */}
{/* Main Content */}
{/* Step-specific content */} {currentStep === 'game-modes' && } {currentStep === 'demo' && } {currentStep === 'matrix-chat' && ( )} {currentStep === 'jitsi-video' && ( )} {currentStep === 'unity-integration' && ( onSuccess, Action onError ) { localPlayer = new Player { id = Guid.NewGuid().ToString(), displayName = displayName, isHost = true, isReady = false }; state = MultiplayerState.Connecting; StartCoroutine(CreateSessionCoroutine( mode, onSuccess, onError)); }`} /> )} {/* Navigation */}
{/* Sidebar */}
{/* Progress */}

Fortschritt

Schritt {currentStepIndex + 1} von {STEPS.length} {Math.round(((currentStepIndex + 1) / STEPS.length) * 100)}%
{/* Architecture Overview */}

Architektur

Unity WebGL
↓ JS Bridge
Matrix + Jitsi
↓ WebSocket/API
Go Backend
{/* Quick Links */}

Wichtige Dateien

  • Go: consent-service/.../matrix/game_rooms.go
  • Go: consent-service/.../jitsi/game_meetings.go
  • C#: Assets/Scripts/Network/MultiplayerManager.cs
  • JS: Assets/Plugins/WebGL/MultiplayerPlugin.jslib
) }