Skip to content

Latest commit

 

History

History
99 lines (72 loc) · 25.5 KB

File metadata and controls

99 lines (72 loc) · 25.5 KB

Architecture Review – Multiplayer & Netcode

Version: 0.1.1 | Status: Entwurf | Verantwortungsbereich: Unabhängiger Reviewer (Multiplayer & Netcode) | Sprint: 4

Zweck

Adversariale Prüfung der Multiplayer-/Netcode-Architektur (Lockstep über Command-Relay, D-033/D-038) auf Protokoll-Löcher, Desync-Forensik-Lücken, Reconnect-/Vertrauensschwachstellen, Maphack-Haltung, Fixed-Point-Migrationsrisiko, Server-Kosten-/Validierungsmodell und Quantum-Fallback-Kriterien. Jeder Befund ist mit Beleg und eigener Begründung versehen; Bestätigen ohne Befund war nicht das Ziel.

Abhängigkeiten

Geprüfte Dokumente

Befunde

ID Schwere Befund (Kurz) Beleg Empfohlene Maßnahme
F-01 KRITISCH Relay ohne eigene Sim hat keinen Trust-Anchor: Match-Ergebnis, Snapshot-Integrität und Desync-Schuld sind serverseitig nicht verifizierbar – 1v1-Ergebniskonflikt unlösbar, Client-Upload-Snapshot ist Manipulationsvektor, Kollusion möglich Networking.md §1.1 (Z. 45, 48), §8 (Z. 153); Replication.md §3.1 (Z. 97), §2.2 Post-Match-Re-Sim des serverseitigen Command-Logs (SimRunner-Instanz, nicht echtzeitkritisch) als Ergebnis-Schiedsrichter und Desync-Arbiter festlegen; Reconnect-Snapshot-Hash zusätzlich gegen die Hash-Historie des reconnectenden Clients selbst prüfen (vor Disconnect gemeldet, fälschungssicher); Kostenmodell um diese Re-Sim-CPU ergänzen
F-02 HOCH Stall-Semantik intern widersprüchlich: „Server schließt Fenster bei seiner Uhr, fehlende Spieler = Leertick" vs. „Match wartet bis zu 5 Ticks" – beides in §2.3; zudem verweist die „Disconnect-Schwelle" auf §5, der keine Schwelle enthält Networking.md §2.3 (Z. 101), §5 (Z. 123–136) Eine Semantik festlegen (Empfehlung: Server taket strikt, verspätete Commands verworfen/verschoben, kein globales Warten; Stall-Zähler pro Slot mit quantifizierter Schwelle, z. B. >20 % Leerticks über 60 s → Disconnect-Ereignis); §5 um die Schwelle ergänzen
F-03 HOCH Desync-Arbitration im 1v1 unmöglich: „Minderheit abweichend" existiert bei 2 Clients nicht; FirstMismatchTick ist clientseitig nicht bestimmbar, weil der Client die Mehrheits-Hashes nicht kennt und der Server nur alle 10 Ticks Hashes sieht Replication.md §2.2 (Z. 66), §2.3 (Z. 79); Networking.md §1.1 Desync-Reaktion für den 2-Client-Fall explizit definieren (kein Schuldspruch möglich → beide Reports, Schiedsspruch per serverseitiger Re-Sim aus F-01; bis dahin Match als ungültig/Remis); FirstMismatchTick aus Server-Sicht neu definieren (erstes abweichendes 10-Tick-Intervall) oder Mehrheits-Hash-Verlauf an Clients zurückspiegeln
F-04 HOCH Fixed-Point-Migration Beta wird als „nur Transport + Mathe-Disziplin" verharmlost: ORCA (D-034, ab Alpha in Float gebaut) und Flow-Field-Steering sind geometrische Float-Algorithmen ohne belegten Fixed-Point-Pfad; Transzendentale (Heading sin/cos, sqrt) unadressiert; float-Direktfelder in GameState.md umgehen die SimVec-Abstraktion; keine Bibliothekswahl; alle Golden-Master-Fixtures müssen neu aufgezeichnet werden Replication.md §6 (Z. 147); GameState.md Z. 24, 77, 84–88, 187; DecisionLog D-033/D-034, Offene Punkte (Z. 403) Migrationsinventar jetzt erstellen (alle float-Felder, alle Mathe-Call-Sites inkl. ORCA/Steering); Regel „keine nackten floats im State – nur SimVec/SimFixed-Typen" sofort in GameState.md durchsetzen; Phase-0-Spike explizit um Steering-Mathe (ORCA-Kern) erweitern; Fixture-Neuaufzeichnung als eigenen Beta-Arbeitspaket-Posten schätzen
F-05 HOCH Quantum-Fallback ist faktisch ein Rewrite, kein Fallback: Networking.md §3 behauptet, der Sim-Kern bleibe erhalten („ohne den Sim-Kern wegzuwerfen"), Research §6 sagt das Gegenteil (Gameplay-Code in Quantum-DSL/ECS); die drei Trigger-Kriterien sind nicht messbar („vertretbarer Aufwand", Schätzmethode für 1,5×-Budget fehlt, „ein Sprint" ohne Längendefinition); keine Entscheidungs-Deadline Networking.md §3 (Z. 106–112); research/Multiplayer_Simulation.md §6 (Z. 87) Fallback ehrlich als Rewrite-Szenario mit vollem Aufwand (Sim-Kern-Portierung, SimRunner-Ersatz, Fixture-Verlust) beziffern; Kriterien operationalisieren (Phase-0-Spike-Kriterien quantifizieren, z. B. „Hash-Divergenz nach X Fixes nicht beseitigbar"); harte Deadline festlegen (Fallback-Entscheidung spätestens Alpha-Abschluss, danach kein Wechsel mehr)
F-06 HOCH Ausführungsort der Übernahme-KI nach D-038 undefiniert: Läuft sie auf einem anderen Spieler-Client, ist sie ein Single Point of Failure (dessen Disconnect = Doppelausfall) und erzeugt Last bei einem Mitspieler; die sauberste Option – dieselbe deterministische KI redundanzfrei auf allen Clients als Teil der Sim – wird nirgends bewertet Networking.md §5 (Z. 128), §4.3 (Z. 120, offener Punkt Z. 158); DecisionLog D-038 Vor Beta entscheiden: (a) Übernahme-KI als deterministisches Sim-System auf allen Clients (kein Netzpfad, kein SPOF – bevorzugt prüfen, erfordert deterministische KI) oder (b) feste Zuteilung mit Failover-Regel; Entscheidung in DecisionLog (D-038-Ergänzung) dokumentieren
F-07 HOCH Keine Client↔Server-Taktsynchronisation spezifiziert: Der Client muss wissen, wann der Server das Fenster für T+2 schließt (Clock-Offset + RTT-Schätzung), und braucht eine Drift-/Speed-Korrektur über 20–35-min-Matches; nichts davon steht im Protokoll Networking.md §2.2 (Z. 67–95), §2.3 (Z. 100–102) Protokoll um Server-Zeit im Handshake/TickBatch (Server-Tick + Server-Timestamp), RTT-/Offset-Schätzung und clientseitige Catch-up-/Slowdown-Regel (±x % Sim-Speed innerhalb eines Korridors) ergänzen; als Pflicht-Abschnitt vor Implementierung
F-08 MITTEL Pause-Vote-Widerspruch: MultiplayerModes.md §3.3 verspricht PvP-Pausen (Vote, 3 × 60 s pro Spieler); Networking.md §5/D-038 verwarf Pause-Vote explizit als DoS-Vektor, und das Protokoll hat keinen Pause-PacketType – ein zugesagtes Feature, das die Architektur nicht liefert gamedesign/MultiplayerModes.md §3.3 (Z. 74); Networking.md §5 (Z. 132), §2.2 (Z. 71–82) Konflikt wie D-038-Vorgehen formal auflösen: entweder PvP-Pause aus GDD streichen oder als begründete Ausnahme (konsentierte Pause ≠ Disconnect-Pause) mit Protokoll-Support (PauseRequest/PauseVote, Tick-eingebettet) spezifizieren; DecisionLog-Eintrag
F-09 MITTEL Ghosting durch besiegte Spieler ungeregelt: Das Observer-Delay (60–120 s) ist als „einzige Informationsbarriere" deklariert, gilt aber nur für Observer-Slots; ein in 2v2/FFA ausgeschiedener Spieler, der das Match weiter verfolgt (Vollsicht nach Niederlage oder Reconnect-freier Zustand), kann seinen Mitspieler live informieren – klassischer Ghosting-Vektor, nirgends adressiert Replication.md §4 (Z. 121); gamedesign/MultiplayerModes.md §6 (Z. 150–157); GameState.md PlayerStatus (Z. 106) Regel festlegen: besiegte Spieler erhalten entweder nur Team-Sicht (Status quo ante) oder werden automatisch in den verzögerten Observer-Feed überführt; in Networking.md §4/§8 und MultiplayerModes.md §6 nachziehen
F-10 MITTEL Handshake-/Auth-Lücken: Das Resume-Token wird in Replication.md §3.2 referenziert, ist aber im Protokoll nicht definiert; keine Spieler-Identität/Authentifizierung im Handshake (SessionId allein ist kein Schutz); HelloAck ohne Größen-/Rate-Disziplin ist UDP-Amplification-Vektor; Integrität/Verschlüsselung (DTLS vs. HMAC) komplett offen – ohne sie sind Hash-Meldungen und Resume-Token trivial fälschbar Networking.md §2.2 (Z. 71–89), Offene Punkte (Z. 162); Replication.md §3.2 (Z. 99) Handshake-Spezifikation vor Beta-Extern-Tests: serverseitiges Session-/Resume-Token (opak, rotierend), Hello-Antwort ≤ Anfrage-Größe + Rate-Limit pro IP, verbindliche Krypto-Entscheidung (Empfehlung: DTLS 1.3 oder zumindest HMAC-Tagging aller Kontrollpakete) mit Datum versehen
F-11 MITTEL Mid-Match-Änderung des adaptiven Input-Delays ist weder im Command-Log noch im Replay abbildbar: Networking.md nennt das Delay zugleich „Teil des Initialzustands" und „sitzungsweit" änderbar – beides zusammen ist inkonsistent; ohne Meta-Eintrag im Strom sind Replays und Desync-Forensik bei Delay-Wechsel nicht reproduzierbar Networking.md §2.3 (Z. 102); Serialization.md Command-Log-Format (Z. 82–104) Meta-Record-Typ im Command-Log definieren (SetInputDelay ab Tick T, server-signiert); Begriff „sitzungsweit" präzisieren (ab Tick X, im Strom protokolliert); ReplayHeader/CommandRecord entsprechend erweitern
F-12 MITTEL Keine Regel für deterministische Behandlung illegaler Commands: Der Server validiert nur Format/Slot/Fenster/Rate – die fachliche Legalität (z. B. unbezahlbares Gebäude, ungültiges Tile) kann er ohne eigene Sim nicht prüfen; wie die Sim wohlgeformte, aber illegale Commands behandelt (ignorieren? teilweise ausführen?), ist nirgends definiert – jede Abweichung der Toleranz zwischen Clients ist eine Desync-Quelle Networking.md §1.1 (Z. 42); Replication.md §1 (Z. 32–52); GameState.md (keine Reject-Regel) In GameState.md/Replication.md eine kanonische Regel festlegen: „Jeder Command, dessen Vorbedingungen bei Ausführung nicht erfüllt sind, wird deterministisch verworfen (No-op, kein Fehlerpfad)"; Unit-Test-Pflicht pro Command-Art um den Illegal-Fall erweitern (Testing.md Ebene 1 deckt „Validierung/Ablehnung" bereits ab – explizit auf Netz- illegale Commands ausdehnen)
F-13 MITTEL Maphack-Detection ohne Ahndung: Die Akzeptanzbegründung (D-033, SC2-Präzedenz) ist dokumentiert, aber „per Hash-Validierung + Replay nachweisbar" ist zahnlos, solange kein Account-, Report- oder Sanktionspfad existiert (Backend explizit „orthogonal/offen"); der Ranked-Re-Eval-Trigger ist unkonkret (kein Zeitpunkt, keine Metrik, kein Owner); das Reputationsrisiko für Beta-PvP eines Premium-RTS (Maphacks ab Tag 1 öffentlich sichtbar) wird nicht thematisiert DecisionLog D-033 (Z. 317); Networking.md §8 (Z. 153); research/Multiplayer_Simulation.md §5, Offene Punkte (Z. 125–126); gamedesign/MultiplayerModes.md §3.7 (Z. 117–122) Re-Eval-Pfad konkretisieren: Owner + Zeitpunkt (z. B. „vor erstem öffentlichem PvP-Test") + Kriterien (Cheating-Report-Rate, Community-Signale); minimalen Ahndungspfad definieren (Match-Invalidate + Replay-Review-Prozess, auch ohne Account-System); Beta-PvP-Kommunikationsrisiko im Risiko-Register ergänzen
F-14 MITTEL Transport-Resilienz-Tests fehlen: Testing.md deckt Desync-Detektion ab, aber keine Netzwerk-Emulation (Paketverlust, Jitter, RTT-Stufen), keine Stall-/Leertick-Pfade, keinen Reconnect-End-to-End-Test, keine 1v1-Desync-Arbitration – genau die Pfade, die F-02/F-03/F-07 betreffen, bleiben ungetestet bis zur Beta Testing.md §Desync-Test-Strategie (Z. 108–113), CI-Tabelle (Z. 135–143) Testplan um eine Transport-Simulations-Schicht am IRelayClient-Interface ergänzen (konfigurierbarer Loss/Jitter/Delay gegen den LocalRelay – ab MVP machbar, da Transport abstrahiert ist); Reconnect-Test (Disconnect → Snapshot → Fast-Forward → Hash-Match) als Golden-Master-Szenario definieren
F-15 NIEDRIG PacketHeader enthält AckBits (Bitmap der letzten 16 Sequenzen), aber kein Basis-Ack-Feld (höchste lückenlos empfangene Sequenz), auf das sich die Bitmap bezieht – ohne Referenz ist die Bitmap wertlos Networking.md §2.2 (Z. 84–89) Header um ushort Ack (oder uint) ergänzen; Bitmap-Breite gegen Paketrate plausibilisieren (10–20 Pakete/s → 16 Bit ≈ 1 s Abdeckung, knapp bei RTT 150 ms + Retransmit-Fenster)
F-16 NIEDRIG Hash-Breiten-Inkonsistenz über drei Dokumente: Replication.md §2.1 spezifiziert xxHash64/ulong, Serialization.md §Skizze xxHash32/uint ComputeStateHash, Testing.md einen abstrakten StateHash – bei einer determinismuskritischen Größe ist Divergenz in den TDDs selbst ein Fehler Replication.md Z. 58, 80–83; Serialization.md Z. 54, 114; Testing.md Z. 50–54 Eine Breite verbindlich festlegen (Empfehlung: 64 bit – Kollisionsbudget bei ~10⁴–10⁵ Hashes/Match und Cross-Client-Vergleichen; 32 bit reicht knapp, bietet aber keinen Puffer bei langfristiger Replay-Datenbank); beide TDDs angleichen
F-17 NIEDRIG Grace-Timing inkonsistent: Protokoll deklariert Disconnect-Ereignis erst nach 30 s Stille, D-038-/GDD-Grace sind 60 s „ab Disconnect-Ereignis" – effektiv 90 s Reconnect-Fenster ab letztem Paket, nicht die kommunizierten 60 s; zusätzlich skaliert der Observer-Mid-Match-Join aus dem „Tick-0-Batch" nicht (20 min Nachsimulation ≈ 96+ s Join-Zeit) Networking.md §2.1 (Z. 63), §5 (Z. 127); MultiplayerModes.md §3.2 (Z. 69); Replication.md §4 (Z. 120) Wahl treffen und dokumentieren: Grace ab letztem Paket oder ab Disconnect-Ereignis (Empfehlung: 60 s ab letztem Paket = 30 s Detection inklusive); Observer-Init auf „neuester Snapshot ≤ Delay-Grenze" korrigieren
F-18 NIEDRIG Kleine Konsistenzfehler: GameState.md PlayerStatus verweist für KI-Übernahme auf D-033 statt D-038; MatchState.ElapsedSeconds ist ein redundanter Float (Tick/10) im hash-relevanten State; RadarPings-Verfall „~4 s" ist nicht tickbasiert spezifiziert; HashRingTail ist als string[] statt ulong[] typisiert GameState.md Z. 106, 187, 160; Replication.md Z. 83 D-038-Referenz korrigieren; ElapsedSeconds aus dem State entfernen oder als uint-Ticks ableiten (View-seitig); Radar-Verfall in Ticks angeben; HashRingTail-Typ zu ulong[] ändern

Begründungen und Gegenrechnungen

F-01 (KRITISCH). Die Architektur verspricht „Server autoritativ über Befehle, Takt und Ergebnis" (Networking.md §1.1), der Server simuliert aber aus Kostengründen nicht (Z. 48). Damit reduziert sich die „Ergebnis-Bestätigung" auf den Vergleich clientseitig gemeldeter Ergebnis-Hashes. Drei konkrete Bruchstellen: (a) 1v1-Ergebniskonflikt – bei zwei Clients mit divergentem Ergebnis-Hash (Desync, Bug oder Betrug) hat der Server kein Mehrheitsvotum und keine Wahrheit; das Dokument spezifiziert keinen Tie-Break. (b) Reconnect-Snapshot – die Snapshot-Quelle ist „round-robin über Clients" (Replication.md §3.1); im 1v1 ist die Quelle zwangsläufig der Gegner. „Hash-validiert" hilft nur, wenn der Validierungs-Hash von einer unabhängigen Partei stammt – ein manipulierter Client liefert Snapshot und passenden Hash aus einer Hand. Die einzig fälschungssichere Referenz ist die Hash-Historie, die der reconnectende Client selbst vor seinem Disconnect gemeldet hat; diese Prüfung ist nirgends vorgesehen. (c) Kollusion – in 2v2/FFA kann eine Mehrheit kolludierender Clients einen ehrlichen Client als „abweichend" brandmarken (F-03 verschärft das). Die verfügbare, kostengünstige Lösung liegt bereits im Haus: Der Server besitzt das vollständige Command-Log; eine post-match bzw. on-demand Re-Simulation (Nova.SimRunner, D-036) liefert Ergebnis-Wahrheit und Desync-Schuldspruch ohne Echtzeit-Sim im Relay-Pfad. Kosten: eine Sim-Instanz pro strittigem Match (Sekunden CPU), nicht pro Match – das Kostenargument „kein Gameplay-State" bleibt im Hot-Path intakt.

F-02 (HOCH). §2.3 Satz 1: „Der Server schließt das Fenster für T+2, wenn seine Uhr T erreicht, und broadcastet das Batch (fehlende Spieler = Leertick)." Satz 2: „Spieler, deren Commands verspätet eintreffen, erzeugen Stall: Das Match wartet bis zu MaxStallTicks." Wer wartet? Wartet der Server mit dem Broadcast, stallen alle Clients global; schließt er bei seiner Uhr, gibt es keinen Stall. Beide Verhaltensmodelle sind genreüblich (SC2 wartet kurz; AoE taket strikt), aber die Architektur muss eines wählen – die Implementierer würden sonst unterschiedliche Varianten bauen. Zusätzlich: „der Vorfall zählt in die Disconnect-Schwelle (§5)" – §5 enthält keine Schwelle, nur das 30-s-Timeout. Bei 6 Clients potenziert sich der Schaden: Ein jitternder Spieler erzeugt im „Warte"-Modell bis zu 500 ms Global-Stall pro Vorkommen, ohne Frequenzdeckel.

F-03 (HOCH). §2.2 unterscheidet „alle gleich" und „Minderheit abweichend" – der 2-Client-Fall hat keine Minderheit. PvP-1v1 ist aber der Beta-Referenzmodus. Zudem ist FirstMismatchTick im Desync-Report als clientseitiger Wert deklariert; der Client kennt jedoch nur seine eigenen Hashes – er kann den ersten abweichenden Tick nicht kennen, weil ihm der Referenz-Hash-Verlauf fehlt (der Server sieht ihn zudem nur alle 10 Ticks). Die behauptete „tickgenaue Eingrenzung" (§2.2.3) ist damit nur nachträglich per SimRunner-Bisektion möglich – was ok ist, aber dann darf das Report-Feld keine tickgenaue Client-Angabe versprechen.

F-04 (HOCH). Gegenrechnung zum Wort „nur" in Replication.md §6: Der Migrationsumfang umfasst (a) alle float-Direktfelder im State – GameState.md deklariert Heading, ReloadTimer, FuseTime, OverharvestMeterSec, SpreadTimerSec, ResearchProgress, ElapsedSeconds als float (Z. 77, 84–88, 123, 174, 187) und unterläuft damit die eigene SimVec-Abstraktion (Z. 24); (b) die Mathe-Call-Sites – Distanz (sqrt), Ausrichtung (sin/cos, atan2) brauchen deterministische Fixed-Point-Ersatzfunktionen; (c) ORCA (D-034, ab Alpha): RVO2-ARTige Algorithmen sind float-geometrisch (Halbebenen-Schnitte, Skalarprodukte); ein bitgenauer Fixed-Point-Port ist ein bekanntes Eigenprojekt, kein Typ-Tausch; (d) sämtliche Golden-Master-Fixtures (Testing.md Ebene 3) und SimRunner-Balancing-Baselines werden ungültig; (e) die Bibliothekswahl ist offen (DecisionLog, Offene Punkte). Risiko-Eskalation: Wenn der Phase-0-Spike nur den Rechenkern (Add/Mul/Div), nicht aber Steering/Pathfinding-Mathe validiert, fällt diese Bombe in der Beta – genau dort, wo der Zeitplan keinen Puffer hat. Empfehlung: Spike-Scope erweitern.

F-05 (HOCH). Kriterium 1 („nicht mit vertretbarem Aufwand behebbar") definiert weder Aufwand noch Messmethode. Kriterium 2 („> 1,5× der Quantum-Integration") verlangt zwei Schätzungen ohne Baseline – nach welcher Methode, von wem, wann? Kriterium 3 („mehr als einen Sprint") ohne Sprint-Längendefinition. Schwerwiegender: Networking.md §3 behauptet, die 5 Regeln hielten „den Quantum-Umstieg möglich, ohne den Sim-Kern wegzuwerfen" – Research §6 sagt explizit „Gameplay-Code wird in Quantums DSL/ECS-Modell geschrieben". Ein Quantum-Wechsel invalidiert Nova.Simulation, Nova.SimRunner (D-036), die Burst/Managed-Doppelstruktur (D-037) und alle Fixtures. Das ist ein Rewrite mit Sunk-Cost-Verlust, und ohne Deadline („spätestens Alpha-Ende") würde diese Entscheidung in der Beta-Phase fallen – dem schlechtestmöglichen Zeitpunkt.

F-06 (HOCH). D-038 ist als „final" deklariert, spezifiziert aber nicht, wo die Übernahme-KI läuft. Optionen: (a) auf dem Server – widerspricht der Kostenfestlegung „Server simuliert nicht" und Networking.md §4.3 („KI-Slots laufen auf dem Server? Nein"); (b) auf einem Mitspieler-Client – SPOF (dessen Disconnect = Doppelausfall des Slots), ungleiche Last, und der offene Punkt §4.3 ist genau diese Frage ohne Antwort; (c) deterministische KI auf allen Clients als Teil der Sim (KI-Ausgabe ist dann kein Netz-Command-Strom, sondern Sim-Ergebnis) – die eleganteste Option, erfordert aber eine voll deterministische KI, was mit der geplanten KI-Architektur (Bedrohungskarten, Plan-Tasks) vereinbar sein muss und nirgends geprüft wird. Solange das offen ist, ist D-038 nicht implementierbar.

F-07 (HOCH). Damit ein Client seine Commands rechtzeitig vor Fensterschluss sendet, muss er die Server-Uhr kennen (Offset + RTT). Nichts im Handshake transportiert Server-Zeit; kein Paket enthält einen Server-Timestamp. Über 20–35 min driftet eine freilaufende Client-Uhr (Quarz-Toleranzen ~20–100 ppm → 2,5–12 s über 35 min) aus dem Sendefenster – ohne Speed-Korrektur (±x % Sim-Tempo innerhalb eines Korridors, wie in jedem Lockstep-System üblich) wird der Client dauerhaft stall-gefährdet. Das ist Standard-Ingenieurwissen des gewählten Modells, muss aber im TDD stehen, sonst wird es vergessen.

F-09 (MITTEL). Das Observer-Delay schützt nur gegen externe Beobachter. Der gefährlichere Informationskanal im Team-Spiel ist der ausgeschiedene Mitspieler: Sichtet ein besiegter Spieler in 2v2 weiter live (unbeschränkte Vollsicht nach Niederlage ist ein naheliegendes UX-Default), kann er per externem Voice-Tool (D-029 verweist selbst auf externe Tools) gegnerische Bewegungen an seinen Teamkollegen melden – vollständig um die Delay-Barriere herum. SC2 löst das, indem Besiegte nur ihre bisherige Team-Sicht behalten. Keine der geprüften Dateien adressiert den Übergang „aktiver Spieler → besiegter Zuschauer".

F-13 (MITTEL). Zur Prüffrage „ist die Akzeptanz sauber begründet": Teilweise. Die Risiko-Akzeptanz selbst ist dokumentiert (D-033, SC2-Präzedenz, Re-Eval-Vorbehalt) und für MVP/Koop tragbar. Unsauber ist der Vollzug: „nachweisbar" setzt voraus, dass jemand die Nachweise auswertet und Konsequenzen zieht – weder ein Report-Eingang noch ein Review-Prozess noch eine Sanktion (Match-Invalidate, Sperre) existieren konzeptionell; das Backend, das Accounts tragen würde, ist explizit „orthogonal/offen" (Research, Offene Punkte). Und der Re-Eval-Pfad hat keinen Auslöser: „bis Ranked-Re-Evaluierung" ist zirkulär, weil Ranked selbst nur unter Vorbehalt steht (D-018) – es fehlt ein datum-/phasengebundener Checkpoint mit Owner und Bewertungskriterien, unabhängig von der Ranked-Frage (Beta-PvP ist bereits öffentlicher Wettbewerb).

Nicht-Befunde

  • Grundmodell-Wahl (Lockstep + Command-Relay statt State-Sync): trägt. Die Bandbreitenrechnung (Research §2.5: Commands skalieren mit APM, nicht Einheitenzahl; State-Sync ~200–300 kB/s/Client bei RTS-Gesamtsicht ohne wirksames Interest Management) ist konsistent in allen Dokumenten übernommen und der Verwerfungsgrund für NGO/Mirror/Fusion sauber belegt.
  • „MP wird Transport-Thema" über LocalRelay: Der MVP-Pfad (in-prozess Relay, identische Command-Pipeline, Input-Delay 2 ab Tag 1) ist die stärkste Struktur-Entscheidung des Pakets – Hash-Ringlog und Command-Log laufen ab MVP produktiv mit (Replication.md §6), Desync-Tooling entsteht nicht nachträglich.
  • Host-Migration-Analyse (§6): korrekt – im Relay-Modell existiert kein Host-State, Lobby-Host ist reine UI-Rolle; der GDD-Konflikt wurde beidseitig aufgelöst (D-038-Angleichung in VictoryConditions.md und MultiplayerModes.md §3.2 verifiziert).
  • NAT/Traversal: ausschließlich ausgehende UDP-Verbindungen, kein STUN/TURN, Port-443-Fallback benannt – für die Zielgruppe schlüssig und risikoarm.
  • D-038-Begründungsqualität: Die Alternativabwägung (Pause-Vote/Auto-Niederlage/KI-Übernahme) mit den verworfenen Optionen und Begründungen entspricht dem DecisionLog-Standard (≥3 Alternativen) und ist in GDD und TDD konsistent nachgezogen.
  • Observer-Puffer-Dimensionierung: 120 s × 6 Slots × <5 kB/s ≈ <4 MB Ringpuffer – Größenordnung stimmt.
  • Versionsbindung von Replays über ProtocolVersion: konsistent mit dem Determinismus-Modell (MultiplayerModes §6 ↔ Replication §5 ↔ Networking §2.2).
  • Offene-Punkte-Ehrlichkeit: Snapshot-Quelle, Hash-Funktion, Snapshot-Größenmessung und PvP-Desync-UX sind als offen deklariert statt weggeschwiegen – die Lücken sind bekannt; dieser Review eskaliert lediglich ihre Schwere (F-01, F-03).

Offene Punkte

  • F-01-Re-Sim-Schiedsrichter und F-06-KI-Ausführungsort erfordern DecisionLog-Ergänzungen (D-038-Folge-Entscheidung); Zuständigkeit und Terminierung klären.
  • F-04: Klären, ob der Phase-0-Spike-Scope um Steering-/ORCA-Mathe erweitert wird; Abstimmung mit dem Pathfinding-Review nötig.
  • F-08: GDD/TDD-Konflikt Pause-Vote – Entscheidungsbedarf analog D-038-Prozedere.
  • F-13: Re-Eval-Checkpoint (Owner, Zeitpunkt, Kriterien) in SprintPlanning/RiskAnalysis aufnehmen lassen.
  • Alle Befunde sind Entwurfsbefunde auf Dokumentebene; keine Implementierung existiert, daher keine Laufzeit-Verifikation möglich.
  • Index-Pflicht: Dieses Dokument legt das Verzeichnis docs/tech/review/ neu an – docs/README.md (Wiki-Index) muss gemäß Dokumentationsstandard nachgezogen werden (durch den Orchestrator; dieser Reviewer ändert nur dieses eine Dokument).

Nächste Schritte

  • Dieses Review als historischen Befund erhalten; Umsetzung und Priorität nur aus den nachgelagerten D-IDs und dem aktiven Recovery-Plan ableiten.

Änderungsverlauf

Version Datum Änderung Autor
0.1.0 2026-07-21 Erstprüfung (18 Befunde: 1 KRITISCH, 6 HOCH, 7 MITTEL, 4 NIEDRIG) Reviewer
0.1.1 2026-07-24 Pflichtabschnitte ergänzt und historischen Review gegenüber dem aktiven Recovery-Vertrag eingeordnet Technical Writer